Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(180)

Side by Side Diff: ash/common/system/chromeos/power/power_status.cc

Issue 2063633002: Render Ash material design battery image icon without PNGs (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: tests added Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ash/common/system/chromeos/power/power_status.h" 5 #include "ash/common/system/chromeos/power/power_status.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
13 #include "chromeos/dbus/dbus_thread_manager.h" 13 #include "chromeos/dbus/dbus_thread_manager.h"
14 #include "chromeos/dbus/power_manager_client.h" 14 #include "chromeos/dbus/power_manager_client.h"
15 #include "grit/ash_resources.h" 15 #include "grit/ash_resources.h"
16 #include "grit/ash_strings.h" 16 #include "grit/ash_strings.h"
17 #include "ui/base/l10n/l10n_util.h" 17 #include "ui/base/l10n/l10n_util.h"
18 #include "ui/base/l10n/time_format.h" 18 #include "ui/base/l10n/time_format.h"
19 #include "ui/base/resource/resource_bundle.h" 19 #include "ui/base/resource/resource_bundle.h"
20 #include "ui/display/display.h"
21 #include "ui/display/screen.h"
22 #include "ui/gfx/canvas.h"
20 #include "ui/gfx/geometry/rect.h" 23 #include "ui/gfx/geometry/rect.h"
21 #include "ui/gfx/image/image.h" 24 #include "ui/gfx/image/image.h"
22 #include "ui/gfx/image/image_skia_operations.h" 25 #include "ui/gfx/image/image_skia_operations.h"
26 #include "ui/gfx/paint_vector_icon.h"
27 #include "ui/gfx/vector_icons_public.h"
23 28
24 namespace ash { 29 namespace ash {
25 namespace { 30 namespace {
26 31
27 // Updates |proto| to ensure that its fields are consistent. 32 // Updates |proto| to ensure that its fields are consistent.
28 void SanitizeProto(power_manager::PowerSupplyProperties* proto) { 33 void SanitizeProto(power_manager::PowerSupplyProperties* proto) {
29 DCHECK(proto); 34 DCHECK(proto);
30 35
31 if (proto->battery_state() == 36 if (proto->battery_state() ==
32 power_manager::PowerSupplyProperties_BatteryState_FULL) 37 power_manager::PowerSupplyProperties_BatteryState_FULL)
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 return IDS_ASH_POWER_SOURCE_PORT_RIGHT_BACK; 91 return IDS_ASH_POWER_SOURCE_PORT_RIGHT_BACK;
87 case power_manager::PowerSupplyProperties_PowerSource_Port_BACK_LEFT: 92 case power_manager::PowerSupplyProperties_PowerSource_Port_BACK_LEFT:
88 return IDS_ASH_POWER_SOURCE_PORT_BACK_LEFT; 93 return IDS_ASH_POWER_SOURCE_PORT_BACK_LEFT;
89 case power_manager::PowerSupplyProperties_PowerSource_Port_BACK_RIGHT: 94 case power_manager::PowerSupplyProperties_PowerSource_Port_BACK_RIGHT:
90 return IDS_ASH_POWER_SOURCE_PORT_BACK_RIGHT; 95 return IDS_ASH_POWER_SOURCE_PORT_BACK_RIGHT;
91 } 96 }
92 NOTREACHED(); 97 NOTREACHED();
93 return 0; 98 return 0;
94 } 99 }
95 100
101 gfx::VectorIconId VectorIconIdForIconBadge(PowerStatus::IconBadge icon_badge) {
102 switch (icon_badge) {
103 case PowerStatus::ICON_BADGE_NONE:
104 return gfx::VectorIconId::VECTOR_ICON_NONE;
105 case PowerStatus::ICON_BADGE_ALERT:
106 return gfx::VectorIconId::SYSTEM_TRAY_BATTERY_ALERT;
107 case PowerStatus::ICON_BADGE_BOLT:
108 return gfx::VectorIconId::SYSTEM_TRAY_BATTERY_BOLT;
109 case PowerStatus::ICON_BADGE_X:
110 return gfx::VectorIconId::SYSTEM_TRAY_BATTERY_X;
111 case PowerStatus::ICON_BADGE_UNRELIABLE:
112 return gfx::VectorIconId::SYSTEM_TRAY_BATTERY_UNRELIABLE;
113 }
114 NOTREACHED();
115 return gfx::VectorIconId::VECTOR_ICON_NONE;
116 }
117
96 static PowerStatus* g_power_status = NULL; 118 static PowerStatus* g_power_status = NULL;
97 119
98 // Minimum battery percentage rendered in UI. 120 // Minimum battery percentage rendered in UI.
99 const int kMinBatteryPercent = 1; 121 const int kMinBatteryPercent = 1;
100 122
101 // Width and height of battery images. 123 // Width and height of battery images.
102 const int kBatteryImageHeight = 25; 124 const int kBatteryImageHeight = 25;
103 const int kBatteryImageWidth = 25; 125 const int kBatteryImageWidth = 25;
104 126
105 // Number of different power states. 127 // Number of different power states.
106 const int kNumPowerImages = 15; 128 const int kNumPowerImages = 15;
107 129
130 // The height of the battery icon in material design (as measured from the
131 // user-visible bottom of the icon to the user-visible top of the icon).
James Cook 2016/06/21 23:19:00 nice comment
tdanderson 2016/06/22 15:25:00 Thanks
132 const int kBatteryImageHeightMD = 12;
133
134 // The dimensions of the canvas containing the material design battery icon.
135 const int kBatteryCanvasSizeMD = 16;
136
137 // The empty background color of the battery icon in the system tray. Used
138 // for material design.
139 // TODO(tdanderson): Move these constants to a shared location if they are
140 // shared by more than one material design system icon.
141 const SkColor kBatteryBaseColor = SkColorSetA(SK_ColorWHITE, 0x4C);
142
143 // The background color of the charged region of the battery in the system
144 // tray. Used for material design.
145 const SkColor kBatteryChargeColor = SK_ColorWHITE;
146
147 // The color of the battery's badge (bolt, unreliable, X).
148 const SkColor kBatteryBadgeColor = SkColorSetA(SK_ColorBLACK, 0xB2);
149
150 // The color used for the battery's badge and charged color when the battery
151 // charge level is critically low.
152 const SkColor kBatteryAlertColor = SkColorSetRGB(0xDA, 0x27, 0x12);
153
108 } // namespace 154 } // namespace
109 155
110 const int PowerStatus::kMaxBatteryTimeToDisplaySec = 24 * 60 * 60; 156 const int PowerStatus::kMaxBatteryTimeToDisplaySec = 24 * 60 * 60;
111 157
112 // static 158 // static
113 void PowerStatus::Initialize() { 159 void PowerStatus::Initialize() {
114 CHECK(!g_power_status); 160 CHECK(!g_power_status);
115 g_power_status = new PowerStatus(); 161 g_power_status = new PowerStatus();
116 } 162 }
117 163
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 return sources; 299 return sources;
254 } 300 }
255 301
256 std::string PowerStatus::GetCurrentPowerSourceID() const { 302 std::string PowerStatus::GetCurrentPowerSourceID() const {
257 return proto_.external_power_source_id(); 303 return proto_.external_power_source_id();
258 } 304 }
259 305
260 PowerStatus::BatteryImageInfo PowerStatus::GetBatteryImageInfo( 306 PowerStatus::BatteryImageInfo PowerStatus::GetBatteryImageInfo(
261 IconSet icon_set) const { 307 IconSet icon_set) const {
262 BatteryImageInfo info; 308 BatteryImageInfo info;
309 CalculateBatteryImageInfoMD(&info);
310 CalculateBatteryImageInfoNonMD(&info, icon_set);
James Cook 2016/06/21 23:19:00 Do you need to do both of these when in the non-MD
tdanderson 2016/06/22 15:25:00 This was to guarantee that all members of BatteryI
311 return info;
312 }
263 313
314 void PowerStatus::CalculateBatteryImageInfoMD(BatteryImageInfo* info) const {
315 if (!IsUsbChargerConnected() && !IsBatteryPresent()) {
316 info->icon_badge = ICON_BADGE_X;
317 info->charge_level = 0;
318 return;
319 }
320
321 if (IsUsbChargerConnected())
322 info->icon_badge = ICON_BADGE_UNRELIABLE;
323 else if (IsLinePowerConnected())
324 info->icon_badge = ICON_BADGE_BOLT;
325 else
326 info->icon_badge = ICON_BADGE_NONE;
327
328 // |charge_state| is a value between 0 and kBatteryImageHeightMD representing
329 // the number of device pixels the battery image should be shown charged. The
330 // exception is when |charge_state| is 0 (a critically-low battery); in this
331 // case, still draw 1dp of charge.
332 int charge_state =
333 static_cast<int>(GetBatteryPercent() / 100.0 * kBatteryImageHeightMD);
334 charge_state = std::max(std::min(charge_state, kBatteryImageHeightMD), 0);
335 info->charge_level = std::max(charge_state, 1);
336
337 // Use ICON_BADGE_ALERT if the battery is critically low and does not already
338 // have a badge assigned.
339 if (!charge_state && info->icon_badge == ICON_BADGE_NONE)
340 info->icon_badge = ICON_BADGE_ALERT;
341 }
342
343 void PowerStatus::CalculateBatteryImageInfoNonMD(
344 BatteryImageInfo* info,
345 const IconSet& icon_set) const {
264 if (IsUsbChargerConnected()) { 346 if (IsUsbChargerConnected()) {
265 info.resource_id = 347 info->resource_id =
266 (icon_set == ICON_DARK) 348 (icon_set == ICON_DARK)
267 ? IDR_AURA_UBER_TRAY_POWER_SMALL_CHARGING_UNRELIABLE_DARK 349 ? IDR_AURA_UBER_TRAY_POWER_SMALL_CHARGING_UNRELIABLE_DARK
268 : IDR_AURA_UBER_TRAY_POWER_SMALL_CHARGING_UNRELIABLE; 350 : IDR_AURA_UBER_TRAY_POWER_SMALL_CHARGING_UNRELIABLE;
269 } else { 351 } else {
270 info.resource_id = (icon_set == ICON_DARK) 352 info->resource_id = (icon_set == ICON_DARK)
271 ? IDR_AURA_UBER_TRAY_POWER_SMALL_DARK 353 ? IDR_AURA_UBER_TRAY_POWER_SMALL_DARK
272 : IDR_AURA_UBER_TRAY_POWER_SMALL; 354 : IDR_AURA_UBER_TRAY_POWER_SMALL;
273 } 355 }
274 356
275 info.offset = IsUsbChargerConnected() ? 0 : (IsLinePowerConnected() ? 1 : 0); 357 info->offset = IsUsbChargerConnected() ? 0 : (IsLinePowerConnected() ? 1 : 0);
276 358
277 if (GetBatteryPercent() >= 100.0) { 359 if (GetBatteryPercent() >= 100.0) {
278 info.index = kNumPowerImages - 1; 360 info->index = kNumPowerImages - 1;
279 } else if (!IsBatteryPresent()) { 361 } else if (!IsBatteryPresent()) {
280 info.index = kNumPowerImages; 362 info->index = kNumPowerImages;
281 } else { 363 } else {
282 info.index = 364 info->index =
283 static_cast<int>(GetBatteryPercent() / 100.0 * (kNumPowerImages - 1)); 365 static_cast<int>(GetBatteryPercent() / 100.0 * (kNumPowerImages - 1));
284 info.index = std::max(std::min(info.index, kNumPowerImages - 2), 0); 366 info->index = std::max(std::min(info->index, kNumPowerImages - 2), 0);
367 }
368 }
369
370 gfx::ImageSkia PowerStatus::GetBatteryImage(
371 const BatteryImageInfo& info) const {
372 if (!MaterialDesignController::UseMaterialDesignSystemIcons())
373 return GetBatteryImageNonMD(info);
374
375 const bool use_alert_color =
376 (info.charge_level == 1 && info.icon_badge != ICON_BADGE_BOLT);
James Cook 2016/06/21 23:19:00 Is this the same "1" as in line 335? I would eithe
tdanderson 2016/06/22 15:25:00 Done.
377 const SkColor badge_color =
378 use_alert_color ? kBatteryAlertColor : kBatteryBadgeColor;
379 const SkColor charge_color =
380 use_alert_color ? kBatteryAlertColor : kBatteryChargeColor;
381 gfx::Canvas canvas(
382 gfx::Size(kBatteryCanvasSizeMD, kBatteryCanvasSizeMD),
383 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor(),
384 true);
385
386 // Paint the battery's base (background) color.
387 PaintVectorIcon(&canvas, gfx::VectorIconId::SYSTEM_TRAY_BATTERY,
388 kBatteryCanvasSizeMD, kBatteryBaseColor);
389
390 // Paint the charged portion of the battery. Note that |charge_height| adjusts
391 // for the 2dp of padding between the bottom of the battery icon and the
392 // bottom edge of |canvas|.
393 const int charge_height = info.charge_level + 2;
394 gfx::Rect clip_rect(0, kBatteryCanvasSizeMD - charge_height,
395 kBatteryCanvasSizeMD, charge_height);
396 canvas.Save();
397 canvas.ClipRect(clip_rect);
398 PaintVectorIcon(&canvas, gfx::VectorIconId::SYSTEM_TRAY_BATTERY,
399 kBatteryCanvasSizeMD, charge_color);
400 canvas.Restore();
401
402 // Paint the badge over top of the battery, if applicable.
403 if (info.icon_badge != ICON_BADGE_NONE) {
404 PaintVectorIcon(&canvas, VectorIconIdForIconBadge(info.icon_badge),
405 kBatteryCanvasSizeMD, badge_color);
285 } 406 }
286 407
287 return info; 408 return gfx::ImageSkia(canvas.ExtractImageRep());
288 } 409 }
289 410
290 gfx::ImageSkia PowerStatus::GetBatteryImage(IconSet icon_set) const { 411 gfx::ImageSkia PowerStatus::GetBatteryImageNonMD(
291 const BatteryImageInfo info = GetBatteryImageInfo(icon_set); 412 const BatteryImageInfo& info) const {
292 gfx::Image all; 413 gfx::Image all;
293 all = ui::ResourceBundle::GetSharedInstance().GetImageNamed(info.resource_id); 414 all = ui::ResourceBundle::GetSharedInstance().GetImageNamed(info.resource_id);
294 gfx::Rect region(info.offset * kBatteryImageWidth, 415 gfx::Rect region(info.offset * kBatteryImageWidth,
295 info.index * kBatteryImageHeight, kBatteryImageWidth, 416 info.index * kBatteryImageHeight, kBatteryImageWidth,
296 kBatteryImageHeight); 417 kBatteryImageHeight);
297 return gfx::ImageSkiaOperations::ExtractSubset(*all.ToImageSkia(), region); 418 return gfx::ImageSkiaOperations::ExtractSubset(*all.ToImageSkia(), region);
298 } 419 }
299 420
300 base::string16 PowerStatus::GetAccessibleNameString( 421 base::string16 PowerStatus::GetAccessibleNameString(
301 bool full_description) const { 422 bool full_description) const {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 } 483 }
363 484
364 void PowerStatus::PowerChanged( 485 void PowerStatus::PowerChanged(
365 const power_manager::PowerSupplyProperties& proto) { 486 const power_manager::PowerSupplyProperties& proto) {
366 proto_ = proto; 487 proto_ = proto;
367 SanitizeProto(&proto_); 488 SanitizeProto(&proto_);
368 FOR_EACH_OBSERVER(Observer, observers_, OnPowerStatusChanged()); 489 FOR_EACH_OBSERVER(Observer, observers_, OnPowerStatusChanged());
369 } 490 }
370 491
371 } // namespace ash 492 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698