Commit 0ab9fa5e authored by Tove Petersson's avatar Tove Petersson Committed by Commit Bot

Added chrome.system.powerSource Chrome App API.

Bug: 832054
Change-Id: Id8292443a67fc85f708138dd790abea76384a24d
Reviewed-on: https://chromium-review.googlesource.com/1039446
Commit-Queue: Tove Petersson <tovep@chromium.org>
Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Reviewed-by: default avatarDan Erat <derat@chromium.org>
Reviewed-by: default avatarToni Barzic <tbarzic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#567582}
parent 46081f63
...@@ -776,6 +776,7 @@ TEST(PermissionsTest, PermissionMessages) { ...@@ -776,6 +776,7 @@ TEST(PermissionsTest, PermissionMessages) {
skip.insert(APIPermission::kSystemDisplay); skip.insert(APIPermission::kSystemDisplay);
skip.insert(APIPermission::kSystemMemory); skip.insert(APIPermission::kSystemMemory);
skip.insert(APIPermission::kSystemNetwork); skip.insert(APIPermission::kSystemNetwork);
skip.insert(APIPermission::kSystemPowerSource);
skip.insert(APIPermission::kTts); skip.insert(APIPermission::kTts);
skip.insert(APIPermission::kUnlimitedStorage); skip.insert(APIPermission::kUnlimitedStorage);
skip.insert(APIPermission::kWebcamPrivate); skip.insert(APIPermission::kWebcamPrivate);
......
...@@ -662,6 +662,7 @@ source_set("unit_tests") { ...@@ -662,6 +662,7 @@ source_set("unit_tests") {
"api/lock_screen_data/lock_screen_value_store_migrator_impl_unittest.cc", "api/lock_screen_data/lock_screen_value_store_migrator_impl_unittest.cc",
"api/media_perception_private/conversion_utils_unittest.cc", "api/media_perception_private/conversion_utils_unittest.cc",
"api/media_perception_private/media_perception_api_manager_unittest.cc", "api/media_perception_private/media_perception_api_manager_unittest.cc",
"api/system_power_source/system_power_source_api_unittest.cc",
"api/virtual_keyboard_private/virtual_keyboard_private_api_unittest.cc", "api/virtual_keyboard_private/virtual_keyboard_private_api_unittest.cc",
"api/webcam_private/visca_webcam_unittest.cc", "api/webcam_private/visca_webcam_unittest.cc",
] ]
......
...@@ -135,6 +135,7 @@ source_set("api") { ...@@ -135,6 +135,7 @@ source_set("api") {
"//extensions/browser/api/clipboard", "//extensions/browser/api/clipboard",
"//extensions/browser/api/diagnostics", "//extensions/browser/api/diagnostics",
"//extensions/browser/api/networking_config", "//extensions/browser/api/networking_config",
"//extensions/browser/api/system_power_source",
"//extensions/browser/api/virtual_keyboard", "//extensions/browser/api/virtual_keyboard",
"//extensions/browser/api/vpn_provider", "//extensions/browser/api/vpn_provider",
"//extensions/browser/api/webcam_private", "//extensions/browser/api/webcam_private",
......
# Copyright 2018 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.
import("//extensions/buildflags/buildflags.gni")
assert(enable_extensions,
"Cannot depend on extensions because enable_extensions=false.")
source_set("system_power_source") {
sources = [
"system_power_source_api.cc",
"system_power_source_api.h",
]
deps = [
"//extensions/common/api",
]
public_deps = [
"//extensions/browser:browser_sources",
]
}
// Copyright 2018 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 "extensions/browser/api/system_power_source/system_power_source_api.h"
#include <cmath>
#include "base/no_destructor.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/power_manager_client.h"
#include "extensions/browser/event_router.h"
#include "extensions/common/api/system_power_source.h"
namespace extensions {
namespace {
std::unique_ptr<double> RoundDownToTwoSignificantDigits(double d) {
if (!std::isnormal(d) || d <= 0.0)
return nullptr;
int scale = std::floor(std::log10(d));
return std::make_unique<double>(std::floor(d / std::pow(10, scale - 1)) *
std::pow(10, scale - 1));
}
api::system_power_source::PowerSourceType PowerSourceTypeFromProtoValue(
power_manager::PowerSupplyProperties_PowerSource_Type type) {
switch (type) {
case power_manager::PowerSupplyProperties_PowerSource_Type_OTHER:
return api::system_power_source::POWER_SOURCE_TYPE_UNKNOWN;
case power_manager::PowerSupplyProperties_PowerSource_Type_MAINS:
return api::system_power_source::POWER_SOURCE_TYPE_MAINS;
case power_manager::PowerSupplyProperties_PowerSource_Type_USB_C:
case power_manager::PowerSupplyProperties_PowerSource_Type_USB_BC_1_2:
return api::system_power_source::POWER_SOURCE_TYPE_USB;
}
NOTREACHED();
return api::system_power_source::POWER_SOURCE_TYPE_UNKNOWN;
}
std::vector<api::system_power_source::PowerSourceInfo>
PowerSourceInfoVectorFromProtoValue(
const power_manager::PowerSupplyProperties& proto) {
std::vector<api::system_power_source::PowerSourceInfo> power_sources;
base::Optional<std::string> external_power_source_id;
if (proto.has_external_power_source_id())
external_power_source_id = proto.external_power_source_id();
power_sources.reserve(proto.available_external_power_source_size());
for (int i = 0; i < proto.available_external_power_source_size(); ++i) {
const power_manager::PowerSupplyProperties_PowerSource& power_source_in =
proto.available_external_power_source(i);
api::system_power_source::PowerSourceInfo power_source_out;
power_source_out.type =
power_source_in.has_type()
? PowerSourceTypeFromProtoValue(power_source_in.type())
: api::system_power_source::POWER_SOURCE_TYPE_UNKNOWN;
if (power_source_in.has_max_power()) {
// Round to two significant digits for privacy reasons, to reduce the risk
// of finger-printing.
power_source_out.max_power =
RoundDownToTwoSignificantDigits(power_source_in.max_power());
}
power_source_out.active =
external_power_source_id.has_value() &&
external_power_source_id.value() == power_source_in.id();
power_sources.push_back(std::move(power_source_out));
}
return power_sources;
}
} // namespace
// static
BrowserContextKeyedAPIFactory<SystemPowerSourceAPI>*
SystemPowerSourceAPI::GetFactoryInstance() {
static base::NoDestructor<BrowserContextKeyedAPIFactory<SystemPowerSourceAPI>>
instance;
return instance.get();
}
SystemPowerSourceAPI::SystemPowerSourceAPI(content::BrowserContext* context)
: browser_context_(context), power_manager_observer_(this) {
chromeos::PowerManagerClient* power_manager_client =
chromeos::DBusThreadManager::Get()->GetPowerManagerClient();
power_manager_observer_.Add(power_manager_client);
}
SystemPowerSourceAPI::~SystemPowerSourceAPI() = default;
void SystemPowerSourceAPI::PowerChanged(
const power_manager::PowerSupplyProperties& proto) {
EventRouter* event_router = EventRouter::Get(browser_context_);
if (!event_router)
return;
std::unique_ptr<base::ListValue> args =
api::system_power_source::OnPowerChanged::Create(
PowerSourceInfoVectorFromProtoValue(proto));
auto event = std::make_unique<Event>(
events::SYSTEM_POWER_SOURCE_ONPOWERCHANGED,
api::system_power_source::OnPowerChanged::kEventName, std::move(args));
event_router->BroadcastEvent(std::move(event));
}
SystemPowerSourceGetPowerSourceInfoFunction::
SystemPowerSourceGetPowerSourceInfoFunction() = default;
SystemPowerSourceGetPowerSourceInfoFunction::
~SystemPowerSourceGetPowerSourceInfoFunction() = default;
ExtensionFunction::ResponseAction
SystemPowerSourceGetPowerSourceInfoFunction::Run() {
const base::Optional<power_manager::PowerSupplyProperties>&
power_supply_properties = chromeos::DBusThreadManager::Get()
->GetPowerManagerClient()
->GetLastStatus();
if (!power_supply_properties.has_value())
return RespondNow(NoArguments());
return RespondNow(ArgumentList(
api::system_power_source::GetPowerSourceInfo::Results::Create(
PowerSourceInfoVectorFromProtoValue(*power_supply_properties))));
}
SystemPowerSourceRequestStatusUpdateFunction::
SystemPowerSourceRequestStatusUpdateFunction() = default;
SystemPowerSourceRequestStatusUpdateFunction::
~SystemPowerSourceRequestStatusUpdateFunction() = default;
ExtensionFunction::ResponseAction
SystemPowerSourceRequestStatusUpdateFunction::Run() {
chromeos::DBusThreadManager::Get()
->GetPowerManagerClient()
->RequestStatusUpdate();
return RespondNow(NoArguments());
}
} // namespace extensions
// Copyright 2018 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.
#ifndef EXTENSIONS_BROWSER_API_SYSTEM_POWER_SOURCE_SYSTEM_POWER_SOURCE_API_H_
#define EXTENSIONS_BROWSER_API_SYSTEM_POWER_SOURCE_SYSTEM_POWER_SOURCE_API_H_
#include "base/scoped_observer.h"
#include "chromeos/dbus/power_manager_client.h"
#include "extensions/browser/browser_context_keyed_api_factory.h"
#include "extensions/browser/extension_function.h"
#include "extensions/browser/extension_function_histogram_value.h"
namespace extensions {
class SystemPowerSourceAPI : public BrowserContextKeyedAPI,
public chromeos::PowerManagerClient::Observer {
public:
explicit SystemPowerSourceAPI(content::BrowserContext* context);
~SystemPowerSourceAPI() override;
// BrowserContextKeyedAPI implementation.
static BrowserContextKeyedAPIFactory<SystemPowerSourceAPI>*
GetFactoryInstance();
private:
friend class BrowserContextKeyedAPIFactory<SystemPowerSourceAPI>;
// BrowserContextKeyedAPI implementation.
static const char* service_name() { return "SystemPowerSourceAPI"; }
static const bool kServiceIsNULLWhileTesting = true;
// Overridden from PowerManagerClient::Observer.
void PowerChanged(const power_manager::PowerSupplyProperties& proto) override;
content::BrowserContext* const browser_context_;
ScopedObserver<chromeos::PowerManagerClient,
chromeos::PowerManagerClient::Observer>
power_manager_observer_;
DISALLOW_COPY_AND_ASSIGN(SystemPowerSourceAPI);
};
class SystemPowerSourceGetPowerSourceInfoFunction
: public UIThreadExtensionFunction {
public:
SystemPowerSourceGetPowerSourceInfoFunction();
DECLARE_EXTENSION_FUNCTION("system.powerSource.getPowerSourceInfo",
SYSTEM_POWER_SOURCE_GETPOWERSOURCEINFO);
protected:
~SystemPowerSourceGetPowerSourceInfoFunction() override;
ResponseAction Run() override;
private:
DISALLOW_COPY_AND_ASSIGN(SystemPowerSourceGetPowerSourceInfoFunction);
};
class SystemPowerSourceRequestStatusUpdateFunction
: public UIThreadExtensionFunction {
public:
SystemPowerSourceRequestStatusUpdateFunction();
DECLARE_EXTENSION_FUNCTION("system.powerSource.requestStatusUpdate",
SYSTEM_POWER_SOURCE_REQUESTSTATUSUPDATE);
protected:
~SystemPowerSourceRequestStatusUpdateFunction() override;
ResponseAction Run() override;
private:
DISALLOW_COPY_AND_ASSIGN(SystemPowerSourceRequestStatusUpdateFunction);
};
} // namespace extensions
#endif // EXTENSIONS_BROWSER_API_SYSTEM_POWER_SOURCE_SYSTEM_POWER_SOURCE_API_H_
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include "extensions/browser/renderer_startup_helper.h" #include "extensions/browser/renderer_startup_helper.h"
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
#include "extensions/browser/api/system_power_source/system_power_source_api.h"
#include "extensions/browser/api/vpn_provider/vpn_service_factory.h" #include "extensions/browser/api/vpn_provider/vpn_service_factory.h"
#endif // defined(OS_CHROMEOS) #endif // defined(OS_CHROMEOS)
...@@ -93,6 +94,9 @@ void EnsureBrowserContextKeyedServiceFactoriesBuilt() { ...@@ -93,6 +94,9 @@ void EnsureBrowserContextKeyedServiceFactoriesBuilt() {
RuntimeAPI::GetFactoryInstance(); RuntimeAPI::GetFactoryInstance();
StorageFrontend::GetFactoryInstance(); StorageFrontend::GetFactoryInstance();
SystemInfoAPI::GetFactoryInstance(); SystemInfoAPI::GetFactoryInstance();
#if defined(OS_CHROMEOS)
SystemPowerSourceAPI::GetFactoryInstance();
#endif
UsbEventRouter::GetFactoryInstance(); UsbEventRouter::GetFactoryInstance();
UsbGuidMap::GetFactoryInstance(); UsbGuidMap::GetFactoryInstance();
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
......
...@@ -438,6 +438,7 @@ enum HistogramValue { ...@@ -438,6 +438,7 @@ enum HistogramValue {
SAFE_BROWSING_PRIVATE_ON_SECURITY_INTERSTITIAL_PROCEEDED, SAFE_BROWSING_PRIVATE_ON_SECURITY_INTERSTITIAL_PROCEEDED,
ACCESSIBILITY_PRIVATE_ON_SELECT_TO_SPEAK_STATE_CHANGE_REQUESTED, ACCESSIBILITY_PRIVATE_ON_SELECT_TO_SPEAK_STATE_CHANGE_REQUESTED,
INPUT_METHOD_PRIVATE_ON_FOCUS, INPUT_METHOD_PRIVATE_ON_FOCUS,
SYSTEM_POWER_SOURCE_ONPOWERCHANGED,
// Last entry: Add new entries above, then run: // Last entry: Add new entries above, then run:
// python tools/metrics/histograms/update_extension_histograms.py // python tools/metrics/histograms/update_extension_histograms.py
ENUM_BOUNDARY ENUM_BOUNDARY
......
...@@ -1319,6 +1319,8 @@ enum HistogramValue { ...@@ -1319,6 +1319,8 @@ enum HistogramValue {
USERSPRIVATE_GETCURRENTUSER = 1256, USERSPRIVATE_GETCURRENTUSER = 1256,
WALLPAPERPRIVATE_GETSURPRISEMEIMAGE = 1257, WALLPAPERPRIVATE_GETSURPRISEMEIMAGE = 1257,
VIRTUALKEYBOARDPRIVATE_SETOCCLUDEDBOUNDS = 1258, VIRTUALKEYBOARDPRIVATE_SETOCCLUDEDBOUNDS = 1258,
SYSTEM_POWER_SOURCE_GETPOWERSOURCEINFO = 1259,
SYSTEM_POWER_SOURCE_REQUESTSTATUSUPDATE = 1260,
// Last entry: Add new entries above, then run: // Last entry: Add new entries above, then run:
// python tools/metrics/histograms/update_extension_histograms.py // python tools/metrics/histograms/update_extension_histograms.py
ENUM_BOUNDARY ENUM_BOUNDARY
......
...@@ -493,6 +493,10 @@ ...@@ -493,6 +493,10 @@
"dependencies": ["permission:system.network"], "dependencies": ["permission:system.network"],
"contexts": ["blessed_extension"] "contexts": ["blessed_extension"]
}, },
"system.powerSource": {
"dependencies": ["permission:system.powerSource"],
"contexts": ["blessed_extension"]
},
"system.storage": { "system.storage": {
"dependencies": ["permission:system.storage"], "dependencies": ["permission:system.storage"],
"contexts": ["blessed_extension"] "contexts": ["blessed_extension"]
......
...@@ -609,6 +609,12 @@ ...@@ -609,6 +609,12 @@
"whitelist": ["B44D08FD98F1523ED5837D78D0A606EA9D6206E5"] // Web Store "whitelist": ["B44D08FD98F1523ED5837D78D0A606EA9D6206E5"] // Web Store
} }
], ],
"system.powerSource": {
"channel": "dev",
"extension_types": ["platform_app"],
"platforms": ["chromeos"],
"session_types": ["kiosk"]
},
"u2fDevices": { "u2fDevices": {
"channel": "stable", "channel": "stable",
"extension_types": ["extension", "platform_app"], "extension_types": ["extension", "platform_app"],
......
...@@ -50,6 +50,7 @@ extensions_api_schema_files_ = [ ...@@ -50,6 +50,7 @@ extensions_api_schema_files_ = [
"system_display.idl", "system_display.idl",
"system_memory.idl", "system_memory.idl",
"system_network.idl", "system_network.idl",
"system_power_source.idl",
"system_storage.idl", "system_storage.idl",
"test.json", "test.json",
"usb.idl", "usb.idl",
......
// Copyright 2018 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.
// The <code>chrome.system.powerSource</code> API allows Chrome Kiosk Apps to
// query the state of connected power sources.
[platforms=("chromeos")]
namespace system.powerSource {
enum PowerSourceType {
// Unspecified type.
unknown,
// Dedicated charger. Typically single-purpose and non-USB (e.g. barrel
// jack plugs).
mains,
// USB charger, including both low-power Type-A chargers and high-power
// Type-C chargers using USB Power Delivery.
usb
};
dictionary PowerSourceInfo {
// Type of power source.
PowerSourceType type;
// Maximum power this source is capable of delivering if known. Reported in
// watts, rounded to two significant digits.
double? maxPower;
// Whether this power source is connected to the device.
boolean active;
};
callback PowerSourceInfoCallback =
void(optional PowerSourceInfo[] powerSourceInfo);
interface Functions {
// Requests information on attached power sources.
// |callback|: The callback to invoke with the results or
// undefined if the power source information is not known.
static void getPowerSourceInfo(PowerSourceInfoCallback callback);
// Requests a power source status update. Resulting power source status
// updates are observable using $(ref:onPowerChanged).
static void requestStatusUpdate();
};
interface Events {
// Event for changes in the set of connected power sources.
static void onPowerChanged(PowerSourceInfo[] powerSourceInfo);
};
};
...@@ -255,6 +255,7 @@ class APIPermission { ...@@ -255,6 +255,7 @@ class APIPermission {
kCecPrivate, kCecPrivate,
kSafeBrowsingPrivate, kSafeBrowsingPrivate,
kFileSystemRequestDownloads, kFileSystemRequestDownloads,
kSystemPowerSource,
// Last entry: Add new entries above and ensure to update the // Last entry: Add new entries above and ensure to update the
// "ExtensionPermission3" enum in tools/metrics/histograms/histograms.xml // "ExtensionPermission3" enum in tools/metrics/histograms/histograms.xml
// (by running update_extension_permission.py). // (by running update_extension_permission.py).
......
...@@ -105,6 +105,7 @@ ExtensionsAPIPermissions::GetAllPermissions() const { ...@@ -105,6 +105,7 @@ ExtensionsAPIPermissions::GetAllPermissions() const {
{APIPermission::kSystemMemory, "system.memory"}, {APIPermission::kSystemMemory, "system.memory"},
{APIPermission::kSystemNetwork, "system.network"}, {APIPermission::kSystemNetwork, "system.network"},
{APIPermission::kSystemDisplay, "system.display"}, {APIPermission::kSystemDisplay, "system.display"},
{APIPermission::kSystemPowerSource, "system.powerSource"},
{APIPermission::kSystemStorage, "system.storage"}, {APIPermission::kSystemStorage, "system.storage"},
{APIPermission::kU2fDevices, "u2fDevices"}, {APIPermission::kU2fDevices, "u2fDevices"},
{APIPermission::kUnlimitedStorage, "unlimitedStorage", {APIPermission::kUnlimitedStorage, "unlimitedStorage",
......
...@@ -14414,6 +14414,7 @@ Called by update_net_error_codes.py.--> ...@@ -14414,6 +14414,7 @@ Called by update_net_error_codes.py.-->
<int value="421" <int value="421"
label="ACCESSIBILITY_PRIVATE_ON_SELECT_TO_SPEAK_STATE_CHANGE_REQUESTED"/> label="ACCESSIBILITY_PRIVATE_ON_SELECT_TO_SPEAK_STATE_CHANGE_REQUESTED"/>
<int value="422" label="INPUT_METHOD_PRIVATE_ON_FOCUS"/> <int value="422" label="INPUT_METHOD_PRIVATE_ON_FOCUS"/>
<int value="423" label="SYSTEM_POWER_SOURCE_ONPOWERCHANGED"/>
</enum> </enum>
<enum name="ExtensionFileWriteResult"> <enum name="ExtensionFileWriteResult">
...@@ -15727,6 +15728,8 @@ Called by update_net_error_codes.py.--> ...@@ -15727,6 +15728,8 @@ Called by update_net_error_codes.py.-->
<int value="1256" label="USERSPRIVATE_GETCURRENTUSER"/> <int value="1256" label="USERSPRIVATE_GETCURRENTUSER"/>
<int value="1257" label="WALLPAPERPRIVATE_GETSURPRISEMEIMAGE"/> <int value="1257" label="WALLPAPERPRIVATE_GETSURPRISEMEIMAGE"/>
<int value="1258" label="VIRTUALKEYBOARDPRIVATE_SETOCCLUDEDBOUNDS"/> <int value="1258" label="VIRTUALKEYBOARDPRIVATE_SETOCCLUDEDBOUNDS"/>
<int value="1259" label="SYSTEM_POWER_SOURCE_GETPOWERSOURCEINFO"/>
<int value="1260" label="SYSTEM_POWER_SOURCE_REQUESTSTATUSUPDATE"/>
</enum> </enum>
<enum name="ExtensionIconState"> <enum name="ExtensionIconState">
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment