Home | History | Annotate | Download | only in brightness
      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:
     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 
     71   virtual ~BrightnessView() {}
     72 
     73   // |percent| is in the range [0.0, 100.0].
     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.
     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.
     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.
    103   virtual void SliderDragStarted(views::Slider* slider) OVERRIDE {
    104     DCHECK_EQ(slider, slider_);
    105     dragging_ = true;
    106   }
    107 
    108   // Overridden from views:SliderListener.
    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 
    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 
    145 TrayBrightness::~TrayBrightness() {
    146   chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->
    147       RemoveObserver(this);
    148 }
    149 
    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 
    162 void TrayBrightness::HandleInitialBrightness(double percent) {
    163   if (!got_current_percent_)
    164     HandleBrightnessChanged(percent, false);
    165 }
    166 
    167 views::View* TrayBrightness::CreateTrayView(user::LoginStatus status) {
    168   return NULL;
    169 }
    170 
    171 views::View* TrayBrightness::CreateDefaultView(user::LoginStatus status) {
    172   return NULL;
    173 }
    174 
    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 
    184 void TrayBrightness::DestroyTrayView() {
    185 }
    186 
    187 void TrayBrightness::DestroyDefaultView() {
    188   if (is_default_view_)
    189     brightness_view_ = NULL;
    190 }
    191 
    192 void TrayBrightness::DestroyDetailedView() {
    193   if (!is_default_view_)
    194     brightness_view_ = NULL;
    195 }
    196 
    197 void TrayBrightness::UpdateAfterLoginStatusChange(user::LoginStatus status) {
    198 }
    199 
    200 bool TrayBrightness::ShouldHideArrow() const {
    201   return true;
    202 }
    203 
    204 bool TrayBrightness::ShouldShowLauncher() const {
    205   return false;
    206 }
    207 
    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 
    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