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