This source file includes following definitions.
- assertion_
- ApplyBlock
- RemoveBlock
#include "content/browser/power_save_blocker_impl.h"
#include <IOKit/pwr_mgt/IOPMLib.h>
#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/strings/sys_string_conversions.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread.h"
namespace content {
namespace {
struct PowerSaveBlockerLazyInstanceTraits {
static const bool kRegisterOnExit = false;
#ifndef NDEBUG
static const bool kAllowedToAccessOnNonjoinableThread = true;
#endif
static base::Thread* New(void* instance) {
base::Thread* thread = new (instance) base::Thread("PowerSaveBlocker");
thread->Start();
return thread;
}
static void Delete(base::Thread* instance) { }
};
base::LazyInstance<base::Thread, PowerSaveBlockerLazyInstanceTraits>
g_power_thread = LAZY_INSTANCE_INITIALIZER;
}
class PowerSaveBlockerImpl::Delegate
: public base::RefCountedThreadSafe<PowerSaveBlockerImpl::Delegate> {
public:
Delegate(PowerSaveBlockerType type, const std::string& reason)
: type_(type), reason_(reason), assertion_(kIOPMNullAssertionID) {}
void ApplyBlock();
void RemoveBlock();
private:
friend class base::RefCountedThreadSafe<Delegate>;
~Delegate() {}
PowerSaveBlockerType type_;
std::string reason_;
IOPMAssertionID assertion_;
};
void PowerSaveBlockerImpl::Delegate::ApplyBlock() {
DCHECK_EQ(base::PlatformThread::CurrentId(),
g_power_thread.Pointer()->thread_id());
CFStringRef level = NULL;
switch (type_) {
case PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension:
level = kIOPMAssertionTypeNoIdleSleep;
break;
case PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep:
level = kIOPMAssertionTypeNoDisplaySleep;
break;
default:
NOTREACHED();
break;
}
if (level) {
base::ScopedCFTypeRef<CFStringRef> cf_reason(
base::SysUTF8ToCFStringRef(reason_));
IOReturn result = IOPMAssertionCreateWithName(level,
kIOPMAssertionLevelOn,
cf_reason,
&assertion_);
LOG_IF(ERROR, result != kIOReturnSuccess)
<< "IOPMAssertionCreate: " << result;
}
}
void PowerSaveBlockerImpl::Delegate::RemoveBlock() {
DCHECK_EQ(base::PlatformThread::CurrentId(),
g_power_thread.Pointer()->thread_id());
if (assertion_ != kIOPMNullAssertionID) {
IOReturn result = IOPMAssertionRelease(assertion_);
LOG_IF(ERROR, result != kIOReturnSuccess)
<< "IOPMAssertionRelease: " << result;
}
}
PowerSaveBlockerImpl::PowerSaveBlockerImpl(PowerSaveBlockerType type,
const std::string& reason)
: delegate_(new Delegate(type, reason)) {
g_power_thread.Pointer()->message_loop()->PostTask(
FROM_HERE,
base::Bind(&Delegate::ApplyBlock, delegate_));
}
PowerSaveBlockerImpl::~PowerSaveBlockerImpl() {
g_power_thread.Pointer()->message_loop()->PostTask(
FROM_HERE,
base::Bind(&Delegate::RemoveBlock, delegate_));
}
}