blob: 9dd247694cb7a9df4d1381b221dcfaebeb04d763 [file] [log] [blame] [view]
Becky Zhou3e0b5d42019-06-25 21:13:231# Night Mode (aka Dark Theme) on Chrome Android
2
3Night mode (aka Dark Theme) enables users to experience UI surfaces, rendered as Android views, in dark colors. All existing or new user-facing features on Chrome Android should implement a night mode variant of the relevant UI surfaces on Milestone M75+.
4
5[TOC]
6
7## Implement night mode UI for new features
8###Colors
9Colors defined in **color_palette.xml** are independent of night mode (i.e. will not change in night mode), and are used for color references defined in **values/colors.xml** and **values-night/colors.xml**.
10
11Color references in values/colors.xml will be used for day mode (aka light theme), and also for night mode if the particular color reference is not defined in values-night/colors.xml. Color references in values-night/colors.xml will be used for night mode.
12
13**Example**
14In most cases, you should make use of the color references that are already defined in [//src/ui/android/java/res/values/color_palette.xml](https://cs.chromium.org/chromium/src/ui/android/java/res/values/color_palette.xml?q=color_palette.xml&sq=package:chromium&dr) and [//src/ui/android/java/res/values/colors.xml](https://cs.chromium.org/chromium/src/ui/android/java/res/values/colors.xml?sq=package:chromium&dr&g=0) for your new feature.
15
16However as an example, suppose you got approval from [email protected] to add a new background color.
17
18In [//src/ui/android/java/res/values/color_palette.xml](https://cs.chromium.org/chromium/src/ui/android/java/res/values/color_palette.xml?q=color_palette.xml&sq=package:chromium&dr), add
19```xml
20<color name="new_bg_color_light">some light background color</color>
21<color name="new_bg_color_dark">some dark background color</color>
22```
23
24In [//src/ui/android/java/res/values/colors.xml](https://cs.chromium.org/chromium/src/ui/android/java/res/values/colors.xml?sq=package:chromium&dr&g=0), add
25```xml
26<color name="new_bg_color">@color/new_bg_color_light</color>
27```
28
Theresa Wellingtone66c2442020-02-07 01:17:2629In [//src/ui/android/java/res/values-night/colors.xml](https://cs.chromium.org/chromium/src/ui/android/java/res/values-night/colors.xml), add
Becky Zhou3e0b5d42019-06-25 21:13:2330```xml
31<color name="new_bg_color">@color/new_bg_color_dark</color>
32```
33
34An example to use this color in XML:
35```xml
36<View
37 ...
38 android:background="new_bg_color" />
39```
40
41An example to use this color in Java:
42```java
43mView.setBackgroundResource(R.color.new_bg_color);
44mView.setBackgroundColor(
45 ApiCompatibilityUtils.getColor(mView.getResources(), R.color.new_bg_color));
46```
47
48Optionally, if the color is used exclusively for your feature, or if you want to easily update this color for your feature in the future, in the values/colors.xml that contains colors specifically for your feature, add
49```xml
50<color name="my_shiny_new_feature_bg_color">@color/new_bg_color</color>
51```
52
53If your feature needs colors that don't change based on day/night mode (e.g incognito mode UI), in the values/colors.xml that contains colors specifically for your feature, reference the colors defined in color_palette.xml. There is no need to define the color reference in values-night/colors.xml.
54```xml
55<!-- Dark background color for my shiny new feature regardless of day/night mode. -->
56<color name="my_shiny_new_feature_bg_color_dark">@color/new_bg_color_dark</color>
57```
58
59###Styles
60Colors used in styles can be either adaptcive or independent of night mode. When using existing or adding new styles, make sure the colors used in the styles fit your need.
61
62**Best practice of naming styles**
63
64* If the color adapts for night mode, avoid mentioning a specific color in the style name since it may not be accurate in night mode.
65```xml
66<!-- OK -->
67<style name="TextAppearance.Headline">
68 <!-- default_text_color is dark grey in day mode, and white in night mode. -->
69 <item name="android:textColor">@color/default_text_color</item>
70 ...
71</style>
72
73<!-- NOT OK -->
74<style name="TextAppearance.DarkGreyHeadline">
75 <!-- default_text_color is dark grey in day mode, and white in night mode. -->
76 <item name="android:textColor">@color/default_text_color</item>
77 ...
78</style>
79
80<!-- OK -->
81<style name="TextAppearance.ButtonText.Blue">
82 <!-- some_blue_color is dark blue in day mode, and light blue in night mode. -->
83 <item name="android:textColor">@color/some_blue_color</item>
84</style>
85```
86* If independent of night mode, mention a specific color or where it is generally used.
87```xml
88<!-- OK -->
89<style name="TextAppearance.Headline.White">
90 <item name="android:textColor">@android:color/white</item>
91 ...
92</style>
93
94<!-- OK -->
95<style name="TextAppearance.Body.Incognito">
96 <item name="android:textColor">@android:color/white</item>
97 ...
98</style>
99```
100
101###Themes
102If adding a new theme, make sure the parent (or any indirect ancestor) theme of the new theme is one of the AppCompat DayNight themes (prefixed with `Theme.AppCompat.DayNight`), or alternatively, define the same theme in values-night/ with the desired parent theme for night mode. See [dark theme](https://developer.android.com/preview/features/darktheme) in Android developer guide for more details.
103
104###Troubleshooting
105* Make sure `View` is inflated from `Activity` context instead of `Application` context
106 * `RemoteView` is an exception. See [RemoteViewsWithNightModeInflater.java](https://cs.chromium.org/chromium/src/chrome/android/java/src/org/chromium/chrome/browser/night_mode/RemoteViewsWithNightModeInflater.java?) for details.
107* Make sure color resources are accessed from `Activity` or `View` context instead of `Application` context
108* Check whether `Configuration.uiMode & UI_MODE_NIGHT_MASK` gives the correct UI night mode
109 * If uiMode is not correct, it could be a support library issue or an Android framework issue. You can contact [email protected] for help.
110
111## Test new features in night mode
112### Automatic Testing
Evan Stadea1937072019-12-17 22:05:59113Render tests are the recommended way to verify the appearance of night mode UI. If you are not familiar with render tests, please take a look at [render test instructions](/ui/android/javatests/src/org/chromium/ui/test/util/RENDER_TESTS.md) to learn about how to write a new render test and upload golden images.
Becky Zhou3e0b5d42019-06-25 21:13:23114
115**For tests using DummyUiActivity:**
116
117* Put all the render tests into a separate test suite
118* Use class parameter [`NightModeTestUtils.NightModeParams.class`](https://cs.chromium.org/chromium/src/chrome/android/javatests/src/org/chromium/chrome/browser/night_mode/NightModeTestUtils.java?type=cs&q=NightModeTestUtils.NightModeParams)
119* Pass in a boolean parameter that indicates night mode state in constructor
120* Set up night mode in constructor by calling [`NightModeTestUtils#setUpNightModeForDummyUiActivity()`](https://cs.chromium.org/chromium/src/chrome/android/javatests/src/org/chromium/chrome/browser/night_mode/NightModeTestUtils.java?type=cs&q=setUpNightModeForDummyUiActivity&sq=package:chromium) and [`RenderTestRule#setNightModeEnabled()`](https://cs.chromium.org/chromium/src/chrome/test/android/javatests/src/org/chromium/chrome/test/util/RenderTestRule.java?type=cs&q=setNightModeEnabled)
Evan Stade7cd46e442019-12-09 21:32:46121* During [`tearDownTest()`](https://cs.chromium.org/chromium/src/ui/android/javatests/src/org/chromium/ui/test/util/DummyUiActivityTestCase.java?type=cs&q=tearDownTest), reset night mode state by calling [`NightModeTestUtils#tearDownNightModeForDummyUiActivity()`](https://cs.chromium.org/chromium/src/chrome/android/javatests/src/org/chromium/chrome/browser/night_mode/NightModeTestUtils.java?type=cs&q=tearDownNightModeForDummyUiActivity)
Becky Zhou3e0b5d42019-06-25 21:13:23122
123See [this CL](https://chromium-review.googlesource.com/c/chromium/src/+/1613883) as an example
124
125**For tests using ChromeActivityTestRule:**
126
127* In the method annotated with `@BeforeClass`, initialize states by calling [`NightModeTestUtils.setUpNightModeBeforeChromeActivityLaunched()`](https://cs.chromium.org/chromium/src/chrome/android/javatests/src/org/chromium/chrome/browser/night_mode/NightModeTestUtils.java?type=cs&q=setUpNightModeBeforeChromeActivityLaunched)
128* Add method `setupNightMode()` with annotation `@ParameterAnnotations.UseMethodParameterBefore(NightModeTestUtils.NightModeParams.class)`
129* In method `setupNightMode()`, set up night mode state by calling [`NightModeTestUtils#setUpNightModeForChromeActivity()`](https://cs.chromium.org/chromium/src/chrome/android/javatests/src/org/chromium/chrome/browser/night_mode/NightModeTestUtils.java?type=cs&q=setUpNightModeForChromeActivity) and [`RenderTestRule#setNightModeEnabled()`](https://cs.chromium.org/chromium/src/chrome/test/android/javatests/src/org/chromium/chrome/test/util/RenderTestRule.java?type=cs&q=setNightModeEnabled)
130* In the method annotated with `@AfterClass`, reset night mode state by calling [`tearDownNightModeAfterChromeActivityDestroyed`](https://cs.chromium.org/chromium/src/chrome/android/javatests/src/org/chromium/chrome/browser/night_mode/NightModeTestUtils.java?type=cs&q=tearDownNightModeAfterChromeActivityDestroyed)
131
132See [this CL](https://chromium-review.googlesource.com/c/chromium/src/+/1656668) as an example
133
134###Manual Testing
135Different ways to turn on night mode:
136
137* Go to Chrome **Settings -> Themes** on Android L+
138* Turn on power save mode (aka **battery saver**) on Android L+
139* Go to **Android Settings -> Developer options -> Night mode** on Android P
140* Go to **Android Settings -> Display -> Theme** on Android Q
141
142Ways to turn on night mode on **custom tab**:
143
144* Turn on power save mode (aka **battery saver**) on Android P+
145* Go to **Android Settings -> Developer options -> Night mode** on Android P
146* Go to **Android Settings -> Display -> Theme** on Android Q
Peter Conn6eb0e1d2019-08-08 07:39:05147* [Set color scheme](https://cs.chromium.org/chromium/src/third_party/android_sdk/androidx_browser/browser/src/main/java/androidx/browser/customtabs/CustomTabsIntent.java?) to `COLOR_SCHEME_DARK` on creating a `CustomTabsIntent.Builder`
Becky Zhou3e0b5d42019-06-25 21:13:23148
149Some tips:
150
151* If building **chrome\_apk**, add `compress_resources = false` in gn args to disable Lemon compression. See [Issue 957286](https://crbug.com/957286) for details.
152* Night mode is only available on L+
153* Animation is turned off when in power save mode on Andoird L-O
154
155## Optional: Add independent night mode control to an Activity
156Most of the features will follow the app-wise night mode control, but some features might require introduction of an independent night mode control. For example, custom tab will not follow the app-wise night mode control, but instead, will respect the night mode settings from the host app. In such cases, you can
157
1581. Create your own implementation of [`NightModeStateProvider`](https://cs.chromium.org/chromium/src/chrome/android/java/src/org/chromium/chrome/browser/night_mode/NightModeStateProvider.java)
1592. Override [`ChromeBaseAppCompatActivity#createNightModeStateProvier()`](https://cs.chromium.org/chromium/src/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java?type=cs&q=createNightModeStateProvider)
1603. Use [`AppCompatDelegate#setLocalNightMode()`](https://developer.android.com/reference/android/support/v7/app/AppCompatDelegate.html#setLocalNightMode(int)) to update night mode in the `Configuration` of the `Activity`