root/chrome/browser/extensions/api/power/power_api_manager.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. LevelToPowerSaveBlockerType
  2. GetInstance
  3. AddRequest
  4. RemoveRequest
  5. SetCreateBlockerFunctionForTesting
  6. Observe
  7. current_level_
  8. UpdatePowerSaveBlocker

// Copyright (c) 2013 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 "chrome/browser/extensions/api/power/power_api_manager.h"

#include "base/bind.h"
#include "chrome/browser/chrome_notification_types.h"
#include "content/public/browser/notification_service.h"
#include "extensions/common/extension.h"

namespace extensions {

namespace {

const char kPowerSaveBlockerReason[] = "extension";

content::PowerSaveBlocker::PowerSaveBlockerType
LevelToPowerSaveBlockerType(api::power::Level level) {
  switch (level) {
    case api::power::LEVEL_SYSTEM:
      return content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension;
    case api::power::LEVEL_DISPLAY:  // fallthrough
    case api::power::LEVEL_NONE:
      return content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep;
  }
  NOTREACHED() << "Unhandled level " << level;
  return content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep;
}

}  // namespace

// static
PowerApiManager* PowerApiManager::GetInstance() {
  return Singleton<PowerApiManager>::get();
}

void PowerApiManager::AddRequest(const std::string& extension_id,
                                 api::power::Level level) {
  extension_levels_[extension_id] = level;
  UpdatePowerSaveBlocker();
}

void PowerApiManager::RemoveRequest(const std::string& extension_id) {
  extension_levels_.erase(extension_id);
  UpdatePowerSaveBlocker();
}

void PowerApiManager::SetCreateBlockerFunctionForTesting(
    CreateBlockerFunction function) {
  create_blocker_function_ = !function.is_null() ? function :
      base::Bind(&content::PowerSaveBlocker::Create);
}

void PowerApiManager::Observe(int type,
                              const content::NotificationSource& source,
                              const content::NotificationDetails& details) {
  switch (type) {
    case chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED:
      RemoveRequest(content::Details<extensions::UnloadedExtensionInfo>(
          details)->extension->id());
      UpdatePowerSaveBlocker();
      break;
    case chrome::NOTIFICATION_APP_TERMINATING:
      power_save_blocker_.reset();
      break;
    default:
      NOTREACHED() << "Unexpected notification " << type;
  }
}

PowerApiManager::PowerApiManager()
    : create_blocker_function_(base::Bind(&content::PowerSaveBlocker::Create)),
      current_level_(api::power::LEVEL_SYSTEM) {
  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
                  content::NotificationService::AllSources());
  registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING,
                 content::NotificationService::AllSources());
}

PowerApiManager::~PowerApiManager() {}

void PowerApiManager::UpdatePowerSaveBlocker() {
  if (extension_levels_.empty()) {
    power_save_blocker_.reset();
    return;
  }

  api::power::Level new_level = api::power::LEVEL_SYSTEM;
  for (ExtensionLevelMap::const_iterator it = extension_levels_.begin();
       it != extension_levels_.end(); ++it) {
    if (it->second == api::power::LEVEL_DISPLAY)
      new_level = it->second;
  }

  // If the level changed and we need to create a new blocker, do a swap
  // to ensure that there isn't a brief period where power management is
  // unblocked.
  if (!power_save_blocker_ || new_level != current_level_) {
    content::PowerSaveBlocker::PowerSaveBlockerType type =
        LevelToPowerSaveBlockerType(new_level);
    scoped_ptr<content::PowerSaveBlocker> new_blocker(
        create_blocker_function_.Run(type, kPowerSaveBlockerReason));
    power_save_blocker_.swap(new_blocker);
    current_level_ = new_level;
  }
}

}  // namespace extensions

/* [<][>][^][v][top][bottom][index][help] */