Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/power_save_blocker.h" | 5 #include "content/browser/power_save_blocker.h" |
| 6 | 6 |
| 7 #include <IOKit/pwr_mgt/IOPMLib.h> | 7 #include <IOKit/pwr_mgt/IOPMLib.h> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/lazy_instance.h" | |
| 10 #include "base/threading/platform_thread.h" | 11 #include "base/threading/platform_thread.h" |
| 11 #include "base/threading/thread.h" | 12 #include "base/threading/thread.h" |
| 12 #include "content/public/browser/browser_thread.h" | 13 #include "content/public/browser/browser_thread.h" |
| 13 | 14 |
| 14 using content::BrowserThread; | 15 using content::BrowserThread; |
| 15 | 16 |
| 16 namespace { | 17 namespace { |
| 17 | 18 |
| 18 // Power management cannot be done on the UI thread. IOPMAssertionCreate does a | 19 // Power management cannot be done on the UI thread. IOPMAssertionCreate does a |
| 19 // synchronous MIG call to configd, so if it is called on the main thread the UI | 20 // synchronous MIG call to configd, so if it is called on the main thread the UI |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 64 | 65 |
| 65 if (!g_power_thread) { | 66 if (!g_power_thread) { |
| 66 g_power_assertion = kIOPMNullAssertionID; | 67 g_power_assertion = kIOPMNullAssertionID; |
| 67 g_power_thread = new base::Thread("PowerSaveBlocker"); | 68 g_power_thread = new base::Thread("PowerSaveBlocker"); |
| 68 g_power_thread->Start(); | 69 g_power_thread->Start(); |
| 69 } | 70 } |
| 70 | 71 |
| 71 g_power_thread->message_loop()-> | 72 g_power_thread->message_loop()-> |
| 72 PostTask(FROM_HERE, base::Bind(CreateSleepAssertion, type)); | 73 PostTask(FROM_HERE, base::Bind(CreateSleepAssertion, type)); |
| 73 } | 74 } |
| 75 | |
| 76 // ====== ^^ the deprecated way ^^ vv the way that doesn't work yet vv ====== | |
|
Nico
2012/06/05 20:30:11
Why not wait with committing until it works?
Mike Mammarella
2012/06/05 20:39:30
It would work, but only on OS X. There are three o
Avi (use Gerrit)
2012/06/05 20:40:24
This is a joke; the new code works perfectly.
Nico
2012/06/05 21:08:45
Reword the comment to "// TODO: The below will rep
| |
| 77 | |
| 78 namespace { | |
| 79 | |
| 80 // Power management cannot be done on the UI thread. IOPMAssertionCreate does a | |
| 81 // synchronous MIG call to configd, so if it is called on the main thread the UI | |
| 82 // is at the mercy of another process. See http://crbug.com/79559 and | |
| 83 // http://www.opensource.apple.com/source/IOKitUser/IOKitUser-514.16.31/pwr_mgt. subproj/IOPMLibPrivate.c . | |
| 84 struct PowerSaveBlockerLazyInstanceTraits { | |
| 85 static const bool kRegisterOnExit = false; | |
| 86 static const bool kAllowedToAccessOnNonjoinableThread = true; | |
| 87 | |
| 88 static base::Thread* New(void* instance) { | |
| 89 base::Thread* thread = new (instance) base::Thread("PowerSaveBlocker"); | |
| 90 thread->Start(); | |
|
Nico
2012/06/05 21:08:45
It's also surprising to me that g_power_thread2->P
Avi (use Gerrit)
2012/06/05 21:11:41
That worked in the code above because PowerSaveBlo
| |
| 91 return thread; | |
| 92 } | |
| 93 static void Delete(base::Thread* instance) { } | |
| 94 }; | |
| 95 base::LazyInstance<base::Thread, PowerSaveBlockerLazyInstanceTraits> | |
| 96 g_power_thread2 = LAZY_INSTANCE_INITIALIZER; | |
| 97 | |
| 98 } // namespace | |
| 99 | |
| 100 // TODO(avi): Remove after the old interface goes away. | |
| 101 #define PowerSaveBlocker PowerSaveBlocker2 | |
|
Nico
2012/06/05 20:30:11
This is confusing to me. Why not remove this defin
Mike Mammarella
2012/06/05 20:39:30
This makes the eventual patch smaller since we jus
Avi (use Gerrit)
2012/06/05 20:40:24
The new interface _is_ called PSB2. This is used i
Nico
2012/06/05 20:42:02
With "Everything" just being the 77 lines below th
Avi (use Gerrit)
2012/06/05 20:58:30
Yes, that is the definition of "everything" we're
Nico
2012/06/05 21:08:45
Changing that takes about 2s in a text editor. I d
| |
| 102 | |
| 103 namespace content { | |
| 104 | |
| 105 class PowerSaveBlocker::Delegate | |
| 106 : public base::RefCountedThreadSafe<PowerSaveBlocker::Delegate> { | |
| 107 public: | |
| 108 Delegate(PowerSaveBlockerType type, const std::string& reason) | |
| 109 : type_(type), reason_(reason), assertion_(kIOPMNullAssertionID) {} | |
| 110 | |
| 111 // Does the actual work to apply or remove the desired power save block. | |
| 112 void ApplyBlock(); | |
| 113 void RemoveBlock(); | |
| 114 | |
| 115 private: | |
| 116 friend class base::RefCountedThreadSafe<PowerSaveBlocker::Delegate>; | |
| 117 ~Delegate() {} | |
| 118 PowerSaveBlockerType type_; | |
| 119 std::string reason_; | |
| 120 IOPMAssertionID assertion_; | |
| 121 }; | |
| 122 | |
| 123 void PowerSaveBlocker::Delegate::ApplyBlock() { | |
| 124 DCHECK_EQ(base::PlatformThread::CurrentId(), | |
| 125 g_power_thread2.Pointer()->thread_id()); | |
| 126 | |
| 127 CFStringRef level = NULL; | |
| 128 // See QA1340 <http://developer.apple.com/library/mac/#qa/qa1340/> for more | |
| 129 // details. | |
| 130 switch (type_) { | |
| 131 case PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension: | |
| 132 level = kIOPMAssertionTypeNoIdleSleep; | |
| 133 break; | |
| 134 case PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep: | |
| 135 level = kIOPMAssertionTypeNoDisplaySleep; | |
| 136 break; | |
| 137 default: | |
| 138 NOTREACHED(); | |
| 139 break; | |
| 140 } | |
| 141 if (level) { | |
| 142 // TODO(avi): Switch to IOPMAssertionCreateWithName when 10.6 is the minimum | |
| 143 // system supported by Chromium. | |
| 144 IOReturn result = IOPMAssertionCreate(level, | |
| 145 kIOPMAssertionLevelOn, | |
| 146 &assertion_); | |
| 147 LOG_IF(ERROR, result != kIOReturnSuccess) | |
| 148 << "IOPMAssertionCreate: " << result; | |
| 149 } | |
| 150 } | |
| 151 | |
| 152 void PowerSaveBlocker::Delegate::RemoveBlock() { | |
| 153 DCHECK_EQ(base::PlatformThread::CurrentId(), | |
| 154 g_power_thread2.Pointer()->thread_id()); | |
| 155 | |
| 156 if (assertion_ != kIOPMNullAssertionID) { | |
| 157 IOReturn result = IOPMAssertionRelease(assertion_); | |
| 158 LOG_IF(ERROR, result != kIOReturnSuccess) | |
| 159 << "IOPMAssertionRelease: " << result; | |
| 160 } | |
| 161 } | |
| 162 | |
| 163 PowerSaveBlocker::PowerSaveBlocker(PowerSaveBlockerType type, | |
| 164 const std::string& reason) | |
| 165 : delegate_(new PowerSaveBlocker::Delegate(type, reason)) { | |
| 166 g_power_thread2.Pointer()->message_loop()->PostTask( | |
| 167 FROM_HERE, | |
| 168 base::Bind(&PowerSaveBlocker::Delegate::ApplyBlock, delegate_)); | |
| 169 } | |
| 170 | |
| 171 PowerSaveBlocker::~PowerSaveBlocker() { | |
| 172 g_power_thread2.Pointer()->message_loop()->PostTask( | |
| 173 FROM_HERE, | |
| 174 base::Bind(&PowerSaveBlocker::Delegate::RemoveBlock, delegate_)); | |
| 175 } | |
| 176 | |
| 177 } // namespace content | |
| OLD | NEW |