15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/options/chromeos/display_options_handler.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ash/display/display_configurator_animation.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/display/display_controller.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/display/display_manager.h"
12ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ash/display/resolution_notification_controller.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/display/display_preferences.h"
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/grit/generated_resources.h"
21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/public/browser/user_metrics.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_ui.h"
23ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "grit/ash_strings.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/display.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen.h"
28a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "ui/gfx/size_conversions.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochusing ash::DisplayManager;
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace options {
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DisplayManager* GetDisplayManager() {
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ash::Shell::GetInstance()->display_manager();
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int64 GetDisplayId(const base::ListValue* args) {
4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Assumes the display ID is specified as the first argument.
4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string id_value;
4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!args->GetString(0, &id_value)) {
4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    LOG(ERROR) << "Can't find ID";
4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return gfx::Display::kInvalidDisplayID;
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int64 display_id = gfx::Display::kInvalidDisplayID;
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!base::StringToInt64(id_value, &display_id)) {
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    LOG(ERROR) << "Invalid display id: " << id_value;
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return gfx::Display::kInvalidDisplayID;
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return display_id;
5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
57effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbase::string16 GetColorProfileName(ui::ColorCalibrationProfile profile) {
58effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  switch (profile) {
59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case ui::COLOR_PROFILE_STANDARD:
60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return l10n_util::GetStringUTF16(
61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_COLOR_PROFILE_STANDARD);
62effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case ui::COLOR_PROFILE_DYNAMIC:
63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return l10n_util::GetStringUTF16(
64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_COLOR_PROFILE_DYNAMIC);
65effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case ui::COLOR_PROFILE_MOVIE:
66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return l10n_util::GetStringUTF16(
67effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_COLOR_PROFILE_MOVIE);
68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case ui::COLOR_PROFILE_READING:
69effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return l10n_util::GetStringUTF16(
70effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_COLOR_PROFILE_READING);
71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case ui::NUM_COLOR_PROFILES:
72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      break;
73effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
75effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  NOTREACHED();
76effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return base::string16();
77effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
78effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)int GetIntOrDouble(const base::DictionaryValue* dict,
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   const std::string& field) {
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  double double_result = 0;
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (dict->GetDouble(field, &double_result))
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return static_cast<int>(double_result);
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int result = 0;
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  dict->GetInteger(field, &result);
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return result;
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool GetFloat(const base::DictionaryValue* dict,
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              const std::string& field,
925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              float* result) {
935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  double double_result = 0;
945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (dict->GetDouble(field, &double_result)) {
955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    *result = static_cast<float>(double_result);
965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return true;
975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return false;
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool ConvertValueToDisplayMode(const base::DictionaryValue* dict,
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               ash::DisplayMode* mode) {
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  mode->size.set_width(GetIntOrDouble(dict, "originalWidth"));
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  mode->size.set_height(GetIntOrDouble(dict, "originalHeight"));
1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (mode->size.IsEmpty()) {
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    LOG(ERROR) << "missing width or height.";
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!GetFloat(dict, "refreshRate", &mode->refresh_rate)) {
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    LOG(ERROR) << "missing refreshRate.";
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!GetFloat(dict, "scale", &mode->ui_scale)) {
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    LOG(ERROR) << "missing ui-scale.";
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!GetFloat(dict, "deviceScaleFactor", &mode->device_scale_factor)) {
1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    LOG(ERROR) << "missing deviceScaleFactor.";
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return true;
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)base::DictionaryValue* ConvertDisplayModeToValue(int64 display_id,
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                 const ash::DisplayMode& mode) {
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool is_internal = GetDisplayManager()->IsInternalDisplayId(display_id);
1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::DictionaryValue* result = new base::DictionaryValue();
1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  gfx::Size size_dip = mode.GetSizeInDIP();
1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  result->SetInteger("width", size_dip.width());
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  result->SetInteger("height", size_dip.height());
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  result->SetInteger("originalWidth", mode.size.width());
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  result->SetInteger("originalHeight", mode.size.height());
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  result->SetDouble("deviceScaleFactor", mode.device_scale_factor);
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  result->SetDouble("scale", mode.ui_scale);
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  result->SetDouble("refreshRate", mode.refresh_rate);
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  result->SetBoolean(
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "isBest", is_internal ? (mode.ui_scale == 1.0f) : mode.native);
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  result->SetBoolean("isNative", mode.native);
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  result->SetBoolean(
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      "selected", mode.IsEquivalent(
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          GetDisplayManager()->GetActiveModeForDisplayId(display_id)));
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return result;
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DisplayOptionsHandler::DisplayOptionsHandler() {
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if !defined(USE_ATHENA)
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // ash::Shell doesn't exist in Athena.
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // See: http://crbug.com/416961
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ash::Shell::GetInstance()->display_controller()->AddObserver(this);
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DisplayOptionsHandler::~DisplayOptionsHandler() {
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if !defined(USE_ATHENA)
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // ash::Shell doesn't exist in Athena.
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ash::Shell::GetInstance()->display_controller()->RemoveObserver(this);
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayOptionsHandler::GetLocalizedValues(
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::DictionaryValue* localized_strings) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(localized_strings);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterTitle(localized_strings, "displayOptionsPage",
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_TAB_TITLE);
16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  localized_strings->SetString(
16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      "selectedDisplayTitleOptions", l10n_util::GetStringUTF16(
17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_OPTIONS));
17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  localized_strings->SetString(
17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      "selectedDisplayTitleResolution", l10n_util::GetStringUTF16(
17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_RESOLUTION));
17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  localized_strings->SetString(
17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      "selectedDisplayTitleOrientation", l10n_util::GetStringUTF16(
17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_ORIENTATION));
17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  localized_strings->SetString(
17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      "selectedDisplayTitleOverscan", l10n_util::GetStringUTF16(
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_OVERSCAN));
18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  localized_strings->SetString("startMirroring", l10n_util::GetStringUTF16(
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_START_MIRRORING));
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  localized_strings->SetString("stopMirroring", l10n_util::GetStringUTF16(
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_STOP_MIRRORING));
18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  localized_strings->SetString("mirroringDisplay", l10n_util::GetStringUTF16(
18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_MIRRORING_DISPLAY_NAME));
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  localized_strings->SetString("setPrimary", l10n_util::GetStringUTF16(
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_SET_PRIMARY));
18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  localized_strings->SetString("annotateBest", l10n_util::GetStringUTF16(
19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_RESOLUTION_ANNOTATION_BEST));
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  localized_strings->SetString("annotateNative", l10n_util::GetStringUTF16(
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_RESOLUTION_ANNOTATION_NATIVE));
19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  localized_strings->SetString("orientation0", l10n_util::GetStringUTF16(
19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_STANDARD_ORIENTATION));
19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  localized_strings->SetString("orientation90", l10n_util::GetStringUTF16(
196ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      IDS_ASH_STATUS_TRAY_DISPLAY_ORIENTATION_90));
19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  localized_strings->SetString("orientation180", l10n_util::GetStringUTF16(
198ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      IDS_ASH_STATUS_TRAY_DISPLAY_ORIENTATION_180));
19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  localized_strings->SetString("orientation270", l10n_util::GetStringUTF16(
200ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      IDS_ASH_STATUS_TRAY_DISPLAY_ORIENTATION_270));
20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  localized_strings->SetString(
20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      "startCalibratingOverscan", l10n_util::GetStringUTF16(
20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_START_CALIBRATING_OVERSCAN));
204effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  localized_strings->SetString(
205effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      "selectedDisplayColorProfile", l10n_util::GetStringUTF16(
206effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          IDS_OPTIONS_SETTINGS_DISPLAY_OPTIONS_COLOR_PROFILE));
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayOptionsHandler::InitializePage() {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(web_ui());
2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if !defined(USE_ATHENA)
2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  web_ui()->CallJavascriptFunction(
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "options.BrowserOptions.enableDisplayButton",
2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::FundamentalValue(true));
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayOptionsHandler::RegisterMessages() {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_ui()->RegisterMessageCallback(
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "getDisplayInfo",
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&DisplayOptionsHandler::HandleDisplayInfo,
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)));
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_ui()->RegisterMessageCallback(
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "setMirroring",
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&DisplayOptionsHandler::HandleMirroring,
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)));
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_ui()->RegisterMessageCallback(
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "setPrimary",
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&DisplayOptionsHandler::HandleSetPrimary,
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)));
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_ui()->RegisterMessageCallback(
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "setDisplayLayout",
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&DisplayOptionsHandler::HandleDisplayLayout,
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)));
23590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  web_ui()->RegisterMessageCallback(
2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      "setDisplayMode",
2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(&DisplayOptionsHandler::HandleSetDisplayMode,
238a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                 base::Unretained(this)));
239a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  web_ui()->RegisterMessageCallback(
24090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      "setOrientation",
24190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::Bind(&DisplayOptionsHandler::HandleSetOrientation,
24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 base::Unretained(this)));
243effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  web_ui()->RegisterMessageCallback(
244effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      "setColorProfile",
245effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      base::Bind(&DisplayOptionsHandler::HandleSetColorProfile,
246effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                 base::Unretained(this)));
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayOptionsHandler::OnDisplayConfigurationChanging() {
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayOptionsHandler::OnDisplayConfigurationChanged() {
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SendAllDisplayInfo();
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayOptionsHandler::SendAllDisplayInfo() {
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DisplayManager* display_manager = GetDisplayManager();
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
259ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  std::vector<gfx::Display> displays;
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) {
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    displays.push_back(display_manager->GetDisplayAt(i));
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SendDisplayInfo(displays);
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayOptionsHandler::SendDisplayInfo(
267ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    const std::vector<gfx::Display>& displays) {
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DisplayManager* display_manager = GetDisplayManager();
26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::FundamentalValue mirroring(display_manager->IsMirrored());
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 primary_id = ash::Shell::GetScreen()->GetPrimaryDisplay().id();
27290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::ListValue js_displays;
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < displays.size(); ++i) {
274ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    const gfx::Display& display = displays[i];
275c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    const ash::DisplayInfo& display_info =
276ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        display_manager->GetDisplayInfo(display.id());
277ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    const gfx::Rect& bounds = display.bounds();
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::DictionaryValue* js_display = new base::DictionaryValue();
279ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    js_display->SetString("id", base::Int64ToString(display.id()));
28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    js_display->SetInteger("x", bounds.x());
28190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    js_display->SetInteger("y", bounds.y());
28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    js_display->SetInteger("width", bounds.width());
28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    js_display->SetInteger("height", bounds.height());
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    js_display->SetString("name",
285ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                          display_manager->GetDisplayNameForId(display.id()));
286ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    js_display->SetBoolean("isPrimary", display.id() == primary_id);
287ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    js_display->SetBoolean("isInternal", display.IsInternal());
28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    js_display->SetInteger("orientation",
28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                           static_cast<int>(display_info.rotation()));
290f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    base::ListValue* js_resolutions = new base::ListValue();
2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::vector<ash::DisplayMode>& display_modes =
2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        display_info.display_modes();
294f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    for (size_t i = 0; i < display_modes.size(); ++i) {
2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      js_resolutions->Append(
2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          ConvertDisplayModeToValue(display.id(), display_modes[i]));
297f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
298f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    js_display->Set("resolutions", js_resolutions);
299effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
300effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    js_display->SetInteger("colorProfile", display_info.color_profile());
301effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    base::ListValue* available_color_profiles = new base::ListValue();
302effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    for (size_t i = 0;
303effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch         i < display_info.available_color_profiles().size(); ++i) {
304effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      base::DictionaryValue* color_profile_dict = new base::DictionaryValue();
305effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      ui::ColorCalibrationProfile color_profile =
306effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          display_info.available_color_profiles()[i];
307effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      color_profile_dict->SetInteger("profileId", color_profile);
308effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      color_profile_dict->SetString("name", GetColorProfileName(color_profile));
309effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      available_color_profiles->Append(color_profile_dict);
310effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    }
311effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    js_display->Set("availableColorProfiles", available_color_profiles);
31290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    js_displays.Append(js_display);
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> layout_value(base::Value::CreateNullValue());
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> offset_value(base::Value::CreateNullValue());
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (display_manager->GetNumDisplays() > 1) {
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ash::DisplayLayout layout =
3193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        display_manager->GetCurrentDisplayLayout();
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layout_value.reset(new base::FundamentalValue(layout.position));
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    offset_value.reset(new base::FundamentalValue(layout.offset));
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_ui()->CallJavascriptFunction(
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "options.DisplayOptions.setDisplayInfo",
32690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      mirroring, js_displays, *layout_value.get(), *offset_value.get());
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayOptionsHandler::OnFadeOutForMirroringFinished(bool is_mirroring) {
33090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ash::Shell::GetInstance()->display_manager()->SetMirrorMode(is_mirroring);
331c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Not necessary to start fade-in animation. DisplayConfigurator will do that.
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayOptionsHandler::OnFadeOutForDisplayLayoutFinished(
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int position, int offset) {
336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SetCurrentDisplayLayout(
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ash::DisplayLayout::FromInts(position, offset));
3385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ash::Shell::GetInstance()->display_configurator_animation()->
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      StartFadeInAnimation();
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayOptionsHandler::HandleDisplayInfo(
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::ListValue* unused_args) {
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SendAllDisplayInfo();
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayOptionsHandler::HandleMirroring(const base::ListValue* args) {
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!args->empty());
349c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  content::RecordAction(
350c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      base::UserMetricsAction("Options_DisplayToggleMirroring"));
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_mirroring = false;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  args->GetBoolean(0, &is_mirroring);
3535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ash::Shell::GetInstance()->display_configurator_animation()->
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      StartFadeOutAnimation(base::Bind(
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &DisplayOptionsHandler::OnFadeOutForMirroringFinished,
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Unretained(this),
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          is_mirroring));
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayOptionsHandler::HandleSetPrimary(const base::ListValue* args) {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!args->empty());
362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int64 display_id = GetDisplayId(args);
36390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (display_id == gfx::Display::kInvalidDisplayID)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
366c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  content::RecordAction(base::UserMetricsAction("Options_DisplaySetPrimary"));
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ash::Shell::GetInstance()->display_controller()->
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SetPrimaryDisplayId(display_id);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayOptionsHandler::HandleDisplayLayout(const base::ListValue* args) {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  double layout = -1;
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  double offset = -1;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!args->GetDouble(0, &layout) || !args->GetDouble(1, &offset)) {
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Invalid parameter";
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SendAllDisplayInfo();
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_LE(ash::DisplayLayout::TOP, layout);
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GE(ash::DisplayLayout::LEFT, layout);
381c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  content::RecordAction(base::UserMetricsAction("Options_DisplayRearrange"));
3825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ash::Shell::GetInstance()->display_configurator_animation()->
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      StartFadeOutAnimation(base::Bind(
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &DisplayOptionsHandler::OnFadeOutForDisplayLayoutFinished,
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Unretained(this),
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          static_cast<int>(layout),
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          static_cast<int>(offset)));
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void DisplayOptionsHandler::HandleSetDisplayMode(const base::ListValue* args) {
39190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!args->empty());
39290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
39390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int64 display_id = GetDisplayId(args);
39490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (display_id == gfx::Display::kInvalidDisplayID)
39590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
39690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const base::DictionaryValue* mode_data = NULL;
3985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!args->GetDictionary(1, &mode_data)) {
3995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    LOG(ERROR) << "Failed to get mode data";
40090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
40190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
402a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
4035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ash::DisplayMode mode;
4045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!ConvertValueToDisplayMode(mode_data, &mode))
405a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return;
406a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
407c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  content::RecordAction(
408c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      base::UserMetricsAction("Options_DisplaySetResolution"));
4095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ash::DisplayManager* display_manager = GetDisplayManager();
4105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ash::DisplayMode current_mode =
4115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      display_manager->GetActiveModeForDisplayId(display_id);
4125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (display_manager->SetDisplayMode(display_id, mode)) {
4135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ash::Shell::GetInstance()->resolution_notification_controller()->
4145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        PrepareNotification(
4155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            display_id, current_mode, mode, base::Bind(&StoreDisplayPrefs));
416a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
41790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
41890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
41990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void DisplayOptionsHandler::HandleSetOrientation(const base::ListValue* args) {
42090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!args->empty());
42190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
42290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int64 display_id = GetDisplayId(args);
42390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (display_id == gfx::Display::kInvalidDisplayID)
42490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
42590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
42690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string rotation_value;
42790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  gfx::Display::Rotation new_rotation = gfx::Display::ROTATE_0;
42890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!args->GetString(1, &rotation_value)) {
42990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    LOG(ERROR) << "Can't find new orientation";
43090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
43190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
43290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (rotation_value == "90")
43390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    new_rotation = gfx::Display::ROTATE_90;
43490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  else if (rotation_value == "180")
43590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    new_rotation = gfx::Display::ROTATE_180;
43690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  else if (rotation_value == "270")
43790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    new_rotation = gfx::Display::ROTATE_270;
43890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  else if (rotation_value != "0")
43990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    LOG(ERROR) << "Invalid rotation: " << rotation_value << " Falls back to 0";
44090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
441c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  content::RecordAction(
442c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      base::UserMetricsAction("Options_DisplaySetOrientation"));
44390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  GetDisplayManager()->SetDisplayRotation(display_id, new_rotation);
44490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
44590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
446effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid DisplayOptionsHandler::HandleSetColorProfile(const base::ListValue* args) {
447effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK(!args->empty());
448effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  int64 display_id = GetDisplayId(args);
449effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (display_id == gfx::Display::kInvalidDisplayID)
450effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return;
451effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
452effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::string profile_value;
453effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!args->GetString(1, &profile_value)) {
454effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    LOG(ERROR) << "Invalid profile_value";
455effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return;
456effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
457effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
458effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  int profile_id;
459effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!base::StringToInt(profile_value, &profile_id)) {
460effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    LOG(ERROR) << "Invalid profile: " << profile_value;
461effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return;
462effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
463effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
464effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (profile_id < ui::COLOR_PROFILE_STANDARD ||
465effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      profile_id > ui::COLOR_PROFILE_READING) {
466effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    LOG(ERROR) << "Invalid profile_id: " << profile_id;
467effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return;
468effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
469effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
470effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  GetDisplayManager()->SetColorCalibrationProfile(
471effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      display_id, static_cast<ui::ColorCalibrationProfile>(profile_id));
472effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  SendAllDisplayInfo();
473effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
474effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace options
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
477