summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormichaelpg <michaelpg@chromium.org>2015-12-10 22:16:59 -0800
committerCommit bot <commit-bot@chromium.org>2015-12-11 06:18:01 +0000
commit7dc48c4c43099b3c1f26404fdbb04b3b7911c54c (patch)
treede297940de81deecf8e64f274d1dba1adb6582bb
parent303f0cee736c07826eb4783680119189a2a90125 (diff)
downloadchromium_src-7dc48c4c43099b3c1f26404fdbb04b3b7911c54c.zip
chromium_src-7dc48c4c43099b3c1f26404fdbb04b3b7911c54c.tar.gz
chromium_src-7dc48c4c43099b3c1f26404fdbb04b3b7911c54c.tar.bz2
Add power sources in Device Emulator battery settings
This lets us add fake power sources (A/C adapters, USB adapters, USB TYpe-C devices) for manually testing power UI. BUG=547260 Review URL: https://codereview.chromium.org/1505403002 Cr-Commit-Position: refs/heads/master@{#364631}
-rw-r--r--chrome/browser/resources/chromeos/emulator/battery_settings.html49
-rw-r--r--chrome/browser/resources/chromeos/emulator/battery_settings.js87
-rw-r--r--chrome/browser/resources/chromeos/emulator/shared_styles.css4
-rw-r--r--chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc98
-rw-r--r--chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.h2
-rw-r--r--chromeos/dbus/fake_power_manager_client.cc22
6 files changed, 210 insertions, 52 deletions
diff --git a/chrome/browser/resources/chromeos/emulator/battery_settings.html b/chrome/browser/resources/chromeos/emulator/battery_settings.html
index 6ed0b1a..06369d1 100644
--- a/chrome/browser/resources/chromeos/emulator/battery_settings.html
+++ b/chrome/browser/resources/chromeos/emulator/battery_settings.html
@@ -3,8 +3,11 @@
<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/device-icons.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-dropdown-menu/paper-dropdown-menu.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-menu/paper-menu.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-group/paper-radio-group.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-button/paper-radio-button.html">
@@ -18,15 +21,6 @@
<span>[[title]]</span>
</div>
<label>
- <span class="form-label">External power</span>
- <paper-radio-group selected="{{externalPower}}">
- <template is="dom-repeat" items="[[externalPowerOptions]]">
- <paper-radio-button name="[[item]]">[[item]]</paper-radio-button>
- </template>
- </paper-radio-group>
- </label>
-
- <label>
<span class="form-label">Battery state</span>
<paper-radio-group selected="{{batteryState}}">
<template is="dom-repeat" items="[[batteryStateOptions]]">
@@ -49,6 +43,43 @@
</paper-input>
</div>
</iron-collapse>
+
+ <table class="devices-table">
+ <tbody>
+ <tr class="table-section-header">
+ <td>Power sources</td>
+ <td class="centered-cell-label">Connected</td>
+ <td class="centered-cell-label">Role</td>
+ <td class="centered-cell-label">Amps</td>
+ </tr>
+ <template is="dom-repeat" items="{{powerSourceOptions}}">
+ <tr>
+ <td class="alias-cell">[[item.name]]</td>
+ <td class="control-cell">
+ <paper-checkbox checked="{{item.connected}}"></paper-checkbox>
+ </td>
+ <td class="control-cell">
+ <paper-button on-tap="onSetAsSourceTap"
+ hidden$="[[!isDualRole(item)]]"
+ raised="[[!isSelectedSource(item, selectedPowerSourceId)]]"
+ disabled="[[!canBecomeSource(item, selectedPowerSourceId, powerSourceOptions.*)]]">
+ Set as source
+ </paper-button>
+ <div hidden$="[[isDualRole(item)]]">Source</div>
+ </td>
+ <td class="control-cell">
+ <paper-dropdown-menu class="device-class-group"
+ disabled="[[!item.variablePower]]">
+ <paper-menu selected="{{item.power}}"
+ class="dropdown-content" attr-for-selected="data-value">
+ <paper-item data-value="high">High</paper-item>
+ <paper-item data-value="low">Low</paper-item>
+ </paper-menu>
+ </paper-dropdown-menu>
+ </td>
+ </template>
+ </tbody>
+ </table>
</div>
</template>
<script src="battery_settings.js"></script>
diff --git a/chrome/browser/resources/chromeos/emulator/battery_settings.js b/chrome/browser/resources/chromeos/emulator/battery_settings.js
index 79b8d41..2e3b8ce 100644
--- a/chrome/browser/resources/chromeos/emulator/battery_settings.js
+++ b/chrome/browser/resources/chromeos/emulator/battery_settings.js
@@ -31,25 +31,39 @@ var BatterySettings = Polymer({
},
/**
- * A string representing a value in the
- * PowerSupplyProperties_ExternalPower enumeration.
+ * Example charging devices that can be connected. Chargers are split
+ * between dedicated chargers (which will always provide power if no
+ * higher-power dedicated charger is connected) and dual-role USB chargers
+ * (which only provide power if configured as a source and no dedicated
+ * charger is connected).
*/
- externalPower: {
- type: String,
- observer: 'externalPowerChanged',
- },
-
- /**
- * An array representing the external power options.
- * The names are ordered based on the
- * PowerSupplyProperties_ExternalPower enumeration. These values must be
- * in sync.
- */
- externalPowerOptions: {
+ powerSourceOptions: {
type: Array,
- value: function() { return ['AC', 'USB (Low Power)', 'Disconnected']; }
+ value: function() {
+ return [
+ {id: '0', name: 'AC Charger 1', type: 'DedicatedCharger',
+ port: 0, connected: false, power: 'high'},
+ {id: '1', name: 'AC Charger 2', type: 'DedicatedCharger',
+ port: 1, connected: false, power: 'high'},
+ {id: '2', name: 'USB Charger 1', type: 'DedicatedCharger',
+ port: 2, connected: false, power: 'low', variablePower: true},
+ {id: '3', name: 'USB Charger 2', type: 'DedicatedCharger',
+ port: 3, connected: false, power: 'low', variablePower: true},
+ {id: '4', name: 'Dual-role USB 1', type: 'DualRoleUSB',
+ port: 4, connected: false, power: 'low'},
+ {id: '5', name: 'Dual-role USB 2', type: 'DualRoleUSB',
+ port: 5, connected: false, power: 'low'},
+ {id: '6', name: 'Dual-role USB 3', type: 'DualRoleUSB',
+ port: 6, connected: false, power: 'low'},
+ {id: '7', name: 'Dual-role USB 4', type: 'DualRoleUSB',
+ port: 7, connected: false, power: 'low'},
+ ];
+ },
},
+ /** The ID of the current power source, or the empty string. */
+ selectedPowerSourceId: String,
+
/** A string representing the time left until the battery is discharged. */
timeUntilEmpty: String,
@@ -63,6 +77,10 @@ var BatterySettings = Polymer({
},
},
+ observers: [
+ 'powerSourcesChanged(powerSourceOptions.*)',
+ ],
+
initialize: function() {
if (!this.initialized) {
chrome.send('requestPowerInfo');
@@ -76,6 +94,10 @@ var BatterySettings = Polymer({
chrome.send('updateBatteryPercent', [this.percent]);
},
+ onSetAsSourceTap: function(e) {
+ chrome.send('updatePowerSourceId', [e.model.item.id]);
+ },
+
batteryStateChanged: function(batteryState) {
// Find the index of the selected battery state.
var index = this.batteryStateOptions.indexOf(batteryState);
@@ -84,12 +106,12 @@ var BatterySettings = Polymer({
chrome.send('updateBatteryState', [index]);
},
- externalPowerChanged: function(externalPower) {
- // Find the index of the selected power source.
- var index = this.externalPowerOptions.indexOf(externalPower);
- if (index < 0)
- return;
- chrome.send('updateExternalPower', [index]);
+ powerSourcesChanged: function() {
+ var connectedPowerSources =
+ this.powerSourceOptions.filter(function(source) {
+ return source.connected;
+ });
+ chrome.send('updatePowerSources', [connectedPowerSources]);
},
onTimeUntilEmptyChange: function(e) {
@@ -108,13 +130,32 @@ var BatterySettings = Polymer({
this.batteryPercent = power_properties.battery_percent;
this.batteryState =
this.batteryStateOptions[power_properties.battery_state];
- this.externalPower =
- this.externalPowerOptions[power_properties.external_power];
this.timeUntilEmpty = power_properties.battery_time_to_empty_sec;
this.timeUntilFull = power_properties.battery_time_to_full_sec;
+ this.selectedPowerSourceId = power_properties.external_power_source_id;
},
isBatteryPresent: function() {
return this.batteryState != 'Not Present';
},
+
+ isDualRole: function(source) {
+ return source.type == 'DualRoleUSB';
+ },
+
+ isSelectedSource: function(source) {
+ return source.id == this.selectedPowerSourceId;
+ },
+
+ canAmpsChange: function(type) {
+ return type == 'USB';
+ },
+
+ canBecomeSource: function(source, selectedId, powerSourceOptionsChange) {
+ if (!source.connected || !this.isDualRole(source))
+ return false;
+ return !this.powerSourceOptions.some(function(source) {
+ return source.connected && source.type == 'DedicatedCharger';
+ });
+ },
});
diff --git a/chrome/browser/resources/chromeos/emulator/shared_styles.css b/chrome/browser/resources/chromeos/emulator/shared_styles.css
index 4cab8cd..265a69b 100644
--- a/chrome/browser/resources/chromeos/emulator/shared_styles.css
+++ b/chrome/browser/resources/chromeos/emulator/shared_styles.css
@@ -122,3 +122,7 @@ paper-radio-button {
color: rgb(82, 101, 162);
width: 200px;
}
+
+[hidden] {
+ display: none !important;
+}
diff --git a/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc b/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc
index e039325..d4eebc7 100644
--- a/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc
@@ -35,9 +35,10 @@ const char kRemoveAudioNode[] = "removeAudioNode";
const char kRemoveBluetoothDevice[] = "removeBluetoothDevice";
const char kUpdateBatteryPercent[] = "updateBatteryPercent";
const char kUpdateBatteryState[] = "updateBatteryState";
-const char kUpdateExternalPower[] = "updateExternalPower";
const char kUpdateTimeToEmpty[] = "updateTimeToEmpty";
const char kUpdateTimeToFull[] = "updateTimeToFull";
+const char kUpdatePowerSources[] = "updatePowerSources";
+const char kUpdatePowerSourceId[] = "updatePowerSourceId";
// Define callback functions that will update the JavaScript variable
// and the web UI.
@@ -58,6 +59,10 @@ const char kUpdatePowerPropertiesJSCallback[] =
const char kPairedPropertyName[] = "Paired";
+// Wattages to use as max power for power sources.
+const double kPowerLevelHigh = 50;
+const double kPowerLevelLow = 2;
+
} // namespace
namespace chromeos {
@@ -172,9 +177,11 @@ void DeviceEmulatorMessageHandler::PowerObserver::PowerChanged(
proto.battery_time_to_empty_sec());
power_properties.SetInteger("battery_time_to_full_sec",
proto.battery_time_to_full_sec());
+ power_properties.SetString("external_power_source_id",
+ proto.external_power_source_id());
owner_->web_ui()->CallJavascriptFunction(kUpdatePowerPropertiesJSCallback,
- power_properties);
+ power_properties);
}
DeviceEmulatorMessageHandler::DeviceEmulatorMessageHandler()
@@ -349,19 +356,6 @@ void DeviceEmulatorMessageHandler::UpdateBatteryState(
}
}
-void DeviceEmulatorMessageHandler::UpdateExternalPower(
- const base::ListValue* args) {
- int power_source;
- if (args->GetInteger(0, &power_source)) {
- power_manager::PowerSupplyProperties props =
- fake_power_manager_client_->props();
- props.set_external_power(
- static_cast<power_manager::PowerSupplyProperties_ExternalPower>(
- power_source));
- fake_power_manager_client_->UpdatePowerProperties(props);
- }
-}
-
void DeviceEmulatorMessageHandler::UpdateTimeToEmpty(
const base::ListValue* args) {
int new_time;
@@ -384,6 +378,68 @@ void DeviceEmulatorMessageHandler::UpdateTimeToFull(
}
}
+void DeviceEmulatorMessageHandler::UpdatePowerSources(
+ const base::ListValue* args) {
+ const base::ListValue* sources;
+ CHECK(args->GetList(0, &sources));
+ power_manager::PowerSupplyProperties props =
+ fake_power_manager_client_->props();
+
+ std::string selected_id = props.external_power_source_id();
+
+ props.clear_available_external_power_source();
+ props.set_external_power_source_id("");
+
+ // Try to find the previously selected source in the list.
+ const power_manager::PowerSupplyProperties_PowerSource* selected_source =
+ nullptr;
+ for (const auto& val : *sources) {
+ const base::DictionaryValue* dict;
+ CHECK(val->GetAsDictionary(&dict));
+ power_manager::PowerSupplyProperties_PowerSource* source =
+ props.add_available_external_power_source();
+ std::string id;
+ CHECK(dict->GetString("id", &id));
+ source->set_id(id);
+ std::string device_type;
+ CHECK(dict->GetString("type", &device_type));
+ source->set_active_by_default(device_type == "DedicatedCharger");
+ int port;
+ CHECK(dict->GetInteger("port", &port));
+ source->set_port(
+ static_cast<power_manager::PowerSupplyProperties_PowerSource_Port>(
+ port));
+ std::string power_level;
+ CHECK(dict->GetString("power", &power_level));
+ source->set_max_power(
+ power_level == "high" ? kPowerLevelHigh : kPowerLevelLow);
+ if (id == selected_id)
+ selected_source = source;
+ }
+
+ // Emulate the device's source selection process.
+ for (const auto& source : props.available_external_power_source()) {
+ if (!source.active_by_default())
+ continue;
+ if (selected_source && selected_source->active_by_default() &&
+ source.max_power() < selected_source->max_power()) {
+ continue;
+ }
+ selected_source = &source;
+ }
+
+ fake_power_manager_client_->UpdatePowerProperties(props);
+ fake_power_manager_client_->SetPowerSource(
+ selected_source ? selected_source->id() : "");
+}
+
+void DeviceEmulatorMessageHandler::UpdatePowerSourceId(
+ const base::ListValue* args) {
+ std::string id;
+ CHECK(args->GetString(0, &id));
+ fake_power_manager_client_->SetPowerSource(id);
+}
+
void DeviceEmulatorMessageHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
kRequestPowerInfo,
@@ -398,10 +454,6 @@ void DeviceEmulatorMessageHandler::RegisterMessages() {
base::Bind(&DeviceEmulatorMessageHandler::UpdateBatteryState,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
- kUpdateExternalPower,
- base::Bind(&DeviceEmulatorMessageHandler::UpdateExternalPower,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback(
kUpdateTimeToEmpty,
base::Bind(&DeviceEmulatorMessageHandler::UpdateTimeToEmpty,
base::Unretained(this)));
@@ -410,6 +462,14 @@ void DeviceEmulatorMessageHandler::RegisterMessages() {
base::Bind(&DeviceEmulatorMessageHandler::UpdateTimeToFull,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
+ kUpdatePowerSources,
+ base::Bind(&DeviceEmulatorMessageHandler::UpdatePowerSources,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ kUpdatePowerSourceId,
+ base::Bind(&DeviceEmulatorMessageHandler::UpdatePowerSourceId,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
kRequestAudioNodes,
base::Bind(&DeviceEmulatorMessageHandler::HandleRequestAudioNodes,
base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.h b/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.h
index 882af77..a6d5224 100644
--- a/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.h
+++ b/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.h
@@ -77,6 +77,8 @@ class DeviceEmulatorMessageHandler
void UpdateExternalPower(const base::ListValue* args);
void UpdateTimeToEmpty(const base::ListValue* args);
void UpdateTimeToFull(const base::ListValue* args);
+ void UpdatePowerSources(const base::ListValue* args);
+ void UpdatePowerSourceId(const base::ListValue* args);
// content::WebUIMessageHandler:
void RegisterMessages() override;
diff --git a/chromeos/dbus/fake_power_manager_client.cc b/chromeos/dbus/fake_power_manager_client.cc
index 9db2303..c34ab35 100644
--- a/chromeos/dbus/fake_power_manager_client.cc
+++ b/chromeos/dbus/fake_power_manager_client.cc
@@ -12,6 +12,11 @@
namespace chromeos {
+namespace {
+// Minimum power for a USB power source to be classified as AC.
+const double kUsbMinAcWatts = 24;
+}
+
FakePowerManagerClient::FakePowerManagerClient()
: num_request_restart_calls_(0),
num_request_shutdown_calls_(0),
@@ -111,7 +116,22 @@ void FakePowerManagerClient::SetIsProjecting(bool is_projecting) {
is_projecting_ = is_projecting;
}
-void FakePowerManagerClient::SetPowerSource(const std::string& id) {}
+void FakePowerManagerClient::SetPowerSource(const std::string& id) {
+ props_.set_external_power_source_id(id);
+ props_.set_external_power(
+ power_manager::PowerSupplyProperties_ExternalPower_DISCONNECTED);
+ for (const auto& source : props_.available_external_power_source()) {
+ if (source.id() == id) {
+ props_.set_external_power(
+ !source.active_by_default() || source.max_power() < kUsbMinAcWatts
+ ? power_manager::PowerSupplyProperties_ExternalPower_USB
+ : power_manager::PowerSupplyProperties_ExternalPower_AC);
+ break;
+ }
+ }
+
+ NotifyObservers();
+}
base::Closure FakePowerManagerClient::GetSuspendReadinessCallback() {
++num_pending_suspend_readiness_callbacks_;