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