Bug 1755316 - Add audio tests with simultaneous processes r=alwu
[gecko.git] / widget / android / nsLookAndFeel.cpp
blob9b6f57853393b4feb7ae6af0f3a69444af189292
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsStyleConsts.h"
7 #include "nsXULAppAPI.h"
8 #include "nsLookAndFeel.h"
9 #include "Theme.h"
10 #include "gfxFont.h"
11 #include "gfxFontConstants.h"
12 #include "mozilla/FontPropertyTypes.h"
13 #include "mozilla/gfx/2D.h"
14 #include "mozilla/Preferences.h"
15 #include "mozilla/StaticPrefs_widget.h"
16 #include "mozilla/java/GeckoAppShellWrappers.h"
17 #include "mozilla/java/GeckoRuntimeWrappers.h"
18 #include "mozilla/java/GeckoSystemStateListenerWrappers.h"
19 #include "ThemeColors.h"
21 using namespace mozilla;
22 using namespace mozilla::widget;
24 static const char16_t UNICODE_BULLET = 0x2022;
26 static void AccentColorPrefChanged(const char*, void*) {
27 LookAndFeel::NotifyChangedAllWindows(widget::ThemeChangeKind::Style);
30 nsLookAndFeel::nsLookAndFeel() {
31 Preferences::RegisterCallback(
32 AccentColorPrefChanged,
33 nsDependentCString(
34 StaticPrefs::GetPrefName_widget_non_native_theme_use_theme_accent()));
37 nsLookAndFeel::~nsLookAndFeel() {
38 Preferences::UnregisterCallback(
39 AccentColorPrefChanged,
40 nsDependentCString(
41 StaticPrefs::GetPrefName_widget_non_native_theme_use_theme_accent()));
44 nsresult nsLookAndFeel::GetSystemColors() {
45 if (!jni::IsAvailable()) {
46 return NS_ERROR_FAILURE;
49 auto arr = java::GeckoAppShell::GetSystemColors();
50 if (!arr) {
51 return NS_ERROR_FAILURE;
54 JNIEnv* const env = arr.Env();
55 uint32_t len = static_cast<uint32_t>(env->GetArrayLength(arr.Get()));
56 jint* elements = env->GetIntArrayElements(arr.Get(), 0);
58 uint32_t colorsCount = sizeof(AndroidSystemColors) / sizeof(nscolor);
59 if (len < colorsCount) colorsCount = len;
61 // Convert Android colors to nscolor by switching R and B in the ARGB 32 bit
62 // value
63 nscolor* colors = (nscolor*)&mSystemColors;
65 for (uint32_t i = 0; i < colorsCount; i++) {
66 uint32_t androidColor = static_cast<uint32_t>(elements[i]);
67 uint8_t r = (androidColor & 0x00ff0000) >> 16;
68 uint8_t b = (androidColor & 0x000000ff);
69 colors[i] = (androidColor & 0xff00ff00) | (b << 16) | r;
72 env->ReleaseIntArrayElements(arr.Get(), elements, 0);
74 return NS_OK;
77 void nsLookAndFeel::NativeInit() {
78 EnsureInitSystemColors();
79 EnsureInitShowPassword();
80 RecordTelemetry();
83 void nsLookAndFeel::RefreshImpl() {
84 mInitializedSystemColors = false;
85 mInitializedShowPassword = false;
86 nsXPLookAndFeel::RefreshImpl();
89 nsresult nsLookAndFeel::NativeGetColor(ColorID aID, ColorScheme aColorScheme,
90 nscolor& aColor) {
91 EnsureInitSystemColors();
92 if (!mInitializedSystemColors) {
93 // Failure to initialize colors is an error condition. Return black.
94 aColor = 0;
95 return NS_ERROR_FAILURE;
98 // Highlight/Highlighttext have native equivalents that we can map to (on
99 // Android) which should work fine, regardless of the color-scheme.
100 switch (aID) {
101 case ColorID::Highlight: {
102 // Matched to action_accent in java codebase. This works fine with both
103 // light and dark color scheme.
104 nscolor accent =
105 Color(ColorID::MozAccentColor, aColorScheme, UseStandins::No);
106 aColor =
107 NS_RGBA(NS_GET_R(accent), NS_GET_G(accent), NS_GET_B(accent), 78);
108 return NS_OK;
110 case ColorID::Highlighttext:
111 // Selection background is transparent enough that any foreground color
112 // will do.
113 aColor = NS_SAME_AS_FOREGROUND_COLOR;
114 return NS_OK;
115 default:
116 break;
119 if (aColorScheme == ColorScheme::Dark) {
120 if (auto darkColor = GenericDarkColor(aID)) {
121 aColor = *darkColor;
122 return NS_OK;
126 // XXX we'll want to use context.obtainStyledAttributes on the java side to
127 // get all of these; see TextView.java for a good example.
128 auto UseNativeAccent = [this] {
129 return mSystemColors.colorAccent &&
130 StaticPrefs::widget_non_native_theme_use_theme_accent();
133 switch (aID) {
134 // These colors don't seem to be used for anything anymore in Mozilla
135 // The CSS2 colors below are used.
136 case ColorID::MozMenubartext:
137 aColor = mSystemColors.colorForeground;
138 break;
140 case ColorID::ThemedScrollbarThumbInactive:
141 case ColorID::ThemedScrollbarThumb:
142 // We don't need to care about the Active and Hover colors because Android
143 // scrollbars can't be hovered (they always have pointer-events: none).
144 aColor = NS_RGBA(119, 119, 119, 102);
145 break;
147 case ColorID::IMESelectedRawTextBackground:
148 case ColorID::IMESelectedConvertedTextBackground:
149 aColor = mSystemColors.textColorHighlight;
150 break;
151 case ColorID::IMESelectedRawTextForeground:
152 case ColorID::IMESelectedConvertedTextForeground:
153 aColor = mSystemColors.textColorPrimaryInverse;
154 break;
155 case ColorID::IMERawInputBackground:
156 case ColorID::IMEConvertedTextBackground:
157 aColor = NS_TRANSPARENT;
158 break;
159 case ColorID::IMERawInputForeground:
160 case ColorID::IMEConvertedTextForeground:
161 case ColorID::IMERawInputUnderline:
162 case ColorID::IMEConvertedTextUnderline:
163 aColor = NS_SAME_AS_FOREGROUND_COLOR;
164 break;
165 case ColorID::IMESelectedRawTextUnderline:
166 case ColorID::IMESelectedConvertedTextUnderline:
167 aColor = NS_TRANSPARENT;
168 break;
169 case ColorID::SpellCheckerUnderline:
170 aColor = NS_RGB(0xff, 0x00, 0x00);
171 break;
173 // css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
174 case ColorID::Activeborder: // active window border
175 case ColorID::Appworkspace: // MDI background color
176 case ColorID::Activecaption: // active window caption background
177 case ColorID::Background: // desktop background
178 case ColorID::Inactiveborder: // inactive window border
179 case ColorID::Inactivecaption: // inactive window caption
180 case ColorID::Scrollbar: // scrollbar gray area
181 aColor = mSystemColors.colorBackground;
182 break;
183 case ColorID::Graytext: // disabled text in windows, menus, etc.
184 aColor = NS_RGB(0xb1, 0xa5, 0x98);
185 break;
186 // FIXME: -moz-cellhighlight should show some kind of unfocused state.
187 case ColorID::MozCellhighlight:
188 case ColorID::Selecteditem:
189 case ColorID::MozAccentColor:
190 aColor = UseNativeAccent() ? mSystemColors.colorAccent
191 : widget::sDefaultAccent.ToABGR();
192 break;
193 case ColorID::MozCellhighlighttext:
194 case ColorID::Selecteditemtext:
195 case ColorID::MozAccentColorForeground:
196 aColor = UseNativeAccent() ? ThemeColors::ComputeCustomAccentForeground(
197 mSystemColors.colorAccent)
198 : widget::sDefaultAccentForeground.ToABGR();
199 break;
200 case ColorID::Fieldtext:
201 aColor = NS_RGB(0x1a, 0x1a, 0x1a);
202 break;
203 case ColorID::Inactivecaptiontext:
204 // text in inactive window caption
205 aColor = mSystemColors.textColorTertiary;
206 break;
207 case ColorID::Infobackground:
208 aColor = NS_RGB(0xf5, 0xf5, 0xb5);
209 break;
210 case ColorID::Infotext:
211 case ColorID::Threeddarkshadow: // 3-D shadow outer edge color
212 case ColorID::MozButtondefault: // default button border color
213 aColor = NS_RGB(0x00, 0x00, 0x00);
214 break;
215 case ColorID::Menu:
216 aColor = NS_RGB(0xf7, 0xf5, 0xf3);
217 break;
219 case ColorID::Buttonface:
220 case ColorID::MozButtondisabledface:
221 case ColorID::Threedface:
222 case ColorID::Threedlightshadow:
223 case ColorID::MozDisabledfield:
224 aColor = NS_RGB(0xec, 0xe7, 0xe2);
225 break;
227 case ColorID::Buttonhighlight:
228 case ColorID::Field:
229 case ColorID::Threedhighlight:
230 case ColorID::MozCombobox:
231 case ColorID::MozEventreerow:
232 aColor = NS_RGB(0xff, 0xff, 0xff);
233 break;
235 case ColorID::Buttonshadow:
236 case ColorID::Threedshadow:
237 aColor = NS_RGB(0xae, 0xa1, 0x94);
238 break;
240 case ColorID::MozDialog:
241 case ColorID::Window:
242 case ColorID::Windowframe:
243 aColor = NS_RGB(0xef, 0xeb, 0xe7);
244 break;
245 case ColorID::Buttontext:
246 case ColorID::Captiontext:
247 case ColorID::Menutext:
248 case ColorID::MozButtonhovertext:
249 case ColorID::MozDialogtext:
250 case ColorID::MozComboboxtext:
251 case ColorID::Windowtext:
252 case ColorID::MozColheadertext:
253 case ColorID::MozColheaderhovertext:
254 aColor = NS_RGB(0x10, 0x10, 0x10);
255 break;
256 case ColorID::MozDragtargetzone:
257 aColor = mSystemColors.textColorHighlight;
258 break;
259 case ColorID::MozButtonhoverface:
260 case ColorID::MozButtonactiveface:
261 aColor = NS_RGB(0xf3, 0xf0, 0xed);
262 break;
263 case ColorID::MozMenuhover:
264 aColor = NS_RGB(0xee, 0xee, 0xee);
265 break;
266 case ColorID::MozMenubarhovertext:
267 case ColorID::MozMenuhovertext:
268 aColor = NS_RGB(0x77, 0x77, 0x77);
269 break;
270 case ColorID::MozOddtreerow:
271 aColor = NS_TRANSPARENT;
272 break;
273 case ColorID::MozNativehyperlinktext:
274 aColor = NS_RGB(0, 0, 0xee);
275 break;
276 default:
277 /* default color is BLACK */
278 aColor = 0;
279 return NS_ERROR_FAILURE;
282 return NS_OK;
285 nsresult nsLookAndFeel::NativeGetInt(IntID aID, int32_t& aResult) {
286 nsresult rv = NS_OK;
288 switch (aID) {
289 case IntID::ScrollButtonLeftMouseButtonAction:
290 aResult = 0;
291 break;
293 case IntID::ScrollButtonMiddleMouseButtonAction:
294 case IntID::ScrollButtonRightMouseButtonAction:
295 aResult = 3;
296 break;
298 case IntID::CaretBlinkTime:
299 aResult = 500;
300 break;
302 case IntID::CaretBlinkCount:
303 aResult = 10;
304 break;
306 case IntID::CaretWidth:
307 aResult = 1;
308 break;
310 case IntID::ShowCaretDuringSelection:
311 aResult = 0;
312 break;
314 case IntID::SelectTextfieldsOnKeyFocus:
315 // Select textfield content when focused by kbd
316 // used by EventStateManager::sTextfieldSelectModel
317 aResult = 1;
318 break;
320 case IntID::SubmenuDelay:
321 aResult = 200;
322 break;
324 case IntID::TooltipDelay:
325 aResult = 500;
326 break;
328 case IntID::MenusCanOverlapOSBar:
329 // we want XUL popups to be able to overlap the task bar.
330 aResult = 1;
331 break;
333 case IntID::ScrollArrowStyle:
334 aResult = eScrollArrowStyle_Single;
335 break;
337 case IntID::ScrollSliderStyle:
338 aResult = eScrollThumbStyle_Proportional;
339 break;
341 case IntID::UseOverlayScrollbars:
342 aResult = 1;
343 break;
345 case IntID::SpellCheckerUnderlineStyle:
346 aResult = NS_STYLE_TEXT_DECORATION_STYLE_WAVY;
347 break;
349 case IntID::ScrollbarButtonAutoRepeatBehavior:
350 aResult = 0;
351 break;
353 case IntID::ContextMenuOffsetVertical:
354 case IntID::ContextMenuOffsetHorizontal:
355 aResult = 2;
356 break;
358 case IntID::PrefersReducedMotion:
359 aResult = java::GeckoSystemStateListener::PrefersReducedMotion();
360 break;
362 case IntID::PrimaryPointerCapabilities:
363 aResult = java::GeckoAppShell::GetAllPointerCapabilities();
365 // We cannot assume what is primary device, so we use Blink's way for web
366 // compatibility (https://crbug.com/136119#c6). If having coarse
367 // capability in any devices, return it.
368 if (aResult & static_cast<int32_t>(PointerCapabilities::Coarse)) {
369 aResult = static_cast<int32_t>(PointerCapabilities::Coarse);
371 break;
373 case IntID::AllPointerCapabilities:
374 aResult = java::GeckoAppShell::GetAllPointerCapabilities();
375 break;
377 case IntID::SystemUsesDarkTheme: {
378 java::GeckoRuntime::LocalRef runtime = java::GeckoRuntime::GetInstance();
379 aResult = runtime && runtime->UsesDarkTheme();
380 break;
383 case IntID::DragThresholdX:
384 case IntID::DragThresholdY:
385 // Threshold where a tap becomes a drag, in 1/240" reference pixels.
386 aResult = 25;
387 break;
389 case IntID::TouchDeviceSupportPresent:
390 // Touch support is always enabled on android.
391 aResult = 1;
392 break;
394 default:
395 aResult = 0;
396 rv = NS_ERROR_FAILURE;
399 return rv;
402 nsresult nsLookAndFeel::NativeGetFloat(FloatID aID, float& aResult) {
403 nsresult rv = NS_OK;
405 switch (aID) {
406 case FloatID::IMEUnderlineRelativeSize:
407 aResult = 1.0f;
408 break;
410 case FloatID::SpellCheckerUnderlineRelativeSize:
411 aResult = 1.0f;
412 break;
414 default:
415 aResult = -1.0;
416 rv = NS_ERROR_FAILURE;
417 break;
419 return rv;
422 bool nsLookAndFeel::NativeGetFont(FontID aID, nsString& aFontName,
423 gfxFontStyle& aFontStyle) {
424 aFontName.AssignLiteral("Roboto");
425 aFontStyle.style = FontSlantStyle::Normal();
426 aFontStyle.weight = FontWeight::Normal();
427 aFontStyle.stretch = FontStretch::Normal();
428 aFontStyle.size = 9.0 * 96.0f / 72.0f;
429 aFontStyle.systemFont = true;
430 return true;
433 bool nsLookAndFeel::GetEchoPasswordImpl() {
434 EnsureInitShowPassword();
435 return mShowPassword;
438 uint32_t nsLookAndFeel::GetPasswordMaskDelayImpl() {
439 // This value is hard-coded in Android OS's PasswordTransformationMethod.java
440 return 1500;
443 char16_t nsLookAndFeel::GetPasswordCharacterImpl() {
444 // This value is hard-coded in Android OS's PasswordTransformationMethod.java
445 return UNICODE_BULLET;
448 void nsLookAndFeel::EnsureInitSystemColors() {
449 if (!mInitializedSystemColors) {
450 mInitializedSystemColors = NS_SUCCEEDED(GetSystemColors());
454 void nsLookAndFeel::EnsureInitShowPassword() {
455 if (!mInitializedShowPassword && jni::IsAvailable()) {
456 mShowPassword = java::GeckoAppShell::GetShowPasswordSetting();
457 mInitializedShowPassword = true;