OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "ash/display/resolution_notification_controller.h" | |
6 | |
7 #include "ash/display/display_controller.h" | |
8 #include "ash/display/display_manager.h" | |
9 #include "ash/shell.h" | |
10 #include "base/strings/utf_string_conversions.h" | |
11 #include "grit/ash_resources.h" | |
12 #include "grit/ash_strings.h" | |
13 #include "ui/base/l10n/l10n_util.h" | |
14 #include "ui/base/l10n/time_format.h" | |
15 #include "ui/base/resource/resource_bundle.h" | |
16 #include "ui/gfx/display.h" | |
17 #include "ui/gfx/screen.h" | |
18 #include "ui/message_center/message_center.h" | |
19 #include "ui/message_center/notification.h" | |
20 #include "ui/message_center/notification_delegate.h" | |
21 | |
22 using message_center::Notification; | |
23 | |
24 namespace ash { | |
25 namespace internal { | |
26 namespace { | |
27 | |
28 bool g_use_timer = true; | |
29 | |
30 class ResolutionChangeNotificationDelegate | |
31 : public message_center::NotificationDelegate { | |
32 public: | |
33 ResolutionChangeNotificationDelegate( | |
34 ResolutionNotificationController* controller, | |
35 bool has_timeout); | |
36 | |
37 protected: | |
38 virtual ~ResolutionChangeNotificationDelegate(); | |
39 | |
40 private: | |
41 // message_center::NotificationDelegate overrides: | |
42 virtual void Display() OVERRIDE; | |
43 virtual void Error() OVERRIDE; | |
44 virtual void Close(bool by_user) OVERRIDE; | |
45 virtual void Click() OVERRIDE; | |
46 virtual void ButtonClick(int button_index) OVERRIDE; | |
47 | |
48 ResolutionNotificationController* controller_; | |
49 bool has_timeout_; | |
50 | |
51 DISALLOW_COPY_AND_ASSIGN(ResolutionChangeNotificationDelegate); | |
52 }; | |
53 | |
54 ResolutionChangeNotificationDelegate::ResolutionChangeNotificationDelegate( | |
55 ResolutionNotificationController* controller, | |
56 bool has_timeout) | |
57 : controller_(controller), | |
58 has_timeout_(has_timeout) { | |
59 DCHECK(controller_); | |
60 } | |
61 | |
62 ResolutionChangeNotificationDelegate::~ResolutionChangeNotificationDelegate() { | |
63 } | |
64 | |
65 void ResolutionChangeNotificationDelegate::Display() { | |
66 } | |
67 | |
68 void ResolutionChangeNotificationDelegate::Error() { | |
69 } | |
70 | |
71 void ResolutionChangeNotificationDelegate::Close(bool by_user) { | |
72 if (by_user) | |
73 controller_->AcceptResolutionChange(); | |
74 } | |
75 | |
76 void ResolutionChangeNotificationDelegate::Click() { | |
77 } | |
78 | |
79 void ResolutionChangeNotificationDelegate::ButtonClick(int button_index) { | |
80 // If there's the timeout, the first button is "Accept". Otherwise the | |
81 // button click should be "Revert". | |
82 if (has_timeout_ && button_index == 0) | |
83 controller_->AcceptResolutionChange(); | |
84 else | |
85 controller_->RevertResolutionChange(); | |
86 } | |
87 | |
88 } // namespace | |
89 | |
90 // static | |
91 const int ResolutionNotificationController::kTimeoutInSec = 15; | |
92 | |
93 // static | |
94 const char ResolutionNotificationController::kNotificationId[] = | |
95 "chrome://settings/display/resolution"; | |
96 | |
97 ResolutionNotificationController::ResolutionChangeInfo::ResolutionChangeInfo( | |
98 int64 display_id, | |
99 const gfx::Size& old_resolution, | |
100 const gfx::Size& new_resolution, | |
101 const base::Closure& accept_callback) | |
102 : display_id(display_id), | |
103 old_resolution(old_resolution), | |
104 new_resolution(new_resolution), | |
105 accept_callback(accept_callback), | |
106 timeout_count(0) { | |
107 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); | |
108 if (!display_manager->HasInternalDisplay() && | |
109 display_manager->num_connected_displays() == 1u) { | |
110 timeout_count = kTimeoutInSec; | |
111 } | |
112 } | |
113 | |
114 ResolutionNotificationController::ResolutionChangeInfo:: | |
115 ~ResolutionChangeInfo() { | |
116 } | |
117 | |
118 ResolutionNotificationController::ResolutionNotificationController() { | |
119 Shell::GetInstance()->display_controller()->AddObserver(this); | |
120 Shell::GetScreen()->AddObserver(this); | |
121 } | |
122 | |
123 ResolutionNotificationController::~ResolutionNotificationController() { | |
124 Shell::GetInstance()->display_controller()->RemoveObserver(this); | |
125 Shell::GetScreen()->RemoveObserver(this); | |
126 } | |
127 | |
128 void ResolutionNotificationController::SetDisplayResolutionAndNotify( | |
129 int64 display_id, | |
130 const gfx::Size& old_resolution, | |
131 const gfx::Size& new_resolution, | |
132 const base::Closure& accept_callback) { | |
133 change_info_.reset(new ResolutionChangeInfo( | |
134 display_id, old_resolution, new_resolution, accept_callback)); | |
135 | |
136 // SetDisplayResolution() causes OnConfigurationChanged() and the notification | |
137 // will be shown at that point. | |
138 Shell::GetInstance()->display_manager()->SetDisplayResolution( | |
139 display_id, new_resolution); | |
140 } | |
141 | |
142 bool ResolutionNotificationController::DoesNotificationTimeout() { | |
143 return change_info_ && change_info_->timeout_count > 0; | |
144 } | |
145 | |
146 void ResolutionNotificationController::CreateOrUpdateNotification() { | |
147 message_center::MessageCenter* message_center = | |
148 message_center::MessageCenter::Get(); | |
149 if (!change_info_) { | |
150 message_center->RemoveNotification(kNotificationId, false /* by_user */); | |
151 return; | |
152 } | |
153 | |
154 base::string16 timeout_message; | |
155 message_center::RichNotificationData data; | |
156 if (change_info_->timeout_count > 0) { | |
157 data.buttons.push_back(message_center::ButtonInfo( | |
158 l10n_util::GetStringUTF16(IDS_ASH_DISPLAY_RESOLUTION_CHANGE_ACCEPT))); | |
159 timeout_message = l10n_util::GetStringFUTF16( | |
160 IDS_ASH_DISPLAY_RESOLUTION_TIMEOUT, | |
161 ui::TimeFormat::TimeDurationLong( | |
162 base::TimeDelta::FromSeconds(change_info_->timeout_count))); | |
163 } | |
164 data.buttons.push_back(message_center::ButtonInfo( | |
165 l10n_util::GetStringUTF16(IDS_ASH_DISPLAY_RESOLUTION_CHANGE_REVERT))); | |
166 | |
167 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); | |
168 scoped_ptr<Notification> notification(new Notification( | |
169 message_center::NOTIFICATION_TYPE_SIMPLE, | |
170 kNotificationId, | |
171 l10n_util::GetStringFUTF16( | |
172 IDS_ASH_STATUS_TRAY_DISPLAY_RESOLUTION_CHANGED, | |
173 UTF8ToUTF16(Shell::GetInstance()->display_manager()-> | |
174 GetDisplayNameForId(change_info_->display_id)), | |
175 UTF8ToUTF16(change_info_->new_resolution.ToString())), | |
176 timeout_message, | |
177 bundle.GetImageNamed(IDR_AURA_UBER_TRAY_DISPLAY), | |
178 base::string16() /* display_source */, | |
179 std::string() /* extension_id */, | |
180 data, | |
181 new ResolutionChangeNotificationDelegate( | |
182 this, change_info_->timeout_count > 0))); | |
183 notification->SetSystemPriority(); | |
184 message_center->AddNotification(notification.Pass()); | |
185 } | |
186 | |
187 void ResolutionNotificationController::OnTimerTick() { | |
188 if (!change_info_) | |
189 return; | |
190 | |
191 --change_info_->timeout_count; | |
192 if (change_info_->timeout_count == 0) | |
193 RevertResolutionChange(); | |
194 else | |
195 CreateOrUpdateNotification(); | |
196 } | |
197 | |
198 void ResolutionNotificationController::AcceptResolutionChange() { | |
199 message_center::MessageCenter::Get()->RemoveNotification( | |
200 kNotificationId, false /* by_user */); | |
201 base::Closure callback = change_info_->accept_callback; | |
202 change_info_.reset(); | |
203 callback.Run(); | |
204 } | |
205 | |
206 void ResolutionNotificationController::RevertResolutionChange() { | |
207 message_center::MessageCenter::Get()->RemoveNotification( | |
208 kNotificationId, false /* by_user */); | |
209 int64 display_id = change_info_->display_id; | |
210 gfx::Size old_resolution = change_info_->old_resolution; | |
211 change_info_.reset(); | |
212 Shell::GetInstance()->display_manager()->SetDisplayResolution( | |
213 display_id, old_resolution); | |
214 } | |
215 | |
216 void ResolutionNotificationController::OnDisplayBoundsChanged( | |
217 const gfx::Display& display) { | |
218 } | |
219 | |
220 void ResolutionNotificationController::OnDisplayAdded( | |
221 const gfx::Display& new_display) { | |
222 } | |
223 | |
224 void ResolutionNotificationController::OnDisplayRemoved( | |
225 const gfx::Display& old_display) { | |
226 if (change_info_ && change_info_->display_id == old_display.id()) { | |
227 if (change_info_->timeout_count > 0) | |
228 RevertResolutionChange(); | |
229 else | |
230 AcceptResolutionChange(); | |
Daniel Erat
2013/08/09 15:50:24
can you explain this part? why does the change get
Jun Mukai
2013/08/09 16:49:16
What I concerned is the following situation:
1. co
Daniel Erat
2013/08/09 16:55:46
ah, i didn't realize that this was for the multipl
| |
231 } | |
232 } | |
233 | |
234 void ResolutionNotificationController::OnDisplayConfigurationChanged() { | |
235 if (!change_info_) | |
236 return; | |
237 | |
238 CreateOrUpdateNotification(); | |
239 if (g_use_timer && change_info_->timeout_count > 0) { | |
240 change_info_->timer.Start(FROM_HERE, | |
241 base::TimeDelta::FromSeconds(1), | |
242 this, | |
243 &ResolutionNotificationController::OnTimerTick); | |
244 } | |
245 } | |
246 | |
247 void ResolutionNotificationController::SuppressTimerForTest() { | |
248 g_use_timer = false; | |
249 } | |
250 | |
251 } // namespace internal | |
252 } // namespace ash | |
OLD | NEW |