| Index: chrome/browser/chromeos/power/renderer_freezer.cc
|
| diff --git a/chrome/browser/chromeos/power/renderer_freezer.cc b/chrome/browser/chromeos/power/renderer_freezer.cc
|
| index 7749843daab6ee61d28030a6302c0fb08cb1d68e..1aaa79a75293dc5590e924c1c0aa189f970a0c29 100644
|
| --- a/chrome/browser/chromeos/power/renderer_freezer.cc
|
| +++ b/chrome/browser/chromeos/power/renderer_freezer.cc
|
| @@ -4,87 +4,67 @@
|
|
|
| #include "chrome/browser/chromeos/power/renderer_freezer.h"
|
|
|
| -#include <cstring> // needed for strlen()
|
| -
|
| #include "base/bind.h"
|
| -#include "base/files/file_util.h"
|
| #include "base/logging.h"
|
| #include "base/message_loop/message_loop.h"
|
| #include "chromeos/dbus/dbus_thread_manager.h"
|
|
|
| namespace chromeos {
|
|
|
| -namespace {
|
| -const char kFreezerStatePath[] =
|
| - "/sys/fs/cgroup/freezer/chrome_renderers/freezer.state";
|
| -const char kFreezeCommand[] = "FROZEN";
|
| -const char kThawCommand[] = "THAWED";
|
| +RendererFreezer::RendererFreezer(scoped_ptr<RendererFreezer::Delegate> delegate)
|
| + : frozen_(false),
|
| + delegate_(delegate.Pass()),
|
| + weak_factory_(this) {
|
| + if (delegate_->CanFreezeRenderers())
|
| + DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(this);
|
| +}
|
|
|
| -} // namespace
|
| +RendererFreezer::~RendererFreezer() {
|
| + if (delegate_->CanFreezeRenderers())
|
| + DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this);
|
| +}
|
|
|
| void RendererFreezer::SuspendImminent() {
|
| - // SuspendImminent() might end up being called multiple times before we run
|
| - // OnReadyToSuspend() (crbug.com/414396). In case a callback is already
|
| - // pending, we only store the new callback and do nothing else.
|
| - if (suspend_readiness_callback_.is_null()) {
|
| - // There is no callback pending so post the task.
|
| - base::MessageLoop::current()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&RendererFreezer::OnReadyToSuspend,
|
| - weak_factory_.GetWeakPtr()));
|
| - }
|
| -
|
| - // Always update the callback because only the most recent one matters.
|
| - suspend_readiness_callback_ = DBusThreadManager::Get()
|
| - ->GetPowerManagerClient()
|
| - ->GetSuspendReadinessCallback();
|
| + // If there was already a callback pending, this will cancel it and create a
|
| + // new one.
|
| + suspend_readiness_callback_.Reset(
|
| + base::Bind(&RendererFreezer::OnReadyToSuspend,
|
| + weak_factory_.GetWeakPtr(),
|
| + DBusThreadManager::Get()
|
| + ->GetPowerManagerClient()
|
| + ->GetSuspendReadinessCallback()));
|
| +
|
| + base::MessageLoop::current()->PostTask(
|
| + FROM_HERE, suspend_readiness_callback_.callback());
|
| }
|
|
|
| void RendererFreezer::SuspendDone(const base::TimeDelta& sleep_duration) {
|
| + // If we get a SuspendDone before we've had a chance to run OnReadyForSuspend,
|
| + // we should cancel it because we no longer want to freeze the renderers. If
|
| + // we've already run it then cancelling the callback shouldn't really make a
|
| + // difference.
|
| + suspend_readiness_callback_.Cancel();
|
| +
|
| if (!frozen_)
|
| return;
|
|
|
| - if (base::WriteFile(state_path_, kThawCommand, strlen(kThawCommand)) !=
|
| - static_cast<int>(strlen(kThawCommand))) {
|
| + if (!delegate_->ThawRenderers()) {
|
| // We failed to write the thaw command and the renderers are still frozen.
|
| // We are in big trouble because none of the tabs will be responsive so
|
| // let's crash the browser instead.
|
| - PLOG(FATAL) << "Unable to thaw processes in the cgroup freezer.";
|
| + LOG(FATAL) << "Unable to thaw renderers.";
|
| }
|
|
|
| frozen_ = false;
|
| }
|
|
|
| -void RendererFreezer::OnReadyToSuspend() {
|
| - if (base::WriteFile(state_path_, kFreezeCommand, strlen(kFreezeCommand)) !=
|
| - static_cast<int>(strlen(kFreezeCommand))) {
|
| - PLOG(WARNING) << "Unable to freeze processes in the cgroup freezer.";
|
| - } else {
|
| +void RendererFreezer::OnReadyToSuspend(
|
| + const base::Closure& power_manager_callback) {
|
| + if (delegate_->FreezeRenderers())
|
| frozen_ = true;
|
| - }
|
| -
|
| - CHECK(!suspend_readiness_callback_.is_null()); // crbug.com/414396
|
| - suspend_readiness_callback_.Run();
|
| - suspend_readiness_callback_.Reset();
|
| -}
|
| -
|
| -RendererFreezer::RendererFreezer()
|
| - : state_path_(base::FilePath(kFreezerStatePath)),
|
| - enabled_(base::PathExists(state_path_) &&
|
| - base::PathIsWritable(state_path_)),
|
| - frozen_(false),
|
| - weak_factory_(this) {
|
| - if (enabled_) {
|
| - DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(this);
|
| - } else {
|
| - LOG(WARNING) << "Cgroup freezer does not exist or is not writable. "
|
| - << "Processes will not be frozen during suspend.";
|
| - }
|
| -}
|
|
|
| -RendererFreezer::~RendererFreezer() {
|
| - if (enabled_)
|
| - DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this);
|
| + DCHECK(!power_manager_callback.is_null());
|
| + power_manager_callback.Run();
|
| }
|
|
|
| } // namespace chromeos
|
|
|