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

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: add battery percentage constant 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 "ash/common/material_design/material_design_controller.h"
10 #include "base/logging.h" 11 #include "base/logging.h"
11 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/utf_string_conversions.h" 13 #include "base/strings/utf_string_conversions.h"
13 #include "chromeos/dbus/dbus_thread_manager.h" 14 #include "chromeos/dbus/dbus_thread_manager.h"
14 #include "chromeos/dbus/power_manager_client.h" 15 #include "chromeos/dbus/power_manager_client.h"
15 #include "grit/ash_resources.h" 16 #include "grit/ash_resources.h"
16 #include "grit/ash_strings.h" 17 #include "grit/ash_strings.h"
17 #include "ui/base/l10n/l10n_util.h" 18 #include "ui/base/l10n/l10n_util.h"
18 #include "ui/base/l10n/time_format.h" 19 #include "ui/base/l10n/time_format.h"
19 #include "ui/base/resource/resource_bundle.h" 20 #include "ui/base/resource/resource_bundle.h"
21 #include "ui/display/display.h"
22 #include "ui/display/screen.h"
23 #include "ui/gfx/canvas.h"
20 #include "ui/gfx/geometry/rect.h" 24 #include "ui/gfx/geometry/rect.h"
21 #include "ui/gfx/image/image.h" 25 #include "ui/gfx/image/image.h"
22 #include "ui/gfx/image/image_skia_operations.h" 26 #include "ui/gfx/image/image_skia_operations.h"
27 #include "ui/gfx/paint_vector_icon.h"
28 #include "ui/gfx/vector_icons_public.h"
23 29
24 namespace ash { 30 namespace ash {
25 namespace { 31 namespace {
26 32
27 // Updates |proto| to ensure that its fields are consistent. 33 // Updates |proto| to ensure that its fields are consistent.
28 void SanitizeProto(power_manager::PowerSupplyProperties* proto) { 34 void SanitizeProto(power_manager::PowerSupplyProperties* proto) {
29 DCHECK(proto); 35 DCHECK(proto);
30 36
31 if (proto->battery_state() == 37 if (proto->battery_state() ==
32 power_manager::PowerSupplyProperties_BatteryState_FULL) 38 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; 92 return IDS_ASH_POWER_SOURCE_PORT_RIGHT_BACK;
87 case power_manager::PowerSupplyProperties_PowerSource_Port_BACK_LEFT: 93 case power_manager::PowerSupplyProperties_PowerSource_Port_BACK_LEFT:
88 return IDS_ASH_POWER_SOURCE_PORT_BACK_LEFT; 94 return IDS_ASH_POWER_SOURCE_PORT_BACK_LEFT;
89 case power_manager::PowerSupplyProperties_PowerSource_Port_BACK_RIGHT: 95 case power_manager::PowerSupplyProperties_PowerSource_Port_BACK_RIGHT:
90 return IDS_ASH_POWER_SOURCE_PORT_BACK_RIGHT; 96 return IDS_ASH_POWER_SOURCE_PORT_BACK_RIGHT;
91 } 97 }
92 NOTREACHED(); 98 NOTREACHED();
93 return 0; 99 return 0;
94 } 100 }
95 101
102 gfx::VectorIconId VectorIconIdForIconBadge(PowerStatus::IconBadge icon_badge) {
103 switch (icon_badge) {
104 case PowerStatus::ICON_BADGE_NONE:
105 return gfx::VectorIconId::VECTOR_ICON_NONE;
106 case PowerStatus::ICON_BADGE_ALERT:
107 return gfx::VectorIconId::SYSTEM_TRAY_BATTERY_ALERT;
108 case PowerStatus::ICON_BADGE_BOLT:
109 return gfx::VectorIconId::SYSTEM_TRAY_BATTERY_BOLT;
110 case PowerStatus::ICON_BADGE_X:
111 return gfx::VectorIconId::SYSTEM_TRAY_BATTERY_X;
112 case PowerStatus::ICON_BADGE_UNRELIABLE:
113 return gfx::VectorIconId::SYSTEM_TRAY_BATTERY_UNRELIABLE;
114 }
115 NOTREACHED();
116 return gfx::VectorIconId::VECTOR_ICON_NONE;
117 }
118
96 static PowerStatus* g_power_status = NULL; 119 static PowerStatus* g_power_status = NULL;
97 120
98 // Minimum battery percentage rendered in UI. 121 // Minimum battery percentage rendered in UI.
99 const int kMinBatteryPercent = 1; 122 const int kMinBatteryPercent = 1;
100 123
101 // Width and height of battery images. 124 // Width and height of battery images.
102 const int kBatteryImageHeight = 25; 125 const int kBatteryImageHeight = 25;
103 const int kBatteryImageWidth = 25; 126 const int kBatteryImageWidth = 25;
104 127
105 // Number of different power states. 128 // Number of different power states.
106 const int kNumPowerImages = 15; 129 const int kNumPowerImages = 15;
107 130
131 // The height of the battery icon in material design (as measured from the
132 // user-visible bottom of the icon to the user-visible top of the icon).
133 const int kBatteryImageHeightMd = 12;
134
135 // The dimensions of the canvas containing the material design battery icon.
136 const int kBatteryCanvasSizeMd = 16;
137
138 // The minimum height (in dp) of the charged region of the material design
139 // battery icon when the battery is present and has a charge greater than 0.
140 const int kMinVisualChargeLevelMd = 1;
141
142 // The empty background color of the battery icon in the system tray. Used
143 // for material design.
144 // TODO(tdanderson): Move these constants to a shared location if they are
145 // shared by more than one material design system icon.
146 const SkColor kBatteryBaseColor = SkColorSetA(SK_ColorWHITE, 0x4C);
147
148 // The background color of the charged region of the battery in the system
149 // tray. Used for material design.
150 const SkColor kBatteryChargeColor = SK_ColorWHITE;
151
152 // The color of the battery's badge (bolt, unreliable, X).
153 const SkColor kBatteryBadgeColor = SkColorSetA(SK_ColorBLACK, 0xB2);
154
155 // The color used for the battery's badge and charged color when the battery
156 // charge level is critically low.
157 const SkColor kBatteryAlertColor = SkColorSetRGB(0xDA, 0x27, 0x12);
158
108 } // namespace 159 } // namespace
109 160
161 bool PowerStatus::BatteryImageInfo::operator==(
162 const BatteryImageInfo& o) const {
163 if (ash::MaterialDesignController::UseMaterialDesignSystemIcons())
164 return icon_badge == o.icon_badge && charge_level == o.charge_level;
165
166 // TODO(tdanderson): |resource_id|, |offset|, and |index| are only used for
167 // non-MD. Remove these once MD is enabled by default. See crbug.com/614453.
168 return resource_id == o.resource_id && offset == o.offset && index == o.index;
169 }
170
110 const int PowerStatus::kMaxBatteryTimeToDisplaySec = 24 * 60 * 60; 171 const int PowerStatus::kMaxBatteryTimeToDisplaySec = 24 * 60 * 60;
111 172
173 const double PowerStatus::kCriticalBatteryChargePercentageMd = 5;
174
112 // static 175 // static
113 void PowerStatus::Initialize() { 176 void PowerStatus::Initialize() {
114 CHECK(!g_power_status); 177 CHECK(!g_power_status);
115 g_power_status = new PowerStatus(); 178 g_power_status = new PowerStatus();
116 } 179 }
117 180
118 // static 181 // static
119 void PowerStatus::Shutdown() { 182 void PowerStatus::Shutdown() {
120 CHECK(g_power_status); 183 CHECK(g_power_status);
121 delete g_power_status; 184 delete g_power_status;
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 return sources; 316 return sources;
254 } 317 }
255 318
256 std::string PowerStatus::GetCurrentPowerSourceID() const { 319 std::string PowerStatus::GetCurrentPowerSourceID() const {
257 return proto_.external_power_source_id(); 320 return proto_.external_power_source_id();
258 } 321 }
259 322
260 PowerStatus::BatteryImageInfo PowerStatus::GetBatteryImageInfo( 323 PowerStatus::BatteryImageInfo PowerStatus::GetBatteryImageInfo(
261 IconSet icon_set) const { 324 IconSet icon_set) const {
262 BatteryImageInfo info; 325 BatteryImageInfo info;
326 if (MaterialDesignController::UseMaterialDesignSystemIcons())
327 CalculateBatteryImageInfoMd(&info);
328 else
329 CalculateBatteryImageInfoNonMd(&info, icon_set);
330 return info;
331 }
263 332
333 void PowerStatus::CalculateBatteryImageInfoMd(BatteryImageInfo* info) const {
334 if (!IsUsbChargerConnected() && !IsBatteryPresent()) {
335 info->icon_badge = ICON_BADGE_X;
336 info->charge_level = 0;
337 return;
338 }
339
340 if (IsUsbChargerConnected())
341 info->icon_badge = ICON_BADGE_UNRELIABLE;
342 else if (IsLinePowerConnected())
343 info->icon_badge = ICON_BADGE_BOLT;
344 else
345 info->icon_badge = ICON_BADGE_NONE;
346
347 // |charge_state| is a value between 0 and kBatteryImageHeightMd representing
348 // the number of device pixels the battery image should be shown charged. The
349 // exception is when |charge_state| is 0 (a critically-low battery); in this
350 // case, still draw 1dp of charge.
351 int charge_state =
352 static_cast<int>(GetBatteryPercent() / 100.0 * kBatteryImageHeightMd);
353 charge_state = std::max(std::min(charge_state, kBatteryImageHeightMd), 0);
354 info->charge_level = std::max(charge_state, kMinVisualChargeLevelMd);
355
356 // Use ICON_BADGE_ALERT if the battery is critically low and does not already
357 // have a badge assigned.
358 if (GetBatteryPercent() < kCriticalBatteryChargePercentageMd &&
359 info->icon_badge == ICON_BADGE_NONE) {
360 info->icon_badge = ICON_BADGE_ALERT;
361 }
362 }
363
364 void PowerStatus::CalculateBatteryImageInfoNonMd(
365 BatteryImageInfo* info,
366 const IconSet& icon_set) const {
264 if (IsUsbChargerConnected()) { 367 if (IsUsbChargerConnected()) {
265 info.resource_id = 368 info->resource_id =
266 (icon_set == ICON_DARK) 369 (icon_set == ICON_DARK)
267 ? IDR_AURA_UBER_TRAY_POWER_SMALL_CHARGING_UNRELIABLE_DARK 370 ? IDR_AURA_UBER_TRAY_POWER_SMALL_CHARGING_UNRELIABLE_DARK
268 : IDR_AURA_UBER_TRAY_POWER_SMALL_CHARGING_UNRELIABLE; 371 : IDR_AURA_UBER_TRAY_POWER_SMALL_CHARGING_UNRELIABLE;
269 } else { 372 } else {
270 info.resource_id = (icon_set == ICON_DARK) 373 info->resource_id = (icon_set == ICON_DARK)
271 ? IDR_AURA_UBER_TRAY_POWER_SMALL_DARK 374 ? IDR_AURA_UBER_TRAY_POWER_SMALL_DARK
272 : IDR_AURA_UBER_TRAY_POWER_SMALL; 375 : IDR_AURA_UBER_TRAY_POWER_SMALL;
273 } 376 }
274 377
275 info.offset = IsUsbChargerConnected() ? 0 : (IsLinePowerConnected() ? 1 : 0); 378 info->offset = IsUsbChargerConnected() ? 0 : (IsLinePowerConnected() ? 1 : 0);
276 379
277 if (GetBatteryPercent() >= 100.0) { 380 if (GetBatteryPercent() >= 100.0) {
278 info.index = kNumPowerImages - 1; 381 info->index = kNumPowerImages - 1;
279 } else if (!IsBatteryPresent()) { 382 } else if (!IsBatteryPresent()) {
280 info.index = kNumPowerImages; 383 info->index = kNumPowerImages;
281 } else { 384 } else {
282 info.index = 385 info->index =
283 static_cast<int>(GetBatteryPercent() / 100.0 * (kNumPowerImages - 1)); 386 static_cast<int>(GetBatteryPercent() / 100.0 * (kNumPowerImages - 1));
284 info.index = std::max(std::min(info.index, kNumPowerImages - 2), 0); 387 info->index = std::max(std::min(info->index, kNumPowerImages - 2), 0);
388 }
389 }
390
391 gfx::ImageSkia PowerStatus::GetBatteryImage(
392 const BatteryImageInfo& info) const {
393 if (!MaterialDesignController::UseMaterialDesignSystemIcons())
394 return GetBatteryImageNonMd(info);
395
396 const bool use_alert_color =
397 (info.charge_level == kMinVisualChargeLevelMd && !IsLinePowerConnected());
398 const SkColor badge_color =
399 use_alert_color ? kBatteryAlertColor : kBatteryBadgeColor;
400 const SkColor charge_color =
401 use_alert_color ? kBatteryAlertColor : kBatteryChargeColor;
402 gfx::Canvas canvas(
403 gfx::Size(kBatteryCanvasSizeMd, kBatteryCanvasSizeMd),
404 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor(),
405 true);
406
407 // Paint the battery's base (background) color.
408 PaintVectorIcon(&canvas, gfx::VectorIconId::SYSTEM_TRAY_BATTERY,
409 kBatteryCanvasSizeMd, kBatteryBaseColor);
410
411 // Paint the charged portion of the battery. Note that |charge_height| adjusts
412 // for the 2dp of padding between the bottom of the battery icon and the
413 // bottom edge of |canvas|.
414 const int charge_height = info.charge_level + 2;
415 gfx::Rect clip_rect(0, kBatteryCanvasSizeMd - charge_height,
416 kBatteryCanvasSizeMd, charge_height);
417 canvas.Save();
418 canvas.ClipRect(clip_rect);
419 PaintVectorIcon(&canvas, gfx::VectorIconId::SYSTEM_TRAY_BATTERY,
420 kBatteryCanvasSizeMd, charge_color);
421 canvas.Restore();
422
423 // Paint the badge over top of the battery, if applicable.
424 if (info.icon_badge != ICON_BADGE_NONE) {
425 PaintVectorIcon(&canvas, VectorIconIdForIconBadge(info.icon_badge),
426 kBatteryCanvasSizeMd, badge_color);
285 } 427 }
286 428
287 return info; 429 return gfx::ImageSkia(canvas.ExtractImageRep());
288 } 430 }
289 431
290 gfx::ImageSkia PowerStatus::GetBatteryImage(IconSet icon_set) const { 432 gfx::ImageSkia PowerStatus::GetBatteryImageNonMd(
291 const BatteryImageInfo info = GetBatteryImageInfo(icon_set); 433 const BatteryImageInfo& info) const {
292 gfx::Image all; 434 gfx::Image all;
293 all = ui::ResourceBundle::GetSharedInstance().GetImageNamed(info.resource_id); 435 all = ui::ResourceBundle::GetSharedInstance().GetImageNamed(info.resource_id);
294 gfx::Rect region(info.offset * kBatteryImageWidth, 436 gfx::Rect region(info.offset * kBatteryImageWidth,
295 info.index * kBatteryImageHeight, kBatteryImageWidth, 437 info.index * kBatteryImageHeight, kBatteryImageWidth,
296 kBatteryImageHeight); 438 kBatteryImageHeight);
297 return gfx::ImageSkiaOperations::ExtractSubset(*all.ToImageSkia(), region); 439 return gfx::ImageSkiaOperations::ExtractSubset(*all.ToImageSkia(), region);
298 } 440 }
299 441
300 base::string16 PowerStatus::GetAccessibleNameString( 442 base::string16 PowerStatus::GetAccessibleNameString(
301 bool full_description) const { 443 bool full_description) const {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 } 504 }
363 505
364 void PowerStatus::PowerChanged( 506 void PowerStatus::PowerChanged(
365 const power_manager::PowerSupplyProperties& proto) { 507 const power_manager::PowerSupplyProperties& proto) {
366 proto_ = proto; 508 proto_ = proto;
367 SanitizeProto(&proto_); 509 SanitizeProto(&proto_);
368 FOR_EACH_OBSERVER(Observer, observers_, OnPowerStatusChanged()); 510 FOR_EACH_OBSERVER(Observer, observers_, OnPowerStatusChanged());
369 } 511 }
370 512
371 } // namespace ash 513 } // namespace ash
OLDNEW
« no previous file with comments | « ash/common/system/chromeos/power/power_status.h ('k') | ash/common/system/chromeos/power/power_status_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698