blob: 4472d4bae45fd186ee51c8f3d9c0a3f15c451131 [file]
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/pwr_mgt/IOPMLib.h>
#include "platform/api/task_runner.h"
#include "util/osp_logging.h"
#include "util/scoped_wake_lock.h"
namespace openscreen {
class ScopedWakeLockMac : public ScopedWakeLock {
public:
explicit ScopedWakeLockMac(TaskRunner& task_runner);
~ScopedWakeLockMac() override;
private:
TaskRunner& task_runner_;
struct LockState {
int reference_count = 0;
IOPMAssertionID assertion_id = kIOPMNullAssertionID;
};
static void AcquireWakeLock();
static void ReleaseWakeLock();
static LockState* lock_state_;
};
ScopedWakeLockPtr ScopedWakeLock::Create(TaskRunner& task_runner) {
return TaskRunnerDeleter::MakeUnique<ScopedWakeLockMac>(task_runner,
task_runner);
}
ScopedWakeLockMac::ScopedWakeLockMac(TaskRunner& task_runner)
: ScopedWakeLock(), task_runner_(task_runner) {
task_runner_.PostTask([] {
if (lock_state_->reference_count++ == 0) {
AcquireWakeLock();
}
});
}
ScopedWakeLockMac::~ScopedWakeLockMac() {
task_runner_.PostTask([] {
if (--lock_state_->reference_count == 0) {
ReleaseWakeLock();
}
});
}
// static
void ScopedWakeLockMac::AcquireWakeLock() {
// The new way of doing an IOPM assertion requires constructing a standard
// Foundation dictionary and adding the expected properties.
CFMutableDictionaryRef assertion_properties = CFDictionaryCreateMutable(
0, 3, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
// This property means that we are requesting that the display not dim
// or go to sleep.
CFDictionarySetValue(assertion_properties, kIOPMAssertionTypeKey,
kIOPMAssertionTypeNoDisplaySleep);
CFDictionarySetValue(assertion_properties, kIOPMAssertionNameKey,
CFSTR("Open Screen ScopedWakeLock"));
const IOReturn result = IOPMAssertionCreateWithProperties(
assertion_properties, &lock_state_->assertion_id);
OSP_CHECK_EQ(result, kIOReturnSuccess);
}
// static
void ScopedWakeLockMac::ReleaseWakeLock() {
const IOReturn result = IOPMAssertionRelease(lock_state_->assertion_id);
OSP_CHECK_EQ(result, kIOReturnSuccess);
}
ScopedWakeLockMac::LockState* ScopedWakeLockMac::lock_state_ =
new ScopedWakeLockMac::LockState();
} // namespace openscreen