1 // Copyright 2019 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 "platform/impl/scoped_wake_lock_mac.h"
6
7 #include <CoreFoundation/CoreFoundation.h>
8
9 #include "platform/api/task_runner.h"
10 #include "platform/impl/platform_client_posix.h"
11 #include "util/osp_logging.h"
12
13 namespace openscreen {
14
15 ScopedWakeLockMac::LockState ScopedWakeLockMac::lock_state_{};
16
Create(TaskRunner * task_runner)17 SerialDeletePtr<ScopedWakeLock> ScopedWakeLock::Create(
18 TaskRunner* task_runner) {
19 return SerialDeletePtr<ScopedWakeLock>(task_runner, new ScopedWakeLockMac());
20 }
21
22 namespace {
23
GetTaskRunner()24 TaskRunner* GetTaskRunner() {
25 auto* const platform_client = PlatformClientPosix::GetInstance();
26 OSP_DCHECK(platform_client);
27 auto* const task_runner = platform_client->GetTaskRunner();
28 OSP_DCHECK(task_runner);
29 return task_runner;
30 }
31
32 } // namespace
33
ScopedWakeLockMac()34 ScopedWakeLockMac::ScopedWakeLockMac() : ScopedWakeLock() {
35 GetTaskRunner()->PostTask([] {
36 if (lock_state_.reference_count++ == 0) {
37 AcquireWakeLock();
38 }
39 });
40 }
41
~ScopedWakeLockMac()42 ScopedWakeLockMac::~ScopedWakeLockMac() {
43 GetTaskRunner()->PostTask([] {
44 if (--lock_state_.reference_count == 0) {
45 ReleaseWakeLock();
46 }
47 });
48 }
49
50 // static
AcquireWakeLock()51 void ScopedWakeLockMac::AcquireWakeLock() {
52 // The new way of doing an IOPM assertion requires constructing a standard
53 // Foundation dictionary and adding the expected properties.
54 CFMutableDictionaryRef assertion_properties = CFDictionaryCreateMutable(
55 0, 3, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
56 // This property means that we are requesting that the display not dim
57 // or go to sleep.
58 CFDictionarySetValue(assertion_properties, kIOPMAssertionTypeKey,
59 kIOPMAssertionTypeNoDisplaySleep);
60 CFDictionarySetValue(assertion_properties, kIOPMAssertionNameKey,
61 CFSTR("Open Screen ScopedWakeLock"));
62
63 const IOReturn result = IOPMAssertionCreateWithProperties(
64 assertion_properties, &lock_state_.assertion_id);
65 OSP_DCHECK_EQ(result, kIOReturnSuccess);
66 }
67
68 // static
ReleaseWakeLock()69 void ScopedWakeLockMac::ReleaseWakeLock() {
70 const IOReturn result = IOPMAssertionRelease(lock_state_.assertion_id);
71 OSP_DCHECK_EQ(result, kIOReturnSuccess);
72 }
73
74 } // namespace openscreen
75