diff options
-rw-r--r-- | ash/ash.gyp | 3 | ||||
-rw-r--r-- | ash/shell.cc | 3 | ||||
-rw-r--r-- | ash/shell.h | 5 | ||||
-rw-r--r-- | ash/wm/screen_dimmer.cc | 66 | ||||
-rw-r--r-- | ash/wm/screen_dimmer.h | 67 | ||||
-rw-r--r-- | ash/wm/screen_dimmer_unittest.cc | 78 | ||||
-rw-r--r-- | chrome/browser/chromeos/chrome_browser_main_chromeos.cc | 9 | ||||
-rw-r--r-- | chrome/browser/chromeos/chrome_browser_main_chromeos.h | 2 | ||||
-rw-r--r-- | chrome/browser/chromeos/power/screen_dimming_observer.cc | 26 | ||||
-rw-r--r-- | chrome/browser/chromeos/power/screen_dimming_observer.h | 32 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 | ||||
-rw-r--r-- | chromeos/dbus/power_manager_client.cc | 32 | ||||
-rw-r--r-- | chromeos/dbus/power_manager_client.h | 9 |
13 files changed, 329 insertions, 5 deletions
diff --git a/ash/ash.gyp b/ash/ash.gyp index 34a97b6..f4014ea 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp @@ -231,6 +231,8 @@ 'wm/root_window_layout_manager.cc', 'wm/root_window_layout_manager.h', 'wm/scoped_observer.h', + 'wm/screen_dimmer.cc', + 'wm/screen_dimmer.h', 'wm/shadow.cc', 'wm/shadow.h', 'wm/shadow_controller.cc', @@ -375,6 +377,7 @@ 'wm/panel_layout_manager_unittest.cc', 'wm/power_button_controller_unittest.cc', 'wm/root_window_event_filter_unittest.cc', + 'wm/screen_dimmer_unittest.cc', 'wm/shadow_controller_unittest.cc', 'wm/shelf_layout_manager_unittest.cc', 'wm/system_gesture_event_filter_unittest.cc', diff --git a/ash/shell.cc b/ash/shell.cc index dcf4761..3aab8a5 100644 --- a/ash/shell.cc +++ b/ash/shell.cc @@ -41,6 +41,7 @@ #include "ash/wm/resize_shadow_controller.h" #include "ash/wm/root_window_event_filter.h" #include "ash/wm/root_window_layout_manager.h" +#include "ash/wm/screen_dimmer.h" #include "ash/wm/shadow_controller.h" #include "ash/wm/shelf_layout_manager.h" #include "ash/wm/stacking_controller.h" @@ -575,6 +576,7 @@ Shell::~Shell() { drag_drop_controller_.reset(); magnification_controller_.reset(); resize_shadow_controller_.reset(); + screen_dimmer_.reset(); shadow_controller_.reset(); window_cycle_controller_.reset(); event_client_.reset(); @@ -727,6 +729,7 @@ void Shell::Init() { video_detector_.reset(new VideoDetector); window_cycle_controller_.reset(new WindowCycleController); monitor_controller_.reset(new internal::MonitorController); + screen_dimmer_.reset(new internal::ScreenDimmer); } aura::Window* Shell::GetContainer(int container_id) { diff --git a/ash/shell.h b/ash/shell.h index 38fb751..2f47db3 100644 --- a/ash/shell.h +++ b/ash/shell.h @@ -77,6 +77,7 @@ class PartialScreenshotEventFilter; class ResizeShadowController; class RootWindowEventFilter; class RootWindowLayoutManager; +class ScreenDimmer; class ShadowController; class ShelfLayoutManager; class ShellContextMenu; @@ -236,6 +237,9 @@ class ASH_EXPORT Shell { internal::MagnificationController* magnification_controller() { return magnification_controller_.get(); } + internal::ScreenDimmer* screen_dimmer() { + return screen_dimmer_.get(); + } Launcher* launcher() { return launcher_.get(); } @@ -339,6 +343,7 @@ class ASH_EXPORT Shell { scoped_ptr<internal::EventClientImpl> event_client_; scoped_ptr<internal::MonitorController> monitor_controller_; scoped_ptr<internal::MagnificationController> magnification_controller_; + scoped_ptr<internal::ScreenDimmer> screen_dimmer_; // An event filter that rewrites or drops a key event. scoped_ptr<internal::KeyRewriterEventFilter> key_rewriter_filter_; diff --git a/ash/wm/screen_dimmer.cc b/ash/wm/screen_dimmer.cc new file mode 100644 index 0000000..b902de0 --- /dev/null +++ b/ash/wm/screen_dimmer.cc @@ -0,0 +1,66 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/wm/screen_dimmer.h" + +#include "ash/shell.h" +#include "base/time.h" +#include "ui/aura/root_window.h" +#include "ui/gfx/compositor/layer.h" +#include "ui/gfx/compositor/scoped_layer_animation_settings.h" +#include "ui/gfx/rect.h" +#include "ui/gfx/size.h" + +namespace ash { +namespace internal { + +namespace { + +// Opacity for |dimming_layer_| when it's dimming the screen. +const float kDimmingLayerOpacity = 0.4f; + +// Duration for dimming animations, in milliseconds. +const int kDimmingTransitionMs = 200; + +} // namespace + +ScreenDimmer::ScreenDimmer() : currently_dimming_(false) { + Shell::GetInstance()->GetRootWindow()->AddRootWindowObserver(this); +} + +ScreenDimmer::~ScreenDimmer() { + Shell::GetInstance()->GetRootWindow()->RemoveRootWindowObserver(this); +} + +void ScreenDimmer::SetDimming(bool should_dim) { + if (should_dim == currently_dimming_) + return; + + if (!dimming_layer_.get()) { + dimming_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR)); + dimming_layer_->SetColor(SK_ColorBLACK); + dimming_layer_->SetOpacity(0.0f); + ui::Layer* root_layer = Shell::GetRootWindow()->layer(); + dimming_layer_->SetBounds(root_layer->bounds()); + root_layer->Add(dimming_layer_.get()); + root_layer->StackAtTop(dimming_layer_.get()); + } + + currently_dimming_ = should_dim; + + ui::ScopedLayerAnimationSettings scoped_settings( + dimming_layer_->GetAnimator()); + scoped_settings.SetTransitionDuration( + base::TimeDelta::FromMilliseconds(kDimmingTransitionMs)); + dimming_layer_->SetOpacity(should_dim ? kDimmingLayerOpacity : 0.0f); +} + +void ScreenDimmer::OnRootWindowResized(const aura::RootWindow* root, + const gfx::Size& old_size) { + if (dimming_layer_.get()) + dimming_layer_->SetBounds(gfx::Rect(root->bounds().size())); +} + +} // namespace internal +} // namespace ash diff --git a/ash/wm/screen_dimmer.h b/ash/wm/screen_dimmer.h new file mode 100644 index 0000000..2415b58 --- /dev/null +++ b/ash/wm/screen_dimmer.h @@ -0,0 +1,67 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_WM_SCREEN_DIMMER_H_ +#define ASH_WM_SCREEN_DIMMER_H_ +#pragma once + +#include "ash/ash_export.h" +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" +#include "ui/aura/root_window_observer.h" + +namespace ui { +class Layer; +} + +namespace ash { +namespace internal { + +// ScreenDimmer displays a partially-opaque layer above everything else to +// darken the screen. It shouldn't be used for long-term brightness adjustments +// due to performance considerations -- it's only intended for cases where we +// want to briefly dim the screen (e.g. to indicate to the user that we're about +// to suspend a machine that lacks an internal backlight that can be adjusted). +class ASH_EXPORT ScreenDimmer : public aura::RootWindowObserver { + public: + class TestApi { + public: + explicit TestApi(ScreenDimmer* dimmer) : dimmer_(dimmer) {} + + ui::Layer* layer() { return dimmer_->dimming_layer_.get(); } + + private: + ScreenDimmer* dimmer_; // not owned + + DISALLOW_COPY_AND_ASSIGN(TestApi); + }; + + ScreenDimmer(); + virtual ~ScreenDimmer(); + + // Dim or undim the screen. + void SetDimming(bool should_dim); + + // aura::RootWindowObserver overrides: + virtual void OnRootWindowResized(const aura::RootWindow* root, + const gfx::Size& old_size) OVERRIDE; + + private: + friend class TestApi; + + // Partially-opaque layer that's stacked above all of the root window's + // children and used to dim the screen. NULL until the first time we dim. + scoped_ptr<ui::Layer> dimming_layer_; + + // Are we currently dimming the screen? + bool currently_dimming_; + + DISALLOW_COPY_AND_ASSIGN(ScreenDimmer); +}; + +} // namespace internal +} // namespace ash + +#endif // ASH_WM_SCREEN_DIMMER_H_ diff --git a/ash/wm/screen_dimmer_unittest.cc b/ash/wm/screen_dimmer_unittest.cc new file mode 100644 index 0000000..b66cd2f --- /dev/null +++ b/ash/wm/screen_dimmer_unittest.cc @@ -0,0 +1,78 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/wm/screen_dimmer.h" + +#include "ash/shell.h" +#include "ash/test/ash_test_base.h" +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" +#include "ui/aura/root_window.h" +#include "ui/gfx/compositor/layer.h" + +namespace ash { +namespace test { + +class ScreenDimmerTest : public AshTestBase { + public: + ScreenDimmerTest() : dimmer_(NULL) {} + virtual ~ScreenDimmerTest() {} + + void SetUp() OVERRIDE { + AshTestBase::SetUp(); + dimmer_ = Shell::GetInstance()->screen_dimmer(); + test_api_.reset(new internal::ScreenDimmer::TestApi(dimmer_)); + } + + protected: + internal::ScreenDimmer* dimmer_; // not owned + + scoped_ptr<internal::ScreenDimmer::TestApi> test_api_; + + private: + DISALLOW_COPY_AND_ASSIGN(ScreenDimmerTest); +}; + +TEST_F(ScreenDimmerTest, DimAndUndim) { + // Don't create a layer until we need to. + EXPECT_TRUE(test_api_->layer() == NULL); + dimmer_->SetDimming(false); + EXPECT_TRUE(test_api_->layer() == NULL); + + // When we enable dimming, the layer should be created and stacked at the top + // of the root's children. + dimmer_->SetDimming(true); + ASSERT_TRUE(test_api_->layer() != NULL); + ui::Layer* root_layer = Shell::GetInstance()->GetRootWindow()->layer(); + ASSERT_TRUE(!root_layer->children().empty()); + EXPECT_EQ(test_api_->layer(), root_layer->children().back()); + EXPECT_TRUE(test_api_->layer()->visible()); + EXPECT_GT(test_api_->layer()->GetTargetOpacity(), 0.0f); + + // When we disable dimming, the layer should be animated back to full + // transparency. + dimmer_->SetDimming(false); + ASSERT_TRUE(test_api_->layer() != NULL); + EXPECT_TRUE(test_api_->layer()->visible()); + EXPECT_FLOAT_EQ(0.0f, test_api_->layer()->GetTargetOpacity()); +} + +TEST_F(ScreenDimmerTest, ResizeLayer) { + // The dimming layer should be initially sized to cover the root window. + dimmer_->SetDimming(true); + ui::Layer* dimming_layer = test_api_->layer(); + ASSERT_TRUE(dimming_layer != NULL); + ui::Layer* root_layer = Shell::GetInstance()->GetRootWindow()->layer(); + EXPECT_EQ(gfx::Rect(root_layer->bounds().size()).ToString(), + dimming_layer->bounds().ToString()); + + // When we resize the root window, the dimming layer should be resized to + // match. + gfx::Size kNewSize(400, 300); + Shell::GetInstance()->GetRootWindow()->SetHostSize(kNewSize); + EXPECT_EQ(kNewSize.ToString(), dimming_layer->bounds().size().ToString()); +} + +} // namespace test +} // namespace ash diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc index dfb30fa..ea86e8f 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc @@ -40,6 +40,7 @@ #include "chrome/browser/chromeos/power/power_button_observer.h" #include "chrome/browser/chromeos/power/power_state_override.h" #include "chrome/browser/chromeos/power/resume_observer.h" +#include "chrome/browser/chromeos/power/screen_dimming_observer.h" #include "chrome/browser/chromeos/power/screen_lock_observer.h" #include "chrome/browser/chromeos/power/video_property_writer.h" #include "chrome/browser/chromeos/system/statistics_provider.h" @@ -70,8 +71,6 @@ #include "net/url_request/url_request.h" #include "ui/base/l10n/l10n_util.h" - - class MessageLoopObserver : public MessageLoopForUI::Observer { virtual base::EventStatus WillProcessEvent( const base::NativeEvent& event) OVERRIDE { @@ -439,6 +438,7 @@ void ChromeBrowserMainPartsChromeos::PostBrowserStart() { // initialized. power_button_observer_.reset(new chromeos::PowerButtonObserver); video_property_writer_.reset(new chromeos::VideoPropertyWriter); + screen_dimming_observer_.reset(new chromeos::ScreenDimmingObserver); ChromeBrowserMainPartsLinux::PostBrowserStart(); } @@ -488,9 +488,10 @@ void ChromeBrowserMainPartsChromeos::PostMainMessageLoopRun() { // Let VideoPropertyWriter unregister itself as an observer of the ash::Shell // singleton before the shell is destroyed. video_property_writer_.reset(); - // Remove PowerButtonObserver attached to a D-Bus client before - // DBusThreadManager is shut down. + + // Detach D-Bus clients before DBusThreadManager is shut down. power_button_observer_.reset(); + screen_dimming_observer_.reset(); ChromeBrowserMainPartsLinux::PostMainMessageLoopRun(); } diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.h b/chrome/browser/chromeos/chrome_browser_main_chromeos.h index 1980810..a001ea1 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.h +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.h @@ -14,6 +14,7 @@ class DesktopBackgroundObserver; class PowerButtonObserver; class PowerStateOverride; class ResumeObserver; +class ScreenDimmingObserver; class ScreenLockObserver; class SessionManagerObserver; class VideoPropertyWriter; @@ -48,6 +49,7 @@ class ChromeBrowserMainPartsChromeos : public ChromeBrowserMainPartsLinux { scoped_ptr<chromeos::PowerButtonObserver> power_button_observer_; scoped_ptr<chromeos::PowerStateOverride> power_state_override_; scoped_ptr<chromeos::VideoPropertyWriter> video_property_writer_; + scoped_ptr<chromeos::ScreenDimmingObserver> screen_dimming_observer_; DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainPartsChromeos); }; diff --git a/chrome/browser/chromeos/power/screen_dimming_observer.cc b/chrome/browser/chromeos/power/screen_dimming_observer.cc new file mode 100644 index 0000000..7795760 --- /dev/null +++ b/chrome/browser/chromeos/power/screen_dimming_observer.cc @@ -0,0 +1,26 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/power/screen_dimming_observer.h" + +#include "ash/shell.h" +#include "ash/wm/screen_dimmer.h" +#include "chromeos/dbus/dbus_thread_manager.h" + +namespace chromeos { + +ScreenDimmingObserver::ScreenDimmingObserver() { + DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(this); +} + +ScreenDimmingObserver::~ScreenDimmingObserver() { + DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this); +} + +void ScreenDimmingObserver::ScreenDimmingRequested(ScreenDimmingState state) { + ash::Shell::GetInstance()->screen_dimmer()->SetDimming( + state == PowerManagerClient::Observer::SCREEN_DIMMING_IDLE); +} + +} // namespace chromeos diff --git a/chrome/browser/chromeos/power/screen_dimming_observer.h b/chrome/browser/chromeos/power/screen_dimming_observer.h new file mode 100644 index 0000000..6f6342f --- /dev/null +++ b/chrome/browser/chromeos/power/screen_dimming_observer.h @@ -0,0 +1,32 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_POWER_SCREEN_DIMMING_OBSERVER_H_ +#define CHROME_BROWSER_CHROMEOS_POWER_SCREEN_DIMMING_OBSERVER_H_ +#pragma once + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "chromeos/dbus/power_manager_client.h" + +namespace chromeos { + +// Listens for requests to enable or disable dimming of the screen in software +// (as opposed to by adjusting a backlight). +class ScreenDimmingObserver : public PowerManagerClient::Observer { + public: + // This class registers/unregisters itself as an observer in ctor/dtor. + ScreenDimmingObserver(); + virtual ~ScreenDimmingObserver(); + + private: + // PowerManagerClient::Observer implementation. + virtual void ScreenDimmingRequested(ScreenDimmingState state) OVERRIDE; + + DISALLOW_COPY_AND_ASSIGN(ScreenDimmingObserver); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_POWER_SCREEN_DIMMING_OBSERVER_H_ diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 13af13d..8b2bde5 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -793,6 +793,8 @@ 'browser/chromeos/power/power_state_override.h', 'browser/chromeos/power/resume_observer.cc', 'browser/chromeos/power/resume_observer.h', + 'browser/chromeos/power/screen_dimming_observer.cc', + 'browser/chromeos/power/screen_dimming_observer.h', 'browser/chromeos/power/screen_lock_observer.cc', 'browser/chromeos/power/screen_lock_observer.h', 'browser/chromeos/power/video_property_writer.cc', diff --git a/chromeos/dbus/power_manager_client.cc b/chromeos/dbus/power_manager_client.cc index 26f6705..ca50df7 100644 --- a/chromeos/dbus/power_manager_client.cc +++ b/chromeos/dbus/power_manager_client.cc @@ -111,6 +111,15 @@ class PowerManagerClientImpl : public PowerManagerClient { weak_ptr_factory_.GetWeakPtr()), base::Bind(&PowerManagerClientImpl::SignalConnected, weak_ptr_factory_.GetWeakPtr())); + + power_manager_proxy_->ConnectToSignal( + power_manager::kPowerManagerInterface, + power_manager::kSoftwareScreenDimmingRequestedSignal, + base::Bind( + &PowerManagerClientImpl::SoftwareScreenDimmingRequestedReceived, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&PowerManagerClientImpl::SignalConnected, + weak_ptr_factory_.GetWeakPtr())); } virtual ~PowerManagerClientImpl() { @@ -435,7 +444,6 @@ class PowerManagerClientImpl : public PowerManagerClient { FOR_EACH_OBSERVER(Observer, observers_, UnlockScreenFailed()); } - void IdleNotifySignalReceived(dbus::Signal* signal) { dbus::MessageReader reader(signal); int64 threshold = 0; @@ -464,6 +472,28 @@ class PowerManagerClientImpl : public PowerManagerClient { FOR_EACH_OBSERVER(Observer, observers_, ActiveNotify()); } + void SoftwareScreenDimmingRequestedReceived(dbus::Signal* signal) { + dbus::MessageReader reader(signal); + int32 signal_state = 0; + if (!reader.PopInt32(&signal_state)) { + LOG(ERROR) << "Screen dimming signal had incorrect parameters: " + << signal->ToString(); + return; + } + + Observer::ScreenDimmingState state = Observer::SCREEN_DIMMING_NONE; + switch (signal_state) { + case power_manager::kSoftwareScreenDimmingNone: + state = Observer::SCREEN_DIMMING_NONE; + break; + case power_manager::kSoftwareScreenDimmingIdle: + state = Observer::SCREEN_DIMMING_IDLE; + break; + default: + LOG(ERROR) << "Unhandled screen dimming state " << signal_state; + } + FOR_EACH_OBSERVER(Observer, observers_, ScreenDimmingRequested(state)); + } dbus::ObjectProxy* power_manager_proxy_; dbus::ObjectProxy* session_manager_proxy_; diff --git a/chromeos/dbus/power_manager_client.h b/chromeos/dbus/power_manager_client.h index eb19947..00c27b8 100644 --- a/chromeos/dbus/power_manager_client.h +++ b/chromeos/dbus/power_manager_client.h @@ -39,6 +39,11 @@ class CHROMEOS_EXPORT PowerManagerClient { // Interface for observing changes from the power manager. class Observer { public: + enum ScreenDimmingState { + SCREEN_DIMMING_NONE = 0, + SCREEN_DIMMING_IDLE, + }; + virtual ~Observer() {} // Called when the brightness is changed. @@ -75,6 +80,10 @@ class CHROMEOS_EXPORT PowerManagerClient { // Called when we go from idle to active. virtual void ActiveNotify() {} + + // Called when a request is received to dim or undim the screen in software + // (as opposed to the more-common method of adjusting the backlight). + virtual void ScreenDimmingRequested(ScreenDimmingState state) {} }; enum UpdateRequestType { |