1 // Copyright 2014 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.
5 #include "athena/system/status_icon_container_view.h"
7 #include "athena/resources/athena_resources.h"
8 #include "athena/system/network_selector.h"
10 #include "base/macros.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "chromeos/dbus/dbus_thread_manager.h"
14 #include "chromeos/dbus/power_manager/power_supply_properties.pb.h"
15 #include "chromeos/dbus/power_manager_client.h"
16 #include "chromeos/dbus/update_engine_client.h"
17 #include "chromeos/network/network_state.h"
18 #include "chromeos/network/network_state_handler.h"
19 #include "chromeos/network/network_state_handler_observer.h"
20 #include "chromeos/network/network_type_pattern.h"
21 #include "extensions/shell/common/version.h"
22 #include "ui/aura/window.h"
23 #include "ui/base/resource/resource_bundle.h"
24 #include "ui/gfx/image/image.h"
25 #include "ui/gfx/image/image_skia.h"
26 #include "ui/gfx/image/image_skia_operations.h"
27 #include "ui/views/controls/image_view.h"
28 #include "ui/views/controls/label.h"
29 #include "ui/views/layout/box_layout.h"
34 views::Label
* CreateLabel(SystemUI::ColorScheme color_scheme
,
35 const std::string
& text
) {
36 views::Label
* label
= new views::Label(base::UTF8ToUTF16(text
));
37 label
->SetEnabledColor((color_scheme
== SystemUI::COLOR_SCHEME_LIGHT
)
40 label
->SetAutoColorReadabilityEnabled(false);
41 label
->SetSubpixelRenderingEnabled(false);
42 label
->SetFontList(gfx::FontList().DeriveWithStyle(gfx::Font::BOLD
));
48 class StatusIconContainerView::PowerStatus
49 : public chromeos::PowerManagerClient::Observer
{
51 PowerStatus(SystemUI::ColorScheme color_scheme
,
52 views::ImageView
* icon
)
53 : color_scheme_(color_scheme
),
55 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(
57 chromeos::DBusThreadManager::Get()
58 ->GetPowerManagerClient()
59 ->RequestStatusUpdate();
62 ~PowerStatus() override
{
63 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(
68 const gfx::ImageSkia
GetPowerIcon(
69 const power_manager::PowerSupplyProperties
& proto
) const {
70 // Width and height of battery images.
71 const int kBatteryImageHeight
= 25;
72 const int kBatteryImageWidth
= 25;
74 // Number of different power states.
75 const int kNumPowerImages
= 15;
77 gfx::Image all
= ui::ResourceBundle::GetSharedInstance().GetImageNamed(
78 (color_scheme_
== SystemUI::COLOR_SCHEME_LIGHT
)
79 ? IDR_AURA_UBER_TRAY_POWER_SMALL
80 : IDR_AURA_UBER_TRAY_POWER_SMALL_DARK
);
81 int horiz_offset
= IsCharging(proto
) ? 1 : 0;
83 if (proto
.battery_percent() >= 100) {
84 vert_offset
= kNumPowerImages
- 1;
86 vert_offset
= static_cast<int>((kNumPowerImages
- 1) *
87 proto
.battery_percent() / 100);
88 vert_offset
= std::max(std::min(vert_offset
, kNumPowerImages
- 2), 0);
90 gfx::Rect
region(horiz_offset
* kBatteryImageWidth
,
91 vert_offset
* kBatteryImageHeight
,
94 return gfx::ImageSkiaOperations::ExtractSubset(*all
.ToImageSkia(), region
);
97 bool IsCharging(const power_manager::PowerSupplyProperties
& proto
) const {
98 return proto
.external_power() !=
99 power_manager::PowerSupplyProperties_ExternalPower_DISCONNECTED
;
102 // chromeos::PowerManagerClient::Observer:
103 virtual void PowerChanged(
104 const power_manager::PowerSupplyProperties
& proto
) override
{
105 icon_
->SetImage(GetPowerIcon(proto
));
108 SystemUI::ColorScheme color_scheme_
;
109 views::ImageView
* icon_
;
111 DISALLOW_COPY_AND_ASSIGN(PowerStatus
);
114 class StatusIconContainerView::NetworkStatus
115 : public chromeos::NetworkStateHandlerObserver
{
117 explicit NetworkStatus(views::Label
* label
) : label_(label
) {
118 chromeos::NetworkStateHandler
* handler
=
119 chromeos::NetworkHandler::Get()->network_state_handler();
120 handler
->AddObserver(this, FROM_HERE
);
123 ~NetworkStatus() override
{
124 chromeos::NetworkStateHandler
* handler
=
125 chromeos::NetworkHandler::Get()->network_state_handler();
126 handler
->RemoveObserver(this, FROM_HERE
);
131 std::string status
= "<unknown>";
132 chromeos::NetworkStateHandler
* handler
=
133 chromeos::NetworkHandler::Get()->network_state_handler();
134 const chromeos::NetworkState
* network
= handler
->DefaultNetwork();
136 network
= handler
->ConnectedNetworkByType(
137 chromeos::NetworkTypePattern::NonVirtual());
140 status
= base::StringPrintf(
141 "%s (%s)", network
->ip_address().c_str(), network
->name().c_str());
143 label_
->SetText(base::UTF8ToUTF16(status
));
146 // chromeos::NetworkStateHandlerObserver:
147 virtual void DefaultNetworkChanged(
148 const chromeos::NetworkState
* network
) override
{
152 virtual void NetworkConnectionStateChanged(
153 const chromeos::NetworkState
* network
) override
{
157 virtual void NetworkPropertiesUpdated(
158 const chromeos::NetworkState
* network
) override
{
162 views::Label
* label_
;
164 DISALLOW_COPY_AND_ASSIGN(NetworkStatus
);
167 void StartUpdateCallback(
168 chromeos::UpdateEngineClient::UpdateCheckResult result
) {
169 VLOG(1) << "Callback from RequestUpdateCheck, result " << result
;
172 class StatusIconContainerView::UpdateStatus
173 : public chromeos::UpdateEngineClient::Observer
{
175 UpdateStatus(SystemUI::ColorScheme color_scheme
, views::ImageView
* icon
)
176 : color_scheme_(color_scheme
),
178 chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->AddObserver(
180 chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->
181 RequestUpdateCheck(base::Bind(StartUpdateCallback
));
184 ~UpdateStatus() override
{
185 chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(
189 // chromeos::UpdateEngineClient::Observer:
190 virtual void UpdateStatusChanged(
191 const chromeos::UpdateEngineClient::Status
& status
) override
{
193 chromeos::UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT
) {
196 int image_id
= (color_scheme_
== SystemUI::COLOR_SCHEME_LIGHT
)
197 ? IDR_AURA_UBER_TRAY_UPDATE
198 : IDR_AURA_UBER_TRAY_UPDATE_DARK
;
200 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(image_id
));
204 SystemUI::ColorScheme color_scheme_
;
205 views::ImageView
* icon_
;
207 DISALLOW_COPY_AND_ASSIGN(UpdateStatus
);
210 StatusIconContainerView::StatusIconContainerView(
211 SystemUI::ColorScheme color_scheme
) {
212 const int kHorizontalSpacing
= 10;
213 const int kVerticalSpacing
= 3;
214 const int kBetweenChildSpacing
= 10;
215 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal
,
218 kBetweenChildSpacing
));
220 std::string version_text
=
221 base::StringPrintf("%s (Build %s)", PRODUCT_VERSION
, LAST_CHANGE
);
222 AddChildView(CreateLabel(color_scheme
, version_text
));
224 AddChildView(CreateLabel(color_scheme
, "Network:"));
225 views::Label
* network_label
= CreateLabel(color_scheme
, std::string());
226 AddChildView(network_label
);
227 if (chromeos::NetworkHandler::IsInitialized())
228 network_status_
.reset(new NetworkStatus(network_label
));
230 views::ImageView
* battery_view
= new views::ImageView();
231 AddChildView(battery_view
);
232 power_status_
.reset(new PowerStatus(color_scheme
, battery_view
));
234 views::ImageView
* update_view
= new views::ImageView();
235 AddChildView(update_view
);
236 update_status_
.reset(new UpdateStatus(color_scheme
, update_view
));
239 StatusIconContainerView::~StatusIconContainerView() {
242 bool StatusIconContainerView::OnMousePressed(const ui::MouseEvent
& event
) {
243 CreateNetworkSelector();
247 void StatusIconContainerView::OnGestureEvent(ui::GestureEvent
* event
) {
248 if (event
->type() == ui::ET_GESTURE_TAP
) {
249 CreateNetworkSelector();
254 void StatusIconContainerView::ChildPreferredSizeChanged(views::View
* child
) {
255 PreferredSizeChanged();
258 } // namespace athena