OLD | NEW |
| (Empty) |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "ash/common/system/chromeos/power/dual_role_notification.h" | |
6 | |
7 #include <set> | |
8 | |
9 #include "ash/common/system/chromeos/power/power_status.h" | |
10 #include "ash/common/system/system_notifier.h" | |
11 #include "ash/common/system/tray/system_tray_controller.h" | |
12 #include "ash/common/wm_shell.h" | |
13 #include "ash/resources/grit/ash_resources.h" | |
14 #include "ash/strings/grit/ash_strings.h" | |
15 #include "base/strings/utf_string_conversions.h" | |
16 #include "ui/base/l10n/l10n_util.h" | |
17 #include "ui/base/l10n/time_format.h" | |
18 #include "ui/base/resource/resource_bundle.h" | |
19 #include "ui/gfx/image/image.h" | |
20 #include "ui/message_center/message_center.h" | |
21 #include "ui/message_center/notification.h" | |
22 #include "ui/message_center/notification_delegate.h" | |
23 | |
24 using message_center::MessageCenter; | |
25 using message_center::Notification; | |
26 | |
27 namespace ash { | |
28 namespace { | |
29 | |
30 const char kDualRoleNotificationId[] = "dual-role"; | |
31 | |
32 // Opens power settings on click. | |
33 class DualRoleNotificationDelegate | |
34 : public message_center::NotificationDelegate { | |
35 public: | |
36 DualRoleNotificationDelegate() {} | |
37 | |
38 // Overridden from message_center::NotificationDelegate. | |
39 void Click() override { | |
40 WmShell::Get()->system_tray_controller()->ShowPowerSettings(); | |
41 } | |
42 | |
43 private: | |
44 ~DualRoleNotificationDelegate() override {} | |
45 | |
46 DISALLOW_COPY_AND_ASSIGN(DualRoleNotificationDelegate); | |
47 }; | |
48 | |
49 } // namespace | |
50 | |
51 DualRoleNotification::DualRoleNotification(MessageCenter* message_center) | |
52 : message_center_(message_center), | |
53 num_dual_role_sinks_(0), | |
54 line_power_connected_(false) {} | |
55 | |
56 DualRoleNotification::~DualRoleNotification() { | |
57 if (message_center_->FindVisibleNotificationById(kDualRoleNotificationId)) | |
58 message_center_->RemoveNotification(kDualRoleNotificationId, false); | |
59 } | |
60 | |
61 void DualRoleNotification::Update() { | |
62 const PowerStatus& status = *PowerStatus::Get(); | |
63 DCHECK(status.HasDualRoleDevices()); | |
64 | |
65 std::string current_power_source_id = status.GetCurrentPowerSourceID(); | |
66 | |
67 std::unique_ptr<PowerStatus::PowerSource> new_source; | |
68 std::unique_ptr<PowerStatus::PowerSource> new_sink; | |
69 size_t num_sinks_found = 0; | |
70 for (const auto& source : status.GetPowerSources()) { | |
71 // The power source can't be changed if there's a dedicated charger. | |
72 if (source.type == PowerStatus::DEDICATED_CHARGER) { | |
73 dual_role_source_.reset(); | |
74 line_power_connected_ = true; | |
75 if (message_center_->FindVisibleNotificationById(kDualRoleNotificationId)) | |
76 message_center_->RemoveNotification(kDualRoleNotificationId, false); | |
77 return; | |
78 } | |
79 | |
80 if (source.id == current_power_source_id) { | |
81 new_source.reset(new PowerStatus::PowerSource(source)); | |
82 continue; | |
83 } | |
84 num_sinks_found++; | |
85 // The notification only shows the sink port if it is the only sink. | |
86 if (num_sinks_found == 1) | |
87 new_sink.reset(new PowerStatus::PowerSource(source)); | |
88 else | |
89 new_sink.reset(); | |
90 } | |
91 | |
92 // Check if the notification should change. | |
93 bool change = false; | |
94 if (PowerStatus::Get()->IsLinePowerConnected() != line_power_connected_) { | |
95 change = true; | |
96 line_power_connected_ = PowerStatus::Get()->IsLinePowerConnected(); | |
97 } else if (new_source && dual_role_source_) { | |
98 if (new_source->description_id != dual_role_source_->description_id) | |
99 change = true; | |
100 } else if (new_source || dual_role_source_) { | |
101 change = true; | |
102 } else { | |
103 // Notification differs for 0, 1, and 2+ sinks. | |
104 if ((num_sinks_found < num_dual_role_sinks_ && num_sinks_found < 2) || | |
105 (num_sinks_found > num_dual_role_sinks_ && num_dual_role_sinks_ < 2)) { | |
106 change = true; | |
107 } else if (num_sinks_found == 1) { | |
108 // The description matters if there's only one dual-role device. | |
109 change = new_sink->description_id != dual_role_sink_->description_id; | |
110 } | |
111 } | |
112 | |
113 dual_role_source_ = std::move(new_source); | |
114 dual_role_sink_ = std::move(new_sink); | |
115 num_dual_role_sinks_ = num_sinks_found; | |
116 | |
117 if (!change) | |
118 return; | |
119 | |
120 if (!message_center_->FindVisibleNotificationById(kDualRoleNotificationId)) { | |
121 message_center_->AddNotification(CreateNotification()); | |
122 } else { | |
123 message_center_->UpdateNotification(kDualRoleNotificationId, | |
124 CreateNotification()); | |
125 } | |
126 } | |
127 | |
128 std::unique_ptr<Notification> DualRoleNotification::CreateNotification() { | |
129 base::string16 title; | |
130 if (dual_role_source_) { | |
131 title = l10n_util::GetStringFUTF16( | |
132 IDS_ASH_STATUS_TRAY_CHARGING_FROM_DUAL_ROLE_TITLE, | |
133 l10n_util::GetStringUTF16(dual_role_source_->description_id)); | |
134 } else if (num_dual_role_sinks_ == 1) { | |
135 title = l10n_util::GetStringFUTF16( | |
136 IDS_ASH_STATUS_TRAY_CHARGING_DUAL_ROLE_DEVICE_TITLE, | |
137 l10n_util::GetStringUTF16(dual_role_sink_->description_id)); | |
138 } else { | |
139 title = l10n_util::GetStringUTF16( | |
140 IDS_ASH_STATUS_TRAY_CHARGING_DUAL_ROLE_DEVICES_TITLE); | |
141 } | |
142 | |
143 std::unique_ptr<Notification> notification(new Notification( | |
144 message_center::NOTIFICATION_TYPE_SIMPLE, kDualRoleNotificationId, title, | |
145 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_DUAL_ROLE_MESSAGE), | |
146 ui::ResourceBundle::GetSharedInstance().GetImageNamed( | |
147 IDR_AURA_NOTIFICATION_LOW_POWER_CHARGER), | |
148 base::string16(), GURL(), | |
149 message_center::NotifierId(message_center::NotifierId::SYSTEM_COMPONENT, | |
150 system_notifier::kNotifierDualRole), | |
151 message_center::RichNotificationData(), | |
152 new DualRoleNotificationDelegate)); | |
153 notification->set_priority(message_center::MIN_PRIORITY); | |
154 return notification; | |
155 } | |
156 | |
157 } // namespace ash | |
OLD | NEW |