diff options
author | mdm@chromium.org <mdm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-11 18:02:03 +0000 |
---|---|---|
committer | mdm@chromium.org <mdm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-11 18:02:03 +0000 |
commit | 6b55aecf5481ebb66f6b93d8f34cca5a44197473 (patch) | |
tree | 49cc990738f169b1968bec18376b17acf18ede3f | |
parent | bb23e67631a9c70e51f61e0f39fd1774c7af519f (diff) | |
download | chromium_src-6b55aecf5481ebb66f6b93d8f34cca5a44197473.zip chromium_src-6b55aecf5481ebb66f6b93d8f34cca5a44197473.tar.gz chromium_src-6b55aecf5481ebb66f6b93d8f34cca5a44197473.tar.bz2 |
Power save blocker: switch to new implementation. In addition to making things
much simpler, this will also fix bug 126591 on Windows 8 by activating the new
code in r140668.
BUG=126591
Review URL: https://chromiumcodereview.appspot.com/10542089
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@141433 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | content/browser/download/download_file_impl.cc | 2 | ||||
-rw-r--r-- | content/browser/download/download_file_impl.h | 7 | ||||
-rw-r--r-- | content/browser/download/download_file_manager.cc | 7 | ||||
-rw-r--r-- | content/browser/download/download_file_unittest.cc | 2 | ||||
-rw-r--r-- | content/browser/download/download_manager_impl_unittest.cc | 8 | ||||
-rw-r--r-- | content/browser/power_save_blocker.h | 56 | ||||
-rw-r--r-- | content/browser/power_save_blocker_android.cc | 20 | ||||
-rw-r--r-- | content/browser/power_save_blocker_common.cc | 64 | ||||
-rw-r--r-- | content/browser/power_save_blocker_linux.cc | 475 | ||||
-rw-r--r-- | content/browser/power_save_blocker_mac.cc | 100 | ||||
-rw-r--r-- | content/browser/power_save_blocker_win.cc | 28 | ||||
-rw-r--r-- | content/browser/renderer_host/render_view_host_impl.cc | 12 | ||||
-rw-r--r-- | content/browser/renderer_host/render_view_host_impl.h | 4 | ||||
-rw-r--r-- | content/content_browser.gypi | 1 | ||||
-rw-r--r-- | content/test/test_file_error_injector.cc | 2 |
15 files changed, 65 insertions, 723 deletions
diff --git a/content/browser/download/download_file_impl.cc b/content/browser/download/download_file_impl.cc index ee588b8..b315776 100644 --- a/content/browser/download/download_file_impl.cc +++ b/content/browser/download/download_file_impl.cc @@ -33,7 +33,7 @@ DownloadFileImpl::DownloadFileImpl( DownloadRequestHandleInterface* request_handle, DownloadManager* download_manager, bool calculate_hash, - scoped_ptr<PowerSaveBlocker> power_save_blocker, + scoped_ptr<content::PowerSaveBlocker> power_save_blocker, const net::BoundNetLog& bound_net_log) : file_(info->save_info.file_path, info->url(), diff --git a/content/browser/download/download_file_impl.h b/content/browser/download/download_file_impl.h index 93d6329..de88298 100644 --- a/content/browser/download/download_file_impl.h +++ b/content/browser/download/download_file_impl.h @@ -18,13 +18,12 @@ #include "content/browser/download/download_request_handle.h" #include "net/base/net_log.h" -class PowerSaveBlocker; - struct DownloadCreateInfo; namespace content { class ByteStreamReader; class DownloadManager; +class PowerSaveBlocker; } class CONTENT_EXPORT DownloadFileImpl : virtual public content::DownloadFile { @@ -36,7 +35,7 @@ class CONTENT_EXPORT DownloadFileImpl : virtual public content::DownloadFile { DownloadRequestHandleInterface* request_handle, content::DownloadManager* download_manager, bool calculate_hash, - scoped_ptr<PowerSaveBlocker> power_save_blocker, + scoped_ptr<content::PowerSaveBlocker> power_save_blocker, const net::BoundNetLog& bound_net_log); virtual ~DownloadFileImpl(); @@ -104,7 +103,7 @@ class CONTENT_EXPORT DownloadFileImpl : virtual public content::DownloadFile { base::WeakPtrFactory<DownloadFileImpl> weak_factory_; // RAII handle to keep the system from sleeping while we're downloading. - scoped_ptr<PowerSaveBlocker> power_save_blocker_; + scoped_ptr<content::PowerSaveBlocker> power_save_blocker_; DISALLOW_COPY_AND_ASSIGN(DownloadFileImpl); }; diff --git a/content/browser/download/download_file_manager.cc b/content/browser/download/download_file_manager.cc index f313a98..21c8597 100644 --- a/content/browser/download/download_file_manager.cc +++ b/content/browser/download/download_file_manager.cc @@ -57,9 +57,10 @@ DownloadFile* DownloadFileFactoryImpl::CreateFile( return new DownloadFileImpl( info, stream.Pass(), new DownloadRequestHandle(request_handle), download_manager, calculate_hash, - scoped_ptr<PowerSaveBlocker>( - new PowerSaveBlocker( - PowerSaveBlocker::kPowerSaveBlockPreventSystemSleep)).Pass(), + scoped_ptr<content::PowerSaveBlocker>( + new content::PowerSaveBlocker( + content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension, + "Download in progress")).Pass(), bound_net_log); } diff --git a/content/browser/download/download_file_unittest.cc b/content/browser/download/download_file_unittest.cc index 9d1c661..248610c 100644 --- a/content/browser/download/download_file_unittest.cc +++ b/content/browser/download/download_file_unittest.cc @@ -126,7 +126,7 @@ class DownloadFileTest : public testing::Test { scoped_ptr<content::ByteStreamReader>(input_stream_).Pass(), new DownloadRequestHandle(), download_manager_, calculate_hash, - scoped_ptr<PowerSaveBlocker>(NULL).Pass(), + scoped_ptr<content::PowerSaveBlocker>(NULL).Pass(), net::BoundNetLog())); EXPECT_CALL(*input_stream_, Read(_, _)) diff --git a/content/browser/download/download_manager_impl_unittest.cc b/content/browser/download/download_manager_impl_unittest.cc index 49b022a..b60024d 100644 --- a/content/browser/download/download_manager_impl_unittest.cc +++ b/content/browser/download/download_manager_impl_unittest.cc @@ -392,7 +392,7 @@ DownloadFileWithErrors::DownloadFileWithErrors( new DownloadRequestHandle(), manager, calculate_hash, - scoped_ptr<PowerSaveBlocker>(NULL).Pass(), + scoped_ptr<content::PowerSaveBlocker>(NULL).Pass(), net::BoundNetLog()), forced_error_(net::OK) { } @@ -563,7 +563,7 @@ TEST_F(DownloadManagerTest, MAYBE_StartDownload) { stream_reader.Pass(), new DownloadRequestHandle(), download_manager_, false, - scoped_ptr<PowerSaveBlocker>(NULL).Pass(), + scoped_ptr<content::PowerSaveBlocker>(NULL).Pass(), net::BoundNetLog())); AddDownloadToFileManager(info->download_id, download_file); download_file->Initialize(); @@ -1129,7 +1129,7 @@ TEST_F(DownloadManagerTest, MAYBE_DownloadOverwriteTest) { new DownloadFileImpl(info.get(), stream_output.Pass(), new DownloadRequestHandle(), download_manager_, false, - scoped_ptr<PowerSaveBlocker>(NULL).Pass(), + scoped_ptr<content::PowerSaveBlocker>(NULL).Pass(), net::BoundNetLog())); download_file->Rename(cr_path); // This creates the .temp version of the file. @@ -1208,7 +1208,7 @@ TEST_F(DownloadManagerTest, MAYBE_DownloadRemoveTest) { new DownloadFileImpl(info.get(), stream_output.Pass(), new DownloadRequestHandle(), download_manager_, false, - scoped_ptr<PowerSaveBlocker>(NULL).Pass(), + scoped_ptr<content::PowerSaveBlocker>(NULL).Pass(), net::BoundNetLog())); download_file->Rename(cr_path); // This creates the .temp version of the file. diff --git a/content/browser/power_save_blocker.h b/content/browser/power_save_blocker.h index ee57e27..2d22acf 100644 --- a/content/browser/power_save_blocker.h +++ b/content/browser/power_save_blocker.h @@ -13,55 +13,11 @@ #include "base/memory/ref_counted.h" #include "content/common/content_export.h" -// A RAII-style class to block the system from entering low-power (sleep) mode. -class CONTENT_EXPORT PowerSaveBlocker { - public: - enum PowerSaveBlockerType { - kPowerSaveBlockPreventNone = -1, - - // Prevent the system from going to sleep; allow display sleep. - kPowerSaveBlockPreventSystemSleep, - - // Prevent the system or display from going to sleep. - kPowerSaveBlockPreventDisplaySleep, - - // Count of the values; not valid as a parameter. - kPowerSaveBlockPreventStateCount - }; - - // Pass in the level of sleep prevention desired. kPowerSaveBlockPreventNone - // is not a valid option. - explicit PowerSaveBlocker(PowerSaveBlockerType type); - ~PowerSaveBlocker(); - - private: - // Platform-specific function called when enable state is changed. - // Guaranteed to be called only from the UI thread. - static void ApplyBlock(PowerSaveBlockerType type); - - // Called only from UI thread. - static void AdjustBlockCount(const std::vector<int>& deltas); - - // Invokes AdjustBlockCount on the UI thread. - static void PostAdjustBlockCount(const std::vector<int>& deltas); - - // Returns the highest-severity block type in use. - static PowerSaveBlockerType HighestBlockType(); - - PowerSaveBlockerType type_; - - static int blocker_count_[]; - - DISALLOW_COPY_AND_ASSIGN(PowerSaveBlocker); -}; - namespace content { -// NOT READY YET. PowerSaveBlocker above is soon to be replaced by this class, -// but it's not done yet so client code should use the one above for now. // A RAII-style class to block the system from entering low-power (sleep) mode. // This class is thread-safe; it may be constructed and deleted on any thread. -class CONTENT_EXPORT PowerSaveBlocker2 { +class CONTENT_EXPORT PowerSaveBlocker { public: enum PowerSaveBlockerType { // Prevent the application from being suspended. On some platforms, apps may @@ -81,8 +37,8 @@ class CONTENT_EXPORT PowerSaveBlocker2 { // Pass in the type of power save blocking desired. If multiple types of // blocking are desired, instantiate one PowerSaveBlocker for each type. // |reason| may be provided to the underlying system APIs on some platforms. - PowerSaveBlocker2(PowerSaveBlockerType type, const std::string& reason); - ~PowerSaveBlocker2(); + PowerSaveBlocker(PowerSaveBlockerType type, const std::string& reason); + ~PowerSaveBlocker(); private: class Delegate; @@ -91,15 +47,15 @@ class CONTENT_EXPORT PowerSaveBlocker2 { // lifetime than the RAII container, or additional storage. This member is // here for that purpose. If not used, just define the class as an empty // RefCounted (or RefCountedThreadSafe) like so to make it compile: - // class PowerSaveBlocker2::Delegate - // : public base::RefCounted<PowerSaveBlocker2::Delegate> { + // class PowerSaveBlocker::Delegate + // : public base::RefCounted<PowerSaveBlocker::Delegate> { // private: // friend class base::RefCounted<Delegate>; // ~Delegate() {} // }; scoped_refptr<Delegate> delegate_; - DISALLOW_COPY_AND_ASSIGN(PowerSaveBlocker2); + DISALLOW_COPY_AND_ASSIGN(PowerSaveBlocker); }; } // namespace content diff --git a/content/browser/power_save_blocker_android.cc b/content/browser/power_save_blocker_android.cc index b260124..2de5ef0 100644 --- a/content/browser/power_save_blocker_android.cc +++ b/content/browser/power_save_blocker_android.cc @@ -6,9 +6,23 @@ #include "base/logging.h" -// Called only from UI thread. -// static -void PowerSaveBlocker::ApplyBlock(PowerSaveBlockerType type) { +namespace content { + +class PowerSaveBlocker::Delegate + : public base::RefCounted<PowerSaveBlocker::Delegate> { + private: + friend class base::RefCounted<Delegate>; + ~Delegate() {} +}; + +PowerSaveBlocker::PowerSaveBlocker(PowerSaveBlockerType type, + const std::string& reason) { // TODO(wangxianzhu): Implement it. + // This may be called on any thread. NOTIMPLEMENTED(); } + +PowerSaveBlocker::~PowerSaveBlocker() { +} + +} // namespace content diff --git a/content/browser/power_save_blocker_common.cc b/content/browser/power_save_blocker_common.cc deleted file mode 100644 index 8115b9c..0000000 --- a/content/browser/power_save_blocker_common.cc +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) 2011 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 "content/browser/power_save_blocker.h" - -#include "base/bind.h" -#include "content/public/browser/browser_thread.h" - -using content::BrowserThread; - -// Accessed only from the UI thread. -int PowerSaveBlocker::blocker_count_[kPowerSaveBlockPreventStateCount]; - -PowerSaveBlocker::PowerSaveBlocker(PowerSaveBlockerType type) : type_(type) { - DCHECK_LT(kPowerSaveBlockPreventNone, type); - DCHECK_GT(kPowerSaveBlockPreventStateCount, type); - std::vector<int> change(kPowerSaveBlockPreventStateCount); - ++change[type_]; - PostAdjustBlockCount(change); -} - -PowerSaveBlocker::~PowerSaveBlocker(void) { - std::vector<int> change(kPowerSaveBlockPreventStateCount); - --change[type_]; - PostAdjustBlockCount(change); -} - -// static -void PowerSaveBlocker::PostAdjustBlockCount(const std::vector<int>& deltas) { - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&PowerSaveBlocker::AdjustBlockCount, deltas)); -} - -// Called only from UI thread. -// static -void PowerSaveBlocker::AdjustBlockCount(const std::vector<int>& deltas) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - PowerSaveBlockerType old_block = HighestBlockType(); - - for (size_t i = 0; i < deltas.size(); ++i) - blocker_count_[i] += deltas[i]; - - PowerSaveBlockerType new_block = HighestBlockType(); - - if (new_block != old_block) - ApplyBlock(new_block); -} - -// Called only from UI thread. -PowerSaveBlocker::PowerSaveBlockerType PowerSaveBlocker::HighestBlockType() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - for (PowerSaveBlockerType t = kPowerSaveBlockPreventDisplaySleep; - t >= kPowerSaveBlockPreventSystemSleep; - t = static_cast<PowerSaveBlockerType>(t - 1)) { - if (blocker_count_[t]) - return t; - } - - return kPowerSaveBlockPreventNone; -} diff --git a/content/browser/power_save_blocker_linux.cc b/content/browser/power_save_blocker_linux.cc index e246650..37c1a50 100644 --- a/content/browser/power_save_blocker_linux.cc +++ b/content/browser/power_save_blocker_linux.cc @@ -34,481 +34,6 @@ #include "dbus/object_path.h" #include "dbus/object_proxy.h" -using content::BrowserThread; - -namespace { - -// This class is used to inhibit Power Management on Linux systems using D-Bus -// interfaces. Mainly, there are two interfaces that make this possible. -// org.freedesktop.PowerManagement[.Inhibit] is considered to be the -// desktop-agnostic solution. However, it is only used by KDE4 and XFCE. -// -// org.gnome.SessionManager is the Power Management interface available on GNOME -// desktops. Given that there is no generic solution to this problem, this class -// delegates the task of calling specific D-Bus APIs, to a -// DBusPowerSaveBlock::Delegate object. -// -// This class is a Singleton and the delegate will be instantiated internally, -// when the singleton instance is created, based on the desktop environment in -// which the application is running. When the class is instantiated, if it runs -// under a supported desktop environment it creates the Bus object and the -// delegate. Otherwise, no object is created and the ApplyBlock method will not -// do anything. -class DBusPowerSaveBlocker { - public: - // String passed to D-Bus APIs as the reason for which - // the power management features are temporarily disabled. - static const char kPowerSaveReason[]; - - // This delegate interface represents a concrete implementation for a specific - // D-Bus interface. It is responsible for obtaining specific object proxies, - // making D-Bus method calls and handling D-Bus responses. - // - // When a new DBusPowerBlocker is created, only a specific implementation of - // the delegate is instantiated. See the DBusPowerSaveBlocker constructor for - // more details. This is ref_counted to make sure that the callbacks stay - // alive even after the DBusPowerSaveBlocker object is deleted. - class Delegate : public base::RefCountedThreadSafe<Delegate> { - public: - Delegate() {} - virtual void ApplyBlock(PowerSaveBlocker::PowerSaveBlockerType type) = 0; - - protected: - virtual ~Delegate() {} - - private: - friend class base::RefCountedThreadSafe<Delegate>; - - DISALLOW_COPY_AND_ASSIGN(Delegate); - }; - - // Returns a pointer to the sole instance of this class - static DBusPowerSaveBlocker* GetInstance(); - - // Forwards a power save block request to the concrete implementation of the - // Delegate interface. If |delegate_| is NULL, the application runs under an - // unsupported desktop environment. In this case, the method does nothing. - void ApplyBlock(PowerSaveBlocker::PowerSaveBlockerType type) { - if (delegate_) - delegate_->ApplyBlock(type); - } - - // Getter for the Bus object. Used by the Delegates to obtain object proxies. - scoped_refptr<dbus::Bus> bus() const { return bus_; } - - private: - DBusPowerSaveBlocker(); - virtual ~DBusPowerSaveBlocker(); - - // If DPMS is not enabled, then we don't want to try to disable power saving, - // since on some desktop environments that may enable DPMS with very poor - // default settings (e.g. turning off the display after only 1 second). - static bool DPMSEnabled(); - - // The D-Bus connection. - scoped_refptr<dbus::Bus> bus_; - - // Concrete implementation of the Delegate interface. - scoped_refptr<Delegate> delegate_; - - friend struct DefaultSingletonTraits<DBusPowerSaveBlocker>; - - DISALLOW_COPY_AND_ASSIGN(DBusPowerSaveBlocker); -}; - -// Delegate implementation for KDE4. It uses the -// org.freedesktop.PowerManagement interface. It works on XFCE4, too. -class KDEPowerSaveBlocker : public DBusPowerSaveBlocker::Delegate { - public: - KDEPowerSaveBlocker() - : inhibit_cookie_(0), - pending_inhibit_call_(false), - postponed_uninhibit_call_(false) { - } - - virtual void ApplyBlock( - PowerSaveBlocker::PowerSaveBlockerType type) OVERRIDE { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(pending_inhibit_call_ || !postponed_uninhibit_call_); - - // If we have a pending inhibit call, we add a postponed uninhibit - // request, such that it will be canceled as soon as the response arrives. - // If we have an active inhibit request and receive a new one, - // we ignore it since the 'freedesktop' interface has only one Inhibit level - // and we cannot differentiate between SystemSleep and DisplaySleep, - // so there's no need to make additional D-Bus method calls. - if (type == PowerSaveBlocker::kPowerSaveBlockPreventNone) { - if (pending_inhibit_call_ && postponed_uninhibit_call_) { - return; - } else if (pending_inhibit_call_ && !postponed_uninhibit_call_) { - postponed_uninhibit_call_ = true; - return; - } else if (!pending_inhibit_call_ && inhibit_cookie_ == 0) { - return; - } - } else if ((pending_inhibit_call_ && !postponed_uninhibit_call_) || - inhibit_cookie_ > 0) { - return; - } - - scoped_refptr<dbus::ObjectProxy> object_proxy = - DBusPowerSaveBlocker::GetInstance()->bus()->GetObjectProxy( - "org.freedesktop.PowerManagement", - dbus::ObjectPath("/org/freedesktop/PowerManagement/Inhibit")); - dbus::MethodCall method_call("org.freedesktop.PowerManagement.Inhibit", - "Inhibit"); - dbus::MessageWriter message_writer(&method_call); - base::Callback<void(dbus::Response*)> bus_callback; - - switch (type) { - case PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep: - case PowerSaveBlocker::kPowerSaveBlockPreventSystemSleep: - // The org.freedesktop.PowerManagement.Inhibit interface offers only one - // Inhibit() method, that temporarily disables all power management - // features. We cannot differentiate and disable individual features, - // like display sleep or system sleep. - // The first argument of the Inhibit method is the application name. - // The second argument of the Inhibit method is a string containing - // the reason of the power save block request. - // The method returns a cookie (an int), which we must pass back to the - // UnInhibit method when we cancel our request. - message_writer.AppendString( - CommandLine::ForCurrentProcess()->GetProgram().value()); - message_writer.AppendString(DBusPowerSaveBlocker::kPowerSaveReason); - bus_callback = base::Bind(&KDEPowerSaveBlocker::OnInhibitResponse, - this); - pending_inhibit_call_ = true; - break; - case PowerSaveBlocker::kPowerSaveBlockPreventNone: - // To cancel our inhibit request, we have to call a different method. - // It takes one argument, the cookie returned by the corresponding - // Inhibit method call. - method_call.SetMember("UnInhibit"); - message_writer.AppendUint32(inhibit_cookie_); - bus_callback = base::Bind(&KDEPowerSaveBlocker::OnUnInhibitResponse, - this); - break; - case PowerSaveBlocker::kPowerSaveBlockPreventStateCount: - // This is an invalid argument - NOTREACHED(); - break; - } - - object_proxy->CallMethod(&method_call, - dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, - bus_callback); - } - - protected: - virtual ~KDEPowerSaveBlocker() {} - - private: - // Inhibit() response callback. - // Stores the cookie so we can use it later when calling UnInhibit(). - // If the response from D-Bus is successful and there is a postponed - // uninhibit request, we cancel the cookie that we just received. - void OnInhibitResponse(dbus::Response* response) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(pending_inhibit_call_); - pending_inhibit_call_ = false; - if (response) { - dbus::MessageReader message_reader(response); - if (message_reader.PopUint32(&inhibit_cookie_)) { - if (postponed_uninhibit_call_) { - postponed_uninhibit_call_ = false; - ApplyBlock(PowerSaveBlocker::kPowerSaveBlockPreventNone); - } - return; - } else { - LOG(ERROR) << "Invalid Inhibit() response: " << response->ToString(); - } - } - inhibit_cookie_ = 0; - postponed_uninhibit_call_ = false; - } - - // UnInhibit() method callback. - // We set the |inhibit_cookie_| to 0 even if the D-Bus call failed. - void OnUnInhibitResponse(dbus::Response* response) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - inhibit_cookie_ = 0; - }; - - // The cookie that identifies our last inhibit request, - // or 0 if there is no active inhibit request. - uint32 inhibit_cookie_; - - // True if we made an inhibit call for which - // we did not receive a response yet - bool pending_inhibit_call_; - - // True if we have to cancel the cookie we are about to receive - bool postponed_uninhibit_call_; - - DISALLOW_COPY_AND_ASSIGN(KDEPowerSaveBlocker); -}; - -// Delegate implementation for Gnome, based on org.gnome.SessionManager -class GnomePowerSaveBlocker : public DBusPowerSaveBlocker::Delegate { - public: - // Inhibit flags defined in the org.gnome.SessionManager interface. - // Can be OR'd together and passed as argument to the Inhibit() method - // to specify which power management features we want to suspend. - enum InhibitFlags { - kInhibitLogOut = 1, - kInhibitSwitchUser = 2, - kInhibitSuspendSession = 4, - kInhibitMarkSessionAsIdle = 8 - }; - - GnomePowerSaveBlocker() - : inhibit_cookie_(0), - pending_inhibit_calls_(0), - postponed_uninhibit_calls_(0) {} - - virtual void ApplyBlock( - PowerSaveBlocker::PowerSaveBlockerType type) OVERRIDE { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(postponed_uninhibit_calls_ <= pending_inhibit_calls_); - - // If we have a pending inhibit call, we add a postponed uninhibit request, - // such that it will be canceled as soon as the response arrives. We want to - // cancel the current inhibit request whether |type| is - // kPowerSaveBlockPreventNone or not. If |type| represents an inhibit - // request, we are dealing with the same case as below, just that the reply - // to the previous inhibit request did not arrive yet, so we have to wait - // for the cookie in order to cancel it. Meanwhile, we can still make the - // new request. - // - // We also have to check that postponed_uninhibit_calls_ < - // pending_inhibit_calls_. If this is not the case, then all the pending - // requests were already canceled and we should not increment the number of - // postponed uninhibit requests; otherwise we will cancel unwanted future - // inhibits, that will be made after this call. - // - // NOTE: The implementation is based on the fact that we receive the D-Bus - // replies in the same order in which the requests are made. - if (pending_inhibit_calls_ > 0 && - postponed_uninhibit_calls_ < pending_inhibit_calls_) { - ++postponed_uninhibit_calls_; - // If the call was an Uninhibit, then we are done for the moment. - if (type == PowerSaveBlocker::kPowerSaveBlockPreventNone) - return; - } - - // If we have an active inhibit request and no pending inhibit calls, - // we make an uninhibit request to cancel it now. - if (type != PowerSaveBlocker::kPowerSaveBlockPreventNone && - pending_inhibit_calls_ == 0 && - inhibit_cookie_ > 0) { - ApplyBlock(PowerSaveBlocker::kPowerSaveBlockPreventNone); - } - - static const char kGnomeSessionManagerName[] = "org.gnome.SessionManager"; - scoped_refptr<dbus::ObjectProxy> object_proxy = - DBusPowerSaveBlocker::GetInstance()->bus()->GetObjectProxy( - kGnomeSessionManagerName, - dbus::ObjectPath("/org/gnome/SessionManager")); - dbus::MethodCall method_call(kGnomeSessionManagerName, "Inhibit"); - dbus::MessageWriter message_writer(&method_call); - base::Callback<void(dbus::Response*)> bus_callback; - - unsigned int flags = 0; - switch (type) { - case PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep: - flags |= kInhibitMarkSessionAsIdle; - break; - case PowerSaveBlocker::kPowerSaveBlockPreventSystemSleep: - flags |= kInhibitMarkSessionAsIdle; - flags |= kInhibitSuspendSession; - break; - case PowerSaveBlocker::kPowerSaveBlockPreventNone: - break; - case PowerSaveBlocker::kPowerSaveBlockPreventStateCount: - // This is an invalid argument - NOTREACHED(); - break; - } - - switch (type) { - case PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep: - case PowerSaveBlocker::kPowerSaveBlockPreventSystemSleep: - // To temporarily suspend the power management features on Gnome, - // we call org.gnome.SessionManager.Inhibit(). - // The arguments of the method are: - // app_id: The application identifier - // toplevel_xid: The toplevel X window identifier - // reason: The reason for the inhibit - // flags: Flags that spefify what should be inhibited - // The method returns and inhibit_cookie, used to uniquely identify - // this request. It should be used as an argument to Uninhibit() - // in order to remove the request. - message_writer.AppendString( - CommandLine::ForCurrentProcess()->GetProgram().value()); - message_writer.AppendUint32(0); // should be toplevel_xid - message_writer.AppendString(DBusPowerSaveBlocker::kPowerSaveReason); - message_writer.AppendUint32(flags); - bus_callback = base::Bind(&GnomePowerSaveBlocker::OnInhibitResponse, - this); - ++pending_inhibit_calls_; - break; - case PowerSaveBlocker::kPowerSaveBlockPreventNone: - // To cancel a previous inhibit request we call - // org.gnome.SessionManager.Uninhibit(). - // It takes only one argument, the cookie that identifies - // the request we want to cancel. - method_call.SetMember("Uninhibit"); - message_writer.AppendUint32(inhibit_cookie_); - bus_callback = base::Bind(&GnomePowerSaveBlocker::OnUnInhibitResponse, - this); - ++pending_inhibit_calls_; - break; - case PowerSaveBlocker::kPowerSaveBlockPreventStateCount: - // This is an invalid argument. - NOTREACHED(); - break; - } - - object_proxy->CallMethod(&method_call, - dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, - bus_callback); - } - - protected: - virtual ~GnomePowerSaveBlocker() {} - - private: - // Inhibit() response callback. - // Stores the cookie so we can use it later when calling UnInhibit(). - // If the response from D-Bus is successful and there is a postponed - // uninhibit request, we cancel the cookie that we just received. - void OnInhibitResponse(dbus::Response* response) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK_GT(pending_inhibit_calls_, 0); - --pending_inhibit_calls_; - if (response) { - dbus::MessageReader message_reader(response); - if (message_reader.PopUint32(&inhibit_cookie_)) { - if (postponed_uninhibit_calls_ > 0) { - --postponed_uninhibit_calls_; - ApplyBlock(PowerSaveBlocker::kPowerSaveBlockPreventNone); - } - return; - } else { - LOG(ERROR) << "Invalid Inhibit() response: " << response->ToString(); - } - } - inhibit_cookie_ = 0; - if (postponed_uninhibit_calls_ > 0) { - --postponed_uninhibit_calls_; - } - } - - // Uninhibit() response callback. - // We set the |inhibit_cookie_| to 0 even if the D-Bus call failed. - void OnUnInhibitResponse(dbus::Response* response) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - inhibit_cookie_ = 0; - }; - - // The cookie that identifies our last inhibit request, - // or 0 if there is no active inhibit request. - uint32 inhibit_cookie_; - - // Store the number of inhibit calls for which - // we did not receive a response yet - int pending_inhibit_calls_; - - // Store the number of Uninhibit requests that arrived, - // before the corresponding Inhibit calls were completed. - int postponed_uninhibit_calls_; - - DISALLOW_COPY_AND_ASSIGN(GnomePowerSaveBlocker); -}; - -const char DBusPowerSaveBlocker::kPowerSaveReason[] = "Power Save Blocker"; - -// Initialize the DBusPowerSaveBlocker instance: -// 1. Instantiate a concrete delegate based on the current desktop environment, -// 2. Instantiate the D-Bus object -DBusPowerSaveBlocker::DBusPowerSaveBlocker() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - scoped_ptr<base::Environment> env(base::Environment::Create()); - switch (base::nix::GetDesktopEnvironment(env.get())) { - case base::nix::DESKTOP_ENVIRONMENT_GNOME: - if (DPMSEnabled()) - delegate_ = new GnomePowerSaveBlocker(); - break; - case base::nix::DESKTOP_ENVIRONMENT_XFCE: - case base::nix::DESKTOP_ENVIRONMENT_KDE4: - if (DPMSEnabled()) - delegate_ = new KDEPowerSaveBlocker(); - break; - case base::nix::DESKTOP_ENVIRONMENT_KDE3: - case base::nix::DESKTOP_ENVIRONMENT_OTHER: - // Not supported, so we exit. - // We don't create D-Bus objects. - break; - } - - if (delegate_) { - dbus::Bus::Options options; - options.bus_type = dbus::Bus::SESSION; - options.connection_type = dbus::Bus::PRIVATE; - // Use the FILE thread to service the D-Bus connection, - // since we need a thread that allows I/O operations. - options.dbus_thread_message_loop_proxy = - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE); - bus_ = new dbus::Bus(options); - } -} - -DBusPowerSaveBlocker::~DBusPowerSaveBlocker() { - // We try to shut down the bus, but unfortunately in most of the - // cases when we delete the singleton instance, - // the FILE thread is already stopped and there is no way to - // shutdown the bus object on the origin thread (the UI thread). - // However, this is not a crucial problem since at this point - // we are at the very end of the shutting down phase. - // Connection to D-Bus is just a Unix domain socket, which is not - // a persistent resource, hence the operating system will take care - // of closing it when the process terminates. - if (BrowserThread::IsMessageLoopValid(BrowserThread::FILE)) { - bus_->ShutdownOnDBusThreadAndBlock(); - } -} - -// static -bool DBusPowerSaveBlocker::DPMSEnabled() { - Display* display = base::MessagePumpForUI::GetDefaultXDisplay(); - BOOL enabled = false; - int dummy; - if (DPMSQueryExtension(display, &dummy, &dummy) && DPMSCapable(display)) { - CARD16 state; - DPMSInfo(display, &state, &enabled); - } - return enabled; -} - -// static -DBusPowerSaveBlocker* DBusPowerSaveBlocker::GetInstance() { - return Singleton<DBusPowerSaveBlocker>::get(); -} - -} // namespace - -// Called only from UI thread. -// static -void PowerSaveBlocker::ApplyBlock(PowerSaveBlockerType type) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DBusPowerSaveBlocker::GetInstance()->ApplyBlock(type); -} - -// TODO(mdm): remove from the beginning of the file up to (and including) this -// line to switch to the new implementation. -#define PowerSaveBlocker PowerSaveBlocker2 - namespace { enum DBusAPI { diff --git a/content/browser/power_save_blocker_mac.cc b/content/browser/power_save_blocker_mac.cc index a50d510..b96097d 100644 --- a/content/browser/power_save_blocker_mac.cc +++ b/content/browser/power_save_blocker_mac.cc @@ -12,70 +12,6 @@ #include "base/threading/thread.h" #include "content/public/browser/browser_thread.h" -using content::BrowserThread; - -namespace { - -// Power management cannot be done on the UI thread. IOPMAssertionCreate does a -// synchronous MIG call to configd, so if it is called on the main thread the UI -// is at the mercy of another process. See http://crbug.com/79559 and -// http://www.opensource.apple.com/source/IOKitUser/IOKitUser-514.16.31/pwr_mgt.subproj/IOPMLibPrivate.c . -base::Thread* g_power_thread; -IOPMAssertionID g_power_assertion; - -void CreateSleepAssertion(PowerSaveBlocker::PowerSaveBlockerType type) { - DCHECK_EQ(base::PlatformThread::CurrentId(), g_power_thread->thread_id()); - IOReturn result; - - if (g_power_assertion != kIOPMNullAssertionID) { - result = IOPMAssertionRelease(g_power_assertion); - g_power_assertion = kIOPMNullAssertionID; - LOG_IF(ERROR, result != kIOReturnSuccess) - << "IOPMAssertionRelease: " << result; - } - - CFStringRef level = NULL; - // See QA1340 <http://developer.apple.com/library/mac/#qa/qa1340/> for more - // details. - switch (type) { - case PowerSaveBlocker::kPowerSaveBlockPreventSystemSleep: - level = kIOPMAssertionTypeNoIdleSleep; - break; - case PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep: - level = kIOPMAssertionTypeNoDisplaySleep; - break; - default: - break; - } - if (level) { - result = IOPMAssertionCreate(level, - kIOPMAssertionLevelOn, - &g_power_assertion); - LOG_IF(ERROR, result != kIOReturnSuccess) - << "IOPMAssertionCreate: " << result; - } -} - -} // namespace - -// Called only from UI thread. -// static -void PowerSaveBlocker::ApplyBlock(PowerSaveBlockerType type) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - if (!g_power_thread) { - g_power_assertion = kIOPMNullAssertionID; - g_power_thread = new base::Thread("PowerSaveBlocker"); - g_power_thread->Start(); - } - - g_power_thread->message_loop()-> - PostTask(FROM_HERE, base::Bind(CreateSleepAssertion, type)); -} - -// TODO(avi): Remove ^^^ this code in favor of vvv this code. -// http://crbug.com/126591 - namespace { // Power management cannot be done on the UI thread. IOPMAssertionCreate does a @@ -94,14 +30,14 @@ struct PowerSaveBlockerLazyInstanceTraits { static void Delete(base::Thread* instance) { } }; base::LazyInstance<base::Thread, PowerSaveBlockerLazyInstanceTraits> - g_power_thread2 = LAZY_INSTANCE_INITIALIZER; + g_power_thread = LAZY_INSTANCE_INITIALIZER; } // namespace namespace content { -class PowerSaveBlocker2::Delegate - : public base::RefCountedThreadSafe<PowerSaveBlocker2::Delegate> { +class PowerSaveBlocker::Delegate + : public base::RefCountedThreadSafe<PowerSaveBlocker::Delegate> { public: Delegate(PowerSaveBlockerType type, const std::string& reason) : type_(type), reason_(reason), assertion_(kIOPMNullAssertionID) {} @@ -111,25 +47,25 @@ class PowerSaveBlocker2::Delegate void RemoveBlock(); private: - friend class base::RefCountedThreadSafe<PowerSaveBlocker2::Delegate>; + friend class base::RefCountedThreadSafe<Delegate>; ~Delegate() {} PowerSaveBlockerType type_; std::string reason_; IOPMAssertionID assertion_; }; -void PowerSaveBlocker2::Delegate::ApplyBlock() { +void PowerSaveBlocker::Delegate::ApplyBlock() { DCHECK_EQ(base::PlatformThread::CurrentId(), - g_power_thread2.Pointer()->thread_id()); + g_power_thread.Pointer()->thread_id()); CFStringRef level = NULL; // See QA1340 <http://developer.apple.com/library/mac/#qa/qa1340/> for more // details. switch (type_) { - case PowerSaveBlocker2::kPowerSaveBlockPreventAppSuspension: + case PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension: level = kIOPMAssertionTypeNoIdleSleep; break; - case PowerSaveBlocker2::kPowerSaveBlockPreventDisplaySleep: + case PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep: level = kIOPMAssertionTypeNoDisplaySleep; break; default: @@ -147,9 +83,9 @@ void PowerSaveBlocker2::Delegate::ApplyBlock() { } } -void PowerSaveBlocker2::Delegate::RemoveBlock() { +void PowerSaveBlocker::Delegate::RemoveBlock() { DCHECK_EQ(base::PlatformThread::CurrentId(), - g_power_thread2.Pointer()->thread_id()); + g_power_thread.Pointer()->thread_id()); if (assertion_ != kIOPMNullAssertionID) { IOReturn result = IOPMAssertionRelease(assertion_); @@ -158,18 +94,18 @@ void PowerSaveBlocker2::Delegate::RemoveBlock() { } } -PowerSaveBlocker2::PowerSaveBlocker2(PowerSaveBlockerType type, - const std::string& reason) - : delegate_(new PowerSaveBlocker2::Delegate(type, reason)) { - g_power_thread2.Pointer()->message_loop()->PostTask( +PowerSaveBlocker::PowerSaveBlocker(PowerSaveBlockerType type, + const std::string& reason) + : delegate_(new Delegate(type, reason)) { + g_power_thread.Pointer()->message_loop()->PostTask( FROM_HERE, - base::Bind(&PowerSaveBlocker2::Delegate::ApplyBlock, delegate_)); + base::Bind(&Delegate::ApplyBlock, delegate_)); } -PowerSaveBlocker2::~PowerSaveBlocker2() { - g_power_thread2.Pointer()->message_loop()->PostTask( +PowerSaveBlocker::~PowerSaveBlocker() { + g_power_thread.Pointer()->message_loop()->PostTask( FROM_HERE, - base::Bind(&PowerSaveBlocker2::Delegate::RemoveBlock, delegate_)); + base::Bind(&Delegate::RemoveBlock, delegate_)); } } // namespace content diff --git a/content/browser/power_save_blocker_win.cc b/content/browser/power_save_blocker_win.cc index edecce9..cebc4c7 100644 --- a/content/browser/power_save_blocker_win.cc +++ b/content/browser/power_save_blocker_win.cc @@ -12,32 +12,6 @@ #include "base/win/windows_version.h" #include "content/public/browser/browser_thread.h" -using content::BrowserThread; - -// Called only from UI thread. -// static -void PowerSaveBlocker::ApplyBlock(PowerSaveBlockerType type) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - DWORD flags = ES_CONTINUOUS; - - switch (type) { - case kPowerSaveBlockPreventSystemSleep: - flags |= ES_SYSTEM_REQUIRED; - break; - case kPowerSaveBlockPreventDisplaySleep: - flags |= ES_DISPLAY_REQUIRED; - break; - default: - break; - } - - SetThreadExecutionState(flags); -} - -// TODO(rvargas): Remove after the old interface goes away. -#define PowerSaveBlocker PowerSaveBlocker2 - namespace { int g_blocker_count[2]; @@ -153,7 +127,7 @@ class PowerSaveBlocker::Delegate POWER_REQUEST_TYPE RequestType(); private: - friend class base::RefCountedThreadSafe<PowerSaveBlocker::Delegate>; + friend class base::RefCountedThreadSafe<Delegate>; ~Delegate() {} PowerSaveBlockerType type_; diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index eba176f..528872a 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc @@ -1768,13 +1768,15 @@ void RenderViewHostImpl::OnMediaNotification(int64 player_cookie, bool has_audio, bool is_playing) { if (is_playing) { - PowerSaveBlocker* blocker = NULL; + content::PowerSaveBlocker* blocker = NULL; if (has_video) { - blocker = new PowerSaveBlocker( - PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep); + blocker = new content::PowerSaveBlocker( + content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep, + "Playing video"); } else if (has_audio) { - blocker = new PowerSaveBlocker( - PowerSaveBlocker::kPowerSaveBlockPreventSystemSleep); + blocker = new content::PowerSaveBlocker( + content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension, + "Playing audio"); } if (blocker) diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h index e9bf425..9ee3caa 100644 --- a/content/browser/renderer_host/render_view_host_impl.h +++ b/content/browser/renderer_host/render_view_host_impl.h @@ -28,7 +28,6 @@ #include "webkit/glue/window_open_disposition.h" class ChildProcessSecurityPolicyImpl; -class PowerSaveBlocker; class SessionStorageNamespaceImpl; class SkBitmap; class ViewMsg_Navigate; @@ -47,6 +46,7 @@ class ListValue; namespace content { class TestRenderViewHost; +class PowerSaveBlocker; } namespace ui { @@ -649,7 +649,7 @@ class CONTENT_EXPORT RenderViewHostImpl // Holds PowerSaveBlockers for the media players in use. Key is the // player_cookie passed to OnMediaNotification, value is the PowerSaveBlocker. - typedef std::map<int64, PowerSaveBlocker*> PowerSaveBlockerMap; + typedef std::map<int64, content::PowerSaveBlocker*> PowerSaveBlockerMap; PowerSaveBlockerMap power_save_blockers_; // A list of observers that filter messages. Weak references. diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 5946f2d..2c6bf36 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -443,7 +443,6 @@ 'browser/plugin_service_impl.h', 'browser/power_save_blocker.h', 'browser/power_save_blocker_android.cc', - 'browser/power_save_blocker_common.cc', 'browser/power_save_blocker_linux.cc', 'browser/power_save_blocker_mac.cc', 'browser/power_save_blocker_win.cc', diff --git a/content/test/test_file_error_injector.cc b/content/test/test_file_error_injector.cc index b7585df..a011dc4 100644 --- a/content/test/test_file_error_injector.cc +++ b/content/test/test_file_error_injector.cc @@ -91,7 +91,7 @@ DownloadFileWithErrors::DownloadFileWithErrors( request_handle, download_manager, calculate_hash, - scoped_ptr<PowerSaveBlocker>(NULL).Pass(), + scoped_ptr<content::PowerSaveBlocker>(NULL).Pass(), bound_net_log), source_url_(info->url()), error_info_(error_info), |