diff options
author | michaelpg <michaelpg@chromium.org> | 2015-12-15 13:49:10 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-12-15 21:50:12 +0000 |
commit | 0206373766b7ada80bd6425f9898b84184edc29c (patch) | |
tree | 76fb1800b05ccf660679467a3af4719b14f41bcd /ash | |
parent | cdd01a22e40c8be8ac61eb7c0ec2d84c59bc509f (diff) | |
download | chromium_src-0206373766b7ada80bd6425f9898b84184edc29c.zip chromium_src-0206373766b7ada80bd6425f9898b84184edc29c.tar.gz chromium_src-0206373766b7ada80bd6425f9898b84184edc29c.tar.bz2 |
Show a notification when dual-role devices are connected.
The notification informs the user whether a connected dual-role
device is being used as a power source, or which dual-role devices
this device is charging. It has minimal priority (doesn't toast). It
opens the power settings when clicked.
When the device is using a dedicated charger, the notification
doesn't appear (because we don't override dedicated chargers).
1-pager: https://docs.google.com/document/d/1UPYK_VIhtcBTZgyjfe4ogszqtOdVqmSOXxUTQ28GpJQ/edit#
To test, use chrome://device-emulator in Debug builds.
BUG=547260
Review URL: https://codereview.chromium.org/1515493004
Cr-Commit-Position: refs/heads/master@{#365345}
Diffstat (limited to 'ash')
-rw-r--r-- | ash/ash.gyp | 2 | ||||
-rw-r--r-- | ash/ash_chromeos_strings.grdp | 12 | ||||
-rw-r--r-- | ash/system/chromeos/power/dual_role_notification.cc | 157 | ||||
-rw-r--r-- | ash/system/chromeos/power/dual_role_notification.h | 44 | ||||
-rw-r--r-- | ash/system/chromeos/power/tray_power.cc | 14 | ||||
-rw-r--r-- | ash/system/chromeos/power/tray_power.h | 7 | ||||
-rw-r--r-- | ash/system/chromeos/power/tray_power_unittest.cc | 117 | ||||
-rw-r--r-- | ash/system/system_notifier.cc | 1 | ||||
-rw-r--r-- | ash/system/system_notifier.h | 1 | ||||
-rw-r--r-- | ash/system/tray/system_tray_delegate.cc | 2 | ||||
-rw-r--r-- | ash/system/tray/system_tray_delegate.h | 3 |
11 files changed, 358 insertions, 2 deletions
diff --git a/ash/ash.gyp b/ash/ash.gyp index 1dd7430..f6201bd 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp @@ -326,6 +326,8 @@ 'system/chromeos/network/vpn_list_view.h', 'system/chromeos/power/battery_notification.cc', 'system/chromeos/power/battery_notification.h', + 'system/chromeos/power/dual_role_notification.cc', + 'system/chromeos/power/dual_role_notification.h', 'system/chromeos/power/power_event_observer.cc', 'system/chromeos/power/power_event_observer.h', 'system/chromeos/power/power_status.cc', diff --git a/ash/ash_chromeos_strings.grdp b/ash/ash_chromeos_strings.grdp index 639c698..ce7e6e4 100644 --- a/ash/ash_chromeos_strings.grdp +++ b/ash/ash_chromeos_strings.grdp @@ -30,6 +30,18 @@ <message name="IDS_ASH_STATUS_TRAY_LOW_POWER_CHARGER_MESSAGE_SHORT" desc="The message body of a notification indicating that a low-current USB charger has been connected, short version."> Your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> may not charge while it is turned on. </message> + <message name="IDS_ASH_STATUS_TRAY_CHARGING_FROM_DUAL_ROLE_TITLE" desc="The message title of a notification indicating that the device is being charged by a connected dual-role USB Type-C device."> + Charging from <ph name="POWER_SOURCE">$1<ex>USB-C device (left port)</ex></ph> + </message> + <message name="IDS_ASH_STATUS_TRAY_CHARGING_DUAL_ROLE_DEVICE_TITLE" desc="The message title of a notification indicating that the device is charging the connected USB Type-C device."> + Charging <ph name="POWER_SOURCE">$1<ex>USB-C device (left port)</ex></ph> + </message> + <message name="IDS_ASH_STATUS_TRAY_CHARGING_DUAL_ROLE_DEVICES_TITLE" desc="The message title of a notification indicating that the device is charging multiple connected USB Type-C devices."> + Charging connected USB-C devices + </message> + <message name="IDS_ASH_STATUS_TRAY_DUAL_ROLE_MESSAGE" desc="The message body of a notification, which indicates that the user can click the notification to see and change which device is being used as a power source."> + Click for more options + </message> <message name="IDS_ASH_POWER_SOURCE_PORT_LEFT" desc="The text identifying an external device, when that device is connected to the USB Type-C port on the left side of this device."> USB-C device (left port) </message> diff --git a/ash/system/chromeos/power/dual_role_notification.cc b/ash/system/chromeos/power/dual_role_notification.cc new file mode 100644 index 0000000..0c5cda0 --- /dev/null +++ b/ash/system/chromeos/power/dual_role_notification.cc @@ -0,0 +1,157 @@ +// Copyright 2015 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 "ash/system/chromeos/power/dual_role_notification.h" + +#include <set> + +#include "ash/shell.h" +#include "ash/system/chromeos/power/power_status.h" +#include "ash/system/system_notifier.h" +#include "ash/system/tray/system_tray_delegate.h" +#include "base/strings/utf_string_conversions.h" +#include "grit/ash_resources.h" +#include "grit/ash_strings.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/l10n/time_format.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/image/image.h" +#include "ui/message_center/message_center.h" +#include "ui/message_center/notification.h" +#include "ui/message_center/notification_delegate.h" + +using message_center::MessageCenter; +using message_center::Notification; + +namespace ash { +namespace { + +const char kDualRoleNotificationId[] = "dual-role"; + +// Opens power settings on click. +class DualRoleNotificationDelegate + : public message_center::NotificationDelegate { + public: + DualRoleNotificationDelegate() {} + + // Overridden from message_center::NotificationDelegate. + void Click() override { + Shell::GetInstance()->system_tray_delegate()->ShowPowerSettings(); + } + + private: + ~DualRoleNotificationDelegate() override {} + + DISALLOW_COPY_AND_ASSIGN(DualRoleNotificationDelegate); +}; + +} // namespace + +DualRoleNotification::DualRoleNotification(MessageCenter* message_center) + : message_center_(message_center), + num_dual_role_sinks_(0), + line_power_connected_(false) {} + +DualRoleNotification::~DualRoleNotification() { + if (message_center_->FindVisibleNotificationById(kDualRoleNotificationId)) + message_center_->RemoveNotification(kDualRoleNotificationId, false); +} + +void DualRoleNotification::Update() { + const PowerStatus& status = *PowerStatus::Get(); + DCHECK(status.HasDualRoleDevices()); + + std::string current_power_source_id = status.GetCurrentPowerSourceID(); + + scoped_ptr<PowerStatus::PowerSource> new_source; + scoped_ptr<PowerStatus::PowerSource> new_sink; + size_t num_sinks_found = 0; + for (const auto& source : status.GetPowerSources()) { + // The power source can't be changed if there's a dedicated charger. + if (source.type == PowerStatus::DEDICATED_CHARGER) { + dual_role_source_.reset(); + line_power_connected_ = true; + if (message_center_->FindVisibleNotificationById(kDualRoleNotificationId)) + message_center_->RemoveNotification(kDualRoleNotificationId, false); + return; + } + + if (source.id == current_power_source_id) { + new_source.reset(new PowerStatus::PowerSource(source)); + continue; + } + num_sinks_found++; + // The notification only shows the sink port if it is the only sink. + if (num_sinks_found == 1) + new_sink.reset(new PowerStatus::PowerSource(source)); + else + new_sink.reset(); + } + + // Check if the notification should change. + bool change = false; + if (PowerStatus::Get()->IsLinePowerConnected() != line_power_connected_) { + change = true; + line_power_connected_ = PowerStatus::Get()->IsLinePowerConnected(); + } else if (new_source && dual_role_source_) { + if (new_source->description_id != dual_role_source_->description_id) + change = true; + } else if (new_source || dual_role_source_) { + change = true; + } else { + // Notification differs for 0, 1, and 2+ sinks. + if ((num_sinks_found < num_dual_role_sinks_ && num_sinks_found < 2) || + (num_sinks_found > num_dual_role_sinks_ && num_dual_role_sinks_ < 2)) { + change = true; + } else if (num_sinks_found == 1) { + // The description matters if there's only one dual-role device. + change = new_sink->description_id != dual_role_sink_->description_id; + } + } + + dual_role_source_ = std::move(new_source); + dual_role_sink_ = std::move(new_sink); + num_dual_role_sinks_ = num_sinks_found; + + if (!change) + return; + + if (!message_center_->FindVisibleNotificationById(kDualRoleNotificationId)) { + message_center_->AddNotification(CreateNotification()); + } else { + message_center_->UpdateNotification(kDualRoleNotificationId, + CreateNotification()); + } +} + +scoped_ptr<Notification> DualRoleNotification::CreateNotification() { + base::string16 title; + if (dual_role_source_) { + title = l10n_util::GetStringFUTF16( + IDS_ASH_STATUS_TRAY_CHARGING_FROM_DUAL_ROLE_TITLE, + l10n_util::GetStringUTF16(dual_role_source_->description_id)); + } else if (num_dual_role_sinks_ == 1) { + title = l10n_util::GetStringFUTF16( + IDS_ASH_STATUS_TRAY_CHARGING_DUAL_ROLE_DEVICE_TITLE, + l10n_util::GetStringUTF16(dual_role_sink_->description_id)); + } else { + title = l10n_util::GetStringUTF16( + IDS_ASH_STATUS_TRAY_CHARGING_DUAL_ROLE_DEVICES_TITLE); + } + + scoped_ptr<Notification> notification(new Notification( + message_center::NOTIFICATION_TYPE_SIMPLE, kDualRoleNotificationId, title, + l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_DUAL_ROLE_MESSAGE), + ui::ResourceBundle::GetSharedInstance().GetImageNamed( + IDR_AURA_NOTIFICATION_LOW_POWER_CHARGER), + base::string16(), GURL(), + message_center::NotifierId(message_center::NotifierId::SYSTEM_COMPONENT, + system_notifier::kNotifierDualRole), + message_center::RichNotificationData(), + new DualRoleNotificationDelegate)); + notification->set_priority(message_center::MIN_PRIORITY); + return notification; +} + +} // namespace ash diff --git a/ash/system/chromeos/power/dual_role_notification.h b/ash/system/chromeos/power/dual_role_notification.h new file mode 100644 index 0000000..d49ec08 --- /dev/null +++ b/ash/system/chromeos/power/dual_role_notification.h @@ -0,0 +1,44 @@ +// Copyright 2015 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 ASH_SYSTEM_CHROMEOS_POWER_DUAL_ROLE_NOTIFICATION_H_ +#define ASH_SYSTEM_CHROMEOS_POWER_DUAL_ROLE_NOTIFICATION_H_ + +#include "ash/ash_export.h" +#include "ash/system/chromeos/power/power_status.h" +#include "base/memory/scoped_ptr.h" + +namespace message_center { +class MessageCenter; +class Notification; +} + +namespace ash { + +// Shows a non-toasting MessageCenter notification based on what dual-role +// devices are connected. +class ASH_EXPORT DualRoleNotification { + public: + explicit DualRoleNotification(message_center::MessageCenter* message_center); + ~DualRoleNotification(); + + // Creates or updates the notification. + void Update(); + + private: + // Creates the notification using the updated status. + scoped_ptr<message_center::Notification> CreateNotification(); + + message_center::MessageCenter* message_center_; + scoped_ptr<PowerStatus::PowerSource> dual_role_source_; + scoped_ptr<PowerStatus::PowerSource> dual_role_sink_; + size_t num_dual_role_sinks_; + bool line_power_connected_; + + DISALLOW_COPY_AND_ASSIGN(DualRoleNotification); +}; + +} // namespace ash + +#endif // ASH_SYSTEM_CHROMEOS_POWER_DUAL_ROLE_NOTIFICATION_H_ diff --git a/ash/system/chromeos/power/tray_power.cc b/ash/system/chromeos/power/tray_power.cc index 1ca6dc7..a23b52a 100644 --- a/ash/system/chromeos/power/tray_power.cc +++ b/ash/system/chromeos/power/tray_power.cc @@ -9,6 +9,7 @@ #include "ash/shell.h" #include "ash/system/chromeos/devicetype_utils.h" #include "ash/system/chromeos/power/battery_notification.h" +#include "ash/system/chromeos/power/dual_role_notification.h" #include "ash/system/date/date_view.h" #include "ash/system/system_notifier.h" #include "ash/system/tray/system_tray_delegate.h" @@ -190,6 +191,7 @@ void TrayPower::OnPowerStatusChanged() { return; MaybeShowUsbChargerNotification(); + MaybeShowDualRoleNotification(); if (battery_alert) { // Remove any existing notification so it's dismissed before adding a new @@ -241,6 +243,18 @@ bool TrayPower::MaybeShowUsbChargerNotification() { return false; } +void TrayPower::MaybeShowDualRoleNotification() { + const PowerStatus& status = *PowerStatus::Get(); + if (!status.HasDualRoleDevices()) { + dual_role_notification_.reset(); + return; + } + + if (!dual_role_notification_) + dual_role_notification_.reset(new DualRoleNotification(message_center_)); + dual_role_notification_->Update(); +} + bool TrayPower::UpdateNotificationState() { const PowerStatus& status = *PowerStatus::Get(); if (!status.IsBatteryPresent() || diff --git a/ash/system/chromeos/power/tray_power.h b/ash/system/chromeos/power/tray_power.h index d88bb29..2c84658 100644 --- a/ash/system/chromeos/power/tray_power.h +++ b/ash/system/chromeos/power/tray_power.h @@ -22,6 +22,7 @@ class MessageCenter; namespace ash { class BatteryNotification; +class DualRoleNotification; namespace tray { class PowerTrayView; @@ -83,10 +84,13 @@ class ASH_EXPORT TrayPower : public SystemTrayItem, // Overridden from PowerStatus::Observer. void OnPowerStatusChanged() override; - // Show a notification that a low-power USB charger has been connected. + // Shows a notification that a low-power USB charger has been connected. // Returns true if a notification was shown or explicitly hidden. bool MaybeShowUsbChargerNotification(); + // Shows a notification when dual-role devices are connected. + void MaybeShowDualRoleNotification(); + // Sets |notification_state_|. Returns true if a notification should be shown. bool UpdateNotificationState(); bool UpdateNotificationStateForRemainingTime(); @@ -95,6 +99,7 @@ class ASH_EXPORT TrayPower : public SystemTrayItem, message_center::MessageCenter* message_center_; // Not owned. tray::PowerTrayView* power_tray_; scoped_ptr<BatteryNotification> battery_notification_; + scoped_ptr<DualRoleNotification> dual_role_notification_; NotificationState notification_state_; // Was a USB charger connected the last time OnPowerStatusChanged() was diff --git a/ash/system/chromeos/power/tray_power_unittest.cc b/ash/system/chromeos/power/tray_power_unittest.cc index d0b9705..352cae5 100644 --- a/ash/system/chromeos/power/tray_power_unittest.cc +++ b/ash/system/chromeos/power/tray_power_unittest.cc @@ -20,11 +20,12 @@ namespace { class MockMessageCenter : public message_center::FakeMessageCenter { public: - MockMessageCenter() : add_count_(0), remove_count_(0) {} + MockMessageCenter() : add_count_(0), remove_count_(0), update_count_(0) {} ~MockMessageCenter() override {} int add_count() const { return add_count_; } int remove_count() const { return remove_count_; } + int update_count() const { return update_count_; } // message_center::FakeMessageCenter overrides: void AddNotification(scoped_ptr<Notification> notification) override { @@ -39,6 +40,15 @@ class MockMessageCenter : public message_center::FakeMessageCenter { remove_count_++; notifications_.erase(id); } + void UpdateNotification(const std::string& id, + scoped_ptr<Notification> new_notification) override { + update_count_++; + Notification* notification = FindVisibleNotificationById(id); + if (notification) + notifications_.erase(id); + notifications_.insert( + std::make_pair(new_notification->id(), std::move(new_notification))); + } Notification* FindVisibleNotificationById(const std::string& id) override { auto it = notifications_.find(id); @@ -48,6 +58,7 @@ class MockMessageCenter : public message_center::FakeMessageCenter { private: int add_count_; int remove_count_; + int update_count_; std::map<std::string, scoped_ptr<Notification>> notifications_; DISALLOW_COPY_AND_ASSIGN(MockMessageCenter); @@ -87,6 +98,11 @@ class TrayPowerTest : public test::AshTestBase { return tray_power_->MaybeShowUsbChargerNotification(); } + void MaybeShowDualRoleNotification(const PowerSupplyProperties& proto) { + PowerStatus::Get()->SetProtoForTesting(proto); + tray_power_->MaybeShowDualRoleNotification(); + } + void UpdateNotificationState(const PowerSupplyProperties& proto, TrayPower::NotificationState expected_state, bool expected_add, @@ -199,6 +215,105 @@ TEST_F(TrayPowerTest, MaybeShowUsbChargerNotification) { SetUsbChargerConnected(true); } +TEST_F(TrayPowerTest, MaybeShowDualRoleNotification) { + PowerSupplyProperties discharging = DefaultPowerSupplyProperties(); + discharging.set_supports_dual_role_devices(true); + MaybeShowDualRoleNotification(discharging); + EXPECT_EQ(0, message_center()->add_count()); + EXPECT_EQ(0, message_center()->update_count()); + EXPECT_EQ(0, message_center()->remove_count()); + + // Notification shows when connecting a dual-role device. + PowerSupplyProperties dual_role = DefaultPowerSupplyProperties(); + dual_role.set_supports_dual_role_devices(true); + power_manager::PowerSupplyProperties_PowerSource* source = + dual_role.add_available_external_power_source(); + source->set_id("dual-role1"); + source->set_active_by_default(false); + MaybeShowDualRoleNotification(dual_role); + EXPECT_EQ(1, message_center()->add_count()); + EXPECT_EQ(0, message_center()->update_count()); + EXPECT_EQ(0, message_center()->remove_count()); + + // Connecting another dual-role device updates the notification to be plural. + source = dual_role.add_available_external_power_source(); + source->set_id("dual-role2"); + source->set_active_by_default(false); + MaybeShowDualRoleNotification(dual_role); + EXPECT_EQ(1, message_center()->add_count()); + EXPECT_EQ(1, message_center()->update_count()); + EXPECT_EQ(0, message_center()->remove_count()); + + // Connecting a 3rd dual-role device doesn't affect the notification. + source = dual_role.add_available_external_power_source(); + source->set_id("dual-role3"); + source->set_active_by_default(false); + MaybeShowDualRoleNotification(dual_role); + EXPECT_EQ(1, message_center()->add_count()); + EXPECT_EQ(1, message_center()->update_count()); + EXPECT_EQ(0, message_center()->remove_count()); + + // Connecting a legacy USB device removes the notification. + PowerSupplyProperties legacy(dual_role); + power_manager::PowerSupplyProperties_PowerSource* legacy_source = + legacy.add_available_external_power_source(); + legacy_source->set_id("legacy"); + legacy_source->set_active_by_default(true); + legacy.set_external_power_source_id("legacy"); + legacy.set_external_power( + power_manager::PowerSupplyProperties_ExternalPower_USB); + MaybeShowDualRoleNotification(legacy); + EXPECT_EQ(1, message_center()->add_count()); + EXPECT_EQ(1, message_center()->update_count()); + EXPECT_EQ(1, message_center()->remove_count()); + + // Removing the legacy USB device adds the notification again. + MaybeShowDualRoleNotification(dual_role); + EXPECT_EQ(2, message_center()->add_count()); + EXPECT_EQ(1, message_center()->update_count()); + EXPECT_EQ(1, message_center()->remove_count()); + + // Charging from the device updates the notification. + dual_role.set_external_power_source_id("dual-role1"); + dual_role.set_external_power( + power_manager::PowerSupplyProperties_ExternalPower_USB); + MaybeShowDualRoleNotification(dual_role); + EXPECT_EQ(2, message_center()->add_count()); + EXPECT_EQ(2, message_center()->update_count()); + EXPECT_EQ(1, message_center()->remove_count()); + + // Adding a device as a sink doesn't change the notification, because the + // notification exposes the source. + source = dual_role.add_available_external_power_source(); + source->set_active_by_default(false); + MaybeShowDualRoleNotification(dual_role); + EXPECT_EQ(2, message_center()->add_count()); + EXPECT_EQ(2, message_center()->update_count()); + EXPECT_EQ(1, message_center()->remove_count()); + + // Changing the source to a sink changes the notification. + dual_role.set_external_power_source_id(""); + dual_role.set_external_power( + power_manager::PowerSupplyProperties_ExternalPower_DISCONNECTED); + MaybeShowDualRoleNotification(dual_role); + EXPECT_EQ(2, message_center()->add_count()); + EXPECT_EQ(3, message_center()->update_count()); + EXPECT_EQ(1, message_center()->remove_count()); + + // An unrelated change has no effect. + dual_role.set_battery_time_to_empty_sec(2 * 60 * 60); + MaybeShowDualRoleNotification(dual_role); + EXPECT_EQ(2, message_center()->add_count()); + EXPECT_EQ(3, message_center()->update_count()); + EXPECT_EQ(1, message_center()->remove_count()); + + // Removing devices hides the notification. + MaybeShowDualRoleNotification(discharging); + EXPECT_EQ(2, message_center()->add_count()); + EXPECT_EQ(3, message_center()->update_count()); + EXPECT_EQ(2, message_center()->remove_count()); +} + TEST_F(TrayPowerTest, UpdateNotificationState) { // No notifications when no battery present. PowerSupplyProperties no_battery = DefaultPowerSupplyProperties(); diff --git a/ash/system/system_notifier.cc b/ash/system/system_notifier.cc index 8356a59..808d78c 100644 --- a/ash/system/system_notifier.cc +++ b/ash/system/system_notifier.cc @@ -75,6 +75,7 @@ const char kNotifierDeprecatedAccelerator[] = "ash.accelerator-controller"; const char kNotifierDisplay[] = "ash.display"; const char kNotifierDisplayError[] = "ash.display.error"; const char kNotifierDisplayResolutionChange[] = "ash.display.resolution-change"; +const char kNotifierDualRole[] = "ash.dual-role"; const char kNotifierLocale[] = "ash.locale"; const char kNotifierMultiProfileFirstRun[] = "ash.multi-profile.first-run"; const char kNotifierNetworkPortalDetector[] = "ash.network.portal-detector"; diff --git a/ash/system/system_notifier.h b/ash/system/system_notifier.h index 95bac2f..64ad280 100644 --- a/ash/system/system_notifier.h +++ b/ash/system/system_notifier.h @@ -20,6 +20,7 @@ ASH_EXPORT extern const char kNotifierDeprecatedAccelerator[]; ASH_EXPORT extern const char kNotifierDisplay[]; ASH_EXPORT extern const char kNotifierDisplayResolutionChange[]; ASH_EXPORT extern const char kNotifierDisplayError[]; +ASH_EXPORT extern const char kNotifierDualRole[]; ASH_EXPORT extern const char kNotifierLocale[]; ASH_EXPORT extern const char kNotifierMultiProfileFirstRun[]; ASH_EXPORT extern const char kNotifierNetwork[]; diff --git a/ash/system/tray/system_tray_delegate.cc b/ash/system/tray/system_tray_delegate.cc index a5d49b5..fe081c0 100644 --- a/ash/system/tray/system_tray_delegate.cc +++ b/ash/system/tray/system_tray_delegate.cc @@ -124,6 +124,8 @@ void SystemTrayDelegate::ShowNetworkSettingsForGuid(const std::string& guid) { void SystemTrayDelegate::ShowDisplaySettings() { } +void SystemTrayDelegate::ShowPowerSettings() {} + void SystemTrayDelegate::ShowChromeSlow() { } diff --git a/ash/system/tray/system_tray_delegate.h b/ash/system/tray/system_tray_delegate.h index 3f84f4b..1d2e0c2 100644 --- a/ash/system/tray/system_tray_delegate.h +++ b/ash/system/tray/system_tray_delegate.h @@ -188,6 +188,9 @@ class ASH_EXPORT SystemTrayDelegate { // Shows settings related to multiple displays. virtual void ShowDisplaySettings(); + // Shows settings related to power. + virtual void ShowPowerSettings(); + // Shows the page that lets you disable performance tracing. virtual void ShowChromeSlow(); |