1ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 2ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// found in the LICENSE file. 4ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 5ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ash/display/resolution_notification_controller.h" 6ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 7ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ash/display/display_controller.h" 85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ash/display/display_info.h" 9ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ash/display/display_manager.h" 10ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ash/shell.h" 11424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ash/system/system_notifier.h" 12ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "base/strings/utf_string_conversions.h" 13ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "grit/ash_resources.h" 14ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "grit/ash_strings.h" 15ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ui/base/l10n/l10n_util.h" 16ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ui/base/l10n/time_format.h" 17ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ui/base/resource/resource_bundle.h" 18ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ui/gfx/display.h" 19ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ui/gfx/screen.h" 20ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ui/message_center/message_center.h" 21ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ui/message_center/notification.h" 22ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ui/message_center/notification_delegate.h" 23ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 24ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochusing message_center::Notification; 25ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 26ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochnamespace ash { 27ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochnamespace { 28ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 29ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochbool g_use_timer = true; 30ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 31ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochclass ResolutionChangeNotificationDelegate 32ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : public message_center::NotificationDelegate { 33ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch public: 34ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ResolutionChangeNotificationDelegate( 35ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ResolutionNotificationController* controller, 36ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bool has_timeout); 37ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 38ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch protected: 39ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch virtual ~ResolutionChangeNotificationDelegate(); 40ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 41ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch private: 42ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // message_center::NotificationDelegate overrides: 43ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch virtual void Display() OVERRIDE; 44ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch virtual void Error() OVERRIDE; 45ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch virtual void Close(bool by_user) OVERRIDE; 46ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch virtual void Click() OVERRIDE; 47ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch virtual bool HasClickedListener() OVERRIDE; 48ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch virtual void ButtonClick(int button_index) OVERRIDE; 49ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 50ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ResolutionNotificationController* controller_; 51ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bool has_timeout_; 52ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 53ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DISALLOW_COPY_AND_ASSIGN(ResolutionChangeNotificationDelegate); 54ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}; 55ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 56ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochResolutionChangeNotificationDelegate::ResolutionChangeNotificationDelegate( 57ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ResolutionNotificationController* controller, 58ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bool has_timeout) 59ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : controller_(controller), 60ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch has_timeout_(has_timeout) { 61ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(controller_); 62ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 63ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 64ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochResolutionChangeNotificationDelegate::~ResolutionChangeNotificationDelegate() { 65ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 66ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 67ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid ResolutionChangeNotificationDelegate::Display() { 68ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 69ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 70ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid ResolutionChangeNotificationDelegate::Error() { 71ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 72ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 73ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid ResolutionChangeNotificationDelegate::Close(bool by_user) { 74ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (by_user) 753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) controller_->AcceptResolutionChange(false); 76ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 77ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 78ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid ResolutionChangeNotificationDelegate::Click() { 793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) controller_->AcceptResolutionChange(true); 80ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 81ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 82ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochbool ResolutionChangeNotificationDelegate::HasClickedListener() { 83ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return true; 84ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 85ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 86ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid ResolutionChangeNotificationDelegate::ButtonClick(int button_index) { 87ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // If there's the timeout, the first button is "Accept". Otherwise the 88ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // button click should be "Revert". 89ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (has_timeout_ && button_index == 0) 903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) controller_->AcceptResolutionChange(true); 91ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch else 92ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch controller_->RevertResolutionChange(); 93ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 94ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 95ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} // namespace 96ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 97ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// static 98ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochconst int ResolutionNotificationController::kTimeoutInSec = 15; 99ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 100ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// static 101ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochconst char ResolutionNotificationController::kNotificationId[] = 102ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "chrome://settings/display/resolution"; 103ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 104ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochstruct ResolutionNotificationController::ResolutionChangeInfo { 105ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ResolutionChangeInfo(int64 display_id, 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const DisplayMode& old_resolution, 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const DisplayMode& new_resolution, 108ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const base::Closure& accept_callback); 109ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ~ResolutionChangeInfo(); 110ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 111ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // The id of the display where the resolution change happens. 112ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int64 display_id; 113ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 114ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // The resolution before the change. 1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DisplayMode old_resolution; 116ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The requested resolution. Note that this may be different from 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // |current_resolution| which is the actual resolution set. 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DisplayMode new_resolution; 120ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The actual resolution after the change. 1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DisplayMode current_resolution; 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 124ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // The callback when accept is chosen. 125ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::Closure accept_callback; 126ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 127ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // The remaining timeout in seconds. 0 if the change does not time out. 128ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch uint8 timeout_count; 129ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 130ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // The timer to invoke OnTimerTick() every second. This cannot be 131ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // OneShotTimer since the message contains text "automatically closed in xx 132ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // seconds..." which has to be updated every second. 133ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::RepeatingTimer<ResolutionNotificationController> timer; 134ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 135ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch private: 136ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DISALLOW_COPY_AND_ASSIGN(ResolutionChangeInfo); 137ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}; 138ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 139ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochResolutionNotificationController::ResolutionChangeInfo::ResolutionChangeInfo( 140ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int64 display_id, 1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const DisplayMode& old_resolution, 1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const DisplayMode& new_resolution, 143ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const base::Closure& accept_callback) 144ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : display_id(display_id), 145ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch old_resolution(old_resolution), 146ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch new_resolution(new_resolution), 147ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch accept_callback(accept_callback), 148ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch timeout_count(0) { 149ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DisplayManager* display_manager = Shell::GetInstance()->display_manager(); 150ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!display_manager->HasInternalDisplay() && 151ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch display_manager->num_connected_displays() == 1u) { 152ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch timeout_count = kTimeoutInSec; 153ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 154ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 155ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 156ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochResolutionNotificationController::ResolutionChangeInfo:: 157ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ~ResolutionChangeInfo() { 158ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 159ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 160ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochResolutionNotificationController::ResolutionNotificationController() { 161ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch Shell::GetInstance()->display_controller()->AddObserver(this); 162ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch Shell::GetScreen()->AddObserver(this); 163ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 164ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 165ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochResolutionNotificationController::~ResolutionNotificationController() { 166ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch Shell::GetInstance()->display_controller()->RemoveObserver(this); 167ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch Shell::GetScreen()->RemoveObserver(this); 168ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 169ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ResolutionNotificationController::PrepareNotification( 171ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int64 display_id, 1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const DisplayMode& old_resolution, 1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const DisplayMode& new_resolution, 174ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const base::Closure& accept_callback) { 175ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // If multiple resolution changes are invoked for the same display, 176ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // the original resolution for the first resolution change has to be used 177ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // instead of the specified |old_resolution|. 1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DisplayMode original_resolution; 179ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (change_info_ && change_info_->display_id == display_id) { 1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(change_info_->new_resolution.size == old_resolution.size); 181ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch original_resolution = change_info_->old_resolution; 182ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 183ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 184ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch change_info_.reset(new ResolutionChangeInfo( 185ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch display_id, old_resolution, new_resolution, accept_callback)); 1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!original_resolution.size.IsEmpty()) 187ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch change_info_->old_resolution = original_resolution; 188ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 189ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 190ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochbool ResolutionNotificationController::DoesNotificationTimeout() { 191ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return change_info_ && change_info_->timeout_count > 0; 192ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 193ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 194424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void ResolutionNotificationController::CreateOrUpdateNotification( 195424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bool enable_spoken_feedback) { 196ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch message_center::MessageCenter* message_center = 197ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch message_center::MessageCenter::Get(); 198ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!change_info_) { 199ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch message_center->RemoveNotification(kNotificationId, false /* by_user */); 200ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 201ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 202ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 203ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::string16 timeout_message; 204ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch message_center::RichNotificationData data; 205ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (change_info_->timeout_count > 0) { 206ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch data.buttons.push_back(message_center::ButtonInfo( 207ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch l10n_util::GetStringUTF16(IDS_ASH_DISPLAY_RESOLUTION_CHANGE_ACCEPT))); 208ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch timeout_message = l10n_util::GetStringFUTF16( 209ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch IDS_ASH_DISPLAY_RESOLUTION_TIMEOUT, 210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::TimeFormat::Simple( 211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::TimeFormat::FORMAT_DURATION, ui::TimeFormat::LENGTH_LONG, 212ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::TimeDelta::FromSeconds(change_info_->timeout_count))); 213ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 214ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch data.buttons.push_back(message_center::ButtonInfo( 215ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch l10n_util::GetStringUTF16(IDS_ASH_DISPLAY_RESOLUTION_CHANGE_REVERT))); 216ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 217424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) data.should_make_spoken_feedback_for_popup_updates = enable_spoken_feedback; 218424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::string16 display_name = base::UTF8ToUTF16( 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Shell::GetInstance()->display_manager()->GetDisplayNameForId( 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) change_info_->display_id)); 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::string16 message = 2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (change_info_->new_resolution.size == 2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) change_info_->current_resolution.size) ? 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) l10n_util::GetStringFUTF16( 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IDS_ASH_STATUS_TRAY_DISPLAY_RESOLUTION_CHANGED, 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) display_name, 2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::UTF8ToUTF16(change_info_->new_resolution.size.ToString())) : 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) l10n_util::GetStringFUTF16( 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IDS_ASH_STATUS_TRAY_DISPLAY_RESOLUTION_CHANGED_TO_UNSUPPORTED, 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) display_name, 2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::UTF8ToUTF16(change_info_->new_resolution.size.ToString()), 2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::UTF8ToUTF16(change_info_->current_resolution.size.ToString())); 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 235ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); 236ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch scoped_ptr<Notification> notification(new Notification( 237ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch message_center::NOTIFICATION_TYPE_SIMPLE, 238ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch kNotificationId, 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) message, 240ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch timeout_message, 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bundle.GetImageNamed(IDR_AURA_NOTIFICATION_DISPLAY), 242ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::string16() /* display_source */, 24358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) message_center::NotifierId( 244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) message_center::NotifierId::SYSTEM_COMPONENT, 245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) system_notifier::kNotifierDisplayResolutionChange), 246ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch data, 247ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch new ResolutionChangeNotificationDelegate( 248ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch this, change_info_->timeout_count > 0))); 249ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch notification->SetSystemPriority(); 250ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch message_center->AddNotification(notification.Pass()); 251ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 252ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 253ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid ResolutionNotificationController::OnTimerTick() { 254ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!change_info_) 255ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 256ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 257ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch --change_info_->timeout_count; 258ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (change_info_->timeout_count == 0) 259ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch RevertResolutionChange(); 260ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch else 261424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) CreateOrUpdateNotification(false); 262ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 263ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 2643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ResolutionNotificationController::AcceptResolutionChange( 2653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool close_notification) { 2663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (close_notification) { 2673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) message_center::MessageCenter::Get()->RemoveNotification( 2683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) kNotificationId, false /* by_user */); 2693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 270ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::Closure callback = change_info_->accept_callback; 271ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch change_info_.reset(); 272ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch callback.Run(); 273ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 274ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 275ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid ResolutionNotificationController::RevertResolutionChange() { 276ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch message_center::MessageCenter::Get()->RemoveNotification( 277ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch kNotificationId, false /* by_user */); 278ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int64 display_id = change_info_->display_id; 2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DisplayMode old_resolution = change_info_->old_resolution; 280ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch change_info_.reset(); 2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Shell::GetInstance()->display_manager()->SetDisplayMode( 282ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch display_id, old_resolution); 283ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 284ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 285ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid ResolutionNotificationController::OnDisplayAdded( 286ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const gfx::Display& new_display) { 287ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 288ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 289ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid ResolutionNotificationController::OnDisplayRemoved( 290ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const gfx::Display& old_display) { 291ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (change_info_ && change_info_->display_id == old_display.id()) 292ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch RevertResolutionChange(); 293ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 294ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ResolutionNotificationController::OnDisplayMetricsChanged( 296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const gfx::Display&, uint32_t) { 297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 299ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid ResolutionNotificationController::OnDisplayConfigurationChanged() { 300ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!change_info_) 301ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 302ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) change_info_->current_resolution = Shell::GetInstance()->display_manager()-> 3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GetActiveModeForDisplayId(change_info_->display_id); 305424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) CreateOrUpdateNotification(true); 306ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (g_use_timer && change_info_->timeout_count > 0) { 307ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch change_info_->timer.Start(FROM_HERE, 308ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::TimeDelta::FromSeconds(1), 309ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch this, 310ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch &ResolutionNotificationController::OnTimerTick); 311ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 312ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 313ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 314ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid ResolutionNotificationController::SuppressTimerForTest() { 315ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch g_use_timer = false; 316ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 317ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 318ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} // namespace ash 319