1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/webui/settings/chromeos/device_section.h"
6
7 #include "ash/public/ash_interfaces.h"
8 #include "ash/public/cpp/ash_features.h"
9 #include "ash/public/cpp/night_light_controller.h"
10 #include "ash/public/cpp/stylus_utils.h"
11 #include "base/command_line.h"
12 #include "base/feature_list.h"
13 #include "base/metrics/histogram_functions.h"
14 #include "base/no_destructor.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "chrome/browser/chromeos/login/demo_mode/demo_session.h"
18 #include "chrome/browser/ui/ui_features.h"
19 #include "chrome/browser/ui/webui/settings/chromeos/device_display_handler.h"
20 #include "chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.h"
21 #include "chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.h"
22 #include "chrome/browser/ui/webui/settings/chromeos/device_power_handler.h"
23 #include "chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.h"
24 #include "chrome/browser/ui/webui/settings/chromeos/os_settings_features_util.h"
25 #include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h"
26 #include "chrome/browser/ui/webui/webui_util.h"
27 #include "chrome/common/chrome_features.h"
28 #include "chrome/common/url_constants.h"
29 #include "chrome/common/webui_url_constants.h"
30 #include "chrome/grit/generated_resources.h"
31 #include "chromeos/constants/chromeos_features.h"
32 #include "chromeos/constants/chromeos_switches.h"
33 #include "content/public/browser/web_ui.h"
34 #include "content/public/browser/web_ui_data_source.h"
35 #include "ui/base/l10n/l10n_util.h"
36 #include "ui/base/webui/web_ui_util.h"
37 #include "ui/chromeos/events/keyboard_layout_util.h"
38 #include "ui/display/display_features.h"
39 #include "ui/display/display_switches.h"
40 #include "ui/display/manager/touch_device_manager.h"
41 #include "ui/events/devices/device_data_manager.h"
42
43 namespace chromeos {
44 namespace settings {
45 namespace {
46
GetDeviceSearchConcepts()47 const std::vector<SearchConcept>& GetDeviceSearchConcepts() {
48 static const base::NoDestructor<std::vector<SearchConcept>> tags({
49 {IDS_OS_SETTINGS_TAG_KEYBOARD,
50 mojom::kKeyboardSubpagePath,
51 mojom::SearchResultIcon::kKeyboard,
52 mojom::SearchResultDefaultRank::kMedium,
53 mojom::SearchResultType::kSubpage,
54 {.subpage = mojom::Subpage::kKeyboard}},
55 {IDS_OS_SETTINGS_TAG_KEYBOARD_AUTO_REPEAT,
56 mojom::kKeyboardSubpagePath,
57 mojom::SearchResultIcon::kKeyboard,
58 mojom::SearchResultDefaultRank::kMedium,
59 mojom::SearchResultType::kSetting,
60 {.setting = mojom::Setting::kKeyboardAutoRepeat},
61 {IDS_OS_SETTINGS_TAG_KEYBOARD_AUTO_REPEAT_ALT1,
62 SearchConcept::kAltTagEnd}},
63 {IDS_OS_SETTINGS_TAG_POWER,
64 mojom::kPowerSubpagePath,
65 mojom::SearchResultIcon::kPower,
66 mojom::SearchResultDefaultRank::kMedium,
67 mojom::SearchResultType::kSubpage,
68 {.subpage = mojom::Subpage::kPower}},
69 {IDS_OS_SETTINGS_TAG_DISPLAY_SIZE,
70 mojom::kDisplaySubpagePath,
71 mojom::SearchResultIcon::kDisplay,
72 mojom::SearchResultDefaultRank::kMedium,
73 mojom::SearchResultType::kSetting,
74 {.setting = mojom::Setting::kDisplaySize},
75 {
76 IDS_OS_SETTINGS_TAG_DISPLAY_SIZE_ALT1,
77 IDS_OS_SETTINGS_TAG_DISPLAY_SIZE_ALT2,
78 IDS_OS_SETTINGS_TAG_DISPLAY_SIZE_ALT3,
79 IDS_OS_SETTINGS_TAG_DISPLAY_SIZE_ALT4,
80 IDS_OS_SETTINGS_TAG_DISPLAY_SIZE_ALT5,
81 }},
82 {IDS_OS_SETTINGS_TAG_STORAGE,
83 mojom::kStorageSubpagePath,
84 mojom::SearchResultIcon::kHardDrive,
85 mojom::SearchResultDefaultRank::kMedium,
86 mojom::SearchResultType::kSubpage,
87 {.subpage = mojom::Subpage::kStorage},
88 {IDS_OS_SETTINGS_TAG_STORAGE_ALT1, IDS_OS_SETTINGS_TAG_STORAGE_ALT2,
89 SearchConcept::kAltTagEnd}},
90 {IDS_OS_SETTINGS_TAG_DISPLAY_NIGHT_LIGHT,
91 mojom::kDisplaySubpagePath,
92 mojom::SearchResultIcon::kDisplay,
93 mojom::SearchResultDefaultRank::kLow,
94 mojom::SearchResultType::kSetting,
95 {.setting = mojom::Setting::kNightLight},
96 {IDS_OS_SETTINGS_TAG_DISPLAY_NIGHT_LIGHT_ALT1,
97 IDS_OS_SETTINGS_TAG_DISPLAY_NIGHT_LIGHT_ALT2,
98 SearchConcept::kAltTagEnd}},
99 {IDS_OS_SETTINGS_TAG_DISPLAY,
100 mojom::kDisplaySubpagePath,
101 mojom::SearchResultIcon::kDisplay,
102 mojom::SearchResultDefaultRank::kMedium,
103 mojom::SearchResultType::kSubpage,
104 {.subpage = mojom::Subpage::kDisplay},
105 {IDS_OS_SETTINGS_TAG_DISPLAY_ALT1, IDS_OS_SETTINGS_TAG_DISPLAY_ALT2,
106 SearchConcept::kAltTagEnd}},
107 {IDS_OS_SETTINGS_TAG_KEYBOARD_SHORTCUTS,
108 mojom::kKeyboardSubpagePath,
109 mojom::SearchResultIcon::kKeyboard,
110 mojom::SearchResultDefaultRank::kMedium,
111 mojom::SearchResultType::kSetting,
112 {.setting = mojom::Setting::kKeyboardShortcuts}},
113 {IDS_OS_SETTINGS_TAG_DEVICE,
114 mojom::kDeviceSectionPath,
115 mojom::SearchResultIcon::kLaptop,
116 mojom::SearchResultDefaultRank::kHigh,
117 mojom::SearchResultType::kSection,
118 {.section = mojom::Section::kDevice}},
119 {IDS_OS_SETTINGS_TAG_KEYBOARD_FUNCTION_KEYS,
120 mojom::kKeyboardSubpagePath,
121 mojom::SearchResultIcon::kKeyboard,
122 mojom::SearchResultDefaultRank::kMedium,
123 mojom::SearchResultType::kSetting,
124 {.setting = mojom::Setting::kKeyboardFunctionKeys}},
125 {IDS_OS_SETTINGS_TAG_POWER_IDLE_WHILE_CHARGING,
126 mojom::kPowerSubpagePath,
127 mojom::SearchResultIcon::kPower,
128 mojom::SearchResultDefaultRank::kMedium,
129 mojom::SearchResultType::kSetting,
130 {.setting = mojom::Setting::kPowerIdleBehaviorWhileCharging},
131 {IDS_OS_SETTINGS_TAG_POWER_IDLE_WHILE_CHARGING_ALT1,
132 SearchConcept::kAltTagEnd}},
133 {IDS_OS_SETTINGS_TAG_POWER_IDLE_WHILE_ON_BATTERY,
134 mojom::kPowerSubpagePath,
135 mojom::SearchResultIcon::kPower,
136 mojom::SearchResultDefaultRank::kMedium,
137 mojom::SearchResultType::kSetting,
138 {.setting = mojom::Setting::kPowerIdleBehaviorWhileOnBattery},
139 {IDS_OS_SETTINGS_TAG_POWER_IDLE_WHILE_ON_BATTERY_ALT1,
140 SearchConcept::kAltTagEnd}},
141 });
142 return *tags;
143 }
144
GetTouchpadSearchConcepts()145 const std::vector<SearchConcept>& GetTouchpadSearchConcepts() {
146 static const base::NoDestructor<std::vector<SearchConcept>> tags({
147 {IDS_OS_SETTINGS_TAG_TOUCHPAD_SPEED,
148 mojom::kPointersSubpagePath,
149 mojom::SearchResultIcon::kLaptop,
150 mojom::SearchResultDefaultRank::kMedium,
151 mojom::SearchResultType::kSetting,
152 {.setting = mojom::Setting::kTouchpadSpeed}},
153 {IDS_OS_SETTINGS_TAG_TOUCHPAD_TAP_DRAGGING,
154 mojom::kPointersSubpagePath,
155 mojom::SearchResultIcon::kLaptop,
156 mojom::SearchResultDefaultRank::kMedium,
157 mojom::SearchResultType::kSetting,
158 {.setting = mojom::Setting::kTouchpadTapDragging}},
159 {IDS_OS_SETTINGS_TAG_TOUCHPAD_TAP_TO_CLICK,
160 mojom::kPointersSubpagePath,
161 mojom::SearchResultIcon::kLaptop,
162 mojom::SearchResultDefaultRank::kMedium,
163 mojom::SearchResultType::kSetting,
164 {.setting = mojom::Setting::kTouchpadTapToClick}},
165 {IDS_OS_SETTINGS_TAG_TOUCHPAD,
166 mojom::kPointersSubpagePath,
167 mojom::SearchResultIcon::kLaptop,
168 mojom::SearchResultDefaultRank::kMedium,
169 mojom::SearchResultType::kSubpage,
170 {.subpage = mojom::Subpage::kPointers},
171 {IDS_OS_SETTINGS_TAG_TOUCHPAD_ALT1, SearchConcept::kAltTagEnd}},
172 {IDS_OS_SETTINGS_TAG_TOUCHPAD_REVERSE_SCROLLING,
173 mojom::kPointersSubpagePath,
174 mojom::SearchResultIcon::kLaptop,
175 mojom::SearchResultDefaultRank::kMedium,
176 mojom::SearchResultType::kSetting,
177 {.setting = mojom::Setting::kTouchpadReverseScrolling}},
178 {IDS_OS_SETTINGS_TAG_TOUCHPAD_ACCELERATION,
179 mojom::kPointersSubpagePath,
180 mojom::SearchResultIcon::kLaptop,
181 mojom::SearchResultDefaultRank::kMedium,
182 mojom::SearchResultType::kSetting,
183 {.setting = mojom::Setting::kTouchpadAcceleration}},
184 });
185 return *tags;
186 }
187
188 const std::vector<SearchConcept>&
GetTouchpadScrollAccelerationSearchConcepts()189 GetTouchpadScrollAccelerationSearchConcepts() {
190 static const base::NoDestructor<std::vector<SearchConcept>> tags({
191 {IDS_OS_SETTINGS_TAG_TOUCHPAD_SCROLL_ACCELERATION,
192 mojom::kPointersSubpagePath,
193 mojom::SearchResultIcon::kLaptop,
194 mojom::SearchResultDefaultRank::kMedium,
195 mojom::SearchResultType::kSetting,
196 {.setting = mojom::Setting::kTouchpadScrollAcceleration}},
197 });
198 return *tags;
199 }
200
GetMouseSearchConcepts()201 const std::vector<SearchConcept>& GetMouseSearchConcepts() {
202 static const base::NoDestructor<std::vector<SearchConcept>> tags({
203 {IDS_OS_SETTINGS_TAG_MOUSE_ACCELERATION,
204 mojom::kPointersSubpagePath,
205 mojom::SearchResultIcon::kMouse,
206 mojom::SearchResultDefaultRank::kMedium,
207 mojom::SearchResultType::kSetting,
208 {.setting = mojom::Setting::kMouseAcceleration}},
209 {IDS_OS_SETTINGS_TAG_MOUSE_SWAP_BUTTON,
210 mojom::kPointersSubpagePath,
211 mojom::SearchResultIcon::kMouse,
212 mojom::SearchResultDefaultRank::kMedium,
213 mojom::SearchResultType::kSetting,
214 {.setting = mojom::Setting::kMouseSwapPrimaryButtons}},
215 {IDS_OS_SETTINGS_TAG_MOUSE_SPEED,
216 mojom::kPointersSubpagePath,
217 mojom::SearchResultIcon::kMouse,
218 mojom::SearchResultDefaultRank::kMedium,
219 mojom::SearchResultType::kSetting,
220 {.setting = mojom::Setting::kMouseSpeed}},
221 {IDS_OS_SETTINGS_TAG_MOUSE_REVERSE_SCROLLING,
222 mojom::kPointersSubpagePath,
223 mojom::SearchResultIcon::kMouse,
224 mojom::SearchResultDefaultRank::kMedium,
225 mojom::SearchResultType::kSetting,
226 {.setting = mojom::Setting::kMouseReverseScrolling}},
227 {IDS_OS_SETTINGS_TAG_MOUSE,
228 mojom::kPointersSubpagePath,
229 mojom::SearchResultIcon::kMouse,
230 mojom::SearchResultDefaultRank::kMedium,
231 mojom::SearchResultType::kSubpage,
232 {.subpage = mojom::Subpage::kPointers}},
233 {IDS_OS_SETTINGS_TAG_MOUSE_SCROLL_ACCELERATION,
234 mojom::kPointersSubpagePath,
235 mojom::SearchResultIcon::kMouse,
236 mojom::SearchResultDefaultRank::kMedium,
237 mojom::SearchResultType::kSetting,
238 {.setting = mojom::Setting::kMouseScrollAcceleration}},
239 });
240 return *tags;
241 }
242
GetStylusSearchConcepts()243 const std::vector<SearchConcept>& GetStylusSearchConcepts() {
244 static const base::NoDestructor<std::vector<SearchConcept>> tags({
245 {IDS_OS_SETTINGS_TAG_STYLUS_NOTE_APP,
246 mojom::kStylusSubpagePath,
247 mojom::SearchResultIcon::kStylus,
248 mojom::SearchResultDefaultRank::kMedium,
249 mojom::SearchResultType::kSetting,
250 {.setting = mojom::Setting::kStylusNoteTakingApp},
251 {IDS_OS_SETTINGS_TAG_STYLUS_NOTE_APP_ALT1,
252 IDS_OS_SETTINGS_TAG_STYLUS_NOTE_APP_ALT2, SearchConcept::kAltTagEnd}},
253 {IDS_OS_SETTINGS_TAG_STYLUS_LOCK_SCREEN_LATEST_NOTE,
254 mojom::kStylusSubpagePath,
255 mojom::SearchResultIcon::kStylus,
256 mojom::SearchResultDefaultRank::kMedium,
257 mojom::SearchResultType::kSetting,
258 {.setting = mojom::Setting::kStylusLatestNoteOnLockScreen}},
259 {IDS_OS_SETTINGS_TAG_STYLUS_LOCK_SCREEN_NOTES,
260 mojom::kStylusSubpagePath,
261 mojom::SearchResultIcon::kStylus,
262 mojom::SearchResultDefaultRank::kMedium,
263 mojom::SearchResultType::kSetting,
264 {.setting = mojom::Setting::kStylusNoteTakingFromLockScreen}},
265 {IDS_OS_SETTINGS_TAG_STYLUS_SHELF_TOOLS,
266 mojom::kStylusSubpagePath,
267 mojom::SearchResultIcon::kStylus,
268 mojom::SearchResultDefaultRank::kMedium,
269 mojom::SearchResultType::kSetting,
270 {.setting = mojom::Setting::kStylusToolsInShelf},
271 {IDS_OS_SETTINGS_TAG_STYLUS_SHELF_TOOLS_ALT1,
272 IDS_OS_SETTINGS_TAG_STYLUS_SHELF_TOOLS_ALT2,
273 SearchConcept::kAltTagEnd}},
274 {IDS_OS_SETTINGS_TAG_STYLUS,
275 mojom::kStylusSubpagePath,
276 mojom::SearchResultIcon::kStylus,
277 mojom::SearchResultDefaultRank::kMedium,
278 mojom::SearchResultType::kSubpage,
279 {.subpage = mojom::Subpage::kStylus}},
280 });
281 return *tags;
282 }
283
GetDisplayArrangementSearchConcepts()284 const std::vector<SearchConcept>& GetDisplayArrangementSearchConcepts() {
285 static const base::NoDestructor<std::vector<SearchConcept>> tags({
286 {IDS_OS_SETTINGS_TAG_DISPLAY_ARRANGEMENT,
287 mojom::kDisplaySubpagePath,
288 mojom::SearchResultIcon::kDisplay,
289 mojom::SearchResultDefaultRank::kMedium,
290 mojom::SearchResultType::kSetting,
291 {.setting = mojom::Setting::kDisplayArrangement},
292 {IDS_OS_SETTINGS_TAG_DISPLAY_ARRANGEMENT_ALT1,
293 IDS_OS_SETTINGS_TAG_DISPLAY_ARRANGEMENT_ALT2,
294 SearchConcept::kAltTagEnd}},
295 });
296 return *tags;
297 }
298
GetDisplayMirrorSearchConcepts()299 const std::vector<SearchConcept>& GetDisplayMirrorSearchConcepts() {
300 static const base::NoDestructor<std::vector<SearchConcept>> tags({
301 {IDS_OS_SETTINGS_TAG_MIRRORING,
302 mojom::kDisplaySubpagePath,
303 mojom::SearchResultIcon::kDisplay,
304 mojom::SearchResultDefaultRank::kMedium,
305 mojom::SearchResultType::kSetting,
306 {.setting = mojom::Setting::kDisplayMirroring}},
307 });
308 return *tags;
309 }
310
GetDisplayUnifiedDesktopSearchConcepts()311 const std::vector<SearchConcept>& GetDisplayUnifiedDesktopSearchConcepts() {
312 static const base::NoDestructor<std::vector<SearchConcept>> tags({
313 {IDS_OS_SETTINGS_TAG_UNIFIED_DESKTOP,
314 mojom::kDisplaySubpagePath,
315 mojom::SearchResultIcon::kDisplay,
316 mojom::SearchResultDefaultRank::kMedium,
317 mojom::SearchResultType::kSetting,
318 {.setting = mojom::Setting::kAllowWindowsToSpanDisplays}},
319 });
320 return *tags;
321 }
322
GetDisplayExternalSearchConcepts()323 const std::vector<SearchConcept>& GetDisplayExternalSearchConcepts() {
324 static const base::NoDestructor<std::vector<SearchConcept>> tags({
325 {IDS_OS_SETTINGS_TAG_DISPLAY_RESOLUTION,
326 mojom::kDisplaySubpagePath,
327 mojom::SearchResultIcon::kDisplay,
328 mojom::SearchResultDefaultRank::kMedium,
329 mojom::SearchResultType::kSetting,
330 {.setting = mojom::Setting::kDisplayResolution},
331 {IDS_OS_SETTINGS_TAG_DISPLAY_RESOLUTION_ALT1,
332 IDS_OS_SETTINGS_TAG_DISPLAY_RESOLUTION_ALT2,
333 SearchConcept::kAltTagEnd}},
334 {IDS_OS_SETTINGS_TAG_DISPLAY_OVERSCAN,
335 mojom::kDisplaySubpagePath,
336 mojom::SearchResultIcon::kDisplay,
337 mojom::SearchResultDefaultRank::kMedium,
338 mojom::SearchResultType::kSetting,
339 {.setting = mojom::Setting::kDisplayOverscan}},
340 });
341 return *tags;
342 }
343
344 const std::vector<SearchConcept>&
GetDisplayExternalWithRefreshSearchConcepts()345 GetDisplayExternalWithRefreshSearchConcepts() {
346 static const base::NoDestructor<std::vector<SearchConcept>> tags({
347 {IDS_OS_SETTINGS_TAG_DISPLAY_REFRESH_RATE,
348 mojom::kDisplaySubpagePath,
349 mojom::SearchResultIcon::kDisplay,
350 mojom::SearchResultDefaultRank::kMedium,
351 mojom::SearchResultType::kSetting,
352 {.setting = mojom::Setting::kDisplayRefreshRate},
353 {IDS_OS_SETTINGS_TAG_DISPLAY_REFRESH_RATE_ALT1,
354 IDS_OS_SETTINGS_TAG_DISPLAY_REFRESH_RATE_ALT2,
355 SearchConcept::kAltTagEnd}},
356 });
357 return *tags;
358 }
359
GetDisplayOrientationSearchConcepts()360 const std::vector<SearchConcept>& GetDisplayOrientationSearchConcepts() {
361 static const base::NoDestructor<std::vector<SearchConcept>> tags({
362 {IDS_OS_SETTINGS_TAG_DISPLAY_ORIENTATION,
363 mojom::kDisplaySubpagePath,
364 mojom::SearchResultIcon::kDisplay,
365 mojom::SearchResultDefaultRank::kMedium,
366 mojom::SearchResultType::kSetting,
367 {.setting = mojom::Setting::kDisplayOrientation},
368 {IDS_OS_SETTINGS_TAG_DISPLAY_ORIENTATION_ALT1,
369 SearchConcept::kAltTagEnd}},
370 });
371 return *tags;
372 }
373
GetDisplayAmbientSearchConcepts()374 const std::vector<SearchConcept>& GetDisplayAmbientSearchConcepts() {
375 static const base::NoDestructor<std::vector<SearchConcept>> tags({
376 {IDS_OS_SETTINGS_TAG_DISPLAY_AMBIENT_COLORS,
377 mojom::kDisplaySubpagePath,
378 mojom::SearchResultIcon::kDisplay,
379 mojom::SearchResultDefaultRank::kMedium,
380 mojom::SearchResultType::kSetting,
381 {.setting = mojom::Setting::kAmbientColors}},
382 });
383 return *tags;
384 }
385
GetDisplayTouchCalibrationSearchConcepts()386 const std::vector<SearchConcept>& GetDisplayTouchCalibrationSearchConcepts() {
387 static const base::NoDestructor<std::vector<SearchConcept>> tags({
388 {IDS_OS_SETTINGS_TAG_DISPLAY_TOUCHSCREEN_CALIBRATION,
389 mojom::kDisplaySubpagePath,
390 mojom::SearchResultIcon::kDisplay,
391 mojom::SearchResultDefaultRank::kMedium,
392 mojom::SearchResultType::kSetting,
393 {.setting = mojom::Setting::kTouchscreenCalibration}},
394 });
395 return *tags;
396 }
397
GetDisplayNightLightOnSearchConcepts()398 const std::vector<SearchConcept>& GetDisplayNightLightOnSearchConcepts() {
399 static const base::NoDestructor<std::vector<SearchConcept>> tags({
400 {IDS_OS_SETTINGS_TAG_NIGHT_LIGHT_COLOR_TEMPERATURE,
401 mojom::kDisplaySubpagePath,
402 mojom::SearchResultIcon::kDisplay,
403 mojom::SearchResultDefaultRank::kLow,
404 mojom::SearchResultType::kSetting,
405 {.setting = mojom::Setting::kNightLightColorTemperature}},
406 });
407 return *tags;
408 }
409
GetExternalStorageSearchConcepts()410 const std::vector<SearchConcept>& GetExternalStorageSearchConcepts() {
411 static const base::NoDestructor<std::vector<SearchConcept>> tags({
412 {IDS_OS_SETTINGS_TAG_EXTERNAL_STORAGE,
413 mojom::kExternalStorageSubpagePath,
414 mojom::SearchResultIcon::kHardDrive,
415 mojom::SearchResultDefaultRank::kMedium,
416 mojom::SearchResultType::kSubpage,
417 {.subpage = mojom::Subpage::kExternalStorage}},
418 });
419 return *tags;
420 }
421
GetPowerWithBatterySearchConcepts()422 const std::vector<SearchConcept>& GetPowerWithBatterySearchConcepts() {
423 static const base::NoDestructor<std::vector<SearchConcept>> tags({
424 {IDS_OS_SETTINGS_TAG_POWER_SOURCE,
425 mojom::kPowerSubpagePath,
426 mojom::SearchResultIcon::kPower,
427 mojom::SearchResultDefaultRank::kMedium,
428 mojom::SearchResultType::kSetting,
429 {.setting = mojom::Setting::kPowerSource},
430 {IDS_OS_SETTINGS_TAG_POWER_SOURCE_ALT1,
431 IDS_OS_SETTINGS_TAG_POWER_SOURCE_ALT2, SearchConcept::kAltTagEnd}},
432 });
433 return *tags;
434 }
435
GetPowerWithLaptopLidSearchConcepts()436 const std::vector<SearchConcept>& GetPowerWithLaptopLidSearchConcepts() {
437 static const base::NoDestructor<std::vector<SearchConcept>> tags({
438 {IDS_OS_SETTINGS_TAG_POWER_SLEEP_COVER_CLOSED,
439 mojom::kPowerSubpagePath,
440 mojom::SearchResultIcon::kPower,
441 mojom::SearchResultDefaultRank::kMedium,
442 mojom::SearchResultType::kSetting,
443 {.setting = mojom::Setting::kSleepWhenLaptopLidClosed},
444 {IDS_OS_SETTINGS_TAG_POWER_SLEEP_COVER_CLOSED_ALT1,
445 IDS_OS_SETTINGS_TAG_POWER_SLEEP_COVER_CLOSED_ALT2,
446 SearchConcept::kAltTagEnd}},
447 });
448 return *tags;
449 }
450
IsUnifiedDesktopAvailable()451 bool IsUnifiedDesktopAvailable() {
452 return base::CommandLine::ForCurrentProcess()->HasSwitch(
453 ::switches::kEnableUnifiedDesktop);
454 }
455
DoesDeviceSupportAmbientColor()456 bool DoesDeviceSupportAmbientColor() {
457 return ash::features::IsAllowAmbientEQEnabled();
458 }
459
IsTouchCalibrationAvailable()460 bool IsTouchCalibrationAvailable() {
461 return base::CommandLine::ForCurrentProcess()->HasSwitch(
462 switches::kEnableTouchCalibrationSetting) &&
463 display::HasExternalTouchscreenDevice();
464 }
465
IsListAllDisplayModesEnabled()466 bool IsListAllDisplayModesEnabled() {
467 return display::features::IsListAllDisplayModesEnabled();
468 }
469
AddDeviceKeyboardStrings(content::WebUIDataSource * html_source)470 void AddDeviceKeyboardStrings(content::WebUIDataSource* html_source) {
471 static constexpr webui::LocalizedString keyboard_strings[] = {
472 {"keyboardTitle", IDS_SETTINGS_KEYBOARD_TITLE},
473 {"keyboardKeyCtrl", IDS_SETTINGS_KEYBOARD_KEY_LEFT_CTRL},
474 {"keyboardKeyAlt", IDS_SETTINGS_KEYBOARD_KEY_LEFT_ALT},
475 {"keyboardKeyCapsLock", IDS_SETTINGS_KEYBOARD_KEY_CAPS_LOCK},
476 {"keyboardKeyCommand", IDS_SETTINGS_KEYBOARD_KEY_COMMAND},
477 {"keyboardKeyDiamond", IDS_SETTINGS_KEYBOARD_KEY_DIAMOND},
478 {"keyboardKeyEscape", IDS_SETTINGS_KEYBOARD_KEY_ESCAPE},
479 {"keyboardKeyBackspace", IDS_SETTINGS_KEYBOARD_KEY_BACKSPACE},
480 {"keyboardKeyAssistant", IDS_SETTINGS_KEYBOARD_KEY_ASSISTANT},
481 {"keyboardKeyDisabled", IDS_SETTINGS_KEYBOARD_KEY_DISABLED},
482 {"keyboardKeyExternalCommand",
483 IDS_SETTINGS_KEYBOARD_KEY_EXTERNAL_COMMAND},
484 {"keyboardKeyExternalMeta", IDS_SETTINGS_KEYBOARD_KEY_EXTERNAL_META},
485 {"keyboardKeyMeta", IDS_SETTINGS_KEYBOARD_KEY_META},
486 {"keyboardSendFunctionKeys", IDS_SETTINGS_KEYBOARD_SEND_FUNCTION_KEYS},
487 {"keyboardEnableAutoRepeat", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_ENABLE},
488 {"keyRepeatDelay", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_DELAY},
489 {"keyRepeatDelayLong", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_DELAY_LONG},
490 {"keyRepeatDelayShort", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_DELAY_SHORT},
491 {"keyRepeatRate", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_RATE},
492 {"keyRepeatRateSlow", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_RATE_SLOW},
493 {"keyRepeatRateFast", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_FAST},
494 {"showKeyboardShortcutViewer",
495 IDS_SETTINGS_KEYBOARD_SHOW_SHORTCUT_VIEWER},
496 {"keyboardShowLanguageAndInput",
497 IDS_SETTINGS_KEYBOARD_SHOW_LANGUAGE_AND_INPUT},
498 {"keyboardShowInputSettings", IDS_SETTINGS_KEYBOARD_SHOW_INPUT_SETTINGS},
499 };
500 AddLocalizedStringsBulk(html_source, keyboard_strings);
501
502 html_source->AddLocalizedString("keyboardKeySearch",
503 ui::DeviceUsesKeyboardLayout2()
504 ? IDS_SETTINGS_KEYBOARD_KEY_LAUNCHER
505 : IDS_SETTINGS_KEYBOARD_KEY_SEARCH);
506 html_source->AddLocalizedString(
507 "keyboardSendFunctionKeysDescription",
508 ui::DeviceUsesKeyboardLayout2()
509 ? IDS_SETTINGS_KEYBOARD_SEND_FUNCTION_KEYS_LAYOUT2_DESCRIPTION
510 : IDS_SETTINGS_KEYBOARD_SEND_FUNCTION_KEYS_DESCRIPTION);
511 }
512
AddDeviceStylusStrings(content::WebUIDataSource * html_source)513 void AddDeviceStylusStrings(content::WebUIDataSource* html_source) {
514 static constexpr webui::LocalizedString kStylusStrings[] = {
515 {"stylusTitle", IDS_SETTINGS_STYLUS_TITLE},
516 {"stylusEnableStylusTools", IDS_SETTINGS_STYLUS_ENABLE_STYLUS_TOOLS},
517 {"stylusAutoOpenStylusTools", IDS_SETTINGS_STYLUS_AUTO_OPEN_STYLUS_TOOLS},
518 {"stylusFindMoreAppsPrimary", IDS_SETTINGS_STYLUS_FIND_MORE_APPS_PRIMARY},
519 {"stylusFindMoreAppsSecondary",
520 IDS_SETTINGS_STYLUS_FIND_MORE_APPS_SECONDARY},
521 {"stylusNoteTakingApp", IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_LABEL},
522 {"stylusNoteTakingAppEnabledOnLockScreen",
523 IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_LOCK_SCREEN_CHECKBOX},
524 {"stylusNoteTakingAppKeepsLastNoteOnLockScreen",
525 IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_KEEP_LATEST_NOTE},
526 {"stylusNoteTakingAppLockScreenSettingsHeader",
527 IDS_SETTINGS_STYLUS_LOCK_SCREEN_NOTES_TITLE},
528 {"stylusNoteTakingAppNoneAvailable",
529 IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_NONE_AVAILABLE},
530 {"stylusNoteTakingAppWaitingForAndroid",
531 IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_WAITING_FOR_ANDROID}};
532 AddLocalizedStringsBulk(html_source, kStylusStrings);
533
534 html_source->AddBoolean("hasInternalStylus",
535 ash::stylus_utils::HasInternalStylus());
536 }
537
AddDeviceDisplayStrings(content::WebUIDataSource * html_source)538 void AddDeviceDisplayStrings(content::WebUIDataSource* html_source) {
539 static constexpr webui::LocalizedString kDisplayStrings[] = {
540 {"displayTitle", IDS_SETTINGS_DISPLAY_TITLE},
541 {"displayArrangementText", IDS_SETTINGS_DISPLAY_ARRANGEMENT_TEXT},
542 {"displayArrangementTitle", IDS_SETTINGS_DISPLAY_ARRANGEMENT_TITLE},
543 {"displayMirror", IDS_SETTINGS_DISPLAY_MIRROR},
544 {"displayMirrorDisplayName", IDS_SETTINGS_DISPLAY_MIRROR_DISPLAY_NAME},
545 {"displayAmbientColorTitle", IDS_SETTINGS_DISPLAY_AMBIENT_COLOR_TITLE},
546 {"displayAmbientColorSubtitle",
547 IDS_SETTINGS_DISPLAY_AMBIENT_COLOR_SUBTITLE},
548 {"displayNightLightLabel", IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_LABEL},
549 {"displayNightLightOnAtSunset",
550 IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_ON_AT_SUNSET},
551 {"displayNightLightOffAtSunrise",
552 IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_OFF_AT_SUNRISE},
553 {"displayNightLightScheduleCustom",
554 IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_CUSTOM},
555 {"displayNightLightScheduleLabel",
556 IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_LABEL},
557 {"displayNightLightScheduleNever",
558 IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_NEVER},
559 {"displayNightLightScheduleSunsetToSunRise",
560 IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_SUNSET_TO_SUNRISE},
561 {"displayNightLightStartTime",
562 IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_START_TIME},
563 {"displayNightLightStopTime", IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_STOP_TIME},
564 {"displayNightLightText", IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEXT},
565 {"displayNightLightTemperatureLabel",
566 IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEMPERATURE_LABEL},
567 {"displayNightLightTempSliderMaxLabel",
568 IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEMP_SLIDER_MAX_LABEL},
569 {"displayNightLightTempSliderMinLabel",
570 IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEMP_SLIDER_MIN_LABEL},
571 {"displayUnifiedDesktop", IDS_SETTINGS_DISPLAY_UNIFIED_DESKTOP},
572 {"displayUnifiedDesktopOn", IDS_SETTINGS_DISPLAY_UNIFIED_DESKTOP_ON},
573 {"displayUnifiedDesktopOff", IDS_SETTINGS_DISPLAY_UNIFIED_DESKTOP_OFF},
574 {"displayResolutionTitle", IDS_SETTINGS_DISPLAY_RESOLUTION_TITLE},
575 {"displayResolutionText", IDS_SETTINGS_DISPLAY_RESOLUTION_TEXT},
576 {"displayResolutionTextBest", IDS_SETTINGS_DISPLAY_RESOLUTION_TEXT_BEST},
577 {"displayResolutionTextNative",
578 IDS_SETTINGS_DISPLAY_RESOLUTION_TEXT_NATIVE},
579 {"displayResolutionSublabel", IDS_SETTINGS_DISPLAY_RESOLUTION_SUBLABEL},
580 {"displayResolutionMenuItem", IDS_SETTINGS_DISPLAY_RESOLUTION_MENU_ITEM},
581 {"displayResolutionOnlyMenuItem",
582 IDS_SETTINGS_DISPLAY_RESOLUTION_ONLY_MENU_ITEM},
583 {"displayResolutionInterlacedMenuItem",
584 IDS_SETTINGS_DISPLAY_RESOLUTION_INTERLACED_MENU_ITEM},
585 {"displayRefreshRateTitle", IDS_SETTINGS_DISPLAY_REFRESH_RATE_TITLE},
586 {"displayRefreshRateSublabel",
587 IDS_SETTINGS_DISPLAY_REFRESH_RATE_SUBLABEL},
588 {"displayRefreshRateMenuItem",
589 IDS_SETTINGS_DISPLAY_REFRESH_RATE_MENU_ITEM},
590 {"displayRefreshRateInterlacedMenuItem",
591 IDS_SETTINGS_DISPLAY_REFRESH_RATE_INTERLACED_MENU_ITEM},
592 {"displayZoomTitle", IDS_SETTINGS_DISPLAY_ZOOM_TITLE},
593 {"displayZoomSublabel", IDS_SETTINGS_DISPLAY_ZOOM_SUBLABEL},
594 {"displayZoomValue", IDS_SETTINGS_DISPLAY_ZOOM_VALUE},
595 {"displayZoomLogicalResolutionText",
596 IDS_SETTINGS_DISPLAY_ZOOM_LOGICAL_RESOLUTION_TEXT},
597 {"displayZoomNativeLogicalResolutionNativeText",
598 IDS_SETTINGS_DISPLAY_ZOOM_LOGICAL_RESOLUTION_NATIVE_TEXT},
599 {"displayZoomLogicalResolutionDefaultText",
600 IDS_SETTINGS_DISPLAY_ZOOM_LOGICAL_RESOLUTION_DEFAULT_TEXT},
601 {"displaySizeSliderMinLabel", IDS_SETTINGS_DISPLAY_ZOOM_SLIDER_MINIMUM},
602 {"displaySizeSliderMaxLabel", IDS_SETTINGS_DISPLAY_ZOOM_SLIDER_MAXIMUM},
603 {"displayScreenTitle", IDS_SETTINGS_DISPLAY_SCREEN},
604 {"displayScreenExtended", IDS_SETTINGS_DISPLAY_SCREEN_EXTENDED},
605 {"displayScreenPrimary", IDS_SETTINGS_DISPLAY_SCREEN_PRIMARY},
606 {"displayOrientation", IDS_SETTINGS_DISPLAY_ORIENTATION},
607 {"displayOrientationStandard", IDS_SETTINGS_DISPLAY_ORIENTATION_STANDARD},
608 {"displayOrientationAutoRotate",
609 IDS_SETTINGS_DISPLAY_ORIENTATION_AUTO_ROTATE},
610 {"displayOverscanPageText", IDS_SETTINGS_DISPLAY_OVERSCAN_TEXT},
611 {"displayOverscanPageTitle", IDS_SETTINGS_DISPLAY_OVERSCAN_TITLE},
612 {"displayOverscanSubtitle", IDS_SETTINGS_DISPLAY_OVERSCAN_SUBTITLE},
613 {"displayOverscanInstructions",
614 IDS_SETTINGS_DISPLAY_OVERSCAN_INSTRUCTIONS},
615 {"displayOverscanResize", IDS_SETTINGS_DISPLAY_OVERSCAN_RESIZE},
616 {"displayOverscanPosition", IDS_SETTINGS_DISPLAY_OVERSCAN_POSITION},
617 {"displayOverscanReset", IDS_SETTINGS_DISPLAY_OVERSCAN_RESET},
618 {"displayTouchCalibrationTitle",
619 IDS_SETTINGS_DISPLAY_TOUCH_CALIBRATION_TITLE},
620 {"displayTouchCalibrationText",
621 IDS_SETTINGS_DISPLAY_TOUCH_CALIBRATION_TEXT}};
622 AddLocalizedStringsBulk(html_source, kDisplayStrings);
623
624 html_source->AddBoolean("unifiedDesktopAvailable",
625 IsUnifiedDesktopAvailable());
626
627 html_source->AddBoolean("listAllDisplayModes",
628 IsListAllDisplayModesEnabled());
629
630 html_source->AddBoolean("deviceSupportsAmbientColor",
631 DoesDeviceSupportAmbientColor());
632
633 html_source->AddBoolean("enableTouchCalibrationSetting",
634 IsTouchCalibrationAvailable());
635
636 html_source->AddBoolean(
637 "allowDisplayIdentificationApi",
638 base::FeatureList::IsEnabled(ash::features::kDisplayIdentification));
639
640 html_source->AddString("invalidDisplayId",
641 base::NumberToString(display::kInvalidDisplayId));
642
643 html_source->AddBoolean(
644 "allowDisplayAlignmentApi",
645 base::FeatureList::IsEnabled(ash::features::kDisplayAlignAssist));
646 }
647
AddDeviceStorageStrings(content::WebUIDataSource * html_source,bool is_external_storage_page_available)648 void AddDeviceStorageStrings(content::WebUIDataSource* html_source,
649 bool is_external_storage_page_available) {
650 static constexpr webui::LocalizedString kStorageStrings[] = {
651 {"storageTitle", IDS_SETTINGS_STORAGE_TITLE},
652 {"storageItemInUse", IDS_SETTINGS_STORAGE_ITEM_IN_USE},
653 {"storageItemAvailable", IDS_SETTINGS_STORAGE_ITEM_AVAILABLE},
654 {"storageItemSystem", IDS_SETTINGS_STORAGE_ITEM_SYSTEM},
655 {"storageItemMyFiles", IDS_SETTINGS_STORAGE_ITEM_MY_FILES},
656 {"storageItemBrowsingData", IDS_SETTINGS_STORAGE_ITEM_BROWSING_DATA},
657 {"storageItemApps", IDS_SETTINGS_STORAGE_ITEM_APPS},
658 {"storageItemCrostini", IDS_SETTINGS_STORAGE_ITEM_CROSTINI},
659 {"storageItemOtherUsers", IDS_SETTINGS_STORAGE_ITEM_OTHER_USERS},
660 {"storageSizeComputing", IDS_SETTINGS_STORAGE_SIZE_CALCULATING},
661 {"storageSizeUnknown", IDS_SETTINGS_STORAGE_SIZE_UNKNOWN},
662 {"storageSpaceLowMessageTitle",
663 IDS_SETTINGS_STORAGE_SPACE_LOW_MESSAGE_TITLE},
664 {"storageSpaceLowMessageLine1",
665 IDS_SETTINGS_STORAGE_SPACE_LOW_MESSAGE_LINE_1},
666 {"storageSpaceLowMessageLine2",
667 IDS_SETTINGS_STORAGE_SPACE_LOW_MESSAGE_LINE_2},
668 {"storageSpaceCriticallyLowMessageTitle",
669 IDS_SETTINGS_STORAGE_SPACE_CRITICALLY_LOW_MESSAGE_TITLE},
670 {"storageSpaceCriticallyLowMessageLine1",
671 IDS_SETTINGS_STORAGE_SPACE_CRITICALLY_LOW_MESSAGE_LINE_1},
672 {"storageSpaceCriticallyLowMessageLine2",
673 IDS_SETTINGS_STORAGE_SPACE_CRITICALLY_LOW_MESSAGE_LINE_2},
674 {"storageExternal", IDS_SETTINGS_STORAGE_EXTERNAL},
675 {"storageExternalStorageEmptyListHeader",
676 IDS_SETTINGS_STORAGE_EXTERNAL_STORAGE_EMPTY_LIST_HEADER},
677 {"storageExternalStorageListHeader",
678 IDS_SETTINGS_STORAGE_EXTERNAL_STORAGE_LIST_HEADER},
679 {"storageOverviewAriaLabel", IDS_SETTINGS_STORAGE_OVERVIEW_ARIA_LABEL}};
680 AddLocalizedStringsBulk(html_source, kStorageStrings);
681
682 html_source->AddBoolean("androidEnabled", is_external_storage_page_available);
683
684 html_source->AddString(
685 "storageAndroidAppsExternalDrivesNote",
686 l10n_util::GetStringFUTF16(
687 IDS_SETTINGS_STORAGE_ANDROID_APPS_ACCESS_EXTERNAL_DRIVES_NOTE,
688 base::ASCIIToUTF16(chrome::kArcExternalStorageLearnMoreURL)));
689 }
690
AddDevicePowerStrings(content::WebUIDataSource * html_source)691 void AddDevicePowerStrings(content::WebUIDataSource* html_source) {
692 static constexpr webui::LocalizedString kPowerStrings[] = {
693 {"powerTitle", IDS_SETTINGS_POWER_TITLE},
694 {"powerSourceLabel", IDS_SETTINGS_POWER_SOURCE_LABEL},
695 {"powerSourceBattery", IDS_SETTINGS_POWER_SOURCE_BATTERY},
696 {"powerSourceAcAdapter", IDS_SETTINGS_POWER_SOURCE_AC_ADAPTER},
697 {"powerSourceLowPowerCharger",
698 IDS_SETTINGS_POWER_SOURCE_LOW_POWER_CHARGER},
699 {"calculatingPower", IDS_SETTINGS_POWER_SOURCE_CALCULATING},
700 {"powerIdleLabel", IDS_SETTINGS_POWER_IDLE_LABEL},
701 {"powerIdleWhileChargingLabel",
702 IDS_SETTINGS_POWER_IDLE_WHILE_CHARGING_LABEL},
703 {"powerIdleWhileChargingAriaLabel",
704 IDS_SETTINGS_POWER_IDLE_WHILE_CHARGING_ARIA_LABEL},
705 {"powerIdleWhileOnBatteryLabel",
706 IDS_SETTINGS_POWER_IDLE_WHILE_ON_BATTERY_LABEL},
707 {"powerIdleWhileOnBatteryAriaLabel",
708 IDS_SETTINGS_POWER_IDLE_WHILE_ON_BATTERY_ARIA_LABEL},
709 {"powerIdleDisplayOffSleep", IDS_SETTINGS_POWER_IDLE_DISPLAY_OFF_SLEEP},
710 {"powerIdleDisplayOff", IDS_SETTINGS_POWER_IDLE_DISPLAY_OFF},
711 {"powerIdleDisplayOn", IDS_SETTINGS_POWER_IDLE_DISPLAY_ON},
712 {"powerIdleDisplayShutDown", IDS_SETTINGS_POWER_IDLE_SHUT_DOWN},
713 {"powerIdleDisplayStopSession", IDS_SETTINGS_POWER_IDLE_STOP_SESSION},
714 {"powerLidSleepLabel", IDS_SETTINGS_POWER_LID_CLOSED_SLEEP_LABEL},
715 {"powerLidSignOutLabel", IDS_SETTINGS_POWER_LID_CLOSED_SIGN_OUT_LABEL},
716 {"powerLidShutDownLabel", IDS_SETTINGS_POWER_LID_CLOSED_SHUT_DOWN_LABEL},
717 };
718 AddLocalizedStringsBulk(html_source, kPowerStrings);
719 }
720
721 // Mirrors enum of the same name in enums.xml.
722 enum class TouchpadSensitivity {
723 kNONE = 0,
724 kSlowest = 1,
725 kSlow = 2,
726 kMedium = 3,
727 kFast = 4,
728 kFastest = 5,
729 kMaxValue = kFastest,
730 };
731
732 } // namespace
733
DeviceSection(Profile * profile,SearchTagRegistry * search_tag_registry,PrefService * pref_service)734 DeviceSection::DeviceSection(Profile* profile,
735 SearchTagRegistry* search_tag_registry,
736 PrefService* pref_service)
737 : OsSettingsSection(profile, search_tag_registry),
738 pref_service_(pref_service) {
739 SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
740 updater.AddSearchTags(GetDeviceSearchConcepts());
741
742 if (features::ShouldShowExternalStorageSettings(profile))
743 updater.AddSearchTags(GetExternalStorageSearchConcepts());
744
745 PowerManagerClient* power_manager_client = PowerManagerClient::Get();
746 if (power_manager_client) {
747 power_manager_client->AddObserver(this);
748
749 const base::Optional<power_manager::PowerSupplyProperties>& last_status =
750 power_manager_client->GetLastStatus();
751 if (last_status)
752 PowerChanged(*last_status);
753
754 // Determine whether to show laptop lid power settings.
755 power_manager_client->GetSwitchStates(base::BindOnce(
756 &DeviceSection::OnGotSwitchStates, weak_ptr_factory_.GetWeakPtr()));
757 }
758
759 // Keyboard/mouse search tags are added/removed dynamically.
760 pointer_device_observer_.Init();
761 pointer_device_observer_.AddObserver(this);
762 pointer_device_observer_.CheckDevices();
763
764 // Stylus search tags are added/removed dynamically.
765 ui::DeviceDataManager::GetInstance()->AddObserver(this);
766 UpdateStylusSearchTags();
767
768 // Display search tags are added/removed dynamically.
769 ash::BindCrosDisplayConfigController(
770 cros_display_config_.BindNewPipeAndPassReceiver());
771 mojo::PendingAssociatedRemote<ash::mojom::CrosDisplayConfigObserver> observer;
772 cros_display_config_observer_receiver_.Bind(
773 observer.InitWithNewEndpointAndPassReceiver());
774 cros_display_config_->AddObserver(std::move(observer));
775 OnDisplayConfigChanged();
776
777 // Night Light settings are added/removed dynamically.
778 ash::NightLightController* night_light_controller =
779 ash::NightLightController::GetInstance();
780 if (night_light_controller) {
781 ash::NightLightController::GetInstance()->AddObserver(this);
782 OnNightLightEnabledChanged(
783 ash::NightLightController::GetInstance()->GetEnabled());
784 }
785 }
786
~DeviceSection()787 DeviceSection::~DeviceSection() {
788 pointer_device_observer_.RemoveObserver(this);
789 ui::DeviceDataManager::GetInstance()->RemoveObserver(this);
790
791 PowerManagerClient* power_manager_client = PowerManagerClient::Get();
792 if (power_manager_client)
793 power_manager_client->RemoveObserver(this);
794
795 ash::NightLightController* night_light_controller =
796 ash::NightLightController::GetInstance();
797 if (night_light_controller)
798 night_light_controller->RemoveObserver(this);
799 }
800
AddLoadTimeData(content::WebUIDataSource * html_source)801 void DeviceSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
802 static constexpr webui::LocalizedString kDeviceStrings[] = {
803 {"devicePageTitle", IDS_SETTINGS_DEVICE_TITLE},
804 {"touchPadScrollLabel", IDS_OS_SETTINGS_TOUCHPAD_REVERSE_SCROLL_LABEL},
805 };
806 AddLocalizedStringsBulk(html_source, kDeviceStrings);
807
808 html_source->AddBoolean("isDemoSession",
809 chromeos::DemoSession::IsDeviceInDemoMode());
810 html_source->AddBoolean("enableLanguageSettingsV2",
811 base::FeatureList::IsEnabled(
812 ::chromeos::features::kLanguageSettingsUpdate));
813
814 AddDevicePointersStrings(html_source);
815 AddDeviceKeyboardStrings(html_source);
816 AddDeviceStylusStrings(html_source);
817 AddDeviceDisplayStrings(html_source);
818 AddDeviceStorageStrings(
819 html_source, features::ShouldShowExternalStorageSettings(profile()));
820 AddDevicePowerStrings(html_source);
821 }
822
AddHandlers(content::WebUI * web_ui)823 void DeviceSection::AddHandlers(content::WebUI* web_ui) {
824 if (ash::features::IsDisplayIdentificationEnabled() ||
825 ash::features::IsDisplayAlignmentAssistanceEnabled()) {
826 web_ui->AddMessageHandler(
827 std::make_unique<chromeos::settings::DisplayHandler>());
828 }
829
830 web_ui->AddMessageHandler(
831 std::make_unique<chromeos::settings::KeyboardHandler>());
832 web_ui->AddMessageHandler(
833 std::make_unique<chromeos::settings::PointerHandler>());
834 web_ui->AddMessageHandler(
835 std::make_unique<chromeos::settings::PowerHandler>(pref_service_));
836 web_ui->AddMessageHandler(
837 std::make_unique<chromeos::settings::StylusHandler>());
838 }
839
GetSectionNameMessageId() const840 int DeviceSection::GetSectionNameMessageId() const {
841 return IDS_SETTINGS_DEVICE_TITLE;
842 }
843
GetSection() const844 mojom::Section DeviceSection::GetSection() const {
845 return mojom::Section::kDevice;
846 }
847
GetSectionIcon() const848 mojom::SearchResultIcon DeviceSection::GetSectionIcon() const {
849 return mojom::SearchResultIcon::kLaptop;
850 }
851
GetSectionPath() const852 std::string DeviceSection::GetSectionPath() const {
853 return mojom::kDeviceSectionPath;
854 }
855
LogMetric(mojom::Setting setting,base::Value & value) const856 bool DeviceSection::LogMetric(mojom::Setting setting,
857 base::Value& value) const {
858 switch (setting) {
859 case mojom::Setting::kTouchpadSpeed:
860 base::UmaHistogramEnumeration(
861 "ChromeOS.Settings.Device.TouchpadSpeedValue",
862 static_cast<TouchpadSensitivity>(value.GetInt()));
863 return true;
864
865 case mojom::Setting::kKeyboardFunctionKeys:
866 base::UmaHistogramBoolean("ChromeOS.Settings.Device.KeyboardFunctionKeys",
867 value.GetBool());
868 return true;
869
870 default:
871 return false;
872 }
873 }
874
RegisterHierarchy(HierarchyGenerator * generator) const875 void DeviceSection::RegisterHierarchy(HierarchyGenerator* generator) const {
876 // Pointers.
877 generator->RegisterTopLevelSubpage(
878 IDS_SETTINGS_MOUSE_AND_TOUCHPAD_TITLE, mojom::Subpage::kPointers,
879 mojom::SearchResultIcon::kMouse, mojom::SearchResultDefaultRank::kMedium,
880 mojom::kPointersSubpagePath);
881 static constexpr mojom::Setting kPointersSettings[] = {
882 mojom::Setting::kTouchpadTapToClick,
883 mojom::Setting::kTouchpadTapDragging,
884 mojom::Setting::kTouchpadReverseScrolling,
885 mojom::Setting::kTouchpadAcceleration,
886 mojom::Setting::kTouchpadScrollAcceleration,
887 mojom::Setting::kTouchpadSpeed,
888 mojom::Setting::kMouseSwapPrimaryButtons,
889 mojom::Setting::kMouseReverseScrolling,
890 mojom::Setting::kMouseAcceleration,
891 mojom::Setting::kMouseScrollAcceleration,
892 mojom::Setting::kMouseSpeed,
893 };
894 RegisterNestedSettingBulk(mojom::Subpage::kPointers, kPointersSettings,
895 generator);
896
897 // Keyboard.
898 generator->RegisterTopLevelSubpage(
899 IDS_SETTINGS_KEYBOARD_TITLE, mojom::Subpage::kKeyboard,
900 mojom::SearchResultIcon::kKeyboard,
901 mojom::SearchResultDefaultRank::kMedium, mojom::kKeyboardSubpagePath);
902 static constexpr mojom::Setting kKeyboardSettings[] = {
903 mojom::Setting::kKeyboardFunctionKeys,
904 mojom::Setting::kKeyboardAutoRepeat,
905 mojom::Setting::kKeyboardShortcuts,
906 };
907 RegisterNestedSettingBulk(mojom::Subpage::kKeyboard, kKeyboardSettings,
908 generator);
909
910 // Stylus.
911 generator->RegisterTopLevelSubpage(
912 IDS_SETTINGS_STYLUS_TITLE, mojom::Subpage::kStylus,
913 mojom::SearchResultIcon::kStylus, mojom::SearchResultDefaultRank::kMedium,
914 mojom::kStylusSubpagePath);
915 static constexpr mojom::Setting kStylusSettings[] = {
916 mojom::Setting::kStylusToolsInShelf,
917 mojom::Setting::kStylusNoteTakingApp,
918 mojom::Setting::kStylusNoteTakingFromLockScreen,
919 mojom::Setting::kStylusLatestNoteOnLockScreen,
920 };
921 RegisterNestedSettingBulk(mojom::Subpage::kStylus, kStylusSettings,
922 generator);
923
924 // Display.
925 generator->RegisterTopLevelSubpage(
926 IDS_SETTINGS_DISPLAY_TITLE, mojom::Subpage::kDisplay,
927 mojom::SearchResultIcon::kDisplay,
928 mojom::SearchResultDefaultRank::kMedium, mojom::kDisplaySubpagePath);
929 static constexpr mojom::Setting kDisplaySettings[] = {
930 mojom::Setting::kDisplaySize,
931 mojom::Setting::kNightLight,
932 mojom::Setting::kDisplayOrientation,
933 mojom::Setting::kDisplayArrangement,
934 mojom::Setting::kDisplayResolution,
935 mojom::Setting::kDisplayRefreshRate,
936 mojom::Setting::kDisplayMirroring,
937 mojom::Setting::kAllowWindowsToSpanDisplays,
938 mojom::Setting::kAmbientColors,
939 mojom::Setting::kTouchscreenCalibration,
940 mojom::Setting::kNightLightColorTemperature,
941 mojom::Setting::kDisplayOverscan,
942 };
943 RegisterNestedSettingBulk(mojom::Subpage::kDisplay, kDisplaySettings,
944 generator);
945
946 // Storage.
947 generator->RegisterTopLevelSubpage(
948 IDS_SETTINGS_STORAGE_TITLE, mojom::Subpage::kStorage,
949 mojom::SearchResultIcon::kHardDrive,
950 mojom::SearchResultDefaultRank::kMedium, mojom::kStorageSubpagePath);
951 generator->RegisterNestedSubpage(
952 IDS_SETTINGS_STORAGE_EXTERNAL, mojom::Subpage::kExternalStorage,
953 mojom::Subpage::kStorage, mojom::SearchResultIcon::kHardDrive,
954 mojom::SearchResultDefaultRank::kMedium,
955 mojom::kExternalStorageSubpagePath);
956
957 // Power.
958 generator->RegisterTopLevelSubpage(
959 IDS_SETTINGS_POWER_TITLE, mojom::Subpage::kPower,
960 mojom::SearchResultIcon::kPower, mojom::SearchResultDefaultRank::kMedium,
961 mojom::kPowerSubpagePath);
962 static constexpr mojom::Setting kPowerSettings[] = {
963 mojom::Setting::kPowerIdleBehaviorWhileCharging,
964 mojom::Setting::kPowerIdleBehaviorWhileOnBattery,
965 mojom::Setting::kPowerSource,
966 mojom::Setting::kSleepWhenLaptopLidClosed,
967 };
968 RegisterNestedSettingBulk(mojom::Subpage::kPower, kPowerSettings, generator);
969 }
970
TouchpadExists(bool exists)971 void DeviceSection::TouchpadExists(bool exists) {
972 SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
973 updater.RemoveSearchTags(GetTouchpadSearchConcepts());
974 updater.RemoveSearchTags(GetTouchpadScrollAccelerationSearchConcepts());
975
976 if (exists) {
977 updater.AddSearchTags(GetTouchpadSearchConcepts());
978 if (base::FeatureList::IsEnabled(chromeos::features::kAllowScrollSettings))
979 updater.AddSearchTags(GetTouchpadScrollAccelerationSearchConcepts());
980 }
981 }
982
MouseExists(bool exists)983 void DeviceSection::MouseExists(bool exists) {
984 SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
985
986 if (exists)
987 updater.AddSearchTags(GetMouseSearchConcepts());
988 else
989 updater.RemoveSearchTags(GetMouseSearchConcepts());
990 }
991
PointingStickExists(bool exists)992 void DeviceSection::PointingStickExists(bool exists) {
993 // TODO(crbug.com/1114828): manage search tags when the UI is implemented.
994 }
995
OnDeviceListsComplete()996 void DeviceSection::OnDeviceListsComplete() {
997 UpdateStylusSearchTags();
998 }
999
OnNightLightEnabledChanged(bool enabled)1000 void DeviceSection::OnNightLightEnabledChanged(bool enabled) {
1001 OnDisplayConfigChanged();
1002 }
1003
OnDisplayConfigChanged()1004 void DeviceSection::OnDisplayConfigChanged() {
1005 cros_display_config_->GetDisplayUnitInfoList(
1006 /*single_unified=*/true,
1007 base::BindOnce(&DeviceSection::OnGetDisplayUnitInfoList,
1008 base::Unretained(this)));
1009 }
1010
PowerChanged(const power_manager::PowerSupplyProperties & properties)1011 void DeviceSection::PowerChanged(
1012 const power_manager::PowerSupplyProperties& properties) {
1013 SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
1014
1015 if (properties.battery_state() !=
1016 power_manager::PowerSupplyProperties_BatteryState_NOT_PRESENT) {
1017 updater.AddSearchTags(GetPowerWithBatterySearchConcepts());
1018 }
1019 }
1020
OnGetDisplayUnitInfoList(std::vector<ash::mojom::DisplayUnitInfoPtr> display_unit_info_list)1021 void DeviceSection::OnGetDisplayUnitInfoList(
1022 std::vector<ash::mojom::DisplayUnitInfoPtr> display_unit_info_list) {
1023 cros_display_config_->GetDisplayLayoutInfo(base::BindOnce(
1024 &DeviceSection::OnGetDisplayLayoutInfo, base::Unretained(this),
1025 std::move(display_unit_info_list)));
1026 }
1027
OnGetDisplayLayoutInfo(std::vector<ash::mojom::DisplayUnitInfoPtr> display_unit_info_list,ash::mojom::DisplayLayoutInfoPtr display_layout_info)1028 void DeviceSection::OnGetDisplayLayoutInfo(
1029 std::vector<ash::mojom::DisplayUnitInfoPtr> display_unit_info_list,
1030 ash::mojom::DisplayLayoutInfoPtr display_layout_info) {
1031 bool has_multiple_displays = display_unit_info_list.size() > 1u;
1032
1033 // Mirroring mode is active if there's at least one display and if there's a
1034 // mirror source ID.
1035 bool is_mirrored = !display_unit_info_list.empty() &&
1036 display_layout_info->mirror_source_id.has_value();
1037
1038 bool has_internal_display = false;
1039 bool has_external_display = false;
1040 bool unified_desktop_mode = false;
1041 for (const auto& display_unit_info : display_unit_info_list) {
1042 has_internal_display |= display_unit_info->is_internal;
1043 has_external_display |= !display_unit_info->is_internal;
1044
1045 unified_desktop_mode |= display_unit_info->is_primary &&
1046 display_layout_info->layout_mode ==
1047 ash::mojom::DisplayLayoutMode::kUnified;
1048 }
1049
1050 SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
1051
1052 // Arrangement UI.
1053 if (has_multiple_displays || is_mirrored)
1054 updater.AddSearchTags(GetDisplayArrangementSearchConcepts());
1055 else
1056 updater.RemoveSearchTags(GetDisplayArrangementSearchConcepts());
1057
1058 // Mirror toggle.
1059 if (is_mirrored || (!unified_desktop_mode && has_multiple_displays))
1060 updater.AddSearchTags(GetDisplayMirrorSearchConcepts());
1061 else
1062 updater.RemoveSearchTags(GetDisplayMirrorSearchConcepts());
1063
1064 // Unified Desktop toggle.
1065 if (unified_desktop_mode ||
1066 (IsUnifiedDesktopAvailable() && has_multiple_displays && !is_mirrored)) {
1067 updater.AddSearchTags(GetDisplayUnifiedDesktopSearchConcepts());
1068 } else {
1069 updater.RemoveSearchTags(GetDisplayUnifiedDesktopSearchConcepts());
1070 }
1071
1072 // External display settings.
1073 if (has_external_display)
1074 updater.AddSearchTags(GetDisplayExternalSearchConcepts());
1075 else
1076 updater.RemoveSearchTags(GetDisplayExternalSearchConcepts());
1077
1078 // Refresh Rate dropdown.
1079 if (has_external_display && IsListAllDisplayModesEnabled())
1080 updater.AddSearchTags(GetDisplayExternalWithRefreshSearchConcepts());
1081 else
1082 updater.RemoveSearchTags(GetDisplayExternalWithRefreshSearchConcepts());
1083
1084 // Orientation settings.
1085 if (!unified_desktop_mode)
1086 updater.AddSearchTags(GetDisplayOrientationSearchConcepts());
1087 else
1088 updater.RemoveSearchTags(GetDisplayOrientationSearchConcepts());
1089
1090 // Ambient color settings.
1091 if (DoesDeviceSupportAmbientColor() && has_internal_display)
1092 updater.AddSearchTags(GetDisplayAmbientSearchConcepts());
1093 else
1094 updater.RemoveSearchTags(GetDisplayAmbientSearchConcepts());
1095
1096 // Touch calibration settings.
1097 if (IsTouchCalibrationAvailable())
1098 updater.AddSearchTags(GetDisplayTouchCalibrationSearchConcepts());
1099 else
1100 updater.RemoveSearchTags(GetDisplayTouchCalibrationSearchConcepts());
1101
1102 // Night Light on settings.
1103 if (ash::NightLightController::GetInstance()->GetEnabled())
1104 updater.AddSearchTags(GetDisplayNightLightOnSearchConcepts());
1105 else
1106 updater.RemoveSearchTags(GetDisplayNightLightOnSearchConcepts());
1107 }
1108
OnGotSwitchStates(base::Optional<PowerManagerClient::SwitchStates> result)1109 void DeviceSection::OnGotSwitchStates(
1110 base::Optional<PowerManagerClient::SwitchStates> result) {
1111 SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
1112
1113 if (result && result->lid_state != PowerManagerClient::LidState::NOT_PRESENT)
1114 updater.AddSearchTags(GetPowerWithLaptopLidSearchConcepts());
1115 }
1116
UpdateStylusSearchTags()1117 void DeviceSection::UpdateStylusSearchTags() {
1118 // If not yet complete, wait for OnDeviceListsComplete() callback.
1119 if (!ui::DeviceDataManager::GetInstance()->AreDeviceListsComplete())
1120 return;
1121
1122 SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
1123
1124 // TODO(https://crbug.com/1071905): Only show stylus settings if a stylus has
1125 // been set up. HasStylusInput() will return true for any stylus-compatible
1126 // device, even if it doesn't have a stylus.
1127 if (ash::stylus_utils::HasStylusInput())
1128 updater.AddSearchTags(GetStylusSearchConcepts());
1129 else
1130 updater.RemoveSearchTags(GetStylusSearchConcepts());
1131 }
1132
AddDevicePointersStrings(content::WebUIDataSource * html_source)1133 void DeviceSection::AddDevicePointersStrings(
1134 content::WebUIDataSource* html_source) {
1135 static constexpr webui::LocalizedString kPointersStrings[] = {
1136 {"mouseTitle", IDS_SETTINGS_MOUSE_TITLE},
1137 {"pointingStickTitle", IDS_SETTINGS_POINTING_STICK_TITLE},
1138 {"touchpadTitle", IDS_SETTINGS_TOUCHPAD_TITLE},
1139 {"mouseAndTouchpadTitle", IDS_SETTINGS_MOUSE_AND_TOUCHPAD_TITLE},
1140 {"touchpadTapToClickEnabledLabel",
1141 IDS_SETTINGS_TOUCHPAD_TAP_TO_CLICK_ENABLED_LABEL},
1142 {"touchpadSpeed", IDS_SETTINGS_TOUCHPAD_SPEED_LABEL},
1143 {"pointerSlow", IDS_SETTINGS_POINTER_SPEED_SLOW_LABEL},
1144 {"pointerFast", IDS_SETTINGS_POINTER_SPEED_FAST_LABEL},
1145 {"mouseScrollSpeed", IDS_SETTINGS_MOUSE_SCROLL_SPEED_LABEL},
1146 {"mouseSpeed", IDS_SETTINGS_MOUSE_SPEED_LABEL},
1147 {"mouseSwapButtons", IDS_SETTINGS_MOUSE_SWAP_BUTTONS_LABEL},
1148 {"primaryMouseButtonLeft", IDS_SETTINGS_PRIMARY_MOUSE_BUTTON_LEFT_LABEL},
1149 {"primaryMouseButtonRight",
1150 IDS_SETTINGS_PRIMARY_MOUSE_BUTTON_RIGHT_LABEL},
1151 {"mouseReverseScroll", IDS_SETTINGS_MOUSE_REVERSE_SCROLL_LABEL},
1152 {"mouseAccelerationLabel", IDS_SETTINGS_MOUSE_ACCELERATION_LABEL},
1153 {"mouseScrollAccelerationLabel",
1154 IDS_SETTINGS_MOUSE_SCROLL_ACCELERATION_LABEL},
1155 {"touchpadAccelerationLabel", IDS_SETTINGS_TOUCHPAD_ACCELERATION_LABEL},
1156 {"touchpadScrollAccelerationLabel",
1157 IDS_SETTINGS_TOUCHPAD_SCROLL_ACCELERATION_LABEL},
1158 {"touchpadScrollSpeed", IDS_SETTINGS_TOUCHPAD_SCROLL_SPEED_LABEL},
1159 };
1160 AddLocalizedStringsBulk(html_source, kPointersStrings);
1161
1162 html_source->AddString("naturalScrollLearnMoreLink",
1163 GetHelpUrlWithBoard(chrome::kNaturalScrollHelpURL));
1164
1165 html_source->AddBoolean(
1166 "allowDisableMouseAcceleration",
1167 base::FeatureList::IsEnabled(::features::kAllowDisableMouseAcceleration));
1168 html_source->AddBoolean(
1169 "allowScrollSettings",
1170 base::FeatureList::IsEnabled(::chromeos::features::kAllowScrollSettings));
1171 html_source->AddBoolean(
1172 "separatePointingStickSettings",
1173 base::FeatureList::IsEnabled(::features::kSeparatePointingStickSettings));
1174 }
1175
1176 } // namespace settings
1177 } // namespace chromeos
1178