Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(127)

Side by Side Diff: ui/display/manager/display_preferences.cc

Issue 2760453003: Work In Progess
Patch Set: convert local_state to use pre_client_store_ Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/display/manager/display_preferences.h ('k') | ui/display/manager/json_converter.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 "ui/display/manager/display_preferences.h"
6
7 #include <stddef.h>
8
9 #include "ash/shell.h"
10 #include "base/strings/string16.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_split.h"
13 #include "base/strings/string_util.h"
14 #include "base/sys_info.h"
15 #include "base/values.h"
16 #include "chrome/browser/browser_process.h"
17 #include "chrome/common/pref_names.h"
18 #include "components/prefs/pref_registry_simple.h"
19 #include "components/prefs/pref_service.h"
20 #include "components/prefs/scoped_user_pref_update.h"
21 #include "components/user_manager/user_manager.h"
22 #include "third_party/cros_system_api/dbus/service_constants.h"
23 #include "ui/display/display.h"
24 #include "ui/display/manager/display_layout_store.h"
25 #include "ui/display/manager/display_manager_utilities.h"
26 #include "ui/display/manager/display_pref_util.h"
27 #include "ui/display/manager/json_converter.h"
28 #include "ui/display/types/display_constants.h"
29 #include "ui/gfx/geometry/insets.h"
30 #include "url/url_canon.h"
31 #include "url/url_util.h"
32
33 #include "services/preferences/public/cpp/pref_client_store.h"
34 #include "services/preferences/public/interfaces/preferences.mojom.h"
35
36 namespace display {
37 namespace {
38
39 const char kInsetsTopKey[] = "insets_top";
40 const char kInsetsLeftKey[] = "insets_left";
41 const char kInsetsBottomKey[] = "insets_bottom";
42 const char kInsetsRightKey[] = "insets_right";
43
44 const char kTouchCalibrationWidth[] = "touch_calibration_width";
45 const char kTouchCalibrationHeight[] = "touch_calibration_height";
46 const char kTouchCalibrationPointPairs[] = "touch_calibration_point_pairs";
47
48 // This kind of boilerplates should be done by base::JSONValueConverter but it
49 // doesn't support classes like gfx::Insets for now.
50 // TODO(mukai): fix base::JSONValueConverter and use it here.
51 bool ValueToInsets(const base::DictionaryValue& value, gfx::Insets* insets) {
52 DCHECK(insets);
53 int top = 0;
54 int left = 0;
55 int bottom = 0;
56 int right = 0;
57 if (value.GetInteger(kInsetsTopKey, &top) &&
58 value.GetInteger(kInsetsLeftKey, &left) &&
59 value.GetInteger(kInsetsBottomKey, &bottom) &&
60 value.GetInteger(kInsetsRightKey, &right)) {
61 insets->Set(top, left, bottom, right);
62 return true;
63 }
64 return false;
65 }
66
67 void InsetsToValue(const gfx::Insets& insets, base::DictionaryValue* value) {
68 DCHECK(value);
69 value->SetInteger(kInsetsTopKey, insets.top());
70 value->SetInteger(kInsetsLeftKey, insets.left());
71 value->SetInteger(kInsetsBottomKey, insets.bottom());
72 value->SetInteger(kInsetsRightKey, insets.right());
73 }
74
75 // Unmarshalls the string containing CalibrationPointPairQuad and populates
76 // |point_pair_quad| with the unmarshalled data.
77 bool ParseTouchCalibrationStringValue(
78 const std::string& str,
79 display::TouchCalibrationData::CalibrationPointPairQuad* point_pair_quad) {
80 DCHECK(point_pair_quad);
81 int x = 0, y = 0;
82 std::vector<std::string> parts = base::SplitString(
83 str, " ", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
84 size_t total = point_pair_quad->size();
85 gfx::Point display_point, touch_point;
86 for (std::size_t row = 0; row < total; row++) {
87 if (!base::StringToInt(parts[row * total], &x) ||
88 !base::StringToInt(parts[row * total + 1], &y)) {
89 return false;
90 }
91 display_point.SetPoint(x, y);
92
93 if (!base::StringToInt(parts[row * total + 2], &x) ||
94 !base::StringToInt(parts[row * total + 3], &y)) {
95 return false;
96 }
97 touch_point.SetPoint(x, y);
98
99 (*point_pair_quad)[row] = std::make_pair(display_point, touch_point);
100 }
101 return true;
102 }
103
104 // Retrieves touch calibration associated data from the dictionary and stores
105 // it in an instance of TouchCalibrationData struct.
106 bool ValueToTouchData(const base::DictionaryValue& value,
107 display::TouchCalibrationData* touch_calibration_data) {
108 display::TouchCalibrationData::CalibrationPointPairQuad* point_pair_quad =
109 &(touch_calibration_data->point_pairs);
110
111 std::string str;
112 if (!value.GetString(kTouchCalibrationPointPairs, &str))
113 return false;
114
115 if (!ParseTouchCalibrationStringValue(str, point_pair_quad))
116 return false;
117
118 int width, height;
119 if (!value.GetInteger(kTouchCalibrationWidth, &width) ||
120 !value.GetInteger(kTouchCalibrationHeight, &height)) {
121 return false;
122 }
123 touch_calibration_data->bounds = gfx::Size(width, height);
124 return true;
125 }
126
127 // Stores the touch calibration data into the dictionary.
128 void TouchDataToValue(
129 const display::TouchCalibrationData& touch_calibration_data,
130 base::DictionaryValue* value) {
131 DCHECK(value);
132 std::string str;
133 for (std::size_t row = 0; row < touch_calibration_data.point_pairs.size();
134 row++) {
135 str +=
136 base::IntToString(touch_calibration_data.point_pairs[row].first.x()) +
137 " ";
138 str +=
139 base::IntToString(touch_calibration_data.point_pairs[row].first.y()) +
140 " ";
141 str +=
142 base::IntToString(touch_calibration_data.point_pairs[row].second.x()) +
143 " ";
144 str +=
145 base::IntToString(touch_calibration_data.point_pairs[row].second.y());
146 if (row != touch_calibration_data.point_pairs.size() - 1)
147 str += " ";
148 }
149 value->SetString(kTouchCalibrationPointPairs, str);
150 value->SetInteger(kTouchCalibrationWidth,
151 touch_calibration_data.bounds.width());
152 value->SetInteger(kTouchCalibrationHeight,
153 touch_calibration_data.bounds.height());
154 }
155
156 std::string ColorProfileToString(display::ColorCalibrationProfile profile) {
157 switch (profile) {
158 case display::COLOR_PROFILE_STANDARD:
159 return "standard";
160 case display::COLOR_PROFILE_DYNAMIC:
161 return "dynamic";
162 case display::COLOR_PROFILE_MOVIE:
163 return "movie";
164 case display::COLOR_PROFILE_READING:
165 return "reading";
166 case display::NUM_COLOR_PROFILES:
167 break;
168 }
169 NOTREACHED();
170 return "";
171 }
172
173 display::ColorCalibrationProfile StringToColorProfile(
174 const std::string& value) {
175 if (value == "standard")
176 return display::COLOR_PROFILE_STANDARD;
177 else if (value == "dynamic")
178 return display::COLOR_PROFILE_DYNAMIC;
179 else if (value == "movie")
180 return display::COLOR_PROFILE_MOVIE;
181 else if (value == "reading")
182 return display::COLOR_PROFILE_READING;
183 NOTREACHED();
184 return display::COLOR_PROFILE_STANDARD;
185 }
186
187 // Returns true id the current user can write display preferences to
188 // Local State.
189 bool UserCanSaveDisplayPreference() {
190 user_manager::UserManager* user_manager = user_manager::UserManager::Get();
191 return user_manager->IsUserLoggedIn() &&
192 (user_manager->IsLoggedInAsUserWithGaiaAccount() ||
193 user_manager->IsLoggedInAsSupervisedUser() ||
194 user_manager->IsLoggedInAsKioskApp());
195 }
196
197 void LoadDisplayLayouts(DisplayManager* display_manager,
198 preferences::PrefClientStore* pref_client_store_) {
199 // PrefService* local_state = g_browser_process->local_state();
200 //PrefService* local_state = NULL;
201 display::DisplayLayoutStore* layout_store = display_manager->layout_store();
202
203 const base::Value** value_layouts = nullptr;
204 pref_client_store_->GetValue(prefs::kSecondaryDisplays, value_layouts);
205 const base::DictionaryValue* layouts = nullptr;
206 (*value_layouts)->GetAsDictionary(&layouts);
207
208 for (base::DictionaryValue::Iterator it(*layouts); !it.IsAtEnd();
209 it.Advance()) {
210 std::unique_ptr<display::DisplayLayout> layout(new display::DisplayLayout);
211 if (!display::JsonToDisplayLayout(it.value(), layout.get())) {
212 LOG(WARNING) << "Invalid preference value for " << it.key();
213 continue;
214 }
215
216 if (it.key().find(",") != std::string::npos) {
217 std::vector<std::string> ids_str = base::SplitString(
218 it.key(), ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
219 std::vector<int64_t> ids;
220 for (std::string id_str : ids_str) {
221 int64_t id;
222 if (!base::StringToInt64(id_str, &id))
223 continue;
224 ids.push_back(id);
225 }
226 display::DisplayIdList list =
227 display::GenerateDisplayIdList(ids.begin(), ids.end());
228 layout_store->RegisterLayoutForDisplayIdList(list, std::move(layout));
229 }
230 }
231 }
232
233 void LoadDisplayProperties(DisplayManager* display_manager,
234 preferences::PrefClientStore* pref_client_store_) {
235 const base::Value** value_properties = nullptr;
236 pref_client_store_->GetValue(prefs::kDisplayProperties, value_properties);
237 const base::DictionaryValue* properties = nullptr;
238 (*value_properties)->GetAsDictionary(&properties);
239
240 for (base::DictionaryValue::Iterator it(*properties); !it.IsAtEnd();
241 it.Advance()) {
242 const base::DictionaryValue* dict_value = nullptr;
243 if (!it.value().GetAsDictionary(&dict_value) || dict_value == nullptr)
244 continue;
245 int64_t id = display::kInvalidDisplayId;
246 if (!base::StringToInt64(it.key(), &id) ||
247 id == display::kInvalidDisplayId) {
248 continue;
249 }
250 display::Display::Rotation rotation = display::Display::ROTATE_0;
251 float ui_scale = 1.0f;
252 const gfx::Insets* insets_to_set = nullptr;
253
254 int rotation_value = 0;
255 if (dict_value->GetInteger("rotation", &rotation_value)) {
256 rotation = static_cast<display::Display::Rotation>(rotation_value);
257 }
258 int ui_scale_value = 0;
259 if (dict_value->GetInteger("ui-scale", &ui_scale_value))
260 ui_scale = static_cast<float>(ui_scale_value) / 1000.0f;
261
262 int width = 0, height = 0;
263 dict_value->GetInteger("width", &width);
264 dict_value->GetInteger("height", &height);
265 gfx::Size resolution_in_pixels(width, height);
266
267 float device_scale_factor = 1.0;
268 int dsf_value = 0;
269 if (dict_value->GetInteger("device-scale-factor", &dsf_value))
270 device_scale_factor = static_cast<float>(dsf_value) / 1000.0f;
271
272 gfx::Insets insets;
273 if (ValueToInsets(*dict_value, &insets))
274 insets_to_set = &insets;
275
276 display::TouchCalibrationData calibration_data;
277 display::TouchCalibrationData* calibration_data_to_set = nullptr;
278 if (ValueToTouchData(*dict_value, &calibration_data))
279 calibration_data_to_set = &calibration_data;
280
281 display::ColorCalibrationProfile color_profile =
282 display::COLOR_PROFILE_STANDARD;
283 std::string color_profile_name;
284 if (dict_value->GetString("color_profile_name", &color_profile_name))
285 color_profile = StringToColorProfile(color_profile_name);
286 display_manager->RegisterDisplayProperty(
287 id, rotation, ui_scale, insets_to_set, resolution_in_pixels,
288 device_scale_factor, color_profile, calibration_data_to_set);
289 }
290 }
291
292 void LoadDisplayRotationState(
293 DisplayManager* display_manager,
294 preferences::PrefClientStore* pref_client_store_) {
295
296 const base::Value** value_properties = nullptr;
297 pref_client_store_->GetValue(prefs::kDisplayRotationLock, value_properties);
298 const base::DictionaryValue* properties = nullptr;
299 (*value_properties)->GetAsDictionary(&properties);
300
301 bool rotation_lock = false;
302 if (!properties->GetBoolean("lock", &rotation_lock))
303 return;
304
305 int rotation = display::Display::ROTATE_0;
306 if (!properties->GetInteger("orientation", &rotation))
307 return;
308
309 display_manager->RegisterDisplayRotationProperties(
310 rotation_lock, static_cast<display::Display::Rotation>(rotation));
311 }
312
313 void StoreDisplayLayoutPref(const display::DisplayIdList& list,
314 const display::DisplayLayout& display_layout) {
315 std::string name = display::DisplayIdListToString(list);
316
317 // PrefService* local_state = g_browser_process->local_state();
318 PrefService* local_state = NULL;
319 DictionaryPrefUpdate update(local_state, prefs::kSecondaryDisplays);
320 base::DictionaryValue* pref_data = update.Get();
321 std::unique_ptr<base::Value> layout_value(new base::DictionaryValue());
322 if (pref_data->HasKey(name)) {
323 base::Value* value = nullptr;
324 if (pref_data->Get(name, &value) && value != nullptr)
325 layout_value.reset(value->DeepCopy());
326 }
327 if (display::DisplayLayoutToJson(display_layout, layout_value.get()))
328 pref_data->Set(name, layout_value.release());
329 }
330
331 void StoreCurrentDisplayLayoutPrefs(DisplayManager* display_manager) {
332 if (!UserCanSaveDisplayPreference() ||
333 display_manager->num_connected_displays() < 2) {
334 return;
335 }
336
337 display::DisplayIdList list = display_manager->GetCurrentDisplayIdList();
338 const display::DisplayLayout& display_layout =
339 display_manager->layout_store()->GetRegisteredDisplayLayout(list);
340 StoreDisplayLayoutPref(list, display_layout);
341 }
342
343 void StoreCurrentDisplayProperties(DisplayManager* display_manager) {
344 // PrefService* local_state = g_browser_process->local_state();
345 PrefService* local_state = NULL;
346
347 DictionaryPrefUpdate update(local_state, prefs::kDisplayProperties);
348 base::DictionaryValue* pref_data = update.Get();
349
350 size_t num = display_manager->GetNumDisplays();
351 for (size_t i = 0; i < num; ++i) {
352 const display::Display& display = display_manager->GetDisplayAt(i);
353 int64_t id = display.id();
354 display::ManagedDisplayInfo info = display_manager->GetDisplayInfo(id);
355
356 std::unique_ptr<base::DictionaryValue> property_value(
357 new base::DictionaryValue());
358 // Don't save the display preference in unified mode because its
359 // size and modes can change depending on the combination of displays.
360 if (display_manager->IsInUnifiedMode())
361 continue;
362 property_value->SetInteger("rotation",
363 static_cast<int>(info.GetRotation(
364 display::Display::ROTATION_SOURCE_USER)));
365 property_value->SetInteger(
366 "ui-scale", static_cast<int>(info.configured_ui_scale() * 1000));
367
368 scoped_refptr<display::ManagedDisplayMode> mode =
369 display_manager->GetSelectedModeForDisplayId(id);
370 if (!display.IsInternal() && mode && !mode->native()) {
371 property_value->SetInteger("width", mode->size().width());
372 property_value->SetInteger("height", mode->size().height());
373 property_value->SetInteger(
374 "device-scale-factor",
375 static_cast<int>(mode->device_scale_factor() * 1000));
376 }
377 if (!info.overscan_insets_in_dip().IsEmpty())
378 InsetsToValue(info.overscan_insets_in_dip(), property_value.get());
379 if (info.color_profile() != display::COLOR_PROFILE_STANDARD) {
380 property_value->SetString("color_profile_name",
381 ColorProfileToString(info.color_profile()));
382 }
383 if (info.has_touch_calibration_data())
384 TouchDataToValue(info.GetTouchCalibrationData(), property_value.get());
385 pref_data->Set(base::Int64ToString(id), property_value.release());
386 }
387 }
388
389 typedef std::map<chromeos::DisplayPowerState, std::string>
390 DisplayPowerStateToStringMap;
391
392 const DisplayPowerStateToStringMap* GetDisplayPowerStateToStringMap() {
393 // Don't save or retore ALL_OFF state. crbug.com/318456.
394 static const DisplayPowerStateToStringMap* map = display::CreateToStringMap(
395 chromeos::DISPLAY_POWER_ALL_ON, "all_on",
396 chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
397 "internal_off_external_on",
398 chromeos::DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF,
399 "internal_on_external_off");
400 return map;
401 }
402
403 bool GetDisplayPowerStateFromString(const base::StringPiece& state,
404 chromeos::DisplayPowerState* field) {
405 if (display::ReverseFind(GetDisplayPowerStateToStringMap(), state, field))
406 return true;
407 LOG(ERROR) << "Invalid display power state value:" << state;
408 return false;
409 }
410
411 void StoreDisplayPowerState(chromeos::DisplayPowerState power_state) {
412 const DisplayPowerStateToStringMap* map = GetDisplayPowerStateToStringMap();
413 DisplayPowerStateToStringMap::const_iterator iter = map->find(power_state);
414 if (iter != map->end()) {
415 // PrefService* local_state = g_browser_process->local_state();
416 PrefService* local_state = NULL;
417 local_state->SetString(prefs::kDisplayPowerState, iter->second);
418 }
419 }
420
421 void StoreCurrentDisplayPowerState(DisplayConfigurator* display_configurator) {
422 StoreDisplayPowerState(display_configurator->requested_power_state());
423 }
424
425 void StoreDisplayRotationPrefs(DisplayManager* display_manager,
426 bool rotation_lock) {
427 if (!display::Display::HasInternalDisplay())
428 return;
429
430 // PrefService* local_state = g_browser_process->local_state();
431 PrefService* local_state = NULL;
432 DictionaryPrefUpdate update(local_state, prefs::kDisplayRotationLock);
433 base::DictionaryValue* pref_data = update.Get();
434 pref_data->SetBoolean("lock", rotation_lock);
435 display::Display::Rotation rotation =
436 display_manager->GetDisplayInfo(display::Display::InternalDisplayId())
437 .GetRotation(display::Display::ROTATION_SOURCE_ACCELEROMETER);
438 pref_data->SetInteger("orientation", static_cast<int>(rotation));
439 }
440
441 void StoreCurrentDisplayRotationLockPrefs(DisplayManager* display_manager) {
442 bool rotation_lock =
443 display_manager->registered_internal_display_rotation_lock();
444 StoreDisplayRotationPrefs(display_manager, rotation_lock);
445 }
446
447 } // namespace
448
449 void RegisterDisplayLocalStatePrefs(PrefRegistrySimple* registry) {
450 // Per-display preference.
451 registry->RegisterDictionaryPref(prefs::kSecondaryDisplays);
452 registry->RegisterDictionaryPref(prefs::kDisplayProperties);
453 DisplayPowerStateToStringMap::const_iterator iter =
454 GetDisplayPowerStateToStringMap()->find(chromeos::DISPLAY_POWER_ALL_ON);
455 registry->RegisterStringPref(prefs::kDisplayPowerState, iter->second);
456 registry->RegisterDictionaryPref(prefs::kDisplayRotationLock);
457 }
458
459 void StoreDisplayPrefs(DisplayConfigurator* display_configurator,
460 DisplayManager* display_manager) {
461 // Stores the power state regardless of the login status, because the power
462 // state respects to the current status (close/open) of the lid which can be
463 // changed in any situation. See crbug.com/285360
464 StoreCurrentDisplayPowerState(display_configurator);
465 StoreCurrentDisplayRotationLockPrefs(display_manager);
466
467 // Do not store prefs when the confirmation dialog is shown.
468 if (!UserCanSaveDisplayPreference() ||
469 !ash::Shell::GetInstance()->ShouldSaveDisplaySettings()) {
470 return;
471 }
472
473 StoreCurrentDisplayLayoutPrefs(display_manager);
474 StoreCurrentDisplayProperties(display_manager);
475 }
476
477 void LoadDisplayPreferences(bool first_run_after_boot,
478 DisplayConfigurator* display_configurator,
479 DisplayManager* display_manager,
480 preferences::PrefClientStore* pref_client_store_) {
481 // void LoadDisplayPreferences(bool first_run_after_boot, DisplayConfigurator*
482 // display_configurator, DisplayManager* display_manager) {
483 LOG(ERROR) << "LoadDisplayPreferences a";
484 LoadDisplayLayouts(display_manager, pref_client_store_);
485 LOG(ERROR) << "LoadDisplayPreferences b";
486 LoadDisplayProperties(display_manager, pref_client_store_);
487 LOG(ERROR) << "LoadDisplayPreferences c";
488 LoadDisplayRotationState(display_manager, pref_client_store_);
489 if (!first_run_after_boot) {
490 LOG(ERROR) << "LoadDisplayPreferences 1";
491 // Restore DisplayPowerState:
492 const base::Value** value_properties = nullptr;
493 pref_client_store_->GetValue(prefs::kDisplayPowerState, value_properties);
494 std::string value;
495 (*value_properties)->GetAsString(&value);
496 LOG(ERROR) << "LoadDisplayPreferences 2";
497
498 chromeos::DisplayPowerState power_state;
499 if (GetDisplayPowerStateFromString(value, &power_state)) {
500 LOG(ERROR) << "LoadDisplayPreferences 3";
501 display_configurator->SetInitialDisplayPower(power_state);
502 }
503 LOG(ERROR) << "LoadDisplayPreferences 4";
504 }
505 }
506
507 // Stores the display layout for given display pairs.
508 void StoreDisplayLayoutPrefForTest(const display::DisplayIdList& list,
509 const display::DisplayLayout& layout) {
510 StoreDisplayLayoutPref(list, layout);
511 }
512
513 // Stores the given |power_state|.
514 void StoreDisplayPowerStateForTest(chromeos::DisplayPowerState power_state) {
515 StoreDisplayPowerState(power_state);
516 }
517
518 bool ParseTouchCalibrationStringForTest(
519 const std::string& str,
520 display::TouchCalibrationData::CalibrationPointPairQuad* point_pair_quad) {
521 return ParseTouchCalibrationStringValue(str, point_pair_quad);
522 }
523
524 } // namespace chromeos
OLDNEW
« no previous file with comments | « ui/display/manager/display_preferences.h ('k') | ui/display/manager/json_converter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698