• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "ash/accelerators/accelerator_controller.h"
8 #include "ash/ash_constants.h"
9 #include "ash/metrics/user_metrics_recorder.h"
10 #include "ash/shell.h"
11 #include "ash/system/brightness_control_delegate.h"
12 #include "ash/system/tray/fixed_sized_image_view.h"
13 #include "ash/system/tray/system_tray_delegate.h"
14 #include "ash/system/tray/system_tray_notifier.h"
15 #include "ash/system/tray/tray_constants.h"
16 #include "base/bind.h"
17 #include "base/message_loop/message_loop.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "chromeos/dbus/dbus_thread_manager.h"
20 #include "chromeos/dbus/power_manager_client.h"
21 #include "grit/ash_resources.h"
22 #include "grit/ash_strings.h"
23 #include "ui/base/resource/resource_bundle.h"
24 #include "ui/gfx/image/image.h"
25 #include "ui/views/controls/button/image_button.h"
26 #include "ui/views/controls/image_view.h"
27 #include "ui/views/controls/label.h"
28 #include "ui/views/controls/slider.h"
29 #include "ui/views/layout/box_layout.h"
30 #include "ui/views/view.h"
31 
32 namespace ash {
33 namespace internal {
34 
35 namespace tray {
36 
37 namespace {
38 
39 // We don't let the screen brightness go lower than this when it's being
40 // adjusted via the slider.  Otherwise, if the user doesn't know about the
41 // brightness keys, they may turn the backlight off and not know how to turn it
42 // back on.
43 const double kMinBrightnessPercent = 5.0;
44 
45 }  // namespace
46 
47 class BrightnessView : public views::View,
48                        public views::SliderListener {
49  public:
BrightnessView(double initial_percent)50   explicit BrightnessView(double initial_percent)
51       : dragging_(false),
52         last_percent_(initial_percent) {
53     SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal,
54           kTrayPopupPaddingHorizontal, 0, kTrayPopupPaddingBetweenItems));
55 
56     views::ImageView* icon = new FixedSizedImageView(0, kTrayPopupItemHeight);
57     gfx::Image image = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
58         IDR_AURA_UBER_TRAY_BRIGHTNESS);
59     icon->SetImage(image.ToImageSkia());
60     AddChildView(icon);
61 
62     slider_ = new views::Slider(this, views::Slider::HORIZONTAL);
63     slider_->set_focus_border_color(kFocusBorderColor);
64     slider_->SetValue(static_cast<float>(initial_percent / 100.0));
65     slider_->SetAccessibleName(
66         ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
67             IDS_ASH_STATUS_TRAY_BRIGHTNESS));
68     AddChildView(slider_);
69   }
70 
~BrightnessView()71   virtual ~BrightnessView() {}
72 
73   // |percent| is in the range [0.0, 100.0].
SetBrightnessPercent(double percent)74   void SetBrightnessPercent(double percent) {
75     last_percent_ = percent;
76     if (!dragging_)
77       slider_->SetValue(static_cast<float>(percent / 100.0));
78   }
79 
80  private:
81   // Overridden from views::View.
OnBoundsChanged(const gfx::Rect & old_bounds)82   virtual void OnBoundsChanged(const gfx::Rect& old_bounds) OVERRIDE {
83     int w = width() - slider_->x();
84     slider_->SetSize(gfx::Size(w, slider_->height()));
85   }
86 
87   // Overridden from views:SliderListener.
SliderValueChanged(views::Slider * sender,float value,float old_value,views::SliderChangeReason reason)88   virtual void SliderValueChanged(views::Slider* sender,
89                                   float value,
90                                   float old_value,
91                                   views::SliderChangeReason reason) OVERRIDE {
92     DCHECK_EQ(sender, slider_);
93     if (reason != views::VALUE_CHANGED_BY_USER)
94       return;
95     AcceleratorController* ac = Shell::GetInstance()->accelerator_controller();
96     if (ac->brightness_control_delegate()) {
97       double percent = std::max(value * 100.0, kMinBrightnessPercent);
98       ac->brightness_control_delegate()->SetBrightnessPercent(percent, true);
99     }
100   }
101 
102   // Overridden from views:SliderListener.
SliderDragStarted(views::Slider * slider)103   virtual void SliderDragStarted(views::Slider* slider) OVERRIDE {
104     DCHECK_EQ(slider, slider_);
105     dragging_ = true;
106   }
107 
108   // Overridden from views:SliderListener.
SliderDragEnded(views::Slider * slider)109   virtual void SliderDragEnded(views::Slider* slider) OVERRIDE {
110     DCHECK_EQ(slider, slider_);
111     dragging_ = false;
112     slider_->SetValue(static_cast<float>(last_percent_ / 100.0));
113   }
114 
115   views::Slider* slider_;
116 
117   // Is |slider_| currently being dragged?
118   bool dragging_;
119 
120   // Last brightness level that we observed, in the range [0.0, 100.0].
121   double last_percent_;
122 
123   DISALLOW_COPY_AND_ASSIGN(BrightnessView);
124 };
125 
126 }  // namespace tray
127 
TrayBrightness(SystemTray * system_tray)128 TrayBrightness::TrayBrightness(SystemTray* system_tray)
129     : SystemTrayItem(system_tray),
130       weak_ptr_factory_(this),
131       brightness_view_(NULL),
132       is_default_view_(false),
133       current_percent_(100.0),
134       got_current_percent_(false) {
135   // Post a task to get the initial brightness; the BrightnessControlDelegate
136   // isn't created yet.
137   base::MessageLoopForUI::current()->PostTask(
138       FROM_HERE,
139       base::Bind(&TrayBrightness::GetInitialBrightness,
140                  weak_ptr_factory_.GetWeakPtr()));
141   chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->
142       AddObserver(this);
143 }
144 
~TrayBrightness()145 TrayBrightness::~TrayBrightness() {
146   chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->
147       RemoveObserver(this);
148 }
149 
GetInitialBrightness()150 void TrayBrightness::GetInitialBrightness() {
151   BrightnessControlDelegate* delegate =
152       Shell::GetInstance()->accelerator_controller()->
153       brightness_control_delegate();
154   // Worrisome, but happens in unit tests, so don't log anything.
155   if (!delegate)
156     return;
157   delegate->GetBrightnessPercent(
158       base::Bind(&TrayBrightness::HandleInitialBrightness,
159                  weak_ptr_factory_.GetWeakPtr()));
160 }
161 
HandleInitialBrightness(double percent)162 void TrayBrightness::HandleInitialBrightness(double percent) {
163   if (!got_current_percent_)
164     HandleBrightnessChanged(percent, false);
165 }
166 
CreateTrayView(user::LoginStatus status)167 views::View* TrayBrightness::CreateTrayView(user::LoginStatus status) {
168   return NULL;
169 }
170 
CreateDefaultView(user::LoginStatus status)171 views::View* TrayBrightness::CreateDefaultView(user::LoginStatus status) {
172   return NULL;
173 }
174 
CreateDetailedView(user::LoginStatus status)175 views::View* TrayBrightness::CreateDetailedView(user::LoginStatus status) {
176   CHECK(brightness_view_ == NULL);
177   Shell::GetInstance()->metrics()->RecordUserMetricsAction(
178       ash::UMA_STATUS_AREA_DETAILED_BRIGHTNESS_VIEW);
179   brightness_view_ = new tray::BrightnessView(current_percent_);
180   is_default_view_ = false;
181   return brightness_view_;
182 }
183 
DestroyTrayView()184 void TrayBrightness::DestroyTrayView() {
185 }
186 
DestroyDefaultView()187 void TrayBrightness::DestroyDefaultView() {
188   if (is_default_view_)
189     brightness_view_ = NULL;
190 }
191 
DestroyDetailedView()192 void TrayBrightness::DestroyDetailedView() {
193   if (!is_default_view_)
194     brightness_view_ = NULL;
195 }
196 
UpdateAfterLoginStatusChange(user::LoginStatus status)197 void TrayBrightness::UpdateAfterLoginStatusChange(user::LoginStatus status) {
198 }
199 
ShouldHideArrow() const200 bool TrayBrightness::ShouldHideArrow() const {
201   return true;
202 }
203 
ShouldShowLauncher() const204 bool TrayBrightness::ShouldShowLauncher() const {
205   return false;
206 }
207 
BrightnessChanged(int level,bool user_initiated)208 void TrayBrightness::BrightnessChanged(int level, bool user_initiated) {
209   Shell::GetInstance()->metrics()->RecordUserMetricsAction(
210       ash::UMA_STATUS_AREA_BRIGHTNESS_CHANGED);
211   double percent = static_cast<double>(level);
212   HandleBrightnessChanged(percent, user_initiated);
213 }
214 
HandleBrightnessChanged(double percent,bool user_initiated)215 void TrayBrightness::HandleBrightnessChanged(double percent,
216                                              bool user_initiated) {
217   current_percent_ = percent;
218   got_current_percent_ = true;
219 
220   if (brightness_view_)
221     brightness_view_->SetBrightnessPercent(percent);
222   if (!user_initiated)
223     return;
224 
225   if (brightness_view_)
226     SetDetailedViewCloseDelay(kTrayPopupAutoCloseDelayInSeconds);
227   else
228     PopupDetailedView(kTrayPopupAutoCloseDelayInSeconds, false);
229 }
230 
231 }  // namespace internal
232 }  // namespace ash
233