1// Copyright 2014 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 "chrome/browser/chromeos/power/renderer_freezer.h" 6 7#include "base/bind.h" 8#include "base/logging.h" 9#include "base/message_loop/message_loop.h" 10#include "chromeos/dbus/dbus_thread_manager.h" 11 12namespace chromeos { 13 14RendererFreezer::RendererFreezer(scoped_ptr<RendererFreezer::Delegate> delegate) 15 : frozen_(false), 16 delegate_(delegate.Pass()), 17 weak_factory_(this) { 18 if (delegate_->CanFreezeRenderers()) 19 DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(this); 20} 21 22RendererFreezer::~RendererFreezer() { 23 if (delegate_->CanFreezeRenderers()) 24 DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this); 25} 26 27void RendererFreezer::SuspendImminent() { 28 // If there was already a callback pending, this will cancel it and create a 29 // new one. 30 suspend_readiness_callback_.Reset( 31 base::Bind(&RendererFreezer::OnReadyToSuspend, 32 weak_factory_.GetWeakPtr(), 33 DBusThreadManager::Get() 34 ->GetPowerManagerClient() 35 ->GetSuspendReadinessCallback())); 36 37 base::MessageLoop::current()->PostTask( 38 FROM_HERE, suspend_readiness_callback_.callback()); 39} 40 41void RendererFreezer::SuspendDone(const base::TimeDelta& sleep_duration) { 42 // If we get a SuspendDone before we've had a chance to run OnReadyForSuspend, 43 // we should cancel it because we no longer want to freeze the renderers. If 44 // we've already run it then cancelling the callback shouldn't really make a 45 // difference. 46 suspend_readiness_callback_.Cancel(); 47 48 if (!frozen_) 49 return; 50 51 if (!delegate_->ThawRenderers()) { 52 // We failed to write the thaw command and the renderers are still frozen. 53 // We are in big trouble because none of the tabs will be responsive so 54 // let's crash the browser instead. 55 LOG(FATAL) << "Unable to thaw renderers."; 56 } 57 58 frozen_ = false; 59} 60 61void RendererFreezer::OnReadyToSuspend( 62 const base::Closure& power_manager_callback) { 63 if (delegate_->FreezeRenderers()) 64 frozen_ = true; 65 66 DCHECK(!power_manager_callback.is_null()); 67 power_manager_callback.Run(); 68} 69 70} // namespace chromeos 71