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

Side by Side Diff: chrome/browser/ui/webui/options/chromeos/display_options_handler.cc

Issue 417113012: Introduce user customization of external HighDPI mode for 4K monitor. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/webui/options/chromeos/display_options_handler.h" 5 #include "chrome/browser/ui/webui/options/chromeos/display_options_handler.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "ash/display/display_configurator_animation.h" 9 #include "ash/display/display_configurator_animation.h"
10 #include "ash/display/display_controller.h" 10 #include "ash/display/display_controller.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 47
48 int64 display_id = gfx::Display::kInvalidDisplayID; 48 int64 display_id = gfx::Display::kInvalidDisplayID;
49 if (!base::StringToInt64(id_value, &display_id)) { 49 if (!base::StringToInt64(id_value, &display_id)) {
50 LOG(ERROR) << "Invalid display id: " << id_value; 50 LOG(ERROR) << "Invalid display id: " << id_value;
51 return gfx::Display::kInvalidDisplayID; 51 return gfx::Display::kInvalidDisplayID;
52 } 52 }
53 53
54 return display_id; 54 return display_id;
55 } 55 }
56 56
57 bool CompareDisplayMode(ash::DisplayMode d1, ash::DisplayMode d2) { 57 bool CompareResolution(base::Value* v1, base::Value* v2) {
58 if (d1.size.GetArea() == d2.size.GetArea()) 58 base::DictionaryValue* r1 = NULL;
59 return d1.refresh_rate < d2.refresh_rate; 59 base::DictionaryValue* r2 = NULL;
60 return d1.size.GetArea() < d2.size.GetArea(); 60 if (!v1->GetAsDictionary(&r1))
61 return true;
62 if (!v2->GetAsDictionary(&r2))
63 return false;
64 int width1 = 0, height1 = 0, width2 = 0, height2 = 0;
65 if (!r1->GetInteger("width", &width1) || !r1->GetInteger("height", &height1))
66 return true;
67 if (!r2->GetInteger("width", &width2) || !r2->GetInteger("height", &height2))
68 return false;
69
70 if (width1 * height1 != width2 * height2)
71 return width1 * height1 < width2 * height2;
72
73 double dsf1 = 0, dsf2 = 0;
74 if (!r1->GetDouble("deviceScaleFactor", &dsf1))
75 return true;
76 if (!r2->GetDouble("deviceScaleFactor", &dsf2))
77 return false;
78 return dsf1 < dsf2;
79
80 double refresh1 = 0, refresh2 = 0;
81 if (!r1->GetDouble("refreshRate", &refresh1))
82 return true;
83 if (!r2->GetDouble("refreshRate", &refresh2))
84 return false;
85 // Higher refresh rate should appear first.
86 if (refresh1 != refresh2)
87 return refresh1 > refresh2;
61 } 88 }
62 89
63 base::string16 GetColorProfileName(ui::ColorCalibrationProfile profile) { 90 base::string16 GetColorProfileName(ui::ColorCalibrationProfile profile) {
64 switch (profile) { 91 switch (profile) {
65 case ui::COLOR_PROFILE_STANDARD: 92 case ui::COLOR_PROFILE_STANDARD:
66 return l10n_util::GetStringUTF16( 93 return l10n_util::GetStringUTF16(
67 IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_COLOR_PROFILE_STANDARD); 94 IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_COLOR_PROFILE_STANDARD);
68 case ui::COLOR_PROFILE_DYNAMIC: 95 case ui::COLOR_PROFILE_DYNAMIC:
69 return l10n_util::GetStringUTF16( 96 return l10n_util::GetStringUTF16(
70 IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_COLOR_PROFILE_DYNAMIC); 97 IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_COLOR_PROFILE_DYNAMIC);
71 case ui::COLOR_PROFILE_MOVIE: 98 case ui::COLOR_PROFILE_MOVIE:
72 return l10n_util::GetStringUTF16( 99 return l10n_util::GetStringUTF16(
73 IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_COLOR_PROFILE_MOVIE); 100 IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_COLOR_PROFILE_MOVIE);
74 case ui::COLOR_PROFILE_READING: 101 case ui::COLOR_PROFILE_READING:
75 return l10n_util::GetStringUTF16( 102 return l10n_util::GetStringUTF16(
76 IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_COLOR_PROFILE_READING); 103 IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_COLOR_PROFILE_READING);
77 case ui::NUM_COLOR_PROFILES: 104 case ui::NUM_COLOR_PROFILES:
78 break; 105 break;
79 } 106 }
80 107
81 NOTREACHED(); 108 NOTREACHED();
82 return base::string16(); 109 return base::string16();
83 } 110 }
84 111
112 base::ListValue* CreateResolutionsForUIScale(
113 const ash::DisplayInfo& display_info) {
114 std::vector<float> ui_scales =
115 DisplayManager::GetScalesForDisplay(display_info);
116 gfx::SizeF base_size = display_info.bounds_in_native().size();
117 base::ListValue* result = new base::ListValue();
118
119 base_size.Scale(1.0f / display_info.device_scale_factor());
120 if (display_info.rotation() == gfx::Display::ROTATE_90 ||
121 display_info.rotation() == gfx::Display::ROTATE_270) {
122 float tmp = base_size.width();
123 base_size.set_width(base_size.height());
124 base_size.set_height(tmp);
125 }
126 for (size_t i = 0; i < ui_scales.size(); ++i) {
127 base::DictionaryValue* resolution_info = new base::DictionaryValue();
128 resolution_info->SetDouble("scale", ui_scales[i]);
129 if (ui_scales[i] == 1.0f)
130 resolution_info->SetBoolean("isBest", true);
131 resolution_info->SetBoolean(
132 "selected", display_info.configured_ui_scale() == ui_scales[i]);
133 resolution_info->SetInteger("width", base_size.width() * ui_scales[i]);
134 resolution_info->SetInteger("height", base_size.height() * ui_scales[i]);
135 result->Append(resolution_info);
136 }
137
138 return result;
139 }
140
141 base::ListValue* CreateResolutionsForExternalDisplay(
142 const ash::DisplayInfo& display_info) {
143 base::ListValue* result = new base::ListValue();
144 gfx::Size current_size = display_info.bounds_in_native().size();
145
146 const std::vector<ash::DisplayMode>& display_modes =
147 display_info.display_modes();
148 base::DictionaryValue* largest_resolution_info = NULL;
149 gfx::Size largest_resolution;
150 bool largest_is_selected = false;
151 for (size_t i = 0; i < display_modes.size(); ++i) {
152 base::DictionaryValue* resolution_info = new base::DictionaryValue();
153 gfx::Size resolution = display_modes[i].size;
154 // Picks the largest one as the "best", which is the last element
155 // because |display_modes| is sorted by its area.
156 if (largest_resolution.GetArea() < resolution.GetArea()) {
157 if (largest_resolution_info)
158 largest_resolution_info->SetBoolean("isBest", false);
159 resolution_info->SetBoolean("isBest", true);
160 largest_resolution_info = resolution_info;
161 largest_resolution = resolution;
162 largest_is_selected = (resolution == current_size);
163 }
164 resolution_info->SetBoolean("selected", (resolution == current_size));
165 resolution_info->SetInteger("width", resolution.width());
166 resolution_info->SetInteger("height", resolution.height());
167 if (display_modes[i].refresh_rate > 0.0f) {
168 resolution_info->SetDouble("refreshRate",
169 display_modes[i].refresh_rate);
170 }
171 result->Append(resolution_info);
172 }
173
174 // Add other scale factors for larger external displays.
175 std::vector<float> device_scale_factors =
176 DisplayManager::GetDeviceScaleFactorsForDisplay(display_info);
177 if (device_scale_factors.size() > 1) {
178 for (size_t i = 0; i < device_scale_factors.size(); ++i) {
179 if (device_scale_factors[i] == 1.0f)
180 continue;
181 base::DictionaryValue* resolution_info =
182 largest_resolution_info->DeepCopy();
183 resolution_info->SetBoolean("isBest", false);
184 if (largest_is_selected &&
185 display_info.device_scale_factor() == device_scale_factors[i]) {
186 resolution_info->SetBoolean("selected", true);
187 largest_resolution_info->SetBoolean("selected", false);
188 } else {
189 resolution_info->SetBoolean("selected", false);
190 }
191 resolution_info->SetDouble(
192 "deviceScaleFactor", device_scale_factors[i]);
193 resolution_info->SetInteger(
194 "originalWidth", largest_resolution.width());
195 resolution_info->SetInteger(
196 "originalHeight", largest_resolution.height());
197 resolution_info->SetInteger(
198 "width", largest_resolution.width() / device_scale_factors[i]);
199 resolution_info->SetInteger(
200 "height", largest_resolution.height() / device_scale_factors[i]);
201 result->Append(resolution_info);
202 }
203 largest_resolution_info->SetDouble("deviceScaleFactor", 1.0);
204 }
205 return result;
206 }
207
85 } // namespace 208 } // namespace
86 209
87 DisplayOptionsHandler::DisplayOptionsHandler() { 210 DisplayOptionsHandler::DisplayOptionsHandler() {
88 ash::Shell::GetInstance()->display_controller()->AddObserver(this); 211 ash::Shell::GetInstance()->display_controller()->AddObserver(this);
89 } 212 }
90 213
91 DisplayOptionsHandler::~DisplayOptionsHandler() { 214 DisplayOptionsHandler::~DisplayOptionsHandler() {
92 ash::Shell::GetInstance()->display_controller()->RemoveObserver(this); 215 ash::Shell::GetInstance()->display_controller()->RemoveObserver(this);
93 } 216 }
94 217
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 base::Unretained(this))); 283 base::Unretained(this)));
161 web_ui()->RegisterMessageCallback( 284 web_ui()->RegisterMessageCallback(
162 "setUIScale", 285 "setUIScale",
163 base::Bind(&DisplayOptionsHandler::HandleSetUIScale, 286 base::Bind(&DisplayOptionsHandler::HandleSetUIScale,
164 base::Unretained(this))); 287 base::Unretained(this)));
165 web_ui()->RegisterMessageCallback( 288 web_ui()->RegisterMessageCallback(
166 "setResolution", 289 "setResolution",
167 base::Bind(&DisplayOptionsHandler::HandleSetResolution, 290 base::Bind(&DisplayOptionsHandler::HandleSetResolution,
168 base::Unretained(this))); 291 base::Unretained(this)));
169 web_ui()->RegisterMessageCallback( 292 web_ui()->RegisterMessageCallback(
293 "setDeviceScaleFactor",
294 base::Bind(&DisplayOptionsHandler::HandleSetDeviceScaleFactor,
295 base::Unretained(this)));
296 web_ui()->RegisterMessageCallback(
170 "setOrientation", 297 "setOrientation",
171 base::Bind(&DisplayOptionsHandler::HandleSetOrientation, 298 base::Bind(&DisplayOptionsHandler::HandleSetOrientation,
172 base::Unretained(this))); 299 base::Unretained(this)));
173 web_ui()->RegisterMessageCallback( 300 web_ui()->RegisterMessageCallback(
174 "setColorProfile", 301 "setColorProfile",
175 base::Bind(&DisplayOptionsHandler::HandleSetColorProfile, 302 base::Bind(&DisplayOptionsHandler::HandleSetColorProfile,
176 base::Unretained(this))); 303 base::Unretained(this)));
177 } 304 }
178 305
179 void DisplayOptionsHandler::OnDisplayConfigurationChanging() { 306 void DisplayOptionsHandler::OnDisplayConfigurationChanging() {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 js_display->SetInteger("width", bounds.width()); 339 js_display->SetInteger("width", bounds.width());
213 js_display->SetInteger("height", bounds.height()); 340 js_display->SetInteger("height", bounds.height());
214 js_display->SetString("name", 341 js_display->SetString("name",
215 display_manager->GetDisplayNameForId(display.id())); 342 display_manager->GetDisplayNameForId(display.id()));
216 js_display->SetBoolean("isPrimary", display.id() == primary_id); 343 js_display->SetBoolean("isPrimary", display.id() == primary_id);
217 js_display->SetBoolean("isInternal", display.IsInternal()); 344 js_display->SetBoolean("isInternal", display.IsInternal());
218 js_display->SetInteger("orientation", 345 js_display->SetInteger("orientation",
219 static_cast<int>(display_info.rotation())); 346 static_cast<int>(display_info.rotation()));
220 std::vector<ash::DisplayMode> display_modes; 347 std::vector<ash::DisplayMode> display_modes;
221 std::vector<float> ui_scales; 348 std::vector<float> ui_scales;
222 if (display.IsInternal()) { 349 base::ListValue* js_resolutions = display.IsInternal() ?
223 ui_scales = DisplayManager::GetScalesForDisplay(display_info); 350 CreateResolutionsForUIScale(display_info) :
224 gfx::SizeF base_size = display_info.bounds_in_native().size(); 351 CreateResolutionsForExternalDisplay(display_info);
225 base_size.Scale(1.0f / display_info.device_scale_factor()); 352 std::sort(js_resolutions->begin(), js_resolutions->end(),
226 if (display_info.rotation() == gfx::Display::ROTATE_90 || 353 CompareResolution);
227 display_info.rotation() == gfx::Display::ROTATE_270) {
228 float tmp = base_size.width();
229 base_size.set_width(base_size.height());
230 base_size.set_height(tmp);
231 }
232 for (size_t i = 0; i < ui_scales.size(); ++i) {
233 gfx::SizeF new_size = base_size;
234 new_size.Scale(ui_scales[i]);
235 display_modes.push_back(ash::DisplayMode(
236 gfx::ToFlooredSize(new_size), -1.0f, false, false));
237 }
238 } else {
239 for (size_t i = 0; i < display_info.display_modes().size(); ++i)
240 display_modes.push_back(display_info.display_modes()[i]);
241 }
242 std::sort(display_modes.begin(), display_modes.end(), CompareDisplayMode);
243
244 base::ListValue* js_resolutions = new base::ListValue();
245 gfx::Size current_size = display_info.bounds_in_native().size();
246 for (size_t i = 0; i < display_modes.size(); ++i) {
247 base::DictionaryValue* resolution_info = new base::DictionaryValue();
248 gfx::Size resolution = display_modes[i].size;
249 if (!ui_scales.empty()) {
250 resolution_info->SetDouble("scale", ui_scales[i]);
251 if (ui_scales[i] == 1.0f)
252 resolution_info->SetBoolean("isBest", true);
253 resolution_info->SetBoolean(
254 "selected", display_info.configured_ui_scale() == ui_scales[i]);
255 } else {
256 // Picks the largest one as the "best", which is the last element
257 // because |display_modes| is sorted by its area.
258 if (i == display_modes.size() - 1)
259 resolution_info->SetBoolean("isBest", true);
260 resolution_info->SetBoolean("selected", (resolution == current_size));
261 }
262 resolution_info->SetInteger("width", resolution.width());
263 resolution_info->SetInteger("height", resolution.height());
264 if (display_modes[i].refresh_rate > 0.0f) {
265 resolution_info->SetDouble("refreshRate",
266 display_modes[i].refresh_rate);
267 }
268 js_resolutions->Append(resolution_info);
269 }
270 js_display->Set("resolutions", js_resolutions); 354 js_display->Set("resolutions", js_resolutions);
271 355
272 js_display->SetInteger("colorProfile", display_info.color_profile()); 356 js_display->SetInteger("colorProfile", display_info.color_profile());
273 base::ListValue* available_color_profiles = new base::ListValue(); 357 base::ListValue* available_color_profiles = new base::ListValue();
274 for (size_t i = 0; 358 for (size_t i = 0;
275 i < display_info.available_color_profiles().size(); ++i) { 359 i < display_info.available_color_profiles().size(); ++i) {
276 base::DictionaryValue* color_profile_dict = new base::DictionaryValue(); 360 base::DictionaryValue* color_profile_dict = new base::DictionaryValue();
277 ui::ColorCalibrationProfile color_profile = 361 ui::ColorCalibrationProfile color_profile =
278 display_info.available_color_profiles()[i]; 362 display_info.available_color_profiles()[i];
279 color_profile_dict->SetInteger("profileId", color_profile); 363 color_profile_dict->SetInteger("profileId", color_profile);
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 458
375 GetDisplayManager()->SetDisplayUIScale(display_id, ui_scale); 459 GetDisplayManager()->SetDisplayUIScale(display_id, ui_scale);
376 } 460 }
377 461
378 void DisplayOptionsHandler::HandleSetResolution(const base::ListValue* args) { 462 void DisplayOptionsHandler::HandleSetResolution(const base::ListValue* args) {
379 DCHECK(!args->empty()); 463 DCHECK(!args->empty());
380 int64 display_id = GetDisplayId(args); 464 int64 display_id = GetDisplayId(args);
381 if (display_id == gfx::Display::kInvalidDisplayID) 465 if (display_id == gfx::Display::kInvalidDisplayID)
382 return; 466 return;
383 467
384 content::RecordAction(
385 base::UserMetricsAction("Options_DisplaySetResolution"));
386 double width = 0.0f; 468 double width = 0.0f;
387 double height = 0.0f; 469 double height = 0.0f;
388 if (!args->GetDouble(1, &width) || width == 0.0f) { 470 if (!args->GetDouble(1, &width) || width == 0.0f) {
389 LOG(ERROR) << "Can't find new width"; 471 LOG(ERROR) << "Can't find new width";
390 return; 472 return;
391 } 473 }
392 if (!args->GetDouble(2, &height) || height == 0.0f) { 474 if (!args->GetDouble(2, &height) || height == 0.0f) {
393 LOG(ERROR) << "Can't find new height"; 475 LOG(ERROR) << "Can't find new height";
394 return; 476 return;
395 } 477 }
396 478
397 const ash::DisplayInfo& display_info = 479 const ash::DisplayInfo& display_info =
398 GetDisplayManager()->GetDisplayInfo(display_id); 480 GetDisplayManager()->GetDisplayInfo(display_id);
399 gfx::Size new_resolution = gfx::ToFlooredSize(gfx::SizeF(width, height)); 481 gfx::Size new_resolution = gfx::ToFlooredSize(gfx::SizeF(width, height));
400 gfx::Size old_resolution = display_info.bounds_in_native().size(); 482 gfx::Size old_resolution = display_info.bounds_in_native().size();
483 if (new_resolution == old_resolution)
484 return;
485
401 bool has_new_resolution = false; 486 bool has_new_resolution = false;
402 bool has_old_resolution = false; 487 bool has_old_resolution = false;
403 for (size_t i = 0; i < display_info.display_modes().size(); ++i) { 488 for (size_t i = 0; i < display_info.display_modes().size(); ++i) {
404 ash::DisplayMode display_mode = display_info.display_modes()[i]; 489 ash::DisplayMode display_mode = display_info.display_modes()[i];
405 if (display_mode.size == new_resolution) 490 if (display_mode.size == new_resolution)
406 has_new_resolution = true; 491 has_new_resolution = true;
407 if (display_mode.size == old_resolution) 492 if (display_mode.size == old_resolution)
408 has_old_resolution = true; 493 has_old_resolution = true;
409 } 494 }
410 if (!has_new_resolution) { 495 if (!has_new_resolution) {
411 LOG(ERROR) << "No new resolution " << new_resolution.ToString() 496 LOG(ERROR) << "No new resolution " << new_resolution.ToString()
412 << " is found in the display info " << display_info.ToString(); 497 << " is found in the display info " << display_info.ToString();
413 return; 498 return;
414 } 499 }
415 if (!has_old_resolution) { 500 if (!has_old_resolution) {
416 LOG(ERROR) << "No old resolution " << old_resolution.ToString() 501 LOG(ERROR) << "No old resolution " << old_resolution.ToString()
417 << " is found in the display info " << display_info.ToString(); 502 << " is found in the display info " << display_info.ToString();
418 return; 503 return;
419 } 504 }
420 505
506 content::RecordAction(
507 base::UserMetricsAction("Options_DisplaySetResolution"));
508
509 if (display_info.device_scale_factor() != 1.0f)
510 GetDisplayManager()->SetDisplayDeviceScaleFactor(display_id, 1.0f);
511
421 ash::Shell::GetInstance()->resolution_notification_controller()-> 512 ash::Shell::GetInstance()->resolution_notification_controller()->
422 SetDisplayResolutionAndNotify( 513 SetDisplayResolutionAndNotify(
423 display_id, old_resolution, new_resolution, 514 display_id, old_resolution, new_resolution,
424 base::Bind(&StoreDisplayPrefs)); 515 base::Bind(&StoreDisplayPrefs));
425 } 516 }
426 517
518 void DisplayOptionsHandler::HandleSetDeviceScaleFactor(
519 const base::ListValue* args) {
520 DCHECK(!args->empty());
521 int64 display_id = GetDisplayId(args);
522 if (display_id == gfx::Display::kInvalidDisplayID)
523 return;
524
525 double device_scale_factor = 0.0f;
526 if (!args->GetDouble(1, &device_scale_factor) ||
527 device_scale_factor == 0.0f) {
528 LOG(ERROR) << "Can't find new device scale factor";
529 return;
530 }
531
532 const ash::DisplayInfo& display_info =
533 GetDisplayManager()->GetDisplayInfo(display_id);
534 if (display_info.device_scale_factor() == device_scale_factor)
535 return;
536
537 content::RecordAction(
538 base::UserMetricsAction("Options_DisplaySetExternalDeviceScaleFactor"));
539
540 GetDisplayManager()->SetDisplayDeviceScaleFactor(
541 display_id, device_scale_factor);
542 }
543
427 void DisplayOptionsHandler::HandleSetOrientation(const base::ListValue* args) { 544 void DisplayOptionsHandler::HandleSetOrientation(const base::ListValue* args) {
428 DCHECK(!args->empty()); 545 DCHECK(!args->empty());
429 546
430 int64 display_id = GetDisplayId(args); 547 int64 display_id = GetDisplayId(args);
431 if (display_id == gfx::Display::kInvalidDisplayID) 548 if (display_id == gfx::Display::kInvalidDisplayID)
432 return; 549 return;
433 550
434 std::string rotation_value; 551 std::string rotation_value;
435 gfx::Display::Rotation new_rotation = gfx::Display::ROTATE_0; 552 gfx::Display::Rotation new_rotation = gfx::Display::ROTATE_0;
436 if (!args->GetString(1, &rotation_value)) { 553 if (!args->GetString(1, &rotation_value)) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 return; 592 return;
476 } 593 }
477 594
478 GetDisplayManager()->SetColorCalibrationProfile( 595 GetDisplayManager()->SetColorCalibrationProfile(
479 display_id, static_cast<ui::ColorCalibrationProfile>(profile_id)); 596 display_id, static_cast<ui::ColorCalibrationProfile>(profile_id));
480 SendAllDisplayInfo(); 597 SendAllDisplayInfo();
481 } 598 }
482 599
483 } // namespace options 600 } // namespace options
484 } // namespace chromeos 601 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698