| Index: content/browser/power_save_blocker_x11.cc
 | 
| diff --git a/content/browser/power_save_blocker_x11.cc b/content/browser/power_save_blocker_x11.cc
 | 
| deleted file mode 100644
 | 
| index a177e392ce1466f2469fe0f76908cd1c09959d7d..0000000000000000000000000000000000000000
 | 
| --- a/content/browser/power_save_blocker_x11.cc
 | 
| +++ /dev/null
 | 
| @@ -1,508 +0,0 @@
 | 
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
 | 
| -// Use of this source code is governed by a BSD-style license that can be
 | 
| -// found in the LICENSE file.
 | 
| -
 | 
| -#include <X11/Xlib.h>
 | 
| -#include <X11/extensions/dpms.h>
 | 
| -#include <X11/extensions/scrnsaver.h>
 | 
| -#include <stdint.h>
 | 
| -
 | 
| -#include <memory>
 | 
| -
 | 
| -#include "content/browser/power_save_blocker_impl.h"
 | 
| -// Xlib #defines Status, but we can't have that for some of our headers.
 | 
| -#ifdef Status
 | 
| -#undef Status
 | 
| -#endif
 | 
| -
 | 
| -#include "base/bind.h"
 | 
| -#include "base/callback.h"
 | 
| -#include "base/command_line.h"
 | 
| -#include "base/environment.h"
 | 
| -#include "base/files/file_path.h"
 | 
| -#include "base/location.h"
 | 
| -#include "base/logging.h"
 | 
| -#include "base/macros.h"
 | 
| -#include "base/memory/ref_counted.h"
 | 
| -#include "base/memory/singleton.h"
 | 
| -#include "base/nix/xdg_util.h"
 | 
| -#include "base/synchronization/lock.h"
 | 
| -#include "dbus/bus.h"
 | 
| -#include "dbus/message.h"
 | 
| -#include "dbus/object_path.h"
 | 
| -#include "dbus/object_proxy.h"
 | 
| -#include "ui/gfx/x/x11_types.h"
 | 
| -
 | 
| -namespace {
 | 
| -
 | 
| -enum DBusAPI {
 | 
| -  NO_API,           // Disable. No supported API available.
 | 
| -  GNOME_API,        // Use the GNOME API. (Supports more features.)
 | 
| -  FREEDESKTOP_API,  // Use the FreeDesktop API, for KDE4, KDE5, and XFCE.
 | 
| -};
 | 
| -
 | 
| -// Inhibit flags defined in the org.gnome.SessionManager interface.
 | 
| -// Can be OR'd together and passed as argument to the Inhibit() method
 | 
| -// to specify which power management features we want to suspend.
 | 
| -enum GnomeAPIInhibitFlags {
 | 
| -  INHIBIT_LOGOUT            = 1,
 | 
| -  INHIBIT_SWITCH_USER       = 2,
 | 
| -  INHIBIT_SUSPEND_SESSION   = 4,
 | 
| -  INHIBIT_MARK_SESSION_IDLE = 8
 | 
| -};
 | 
| -
 | 
| -const char kGnomeAPIServiceName[] = "org.gnome.SessionManager";
 | 
| -const char kGnomeAPIInterfaceName[] = "org.gnome.SessionManager";
 | 
| -const char kGnomeAPIObjectPath[] = "/org/gnome/SessionManager";
 | 
| -
 | 
| -const char kFreeDesktopAPIPowerServiceName[] =
 | 
| -    "org.freedesktop.PowerManagement";
 | 
| -const char kFreeDesktopAPIPowerInterfaceName[] =
 | 
| -    "org.freedesktop.PowerManagement.Inhibit";
 | 
| -const char kFreeDesktopAPIPowerObjectPath[] =
 | 
| -    "/org/freedesktop/PowerManagement/Inhibit";
 | 
| -
 | 
| -const char kFreeDesktopAPIScreenServiceName[] = "org.freedesktop.ScreenSaver";
 | 
| -const char kFreeDesktopAPIScreenInterfaceName[] = "org.freedesktop.ScreenSaver";
 | 
| -const char kFreeDesktopAPIScreenObjectPath[] = "/org/freedesktop/ScreenSaver";
 | 
| -
 | 
| -}  // namespace
 | 
