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/system/chromeos/brightness/tray_brightness.h" | |
6 | |
7 #include <algorithm> | |
8 | |
9 #include "ash/accelerators/accelerator_controller.h" | |
10 #include "ash/common/ash_constants.h" | |
11 #include "ash/common/shell_observer.h" | |
12 #include "ash/common/system/tray/fixed_sized_image_view.h" | |
13 #include "ash/common/system/tray/system_tray_delegate.h" | |
14 #include "ash/common/system/tray/tray_constants.h" | |
15 #include "ash/common/wm/maximize_mode/maximize_mode_controller.h" | |
16 #include "ash/common/wm_shell.h" | |
17 #include "ash/shell.h" | |
18 #include "ash/system/brightness_control_delegate.h" | |
19 #include "base/bind.h" | |
20 #include "base/strings/utf_string_conversions.h" | |
21 #include "base/threading/thread_task_runner_handle.h" | |
22 #include "chromeos/dbus/dbus_thread_manager.h" | |
23 #include "chromeos/dbus/power_manager_client.h" | |
24 #include "grit/ash_resources.h" | |
25 #include "grit/ash_strings.h" | |
26 #include "ui/base/resource/resource_bundle.h" | |
27 #include "ui/display/display.h" | |
28 #include "ui/gfx/image/image.h" | |
29 #include "ui/views/controls/button/image_button.h" | |
30 #include "ui/views/controls/image_view.h" | |
31 #include "ui/views/controls/label.h" | |
32 #include "ui/views/controls/slider.h" | |
33 #include "ui/views/layout/box_layout.h" | |
34 #include "ui/views/view.h" | |
35 | |
36 namespace ash { | |
37 namespace tray { | |
38 namespace { | |
39 | |
40 // We don't let the screen brightness go lower than this when it's being | |
41 // adjusted via the slider. Otherwise, if the user doesn't know about the | |
42 // brightness keys, they may turn the backlight off and not know how to turn it | |
43 // back on. | |
44 const double kMinBrightnessPercent = 5.0; | |
45 | |
46 } // namespace | |
47 | |
48 class BrightnessView : public ShellObserver, | |
49 public views::View, | |
50 public views::SliderListener { | |
51 public: | |
52 BrightnessView(bool default_view, double initial_percent); | |
53 ~BrightnessView() override; | |
54 | |
55 bool is_default_view() const { return is_default_view_; } | |
56 | |
57 // |percent| is in the range [0.0, 100.0]. | |
58 void SetBrightnessPercent(double percent); | |
59 | |
60 // ShellObserver: | |
61 void OnMaximizeModeStarted() override; | |
62 void OnMaximizeModeEnded() override; | |
63 | |
64 private: | |
65 // views::View: | |
66 void OnBoundsChanged(const gfx::Rect& old_bounds) override; | |
67 | |
68 // views:SliderListener: | |
69 void SliderValueChanged(views::Slider* sender, | |
70 float value, | |
71 float old_value, | |
72 views::SliderChangeReason reason) override; | |
73 | |
74 // views:SliderListener: | |
75 void SliderDragStarted(views::Slider* slider) override; | |
76 void SliderDragEnded(views::Slider* slider) override; | |
77 | |
78 views::Slider* slider_; | |
79 | |
80 // Is |slider_| currently being dragged? | |
81 bool dragging_; | |
82 | |
83 // True if this view is for the default tray view. Used to control hide/show | |
84 // behaviour of the default view when entering or leaving Maximize Mode. | |
85 bool is_default_view_; | |
86 | |
87 // Last brightness level that we observed, in the range [0.0, 100.0]. | |
88 double last_percent_; | |
89 | |
90 DISALLOW_COPY_AND_ASSIGN(BrightnessView); | |
91 }; | |
92 | |
93 BrightnessView::BrightnessView(bool default_view, double initial_percent) | |
94 : dragging_(false), | |
95 is_default_view_(default_view), | |
96 last_percent_(initial_percent) { | |
97 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, | |
98 kTrayPopupPaddingHorizontal, 0, | |
99 kTrayPopupPaddingBetweenItems)); | |
100 | |
101 views::ImageView* icon = new FixedSizedImageView(0, kTrayPopupItemHeight); | |
102 gfx::Image image = ui::ResourceBundle::GetSharedInstance().GetImageNamed( | |
103 IDR_AURA_UBER_TRAY_BRIGHTNESS); | |
104 icon->SetImage(image.ToImageSkia()); | |
105 AddChildView(icon); | |
106 | |
107 slider_ = new views::Slider(this, views::Slider::HORIZONTAL); | |
108 slider_->set_focus_border_color(kFocusBorderColor); | |
109 slider_->SetValue(static_cast<float>(initial_percent / 100.0)); | |
110 slider_->SetAccessibleName( | |
111 ui::ResourceBundle::GetSharedInstance().GetLocalizedString( | |
112 IDS_ASH_STATUS_TRAY_BRIGHTNESS)); | |
113 AddChildView(slider_); | |
114 | |
115 if (is_default_view_) { | |
116 WmShell::Get()->AddShellObserver(this); | |
117 SetVisible(WmShell::Get() | |
118 ->maximize_mode_controller() | |
119 ->IsMaximizeModeWindowManagerEnabled()); | |
120 } | |
121 } | |
122 | |
123 BrightnessView::~BrightnessView() { | |
124 if (is_default_view_) | |
125 WmShell::Get()->RemoveShellObserver(this); | |
126 } | |
127 | |
128 void BrightnessView::SetBrightnessPercent(double percent) { | |
129 last_percent_ = percent; | |
130 if (!dragging_) | |
131 slider_->SetValue(static_cast<float>(percent / 100.0)); | |
132 } | |
133 | |
134 void BrightnessView::OnMaximizeModeStarted() { | |
135 SetVisible(true); | |
136 } | |
137 | |
138 void BrightnessView::OnMaximizeModeEnded() { | |
139 SetVisible(false); | |
140 } | |
141 | |
142 void BrightnessView::OnBoundsChanged(const gfx::Rect& old_bounds) { | |
143 int w = width() - slider_->x(); | |
144 slider_->SetSize(gfx::Size(w, slider_->height())); | |
145 } | |
146 | |
147 void BrightnessView::SliderValueChanged(views::Slider* sender, | |
148 float value, | |
149 float old_value, | |
150 views::SliderChangeReason reason) { | |
151 DCHECK_EQ(sender, slider_); | |
152 if (reason != views::VALUE_CHANGED_BY_USER) | |
153 return; | |
154 AcceleratorController* ac = Shell::GetInstance()->accelerator_controller(); | |
155 if (ac->brightness_control_delegate()) { | |
156 double percent = std::max(value * 100.0, kMinBrightnessPercent); | |
157 ac->brightness_control_delegate()->SetBrightnessPercent(percent, true); | |
158 } | |
159 } | |
160 | |
161 void BrightnessView::SliderDragStarted(views::Slider* slider) { | |
162 DCHECK_EQ(slider, slider_); | |
163 dragging_ = true; | |
164 } | |
165 | |
166 void BrightnessView::SliderDragEnded(views::Slider* slider) { | |
167 DCHECK_EQ(slider, slider_); | |
168 dragging_ = false; | |
169 slider_->SetValue(static_cast<float>(last_percent_ / 100.0)); | |
170 } | |
171 | |
172 } // namespace tray | |
173 | |
174 TrayBrightness::TrayBrightness(SystemTray* system_tray) | |
175 : SystemTrayItem(system_tray), | |
176 brightness_view_(NULL), | |
177 current_percent_(100.0), | |
178 got_current_percent_(false), | |
179 weak_ptr_factory_(this) { | |
180 // Post a task to get the initial brightness; the BrightnessControlDelegate | |
181 // isn't created yet. | |
182 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
183 FROM_HERE, base::Bind(&TrayBrightness::GetInitialBrightness, | |
184 weak_ptr_factory_.GetWeakPtr())); | |
185 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver( | |
186 this); | |
187 } | |
188 | |
189 TrayBrightness::~TrayBrightness() { | |
190 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver( | |
191 this); | |
192 } | |
193 | |
194 void TrayBrightness::GetInitialBrightness() { | |
195 BrightnessControlDelegate* delegate = Shell::GetInstance() | |
196 ->accelerator_controller() | |
197 ->brightness_control_delegate(); | |
198 // Worrisome, but happens in unit tests, so don't log anything. | |
199 if (!delegate) | |
200 return; | |
201 delegate->GetBrightnessPercent( | |
202 base::Bind(&TrayBrightness::HandleInitialBrightness, | |
203 weak_ptr_factory_.GetWeakPtr())); | |
204 } | |
205 | |
206 void TrayBrightness::HandleInitialBrightness(double percent) { | |
207 if (!got_current_percent_) | |
208 HandleBrightnessChanged(percent, false); | |
209 } | |
210 | |
211 views::View* TrayBrightness::CreateTrayView(LoginStatus status) { | |
212 return NULL; | |
213 } | |
214 | |
215 views::View* TrayBrightness::CreateDefaultView(LoginStatus status) { | |
216 CHECK(brightness_view_ == NULL); | |
217 brightness_view_ = new tray::BrightnessView(true, current_percent_); | |
218 return brightness_view_; | |
219 } | |
220 | |
221 views::View* TrayBrightness::CreateDetailedView(LoginStatus status) { | |
222 CHECK(brightness_view_ == NULL); | |
223 WmShell::Get()->RecordUserMetricsAction( | |
224 UMA_STATUS_AREA_DETAILED_BRIGHTNESS_VIEW); | |
225 brightness_view_ = new tray::BrightnessView(false, current_percent_); | |
226 return brightness_view_; | |
227 } | |
228 | |
229 void TrayBrightness::DestroyTrayView() {} | |
230 | |
231 void TrayBrightness::DestroyDefaultView() { | |
232 if (brightness_view_ && brightness_view_->is_default_view()) | |
233 brightness_view_ = NULL; | |
234 } | |
235 | |
236 void TrayBrightness::DestroyDetailedView() { | |
237 if (brightness_view_ && !brightness_view_->is_default_view()) | |
238 brightness_view_ = NULL; | |
239 } | |
240 | |
241 void TrayBrightness::UpdateAfterLoginStatusChange(LoginStatus status) {} | |
242 | |
243 bool TrayBrightness::ShouldHideArrow() const { | |
244 return true; | |
245 } | |
246 | |
247 bool TrayBrightness::ShouldShowShelf() const { | |
248 return false; | |
249 } | |
250 | |
251 void TrayBrightness::BrightnessChanged(int level, bool user_initiated) { | |
252 WmShell::Get()->RecordUserMetricsAction(UMA_STATUS_AREA_BRIGHTNESS_CHANGED); | |
253 double percent = static_cast<double>(level); | |
254 HandleBrightnessChanged(percent, user_initiated); | |
255 } | |
256 | |
257 void TrayBrightness::HandleBrightnessChanged(double percent, | |
258 bool user_initiated) { | |
259 current_percent_ = percent; | |
260 got_current_percent_ = true; | |
261 | |
262 if (brightness_view_) | |
263 brightness_view_->SetBrightnessPercent(percent); | |
264 | |
265 if (!user_initiated) | |
266 return; | |
267 | |
268 // Never show the bubble on systems that lack internal displays: if an | |
269 // external display's brightness is changed, it may already display the new | |
270 // level via an on-screen display. | |
271 if (!display::Display::HasInternalDisplay()) | |
272 return; | |
273 | |
274 if (brightness_view_) | |
275 SetDetailedViewCloseDelay(kTrayPopupAutoCloseDelayInSeconds); | |
276 else | |
277 PopupDetailedView(kTrayPopupAutoCloseDelayInSeconds, false); | |
278 } | |
279 | |
280 } // namespace ash | |
OLD | NEW |