Commit 366a2194 authored by Sam McNally's avatar Sam McNally Committed by Commit Bot

Add a notification for low-power adapters for battery-less devices.

Reuse the existing notification for low-power USB chargers for low-power
type-C adapters providing less power than is needed to avoid potentially
throttling. Include the suggested adapter power in the notification
message and make the notification dismissible but without a timeout to
ensure the user sees it once per login, but can dismiss it for the rest
of that login session since changing power adapter requires a reboot.

BUG=b:160854398

Change-Id: Ia8a2c9de07b9e054e2253eba92008188de8efbbf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2409392
Commit-Queue: Sam McNally <sammc@chromium.org>
Reviewed-by: default avatarTim Song <tengs@chromium.org>
Reviewed-by: default avatarTetsui Ohkubo <tetsui@chromium.org>
Cr-Commit-Position: refs/heads/master@{#808215}
parent 275d7303
...@@ -1166,6 +1166,12 @@ This file contains the strings for ash. ...@@ -1166,6 +1166,12 @@ This file contains the strings for ash.
<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."> <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. Your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> may not charge while it is turned on.
</message> </message>
<message name="IDS_ASH_STATUS_TRAY_LOW_POWER_ADAPTER_TITLE" desc="The title of a notification indicating that a low-current USB adapter has been connected.">
Low-power adapter connected
</message>
<message name="IDS_ASH_STATUS_TRAY_LOW_POWER_ADAPTER_MESSAGE_SHORT" desc="The message body of a notification indicating that a low-current USB adapter has been connected on a device without a battery, short version.">
Your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> may experience lower performance. Use a certified <ph name="PREFERRED_MINIMUM_POWER">$2<ex>60</ex></ph>W or higher USB-C power adapter.
</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."> <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> Charging from <ph name="POWER_SOURCE">$1<ex>USB-C device (left port)</ex></ph>
</message> </message>
......
794fb8fbb79f320090e562f85e16fe9c972421ea
\ No newline at end of file
794fb8fbb79f320090e562f85e16fe9c972421ea
\ No newline at end of file
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "ash/system/power/battery_notification.h" #include "ash/system/power/battery_notification.h"
#include "ash/system/power/dual_role_notification.h" #include "ash/system/power/dual_role_notification.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/i18n/number_formatting.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/numerics/safe_conversions.h" #include "base/numerics/safe_conversions.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
...@@ -133,18 +134,28 @@ bool PowerNotificationController::MaybeShowUsbChargerNotification() { ...@@ -133,18 +134,28 @@ bool PowerNotificationController::MaybeShowUsbChargerNotification() {
// Check if the notification needs to be created. // Check if the notification needs to be created.
if (show && !usb_charger_was_connected_ && !usb_notification_dismissed_) { if (show && !usb_charger_was_connected_ && !usb_notification_dismissed_) {
bool on_battery = PowerStatus::Get()->IsBatteryPresent();
std::unique_ptr<Notification> notification = CreateSystemNotification( std::unique_ptr<Notification> notification = CreateSystemNotification(
message_center::NOTIFICATION_TYPE_SIMPLE, kUsbNotificationId, message_center::NOTIFICATION_TYPE_SIMPLE, kUsbNotificationId,
l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_LOW_POWER_CHARGER_TITLE), l10n_util::GetStringUTF16(
ui::SubstituteChromeOSDeviceType( on_battery ? IDS_ASH_STATUS_TRAY_LOW_POWER_CHARGER_TITLE
IDS_ASH_STATUS_TRAY_LOW_POWER_CHARGER_MESSAGE_SHORT), : IDS_ASH_STATUS_TRAY_LOW_POWER_ADAPTER_TITLE),
on_battery
? ui::SubstituteChromeOSDeviceType(
IDS_ASH_STATUS_TRAY_LOW_POWER_CHARGER_MESSAGE_SHORT)
: l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_LOW_POWER_ADAPTER_MESSAGE_SHORT,
ui::GetChromeOSDeviceName(),
base::FormatDouble(
PowerStatus::Get()->GetPreferredMinimumPower(), 0)),
base::string16(), GURL(), base::string16(), GURL(),
message_center::NotifierId( message_center::NotifierId(
message_center::NotifierType::SYSTEM_COMPONENT, kNotifierPower), message_center::NotifierType::SYSTEM_COMPONENT, kNotifierPower),
message_center::RichNotificationData(), message_center::RichNotificationData(),
new UsbNotificationDelegate(this), kNotificationLowPowerChargerIcon, new UsbNotificationDelegate(this), kNotificationLowPowerChargerIcon,
message_center::SystemNotificationWarningLevel::WARNING); message_center::SystemNotificationWarningLevel::WARNING);
notification->set_pinned(true); notification->set_pinned(on_battery);
notification->set_never_timeout(!on_battery);
message_center_->AddNotification(std::move(notification)); message_center_->AddNotification(std::move(notification));
return true; return true;
} }
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <string> #include <string>
#include "ash/test/ash_test_base.h" #include "ash/test/ash_test_base.h"
#include "base/strings/utf_string_conversions.h"
#include "chromeos/dbus/power_manager/power_supply_properties.pb.h" #include "chromeos/dbus/power_manager/power_supply_properties.pb.h"
#include "ui/message_center/fake_message_center.h" #include "ui/message_center/fake_message_center.h"
...@@ -261,6 +262,38 @@ TEST_F(PowerNotificationControllerTest, ...@@ -261,6 +262,38 @@ TEST_F(PowerNotificationControllerTest,
EXPECT_EQ(1, message_center()->remove_count()); EXPECT_EQ(1, message_center()->remove_count());
} }
TEST_F(PowerNotificationControllerTest,
MaybeShowUsbChargerNotification_NoBattery) {
// Notification does not show when powered by AC (including high-power
// USB PD.
PowerSupplyProperties ac_connected = DefaultPowerSupplyProperties();
ac_connected.set_external_power(
power_manager::PowerSupplyProperties_ExternalPower_AC);
ac_connected.set_battery_state(
power_manager::PowerSupplyProperties_BatteryState_NOT_PRESENT);
EXPECT_FALSE(MaybeShowUsbChargerNotification(ac_connected));
EXPECT_EQ(0, message_center()->add_count());
EXPECT_EQ(0, message_center()->remove_count());
// Notification shows when powered by low-power USB.
PowerSupplyProperties usb_connected = DefaultPowerSupplyProperties();
usb_connected.set_external_power(
power_manager::PowerSupplyProperties_ExternalPower_USB);
usb_connected.set_battery_state(
power_manager::PowerSupplyProperties_BatteryState_NOT_PRESENT);
EXPECT_TRUE(MaybeShowUsbChargerNotification(usb_connected));
EXPECT_EQ(1, message_center()->add_count());
EXPECT_EQ(0, message_center()->remove_count());
auto* notification =
message_center()->FindVisibleNotificationById("usb-charger");
ASSERT_TRUE(notification);
EXPECT_TRUE(notification->never_timeout());
EXPECT_FALSE(notification->pinned());
EXPECT_NE(std::string::npos,
notification->message().find(base::ASCIIToUTF16("60W")))
<< notification->message();
}
TEST_F(PowerNotificationControllerTest, MaybeShowDualRoleNotification) { TEST_F(PowerNotificationControllerTest, MaybeShowDualRoleNotification) {
PowerSupplyProperties discharging = DefaultPowerSupplyProperties(); PowerSupplyProperties discharging = DefaultPowerSupplyProperties();
discharging.set_supports_dual_role_devices(true); discharging.set_supports_dual_role_devices(true);
......
...@@ -485,6 +485,11 @@ base::string16 PowerStatus::GetInlinedStatusString() const { ...@@ -485,6 +485,11 @@ base::string16 PowerStatus::GetInlinedStatusString() const {
} }
} }
double PowerStatus::GetPreferredMinimumPower() const {
// TODO(b/160854398): Return the value from the proto once it's ready.
return 60.0;
}
PowerStatus::PowerStatus() { PowerStatus::PowerStatus() {
chromeos::PowerManagerClient::Get()->AddObserver(this); chromeos::PowerManagerClient::Get()->AddObserver(this);
chromeos::PowerManagerClient::Get()->RequestStatusUpdate(); chromeos::PowerManagerClient::Get()->RequestStatusUpdate();
......
...@@ -213,6 +213,9 @@ class ASH_EXPORT PowerStatus : public chromeos::PowerManagerClient::Observer { ...@@ -213,6 +213,9 @@ class ASH_EXPORT PowerStatus : public chromeos::PowerManagerClient::Observer {
// For example, "53% - 5:00 left". // For example, "53% - 5:00 left".
base::string16 GetInlinedStatusString() const; base::string16 GetInlinedStatusString() const;
// Returns the device's preferred minimum power input in watts (W).
double GetPreferredMinimumPower() const;
// Updates |proto_|. Does not notify observers. // Updates |proto_|. Does not notify observers.
void SetProtoForTesting(const power_manager::PowerSupplyProperties& proto); void SetProtoForTesting(const power_manager::PowerSupplyProperties& proto);
......
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