| -
 | 
| -namespace content {
 | 
| -
 | 
| -class PowerSaveBlockerImpl::Delegate
 | 
| -    : public base::RefCountedThreadSafe<PowerSaveBlockerImpl::Delegate> {
 | 
| - public:
 | 
| -  // Picks an appropriate D-Bus API to use based on the desktop environment.
 | 
| -  Delegate(PowerSaveBlockerType type,
 | 
| -           const std::string& description,
 | 
| -           bool freedesktop_only,
 | 
| -           scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
 | 
| -           scoped_refptr<base::SingleThreadTaskRunner> blocking_task_runner);
 | 
| -
 | 
| -  // Post a task to initialize the delegate on the UI thread, which will itself
 | 
| -  // then post a task to apply the power save block on the FILE thread.
 | 
| -  void Init();
 | 
| -
 | 
| -  // Post a task to remove the power save block on the FILE thread, unless it
 | 
| -  // hasn't yet been applied, in which case we just prevent it from applying.
 | 
| -  void CleanUp();
 | 
| -
 | 
| - private:
 | 
| -  friend class base::RefCountedThreadSafe<Delegate>;
 | 
| -  ~Delegate() {}
 | 
| -
 | 
| -  // Selects an appropriate D-Bus API to use for this object. Must be called on
 | 
| -  // the UI thread. Checks enqueue_apply_ once an API has been selected, and
 | 
| -  // enqueues a call back to ApplyBlock() if it is true. See the comments for
 | 
| -  // enqueue_apply_ below.
 | 
| -  void InitOnUIThread();
 | 
| -
 | 
| -  // Returns true if ApplyBlock() / RemoveBlock() should be called.
 | 
| -  bool ShouldBlock() const;
 | 
| -
 | 
| -  // Apply or remove the power save block, respectively. These methods should be
 | 
| -  // called once each, on the same thread, per instance. They block waiting for
 | 
| -  // the action to complete (with a timeout); the thread must thus allow I/O.
 | 
| -  void ApplyBlock();
 | 
| -  void RemoveBlock();
 | 
| -
 | 
| -  // Asynchronous callback functions for ApplyBlock and RemoveBlock.
 | 
| -  // Functions do not receive ownership of |response|.
 | 
| -  void ApplyBlockFinished(dbus::Response* response);
 | 
| -  void RemoveBlockFinished(dbus::Response* response);
 | 
| -
 | 
| -  // Wrapper for XScreenSaverSuspend. Checks whether the X11 Screen Saver
 | 
| -  // Extension is available first. If it isn't, this is a no-op.
 | 
| -  // Must be called on the UI thread.
 | 
| -  void XSSSuspendSet(bool suspend);
 | 
| -
 | 
| -  // If DPMS (the power saving system in X11) is not enabled, then we don't want
 | 
| -  // to try to disable power saving, since on some desktop environments that may
 | 
| -  // enable DPMS with very poor default settings (e.g. turning off the display
 | 
| -  // after only 1 second). Must be called on the UI thread.
 | 
| -  bool DPMSEnabled();
 | 
| -
 | 
| -  // If no other method is available (i.e. not running under a Desktop
 | 
| -  // Environment) check whether the X11 Screen Saver Extension can be used
 | 
| -  // to disable the screen saver. Must be called on the UI thread.
 | 
| -  bool XSSAvailable();
 | 
| -
 | 
| -  // Returns an appropriate D-Bus API to use based on the desktop environment.
 | 
| -  // Must be called on the UI thread, as it may call DPMSEnabled() above.
 | 
| -  DBusAPI SelectAPI();
 | 
| -
 | 
| -  const PowerSaveBlockerType type_;
 | 
| -  const std::string description_;
 | 
| -  const bool freedesktop_only_;
 | 
| -
 | 
| -  // Initially, we post a message to the UI thread to select an API. When it
 | 
| -  // finishes, it will post a message to the FILE thread to perform the actual
 | 
| -  // application of the block, unless enqueue_apply_ is false. We set it to
 | 
| -  // false when we post that message, or when RemoveBlock() is called before
 | 
| -  // ApplyBlock() has run. Both api_ and enqueue_apply_ are guarded by lock_.
 | 
| -  DBusAPI api_;
 | 
| -  bool enqueue_apply_;
 | 
| -  base::Lock lock_;
 | 
| -
 | 
| -  // Indicates that a D-Bus power save blocking request is in flight.
 | 
| -  bool block_inflight_;
 | 
| -  // Used to detect erronous redundant calls to RemoveBlock().
 | 
| -  bool unblock_inflight_;
 | 
| -  // Indicates that RemoveBlock() is called before ApplyBlock() has finished.
 | 
| -  // If it's true, then the RemoveBlock() call will be processed immediately
 | 
| -  // after ApplyBlock() has finished.
 | 
| -  bool enqueue_unblock_;
 | 
| -
 | 
| -  scoped_refptr<dbus::Bus> bus_;
 | 
| -
 | 
| -  // The cookie that identifies our inhibit request,
 | 
| -  // or 0 if there is no active inhibit request.
 | 
| -  uint32_t inhibit_cookie_;
 | 
| -
 | 
| -  scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
 | 
| -  scoped_refptr<base::SingleThreadTaskRunner> blocking_task_runner_;
 | 
| -
 | 
| -  DISALLOW_COPY_AND_ASSIGN(Delegate);
 | 
| -};
 | 
| -
 | 
| -PowerSaveBlockerImpl::Delegate::Delegate(
 | 
| -    PowerSaveBlockerType type,
 | 
| -    const std::string& description,
 | 
| -    bool freedesktop_only,
 | 
| -    scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
 | 
| -    scoped_refptr<base::SingleThreadTaskRunner> blocking_task_runner)
 | 
| -    : type_(type),
 | 
| -      description_(description),
 | 
| -      freedesktop_only_(freedesktop_only),
 | 
| -      api_(NO_API),
 | 
| -      enqueue_apply_(false),
 | 
| -      inhibit_cookie_(0),
 | 
| -      ui_task_runner_(ui_task_runner),
 | 
| -      blocking_task_runner_(blocking_task_runner) {
 | 
| -  // We're on the client's thread here, so we don't allocate the dbus::Bus
 | 
| -  // object yet. We'll do it later in ApplyBlock(), on the FILE thread.
 | 
| -}
 | 
| -
 | 
| -void PowerSaveBlockerImpl::Delegate::Init() {
 | 
| -  base::AutoLock lock(lock_);
 | 
| -  DCHECK(!enqueue_apply_);
 | 
| -  enqueue_apply_ = true;
 | 
| -  block_inflight_ = false;
 | 
| -  unblock_inflight_ = false;
 | 
| -  enqueue_unblock_ = false;
 | 
| -  ui_task_runner_->PostTask(FROM_HERE,
 | 
| -                            base::Bind(&Delegate::InitOnUIThread, this));
 | 
| -}
 | 
| -
 | 
| -void PowerSaveBlockerImpl::Delegate::CleanUp() {
 | 
| -  base::AutoLock lock(lock_);
 | 
| -  if (enqueue_apply_) {
 | 
| -    // If a call to ApplyBlock() has not yet been enqueued because we are still
 | 
| -    // initializing on the UI thread, then just cancel it. We don't need to
 | 
| -    // remove the block because we haven't even applied it yet.
 | 
| -    enqueue_apply_ = false;
 | 
| -  } else {
 | 
| -    if (ShouldBlock()) {
 | 
| -      blocking_task_runner_->PostTask(FROM_HERE,
 | 
| -                                      base::Bind(&Delegate::RemoveBlock, this));
 | 
| -    }
 | 
| -
 | 
| -    ui_task_runner_->PostTask(
 | 
| -        FROM_HERE, base::Bind(&Delegate::XSSSuspendSet, this, false));
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -void PowerSaveBlockerImpl::Delegate::InitOnUIThread() {
 | 
| -  DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
 | 
| -  base::AutoLock lock(lock_);
 | 
| -  api_ = SelectAPI();
 | 
| -
 | 
| -  if (enqueue_apply_) {
 | 
| -    if (ShouldBlock()) {
 | 
| -      // The thread we use here becomes the origin and D-Bus thread for the
 | 
| -      // D-Bus library, so we need to use the same thread above for
 | 
| -      // RemoveBlock(). It must be a thread that allows I/O operations, so we
 | 
| -      // use the FILE thread.
 | 
| -      blocking_task_runner_->PostTask(FROM_HERE,
 | 
| -                                      base::Bind(&Delegate::ApplyBlock, this));
 | 
| -    }
 | 
| -    XSSSuspendSet(true);
 | 
| -  }
 | 
| -  enqueue_apply_ = false;
 | 
| -}
 | 
| -
 | 
| -bool PowerSaveBlockerImpl::Delegate::ShouldBlock() const {
 | 
| -  return freedesktop_only_ ? api_ == FREEDESKTOP_API : api_ != NO_API;
 | 
| -}
 | 
| -
 | 
| -void PowerSaveBlockerImpl::Delegate::ApplyBlock() {
 | 
| -  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
 | 
| -  DCHECK(!bus_);  // ApplyBlock() should only be called once.
 | 
| -  DCHECK(!block_inflight_);
 | 
| -
 | 
| -  dbus::Bus::Options options;
 | 
| -  options.bus_type = dbus::Bus::SESSION;
 | 
| -  options.connection_type = dbus::Bus::PRIVATE;
 | 
| -  bus_ = new dbus::Bus(options);
 | 
| -
 | 
| -  scoped_refptr<dbus::ObjectProxy> object_proxy;
 | 
| -  std::unique_ptr<dbus::MethodCall> method_call;
 | 
| -  std::unique_ptr<dbus::MessageWriter> message_writer;
 | 
| -
 | 
| -  switch (api_) {
 | 
| -    case NO_API:
 | 
| -      NOTREACHED();  // We should never call this method with this value.
 | 
| -      return;
 | 
| -    case GNOME_API:
 | 
| -      object_proxy = bus_->GetObjectProxy(
 | 
| -          kGnomeAPIServiceName,
 | 
| -          dbus::ObjectPath(kGnomeAPIObjectPath));
 | 
| -      method_call.reset(
 | 
| -          new dbus::MethodCall(kGnomeAPIInterfaceName, "Inhibit"));
 | 
| -      message_writer.reset(new dbus::MessageWriter(method_call.get()));
 | 
| -      // The arguments of the method are:
 | 
| -      //     app_id:        The application identifier
 | 
| -      //     toplevel_xid:  The toplevel X window identifier
 | 
| -      //     reason:        The reason for the inhibit
 | 
| -      //     flags:         Flags that spefify what should be inhibited
 | 
| -      message_writer->AppendString(
 | 
| -          base::CommandLine::ForCurrentProcess()->GetProgram().value());
 | 
| -      message_writer->AppendUint32(0);  // should be toplevel_xid
 | 
| -      message_writer->AppendString(description_);
 | 
| -      {
 | 
| -        uint32_t flags = 0;
 | 
| -        switch (type_) {
 | 
| -          case kPowerSaveBlockPreventDisplaySleep:
 | 
| -            flags |= INHIBIT_MARK_SESSION_IDLE;
 | 
| -            flags |= INHIBIT_SUSPEND_SESSION;
 | 
| -            break;
 | 
| -          case kPowerSaveBlockPreventAppSuspension:
 | 
| -            flags |= INHIBIT_SUSPEND_SESSION;
 | 
| -            break;
 | 
| -        }
 | 
| -        message_writer->AppendUint32(flags);
 | 
| -      }
 | 
| -      break;
 | 
| -    case FREEDESKTOP_API:
 | 
| -      switch (type_) {
 | 
| -        case kPowerSaveBlockPreventDisplaySleep:
 | 
| -          object_proxy = bus_->GetObjectProxy(
 | 
| -              kFreeDesktopAPIScreenServiceName,
 | 
| -              dbus::ObjectPath(kFreeDesktopAPIScreenObjectPath));
 | 
| -          method_call.reset(new dbus::MethodCall(
 | 
| -              kFreeDesktopAPIScreenInterfaceName, "Inhibit"));
 | 
| -          break;
 | 
| -        case kPowerSaveBlockPreventAppSuspension:
 | 
| -          object_proxy = bus_->GetObjectProxy(
 | 
| -              kFreeDesktopAPIPowerServiceName,
 | 
| -              dbus::ObjectPath(kFreeDesktopAPIPowerObjectPath));
 | 
| -          method_call.reset(new dbus::MethodCall(
 | 
| -              kFreeDesktopAPIPowerInterfaceName, "Inhibit"));
 | 
| -          break;
 | 
| -      }
 | 
| -      message_writer.reset(new dbus::MessageWriter(method_call.get()));
 | 
| -      // The arguments of the method are:
 | 
| -      //     app_id:        The application identifier
 | 
| -      //     reason:        The reason for the inhibit
 | 
| -      message_writer->AppendString(
 | 
| -          base::CommandLine::ForCurrentProcess()->GetProgram().value());
 | 
| -      message_writer->AppendString(description_);
 | 
| -      break;
 | 
| -  }
 | 
| -
 | 
| -  block_inflight_ = true;
 | 
| -  object_proxy->CallMethod(
 | 
| -      method_call.get(), dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
 | 
| -      base::Bind(&PowerSaveBlockerImpl::Delegate::ApplyBlockFinished, this));
 | 
| -}
 | 
| -
 | 
| -void PowerSaveBlockerImpl::Delegate::ApplyBlockFinished(
 | 
| -    dbus::Response* response) {
 | 
| -  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
 | 
| -  DCHECK(bus_);
 | 
| -  DCHECK(block_inflight_);
 | 
| -  block_inflight_ = false;
 | 
| -
 | 
| -  if (response) {
 | 
| -    // The method returns an inhibit_cookie, used to uniquely identify
 | 
| -    // this request. It should be used as an argument to Uninhibit()
 | 
| -    // in order to remove the request.
 | 
| -    dbus::MessageReader message_reader(response);
 | 
| -    if (!message_reader.PopUint32(&inhibit_cookie_))
 | 
| -      LOG(ERROR) << "Invalid Inhibit() response: " << response->ToString();
 | 
| -  } else {
 | 
| -    LOG(ERROR) << "No response to Inhibit() request!";
 | 
| -  }
 | 
| -
 | 
| -  if (enqueue_unblock_) {
 | 
| -    enqueue_unblock_ = false;
 | 
| -    // RemoveBlock() was called while the Inhibit operation was in flight,
 | 
| -    // so go ahead and remove the block now.
 | 
| -    blocking_task_runner_->PostTask(FROM_HERE,
 | 
| -                                    base::Bind(&Delegate::RemoveBlock, this));
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -void PowerSaveBlockerImpl::Delegate::RemoveBlock() {
 | 
| -  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
 | 
| -  DCHECK(bus_);  // RemoveBlock() should only be called once.
 | 
| -  DCHECK(!unblock_inflight_);
 | 
| -
 | 
| -  if (block_inflight_) {
 | 
| -    DCHECK(!enqueue_unblock_);
 | 
| -    // Can't call RemoveBlock until ApplyBlock's async operation has
 | 
| -    // finished. Enqueue it for execution once ApplyBlock is done.
 | 
| -    enqueue_unblock_ = true;
 | 
| -    return;
 | 
| -  }
 | 
| -
 | 
| -  scoped_refptr<dbus::ObjectProxy> object_proxy;
 | 
| -  std::unique_ptr<dbus::MethodCall> method_call;
 | 
| -
 | 
| -  switch (api_) {
 | 
| -    case NO_API:
 | 
| -      NOTREACHED();  // We should never call this method with this value.
 | 
| -      return;
 | 
| -    case GNOME_API:
 | 
| -      object_proxy = bus_->GetObjectProxy(
 | 
| -          kGnomeAPIServiceName,
 | 
| -          dbus::ObjectPath(kGnomeAPIObjectPath));
 | 
| -      method_call.reset(
 | 
| -          new dbus::MethodCall(kGnomeAPIInterfaceName, "Uninhibit"));
 | 
| -      break;
 | 
| -    case FREEDESKTOP_API:
 | 
| -      switch (type_) {
 | 
| -        case kPowerSaveBlockPreventDisplaySleep:
 | 
| -          object_proxy = bus_->GetObjectProxy(
 | 
| -              kFreeDesktopAPIScreenServiceName,
 | 
| -              dbus::ObjectPath(kFreeDesktopAPIScreenObjectPath));
 | 
| -          method_call.reset(new dbus::MethodCall(
 | 
| -              kFreeDesktopAPIScreenInterfaceName, "UnInhibit"));
 | 
| -          break;
 | 
| -        case kPowerSaveBlockPreventAppSuspension:
 | 
| -          object_proxy = bus_->GetObjectProxy(
 | 
| -              kFreeDesktopAPIPowerServiceName,
 | 
| -              dbus::ObjectPath(kFreeDesktopAPIPowerObjectPath));
 | 
| -          method_call.reset(new dbus::MethodCall(
 | 
| -              kFreeDesktopAPIPowerInterfaceName, "UnInhibit"));
 | 
| -          break;
 | 
| -      }
 | 
| -      break;
 | 
| -  }
 | 
| -
 | 
| -  dbus::MessageWriter message_writer(method_call.get());
 | 
| -  message_writer.AppendUint32(inhibit_cookie_);
 | 
| -  unblock_inflight_ = true;
 | 
| -  object_proxy->CallMethod(
 | 
| -      method_call.get(), dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
 | 
| -      base::Bind(&PowerSaveBlockerImpl::Delegate::RemoveBlockFinished, this));
 | 
| -}
 | 
| -
 | 
| -void PowerSaveBlockerImpl::Delegate::RemoveBlockFinished(
 | 
| -    dbus::Response* response) {
 | 
| -  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
 | 
| -  DCHECK(bus_);
 | 
| -  unblock_inflight_ = false;
 | 
| -
 | 
| -  if (!response)
 | 
| -    LOG(ERROR) << "No response to Uninhibit() request!";
 | 
| -  // We don't care about checking the result. We assume it works; we can't
 | 
| -  // really do anything about it anyway if it fails.
 | 
| -  inhibit_cookie_ = 0;
 | 
| -
 | 
| -  bus_->ShutdownAndBlock();
 | 
| -  bus_ = nullptr;
 | 
| -}
 | 
| -
 | 
| -void PowerSaveBlockerImpl::Delegate::XSSSuspendSet(bool suspend) {
 | 
| -  DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
 | 
| -
 | 
| -  if (!XSSAvailable())
 | 
| -    return;
 | 
| -
 | 
| -  XDisplay* display = gfx::GetXDisplay();
 | 
| -  XScreenSaverSuspend(display, suspend);
 | 
| -}
 | 
| -
 | 
| -bool PowerSaveBlockerImpl::Delegate::DPMSEnabled() {
 | 
| -  DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
 | 
| -  XDisplay* display = gfx::GetXDisplay();
 | 
| -  BOOL enabled = false;
 | 
| -  int dummy;
 | 
| -  if (DPMSQueryExtension(display, &dummy, &dummy) && DPMSCapable(display)) {
 | 
| -    CARD16 state;
 | 
| -    DPMSInfo(display, &state, &enabled);
 | 
| -  }
 | 
| -  return enabled;
 | 
| -}
 | 
| -
 | 
| -bool PowerSaveBlockerImpl::Delegate::XSSAvailable() {
 | 
| -  DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
 | 
| -  XDisplay* display = gfx::GetXDisplay();
 | 
| -  int dummy;
 | 
| -  int major;
 | 
| -  int minor;
 | 
| -
 | 
| -  if (!XScreenSaverQueryExtension(display, &dummy, &dummy))
 | 
| -    return false;
 | 
| -
 | 
| -  if (!XScreenSaverQueryVersion(display, &major, &minor))
 | 
| -    return false;
 | 
| -
 | 
| -  return major > 1 || (major == 1 && minor >= 1);
 | 
| -}
 | 
| -
 | 
| -DBusAPI PowerSaveBlockerImpl::Delegate::SelectAPI() {
 | 
| -  DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
 | 
| -  std::unique_ptr<base::Environment> env(base::Environment::Create());
 | 
| -  switch (base::nix::GetDesktopEnvironment(env.get())) {
 | 
| -    case base::nix::DESKTOP_ENVIRONMENT_GNOME:
 | 
| -    case base::nix::DESKTOP_ENVIRONMENT_UNITY:
 | 
| -      if (DPMSEnabled())
 | 
| -        return GNOME_API;
 | 
| -      break;
 | 
| -    case base::nix::DESKTOP_ENVIRONMENT_XFCE:
 | 
| -    case base::nix::DESKTOP_ENVIRONMENT_KDE4:
 | 
| -    case base::nix::DESKTOP_ENVIRONMENT_KDE5:
 | 
| -      if (DPMSEnabled())
 | 
| -        return FREEDESKTOP_API;
 | 
| -      break;
 | 
| -    case base::nix::DESKTOP_ENVIRONMENT_KDE3:
 | 
| -    case base::nix::DESKTOP_ENVIRONMENT_OTHER:
 | 
| -      // Not supported.
 | 
| -      break;
 | 
| -  }
 | 
| -  return NO_API;
 | 
| -}
 | 
| -
 | 
| -PowerSaveBlockerImpl::PowerSaveBlockerImpl(
 | 
| -    PowerSaveBlockerType type,
 | 
| -    Reason reason,
 | 
| -    const std::string& description,
 | 
| -    scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
 | 
| -    scoped_refptr<base::SingleThreadTaskRunner> blocking_task_runner)
 | 
| -    : delegate_(new Delegate(type,
 | 
| -                             description,
 | 
| -                             false /* freedesktop_only */,
 | 
| -                             ui_task_runner,
 | 
| -                             blocking_task_runner)),
 | 
| -      ui_task_runner_(ui_task_runner),
 | 
| -      blocking_task_runner_(blocking_task_runner) {
 | 
| -  delegate_->Init();
 | 
| -
 | 
| -  if (type == kPowerSaveBlockPreventDisplaySleep) {
 | 
| -    freedesktop_suspend_delegate_ = new Delegate(
 | 
| -        kPowerSaveBlockPreventAppSuspension, description,
 | 
| -        true /* freedesktop_only */, ui_task_runner, blocking_task_runner);
 | 
| -    freedesktop_suspend_delegate_->Init();
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -PowerSaveBlockerImpl::~PowerSaveBlockerImpl() {
 | 
| -  delegate_->CleanUp();
 | 
| -  if (freedesktop_suspend_delegate_)
 | 
| -    freedesktop_suspend_delegate_->CleanUp();
 | 
| -}
 | 
| -
 | 
| -}  // namespace content
 | 
| 
 |