diff options
author | michaelpg <michaelpg@chromium.org> | 2015-12-10 22:16:59 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-12-11 06:18:01 +0000 |
commit | 7dc48c4c43099b3c1f26404fdbb04b3b7911c54c (patch) | |
tree | de297940de81deecf8e64f274d1dba1adb6582bb | |
parent | 303f0cee736c07826eb4783680119189a2a90125 (diff) | |
download | chromium_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}
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_; |