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.
5 #include "ash/system/chromeos/brightness/tray_brightness.h"
9 #include "ash/accelerators/accelerator_controller.h"
10 #include "ash/ash_constants.h"
11 #include "ash/metrics/user_metrics_recorder.h"
12 #include "ash/shell.h"
13 #include "ash/shell_observer.h"
14 #include "ash/system/brightness_control_delegate.h"
15 #include "ash/system/tray/fixed_sized_image_view.h"
16 #include "ash/system/tray/system_tray_delegate.h"
17 #include "ash/system/tray/system_tray_notifier.h"
18 #include "ash/system/tray/tray_constants.h"
19 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
20 #include "base/bind.h"
21 #include "base/message_loop/message_loop.h"
22 #include "base/strings/utf_string_conversions.h"
23 #include "chromeos/dbus/dbus_thread_manager.h"
24 #include "chromeos/dbus/power_manager_client.h"
25 #include "grit/ash_resources.h"
26 #include "grit/ash_strings.h"
27 #include "ui/base/resource/resource_bundle.h"
28 #include "ui/gfx/display.h"
29 #include "ui/gfx/image/image.h"
30 #include "ui/views/controls/button/image_button.h"
31 #include "ui/views/controls/image_view.h"
32 #include "ui/views/controls/label.h"
33 #include "ui/views/controls/slider.h"
34 #include "ui/views/layout/box_layout.h"
35 #include "ui/views/view.h"
41 // We don't let the screen brightness go lower than this when it's being
42 // adjusted via the slider. Otherwise, if the user doesn't know about the
43 // brightness keys, they may turn the backlight off and not know how to turn it
45 const double kMinBrightnessPercent
= 5.0;
49 class BrightnessView
: public ShellObserver
,
51 public views::SliderListener
{
53 BrightnessView(bool default_view
, double initial_percent
);
54 ~BrightnessView() override
;
56 bool is_default_view() const {
57 return is_default_view_
;
60 // |percent| is in the range [0.0, 100.0].
61 void SetBrightnessPercent(double percent
);
64 void OnMaximizeModeStarted() override
;
65 void OnMaximizeModeEnded() override
;
69 void OnBoundsChanged(const gfx::Rect
& old_bounds
) override
;
71 // views:SliderListener:
72 void SliderValueChanged(views::Slider
* sender
,
75 views::SliderChangeReason reason
) override
;
77 // views:SliderListener:
78 void SliderDragStarted(views::Slider
* slider
) override
;
79 void SliderDragEnded(views::Slider
* slider
) override
;
81 views::Slider
* slider_
;
83 // Is |slider_| currently being dragged?
86 // True if this view is for the default tray view. Used to control hide/show
87 // behaviour of the default view when entering or leaving Maximize Mode.
88 bool is_default_view_
;
90 // Last brightness level that we observed, in the range [0.0, 100.0].
93 DISALLOW_COPY_AND_ASSIGN(BrightnessView
);
96 BrightnessView::BrightnessView(bool default_view
, double initial_percent
)
98 is_default_view_(default_view
),
99 last_percent_(initial_percent
) {
100 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal
,
101 kTrayPopupPaddingHorizontal
, 0, kTrayPopupPaddingBetweenItems
));
103 views::ImageView
* icon
= new FixedSizedImageView(0, kTrayPopupItemHeight
);
104 gfx::Image image
= ui::ResourceBundle::GetSharedInstance().GetImageNamed(
105 IDR_AURA_UBER_TRAY_BRIGHTNESS
);
106 icon
->SetImage(image
.ToImageSkia());
109 slider_
= new views::Slider(this, views::Slider::HORIZONTAL
);
110 slider_
->set_focus_border_color(kFocusBorderColor
);
111 slider_
->SetValue(static_cast<float>(initial_percent
/ 100.0));
112 slider_
->SetAccessibleName(
113 ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
114 IDS_ASH_STATUS_TRAY_BRIGHTNESS
));
115 AddChildView(slider_
);
117 if (is_default_view_
) {
118 Shell::GetInstance()->AddShellObserver(this);
119 SetVisible(Shell::GetInstance()->maximize_mode_controller()->
120 IsMaximizeModeWindowManagerEnabled());
124 BrightnessView::~BrightnessView() {
125 if (is_default_view_
)
126 Shell::GetInstance()->RemoveShellObserver(this);
129 void BrightnessView::SetBrightnessPercent(double percent
) {
130 last_percent_
= percent
;
132 slider_
->SetValue(static_cast<float>(percent
/ 100.0));
135 void BrightnessView::OnMaximizeModeStarted() {
139 void BrightnessView::OnMaximizeModeEnded() {
143 void BrightnessView::OnBoundsChanged(const gfx::Rect
& old_bounds
) {
144 int w
= width() - slider_
->x();
145 slider_
->SetSize(gfx::Size(w
, slider_
->height()));
148 void BrightnessView::SliderValueChanged(views::Slider
* sender
,
151 views::SliderChangeReason reason
) {
152 DCHECK_EQ(sender
, slider_
);
153 if (reason
!= views::VALUE_CHANGED_BY_USER
)
155 AcceleratorController
* ac
= Shell::GetInstance()->accelerator_controller();
156 if (ac
->brightness_control_delegate()) {
157 double percent
= std::max(value
* 100.0, kMinBrightnessPercent
);
158 ac
->brightness_control_delegate()->SetBrightnessPercent(percent
, true);
162 void BrightnessView::SliderDragStarted(views::Slider
* slider
) {
163 DCHECK_EQ(slider
, slider_
);
167 void BrightnessView::SliderDragEnded(views::Slider
* slider
) {
168 DCHECK_EQ(slider
, slider_
);
170 slider_
->SetValue(static_cast<float>(last_percent_
/ 100.0));
175 TrayBrightness::TrayBrightness(SystemTray
* system_tray
)
176 : SystemTrayItem(system_tray
),
177 brightness_view_(NULL
),
178 current_percent_(100.0),
179 got_current_percent_(false),
180 weak_ptr_factory_(this) {
181 // Post a task to get the initial brightness; the BrightnessControlDelegate
182 // isn't created yet.
183 base::MessageLoopForUI::current()->PostTask(
185 base::Bind(&TrayBrightness::GetInitialBrightness
,
186 weak_ptr_factory_
.GetWeakPtr()));
187 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->
191 TrayBrightness::~TrayBrightness() {
192 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->
193 RemoveObserver(this);
196 void TrayBrightness::GetInitialBrightness() {
197 BrightnessControlDelegate
* delegate
=
198 Shell::GetInstance()->accelerator_controller()->
199 brightness_control_delegate();
200 // Worrisome, but happens in unit tests, so don't log anything.
203 delegate
->GetBrightnessPercent(
204 base::Bind(&TrayBrightness::HandleInitialBrightness
,
205 weak_ptr_factory_
.GetWeakPtr()));
208 void TrayBrightness::HandleInitialBrightness(double percent
) {
209 if (!got_current_percent_
)
210 HandleBrightnessChanged(percent
, false);
213 views::View
* TrayBrightness::CreateTrayView(user::LoginStatus status
) {
217 views::View
* TrayBrightness::CreateDefaultView(user::LoginStatus status
) {
218 CHECK(brightness_view_
== NULL
);
219 brightness_view_
= new tray::BrightnessView(true, current_percent_
);
220 return brightness_view_
;
223 views::View
* TrayBrightness::CreateDetailedView(user::LoginStatus status
) {
224 CHECK(brightness_view_
== NULL
);
225 Shell::GetInstance()->metrics()->RecordUserMetricsAction(
226 ash::UMA_STATUS_AREA_DETAILED_BRIGHTNESS_VIEW
);
227 brightness_view_
= new tray::BrightnessView(false, current_percent_
);
228 return brightness_view_
;
231 void TrayBrightness::DestroyTrayView() {
234 void TrayBrightness::DestroyDefaultView() {
235 if (brightness_view_
&& brightness_view_
->is_default_view())
236 brightness_view_
= NULL
;
239 void TrayBrightness::DestroyDetailedView() {
240 if (brightness_view_
&& !brightness_view_
->is_default_view())
241 brightness_view_
= NULL
;
244 void TrayBrightness::UpdateAfterLoginStatusChange(user::LoginStatus status
) {
247 bool TrayBrightness::ShouldHideArrow() const {
251 bool TrayBrightness::ShouldShowShelf() const {
255 void TrayBrightness::BrightnessChanged(int level
, bool user_initiated
) {
256 Shell::GetInstance()->metrics()->RecordUserMetricsAction(
257 ash::UMA_STATUS_AREA_BRIGHTNESS_CHANGED
);
258 double percent
= static_cast<double>(level
);
259 HandleBrightnessChanged(percent
, user_initiated
);
262 void TrayBrightness::HandleBrightnessChanged(double percent
,
263 bool user_initiated
) {
264 current_percent_
= percent
;
265 got_current_percent_
= true;
267 if (brightness_view_
)
268 brightness_view_
->SetBrightnessPercent(percent
);
273 // Never show the bubble on systems that lack internal displays: if an
274 // external display's brightness is changed, it may already display the new
275 // level via an on-screen display.
276 if (!gfx::Display::HasInternalDisplay())
279 if (brightness_view_
)
280 SetDetailedViewCloseDelay(kTrayPopupAutoCloseDelayInSeconds
);
282 PopupDetailedView(kTrayPopupAutoCloseDelayInSeconds
, false);