| OLD | NEW |
| 1 // Copyright (c) 2012 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 <X11/Xlib.h> | 5 #include <X11/Xlib.h> |
| 6 #include <X11/extensions/dpms.h> | 6 #include <X11/extensions/dpms.h> |
| 7 #include <X11/extensions/scrnsaver.h> | 7 #include <X11/extensions/scrnsaver.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <memory> | 10 #include <memory> |
| 11 | 11 |
| 12 #include "content/browser/power_save_blocker_impl.h" | 12 #include "content/browser/power_save_blocker_impl.h" |
| 13 // Xlib #defines Status, but we can't have that for some of our headers. | 13 // Xlib #defines Status, but we can't have that for some of our headers. |
| 14 #ifdef Status | 14 #ifdef Status |
| 15 #undef Status | 15 #undef Status |
| 16 #endif | 16 #endif |
| 17 | 17 |
| 18 #include "base/bind.h" | 18 #include "base/bind.h" |
| 19 #include "base/callback.h" | 19 #include "base/callback.h" |
| 20 #include "base/command_line.h" | 20 #include "base/command_line.h" |
| 21 #include "base/environment.h" | 21 #include "base/environment.h" |
| 22 #include "base/files/file_path.h" | 22 #include "base/files/file_path.h" |
| 23 #include "base/location.h" | |
| 24 #include "base/logging.h" | 23 #include "base/logging.h" |
| 25 #include "base/macros.h" | 24 #include "base/macros.h" |
| 26 #include "base/memory/ref_counted.h" | 25 #include "base/memory/ref_counted.h" |
| 27 #include "base/memory/singleton.h" | 26 #include "base/memory/singleton.h" |
| 28 #include "base/nix/xdg_util.h" | 27 #include "base/nix/xdg_util.h" |
| 29 #include "base/synchronization/lock.h" | 28 #include "base/synchronization/lock.h" |
| 29 #include "content/public/browser/browser_thread.h" |
| 30 #include "dbus/bus.h" | 30 #include "dbus/bus.h" |
| 31 #include "dbus/message.h" | 31 #include "dbus/message.h" |
| 32 #include "dbus/object_path.h" | 32 #include "dbus/object_path.h" |
| 33 #include "dbus/object_proxy.h" | 33 #include "dbus/object_proxy.h" |
| 34 #include "ui/gfx/x/x11_types.h" | 34 #include "ui/gfx/x/x11_types.h" |
| 35 | 35 |
| 36 namespace { | 36 namespace { |
| 37 | 37 |
| 38 enum DBusAPI { | 38 enum DBusAPI { |
| 39 NO_API, // Disable. No supported API available. | 39 NO_API, // Disable. No supported API available. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 69 } // namespace | 69 } // namespace |
| 70 | 70 |
| 71 namespace content { | 71 namespace content { |
| 72 | 72 |
| 73 class PowerSaveBlockerImpl::Delegate | 73 class PowerSaveBlockerImpl::Delegate |
| 74 : public base::RefCountedThreadSafe<PowerSaveBlockerImpl::Delegate> { | 74 : public base::RefCountedThreadSafe<PowerSaveBlockerImpl::Delegate> { |
| 75 public: | 75 public: |
| 76 // Picks an appropriate D-Bus API to use based on the desktop environment. | 76 // Picks an appropriate D-Bus API to use based on the desktop environment. |
| 77 Delegate(PowerSaveBlockerType type, | 77 Delegate(PowerSaveBlockerType type, |
| 78 const std::string& description, | 78 const std::string& description, |
| 79 bool freedesktop_only, | 79 bool freedesktop_only); |
| 80 scoped_refptr<base::SequencedTaskRunner> ui_task_runner, | |
| 81 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner); | |
| 82 | 80 |
| 83 // Post a task to initialize the delegate on the UI thread, which will itself | 81 // Post a task to initialize the delegate on the UI thread, which will itself |
| 84 // then post a task to apply the power save block on the FILE thread. | 82 // then post a task to apply the power save block on the FILE thread. |
| 85 void Init(); | 83 void Init(); |
| 86 | 84 |
| 87 // Post a task to remove the power save block on the FILE thread, unless it | 85 // Post a task to remove the power save block on the FILE thread, unless it |
| 88 // hasn't yet been applied, in which case we just prevent it from applying. | 86 // hasn't yet been applied, in which case we just prevent it from applying. |
| 89 void CleanUp(); | 87 void CleanUp(); |
| 90 | 88 |
| 91 private: | 89 private: |
| (...skipping 16 matching lines...) Expand all Loading... |
| 108 void RemoveBlock(); | 106 void RemoveBlock(); |
| 109 | 107 |
| 110 // Asynchronous callback functions for ApplyBlock and RemoveBlock. | 108 // Asynchronous callback functions for ApplyBlock and RemoveBlock. |
| 111 // Functions do not receive ownership of |response|. | 109 // Functions do not receive ownership of |response|. |
| 112 void ApplyBlockFinished(dbus::Response* response); | 110 void ApplyBlockFinished(dbus::Response* response); |
| 113 void RemoveBlockFinished(dbus::Response* response); | 111 void RemoveBlockFinished(dbus::Response* response); |
| 114 | 112 |
| 115 // Wrapper for XScreenSaverSuspend. Checks whether the X11 Screen Saver | 113 // Wrapper for XScreenSaverSuspend. Checks whether the X11 Screen Saver |
| 116 // Extension is available first. If it isn't, this is a no-op. | 114 // Extension is available first. If it isn't, this is a no-op. |
| 117 // Must be called on the UI thread. | 115 // Must be called on the UI thread. |
| 118 void XSSSuspendSet(bool suspend); | 116 static void XSSSuspendSet(bool suspend); |
| 119 | 117 |
| 120 // If DPMS (the power saving system in X11) is not enabled, then we don't want | 118 // If DPMS (the power saving system in X11) is not enabled, then we don't want |
| 121 // to try to disable power saving, since on some desktop environments that may | 119 // to try to disable power saving, since on some desktop environments that may |
| 122 // enable DPMS with very poor default settings (e.g. turning off the display | 120 // enable DPMS with very poor default settings (e.g. turning off the display |
| 123 // after only 1 second). Must be called on the UI thread. | 121 // after only 1 second). Must be called on the UI thread. |
| 124 bool DPMSEnabled(); | 122 static bool DPMSEnabled(); |
| 125 | 123 |
| 126 // If no other method is available (i.e. not running under a Desktop | 124 // If no other method is available (i.e. not running under a Desktop |
| 127 // Environment) check whether the X11 Screen Saver Extension can be used | 125 // Environment) check whether the X11 Screen Saver Extension can be used |
| 128 // to disable the screen saver. Must be called on the UI thread. | 126 // to disable the screen saver. Must be called on the UI thread. |
| 129 bool XSSAvailable(); | 127 static bool XSSAvailable(); |
| 130 | 128 |
| 131 // Returns an appropriate D-Bus API to use based on the desktop environment. | 129 // Returns an appropriate D-Bus API to use based on the desktop environment. |
| 132 // Must be called on the UI thread, as it may call DPMSEnabled() above. | 130 // Must be called on the UI thread, as it may call DPMSEnabled() above. |
| 133 DBusAPI SelectAPI(); | 131 static DBusAPI SelectAPI(); |
| 134 | 132 |
| 135 const PowerSaveBlockerType type_; | 133 const PowerSaveBlockerType type_; |
| 136 const std::string description_; | 134 const std::string description_; |
| 137 const bool freedesktop_only_; | 135 const bool freedesktop_only_; |
| 138 | 136 |
| 139 // Initially, we post a message to the UI thread to select an API. When it | 137 // Initially, we post a message to the UI thread to select an API. When it |
| 140 // finishes, it will post a message to the FILE thread to perform the actual | 138 // finishes, it will post a message to the FILE thread to perform the actual |
| 141 // application of the block, unless enqueue_apply_ is false. We set it to | 139 // application of the block, unless enqueue_apply_ is false. We set it to |
| 142 // false when we post that message, or when RemoveBlock() is called before | 140 // false when we post that message, or when RemoveBlock() is called before |
| 143 // ApplyBlock() has run. Both api_ and enqueue_apply_ are guarded by lock_. | 141 // ApplyBlock() has run. Both api_ and enqueue_apply_ are guarded by lock_. |
| 144 DBusAPI api_; | 142 DBusAPI api_; |
| 145 bool enqueue_apply_; | 143 bool enqueue_apply_; |
| 146 base::Lock lock_; | 144 base::Lock lock_; |
| 147 | 145 |
| 148 // Indicates that a D-Bus power save blocking request is in flight. | 146 // Indicates that a D-Bus power save blocking request is in flight. |
| 149 bool block_inflight_; | 147 bool block_inflight_; |
| 150 // Used to detect erronous redundant calls to RemoveBlock(). | 148 // Used to detect erronous redundant calls to RemoveBlock(). |
| 151 bool unblock_inflight_; | 149 bool unblock_inflight_; |
| 152 // Indicates that RemoveBlock() is called before ApplyBlock() has finished. | 150 // Indicates that RemoveBlock() is called before ApplyBlock() has finished. |
| 153 // If it's true, then the RemoveBlock() call will be processed immediately | 151 // If it's true, then the RemoveBlock() call will be processed immediately |
| 154 // after ApplyBlock() has finished. | 152 // after ApplyBlock() has finished. |
| 155 bool enqueue_unblock_; | 153 bool enqueue_unblock_; |
| 156 | 154 |
| 157 scoped_refptr<dbus::Bus> bus_; | 155 scoped_refptr<dbus::Bus> bus_; |
| 158 | 156 |
| 159 // The cookie that identifies our inhibit request, | 157 // The cookie that identifies our inhibit request, |
| 160 // or 0 if there is no active inhibit request. | 158 // or 0 if there is no active inhibit request. |
| 161 uint32_t inhibit_cookie_; | 159 uint32_t inhibit_cookie_; |
| 162 | 160 |
| 163 scoped_refptr<base::SequencedTaskRunner> ui_task_runner_; | |
| 164 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; | |
| 165 | |
| 166 DISALLOW_COPY_AND_ASSIGN(Delegate); | 161 DISALLOW_COPY_AND_ASSIGN(Delegate); |
| 167 }; | 162 }; |
| 168 | 163 |
| 169 PowerSaveBlockerImpl::Delegate::Delegate( | 164 PowerSaveBlockerImpl::Delegate::Delegate(PowerSaveBlockerType type, |
| 170 PowerSaveBlockerType type, | 165 const std::string& description, |
| 171 const std::string& description, | 166 bool freedesktop_only) |
| 172 bool freedesktop_only, | |
| 173 scoped_refptr<base::SequencedTaskRunner> ui_task_runner, | |
| 174 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) | |
| 175 : type_(type), | 167 : type_(type), |
| 176 description_(description), | 168 description_(description), |
| 177 freedesktop_only_(freedesktop_only), | 169 freedesktop_only_(freedesktop_only), |
| 178 api_(NO_API), | 170 api_(NO_API), |
| 179 enqueue_apply_(false), | 171 enqueue_apply_(false), |
| 180 inhibit_cookie_(0), | 172 inhibit_cookie_(0) { |
| 181 ui_task_runner_(ui_task_runner), | |
| 182 blocking_task_runner_(blocking_task_runner) { | |
| 183 // We're on the client's thread here, so we don't allocate the dbus::Bus | 173 // We're on the client's thread here, so we don't allocate the dbus::Bus |
| 184 // object yet. We'll do it later in ApplyBlock(), on the FILE thread. | 174 // object yet. We'll do it later in ApplyBlock(), on the FILE thread. |
| 185 } | 175 } |
| 186 | 176 |
| 187 void PowerSaveBlockerImpl::Delegate::Init() { | 177 void PowerSaveBlockerImpl::Delegate::Init() { |
| 188 base::AutoLock lock(lock_); | 178 base::AutoLock lock(lock_); |
| 189 DCHECK(!enqueue_apply_); | 179 DCHECK(!enqueue_apply_); |
| 190 enqueue_apply_ = true; | 180 enqueue_apply_ = true; |
| 191 block_inflight_ = false; | 181 block_inflight_ = false; |
| 192 unblock_inflight_ = false; | 182 unblock_inflight_ = false; |
| 193 enqueue_unblock_ = false; | 183 enqueue_unblock_ = false; |
| 194 ui_task_runner_->PostTask(FROM_HERE, | 184 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 195 base::Bind(&Delegate::InitOnUIThread, this)); | 185 base::Bind(&Delegate::InitOnUIThread, this)); |
| 196 } | 186 } |
| 197 | 187 |
| 198 void PowerSaveBlockerImpl::Delegate::CleanUp() { | 188 void PowerSaveBlockerImpl::Delegate::CleanUp() { |
| 199 base::AutoLock lock(lock_); | 189 base::AutoLock lock(lock_); |
| 200 if (enqueue_apply_) { | 190 if (enqueue_apply_) { |
| 201 // If a call to ApplyBlock() has not yet been enqueued because we are still | 191 // If a call to ApplyBlock() has not yet been enqueued because we are still |
| 202 // initializing on the UI thread, then just cancel it. We don't need to | 192 // initializing on the UI thread, then just cancel it. We don't need to |
| 203 // remove the block because we haven't even applied it yet. | 193 // remove the block because we haven't even applied it yet. |
| 204 enqueue_apply_ = false; | 194 enqueue_apply_ = false; |
| 205 } else { | 195 } else { |
| 206 if (ShouldBlock()) { | 196 if (ShouldBlock()) { |
| 207 blocking_task_runner_->PostTask(FROM_HERE, | 197 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| 208 base::Bind(&Delegate::RemoveBlock, this)); | 198 base::Bind(&Delegate::RemoveBlock, this)); |
| 209 } | 199 } |
| 210 | 200 |
| 211 ui_task_runner_->PostTask( | 201 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 212 FROM_HERE, base::Bind(&Delegate::XSSSuspendSet, this, false)); | 202 base::Bind(&Delegate::XSSSuspendSet, false)); |
| 213 } | 203 } |
| 214 } | 204 } |
| 215 | 205 |
| 216 void PowerSaveBlockerImpl::Delegate::InitOnUIThread() { | 206 void PowerSaveBlockerImpl::Delegate::InitOnUIThread() { |
| 217 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 207 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 218 base::AutoLock lock(lock_); | 208 base::AutoLock lock(lock_); |
| 219 api_ = SelectAPI(); | 209 api_ = SelectAPI(); |
| 220 | 210 |
| 221 if (enqueue_apply_) { | 211 if (enqueue_apply_) { |
| 222 if (ShouldBlock()) { | 212 if (ShouldBlock()) { |
| 223 // The thread we use here becomes the origin and D-Bus thread for the | 213 // The thread we use here becomes the origin and D-Bus thread for the |
| 224 // D-Bus library, so we need to use the same thread above for | 214 // D-Bus library, so we need to use the same thread above for |
| 225 // RemoveBlock(). It must be a thread that allows I/O operations, so we | 215 // RemoveBlock(). It must be a thread that allows I/O operations, so we |
| 226 // use the FILE thread. | 216 // use the FILE thread. |
| 227 blocking_task_runner_->PostTask(FROM_HERE, | 217 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| 228 base::Bind(&Delegate::ApplyBlock, this)); | 218 base::Bind(&Delegate::ApplyBlock, this)); |
| 229 } | 219 } |
| 230 XSSSuspendSet(true); | 220 XSSSuspendSet(true); |
| 231 } | 221 } |
| 232 enqueue_apply_ = false; | 222 enqueue_apply_ = false; |
| 233 } | 223 } |
| 234 | 224 |
| 235 bool PowerSaveBlockerImpl::Delegate::ShouldBlock() const { | 225 bool PowerSaveBlockerImpl::Delegate::ShouldBlock() const { |
| 236 return freedesktop_only_ ? api_ == FREEDESKTOP_API : api_ != NO_API; | 226 return freedesktop_only_ ? api_ == FREEDESKTOP_API : api_ != NO_API; |
| 237 } | 227 } |
| 238 | 228 |
| 239 void PowerSaveBlockerImpl::Delegate::ApplyBlock() { | 229 void PowerSaveBlockerImpl::Delegate::ApplyBlock() { |
| 240 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); | 230 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 241 DCHECK(!bus_); // ApplyBlock() should only be called once. | 231 DCHECK(!bus_); // ApplyBlock() should only be called once. |
| 242 DCHECK(!block_inflight_); | 232 DCHECK(!block_inflight_); |
| 243 | 233 |
| 244 dbus::Bus::Options options; | 234 dbus::Bus::Options options; |
| 245 options.bus_type = dbus::Bus::SESSION; | 235 options.bus_type = dbus::Bus::SESSION; |
| 246 options.connection_type = dbus::Bus::PRIVATE; | 236 options.connection_type = dbus::Bus::PRIVATE; |
| 247 bus_ = new dbus::Bus(options); | 237 bus_ = new dbus::Bus(options); |
| 248 | 238 |
| 249 scoped_refptr<dbus::ObjectProxy> object_proxy; | 239 scoped_refptr<dbus::ObjectProxy> object_proxy; |
| 250 std::unique_ptr<dbus::MethodCall> method_call; | 240 std::unique_ptr<dbus::MethodCall> method_call; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 } | 302 } |
| 313 | 303 |
| 314 block_inflight_ = true; | 304 block_inflight_ = true; |
| 315 object_proxy->CallMethod( | 305 object_proxy->CallMethod( |
| 316 method_call.get(), dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | 306 method_call.get(), dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
| 317 base::Bind(&PowerSaveBlockerImpl::Delegate::ApplyBlockFinished, this)); | 307 base::Bind(&PowerSaveBlockerImpl::Delegate::ApplyBlockFinished, this)); |
| 318 } | 308 } |
| 319 | 309 |
| 320 void PowerSaveBlockerImpl::Delegate::ApplyBlockFinished( | 310 void PowerSaveBlockerImpl::Delegate::ApplyBlockFinished( |
| 321 dbus::Response* response) { | 311 dbus::Response* response) { |
| 322 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); | 312 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 323 DCHECK(bus_); | 313 DCHECK(bus_); |
| 324 DCHECK(block_inflight_); | 314 DCHECK(block_inflight_); |
| 325 block_inflight_ = false; | 315 block_inflight_ = false; |
| 326 | 316 |
| 327 if (response) { | 317 if (response) { |
| 328 // The method returns an inhibit_cookie, used to uniquely identify | 318 // The method returns an inhibit_cookie, used to uniquely identify |
| 329 // this request. It should be used as an argument to Uninhibit() | 319 // this request. It should be used as an argument to Uninhibit() |
| 330 // in order to remove the request. | 320 // in order to remove the request. |
| 331 dbus::MessageReader message_reader(response); | 321 dbus::MessageReader message_reader(response); |
| 332 if (!message_reader.PopUint32(&inhibit_cookie_)) | 322 if (!message_reader.PopUint32(&inhibit_cookie_)) |
| 333 LOG(ERROR) << "Invalid Inhibit() response: " << response->ToString(); | 323 LOG(ERROR) << "Invalid Inhibit() response: " << response->ToString(); |
| 334 } else { | 324 } else { |
| 335 LOG(ERROR) << "No response to Inhibit() request!"; | 325 LOG(ERROR) << "No response to Inhibit() request!"; |
| 336 } | 326 } |
| 337 | 327 |
| 338 if (enqueue_unblock_) { | 328 if (enqueue_unblock_) { |
| 339 enqueue_unblock_ = false; | 329 enqueue_unblock_ = false; |
| 340 // RemoveBlock() was called while the Inhibit operation was in flight, | 330 // RemoveBlock() was called while the Inhibit operation was in flight, |
| 341 // so go ahead and remove the block now. | 331 // so go ahead and remove the block now. |
| 342 blocking_task_runner_->PostTask(FROM_HERE, | 332 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| 343 base::Bind(&Delegate::RemoveBlock, this)); | 333 base::Bind(&Delegate::RemoveBlock, this)); |
| 344 } | 334 } |
| 345 } | 335 } |
| 346 | 336 |
| 347 void PowerSaveBlockerImpl::Delegate::RemoveBlock() { | 337 void PowerSaveBlockerImpl::Delegate::RemoveBlock() { |
| 348 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); | 338 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 349 DCHECK(bus_); // RemoveBlock() should only be called once. | 339 DCHECK(bus_); // RemoveBlock() should only be called once. |
| 350 DCHECK(!unblock_inflight_); | 340 DCHECK(!unblock_inflight_); |
| 351 | 341 |
| 352 if (block_inflight_) { | 342 if (block_inflight_) { |
| 353 DCHECK(!enqueue_unblock_); | 343 DCHECK(!enqueue_unblock_); |
| 354 // Can't call RemoveBlock until ApplyBlock's async operation has | 344 // Can't call RemoveBlock until ApplyBlock's async operation has |
| 355 // finished. Enqueue it for execution once ApplyBlock is done. | 345 // finished. Enqueue it for execution once ApplyBlock is done. |
| 356 enqueue_unblock_ = true; | 346 enqueue_unblock_ = true; |
| 357 return; | 347 return; |
| 358 } | 348 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 dbus::MessageWriter message_writer(method_call.get()); | 384 dbus::MessageWriter message_writer(method_call.get()); |
| 395 message_writer.AppendUint32(inhibit_cookie_); | 385 message_writer.AppendUint32(inhibit_cookie_); |
| 396 unblock_inflight_ = true; | 386 unblock_inflight_ = true; |
| 397 object_proxy->CallMethod( | 387 object_proxy->CallMethod( |
| 398 method_call.get(), dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | 388 method_call.get(), dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
| 399 base::Bind(&PowerSaveBlockerImpl::Delegate::RemoveBlockFinished, this)); | 389 base::Bind(&PowerSaveBlockerImpl::Delegate::RemoveBlockFinished, this)); |
| 400 } | 390 } |
| 401 | 391 |
| 402 void PowerSaveBlockerImpl::Delegate::RemoveBlockFinished( | 392 void PowerSaveBlockerImpl::Delegate::RemoveBlockFinished( |
| 403 dbus::Response* response) { | 393 dbus::Response* response) { |
| 404 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); | 394 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 405 DCHECK(bus_); | 395 DCHECK(bus_); |
| 406 unblock_inflight_ = false; | 396 unblock_inflight_ = false; |
| 407 | 397 |
| 408 if (!response) | 398 if (!response) |
| 409 LOG(ERROR) << "No response to Uninhibit() request!"; | 399 LOG(ERROR) << "No response to Uninhibit() request!"; |
| 410 // We don't care about checking the result. We assume it works; we can't | 400 // We don't care about checking the result. We assume it works; we can't |
| 411 // really do anything about it anyway if it fails. | 401 // really do anything about it anyway if it fails. |
| 412 inhibit_cookie_ = 0; | 402 inhibit_cookie_ = 0; |
| 413 | 403 |
| 414 bus_->ShutdownAndBlock(); | 404 bus_->ShutdownAndBlock(); |
| 415 bus_ = nullptr; | 405 bus_ = nullptr; |
| 416 } | 406 } |
| 417 | 407 |
| 408 // static |
| 418 void PowerSaveBlockerImpl::Delegate::XSSSuspendSet(bool suspend) { | 409 void PowerSaveBlockerImpl::Delegate::XSSSuspendSet(bool suspend) { |
| 419 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 410 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 420 | 411 |
| 421 if (!XSSAvailable()) | 412 if (!XSSAvailable()) |
| 422 return; | 413 return; |
| 423 | 414 |
| 424 XDisplay* display = gfx::GetXDisplay(); | 415 XDisplay* display = gfx::GetXDisplay(); |
| 425 XScreenSaverSuspend(display, suspend); | 416 XScreenSaverSuspend(display, suspend); |
| 426 } | 417 } |
| 427 | 418 |
| 419 // static |
| 428 bool PowerSaveBlockerImpl::Delegate::DPMSEnabled() { | 420 bool PowerSaveBlockerImpl::Delegate::DPMSEnabled() { |
| 429 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 421 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 430 XDisplay* display = gfx::GetXDisplay(); | 422 XDisplay* display = gfx::GetXDisplay(); |
| 431 BOOL enabled = false; | 423 BOOL enabled = false; |
| 432 int dummy; | 424 int dummy; |
| 433 if (DPMSQueryExtension(display, &dummy, &dummy) && DPMSCapable(display)) { | 425 if (DPMSQueryExtension(display, &dummy, &dummy) && DPMSCapable(display)) { |
| 434 CARD16 state; | 426 CARD16 state; |
| 435 DPMSInfo(display, &state, &enabled); | 427 DPMSInfo(display, &state, &enabled); |
| 436 } | 428 } |
| 437 return enabled; | 429 return enabled; |
| 438 } | 430 } |
| 439 | 431 |
| 432 // static |
| 440 bool PowerSaveBlockerImpl::Delegate::XSSAvailable() { | 433 bool PowerSaveBlockerImpl::Delegate::XSSAvailable() { |
| 441 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 434 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 442 XDisplay* display = gfx::GetXDisplay(); | 435 XDisplay* display = gfx::GetXDisplay(); |
| 443 int dummy; | 436 int dummy; |
| 444 int major; | 437 int major; |
| 445 int minor; | 438 int minor; |
| 446 | 439 |
| 447 if (!XScreenSaverQueryExtension(display, &dummy, &dummy)) | 440 if (!XScreenSaverQueryExtension(display, &dummy, &dummy)) |
| 448 return false; | 441 return false; |
| 449 | 442 |
| 450 if (!XScreenSaverQueryVersion(display, &major, &minor)) | 443 if (!XScreenSaverQueryVersion(display, &major, &minor)) |
| 451 return false; | 444 return false; |
| 452 | 445 |
| 453 return major > 1 || (major == 1 && minor >= 1); | 446 return major > 1 || (major == 1 && minor >= 1); |
| 454 } | 447 } |
| 455 | 448 |
| 449 // static |
| 456 DBusAPI PowerSaveBlockerImpl::Delegate::SelectAPI() { | 450 DBusAPI PowerSaveBlockerImpl::Delegate::SelectAPI() { |
| 457 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 451 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 458 std::unique_ptr<base::Environment> env(base::Environment::Create()); | 452 std::unique_ptr<base::Environment> env(base::Environment::Create()); |
| 459 switch (base::nix::GetDesktopEnvironment(env.get())) { | 453 switch (base::nix::GetDesktopEnvironment(env.get())) { |
| 460 case base::nix::DESKTOP_ENVIRONMENT_GNOME: | 454 case base::nix::DESKTOP_ENVIRONMENT_GNOME: |
| 461 case base::nix::DESKTOP_ENVIRONMENT_UNITY: | 455 case base::nix::DESKTOP_ENVIRONMENT_UNITY: |
| 462 if (DPMSEnabled()) | 456 if (DPMSEnabled()) |
| 463 return GNOME_API; | 457 return GNOME_API; |
| 464 break; | 458 break; |
| 465 case base::nix::DESKTOP_ENVIRONMENT_XFCE: | 459 case base::nix::DESKTOP_ENVIRONMENT_XFCE: |
| 466 case base::nix::DESKTOP_ENVIRONMENT_KDE4: | 460 case base::nix::DESKTOP_ENVIRONMENT_KDE4: |
| 467 case base::nix::DESKTOP_ENVIRONMENT_KDE5: | 461 case base::nix::DESKTOP_ENVIRONMENT_KDE5: |
| 468 if (DPMSEnabled()) | 462 if (DPMSEnabled()) |
| 469 return FREEDESKTOP_API; | 463 return FREEDESKTOP_API; |
| 470 break; | 464 break; |
| 471 case base::nix::DESKTOP_ENVIRONMENT_KDE3: | 465 case base::nix::DESKTOP_ENVIRONMENT_KDE3: |
| 472 case base::nix::DESKTOP_ENVIRONMENT_OTHER: | 466 case base::nix::DESKTOP_ENVIRONMENT_OTHER: |
| 473 // Not supported. | 467 // Not supported. |
| 474 break; | 468 break; |
| 475 } | 469 } |
| 476 return NO_API; | 470 return NO_API; |
| 477 } | 471 } |
| 478 | 472 |
| 479 PowerSaveBlockerImpl::PowerSaveBlockerImpl( | 473 PowerSaveBlockerImpl::PowerSaveBlockerImpl(PowerSaveBlockerType type, |
| 480 PowerSaveBlockerType type, | 474 Reason reason, |
| 481 Reason reason, | 475 const std::string& description) |
| 482 const std::string& description, | 476 : delegate_(new Delegate(type, description, false /* freedesktop_only */)) { |
| 483 scoped_refptr<base::SequencedTaskRunner> ui_task_runner, | |
| 484 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) | |
| 485 : delegate_(new Delegate(type, | |
| 486 description, | |
| 487 false /* freedesktop_only */, | |
| 488 ui_task_runner, | |
| 489 blocking_task_runner)), | |
| 490 ui_task_runner_(ui_task_runner), | |
| 491 blocking_task_runner_(blocking_task_runner) { | |
| 492 delegate_->Init(); | 477 delegate_->Init(); |
| 493 | 478 |
| 494 if (type == kPowerSaveBlockPreventDisplaySleep) { | 479 if (type == kPowerSaveBlockPreventDisplaySleep) { |
| 495 freedesktop_suspend_delegate_ = new Delegate( | 480 freedesktop_suspend_delegate_ = |
| 496 kPowerSaveBlockPreventAppSuspension, description, | 481 new Delegate(kPowerSaveBlockPreventAppSuspension, description, |
| 497 true /* freedesktop_only */, ui_task_runner, blocking_task_runner); | 482 true /* freedesktop_only */); |
| 498 freedesktop_suspend_delegate_->Init(); | 483 freedesktop_suspend_delegate_->Init(); |
| 499 } | 484 } |
| 500 } | 485 } |
| 501 | 486 |
| 502 PowerSaveBlockerImpl::~PowerSaveBlockerImpl() { | 487 PowerSaveBlockerImpl::~PowerSaveBlockerImpl() { |
| 503 delegate_->CleanUp(); | 488 delegate_->CleanUp(); |
| 504 if (freedesktop_suspend_delegate_) | 489 if (freedesktop_suspend_delegate_) |
| 505 freedesktop_suspend_delegate_->CleanUp(); | 490 freedesktop_suspend_delegate_->CleanUp(); |
| 506 } | 491 } |
| 507 | 492 |
| 508 } // namespace content | 493 } // namespace content |
| OLD | NEW |