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

Side by Side Diff: ui/chromeos/network/network_icon.cc

Issue 2435903002: Move tray code from ui/chromeos/network/ (Closed)
Patch Set: Rebase Created 4 years, 1 month 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
« no previous file with comments | « ui/chromeos/network/network_icon.h ('k') | ui/chromeos/network/network_icon_animation.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 "ui/chromeos/network/network_icon.h"
6
7 #include "base/macros.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chromeos/network/device_state.h"
10 #include "chromeos/network/network_connection_handler.h"
11 #include "chromeos/network/network_state.h"
12 #include "chromeos/network/network_state_handler.h"
13 #include "chromeos/network/portal_detector/network_portal_detector.h"
14 #include "grit/ui_chromeos_resources.h"
15 #include "grit/ui_chromeos_strings.h"
16 #include "third_party/cros_system_api/dbus/service_constants.h"
17 #include "third_party/skia/include/core/SkPaint.h"
18 #include "third_party/skia/include/core/SkPath.h"
19 #include "ui/base/l10n/l10n_util.h"
20 #include "ui/base/resource/resource_bundle.h"
21 #include "ui/base/webui/web_ui_util.h"
22 #include "ui/chromeos/material_design_icon_controller.h"
23 #include "ui/chromeos/network/network_icon_animation.h"
24 #include "ui/chromeos/network/network_icon_animation_observer.h"
25 #include "ui/gfx/canvas.h"
26 #include "ui/gfx/color_palette.h"
27 #include "ui/gfx/geometry/insets.h"
28 #include "ui/gfx/geometry/rect.h"
29 #include "ui/gfx/geometry/size_conversions.h"
30 #include "ui/gfx/image/canvas_image_source.h"
31 #include "ui/gfx/image/image_skia_operations.h"
32 #include "ui/gfx/image/image_skia_source.h"
33 #include "ui/gfx/paint_vector_icon.h"
34 #include "ui/gfx/skia_util.h"
35 #include "ui/gfx/vector_icons_public.h"
36
37 using chromeos::DeviceState;
38 using chromeos::NetworkConnectionHandler;
39 using chromeos::NetworkHandler;
40 using chromeos::NetworkPortalDetector;
41 using chromeos::NetworkState;
42 using chromeos::NetworkStateHandler;
43 using chromeos::NetworkTypePattern;
44
45 namespace ui {
46 namespace network_icon {
47
48 namespace {
49
50 // Constants for offseting the badge displayed on top of the signal strength
51 // icon. The badge will extend outside of the base icon bounds by these amounts.
52 // Only used for MD. All values are in dp.
53
54 // The badge offsets are different depending on whether the icon is in the tray
55 // or menu.
56 const int kTrayIconBadgeOffset = 3;
57 const int kMenuIconBadgeOffset = 2;
58
59 // TODO(estade): use kTrayIconSize. See crbug.com/623987
60 const int kTrayIconSide = 16;
61
62 bool UseMd() {
63 return md_icon_controller::UseMaterialDesignNetworkIcons();
64 }
65
66 //------------------------------------------------------------------------------
67 // Struct to pass icon badges to NetworkIconImageSource.
68 struct Badges {
69 gfx::ImageSkia top_left;
70 gfx::ImageSkia top_right;
71 gfx::ImageSkia bottom_left;
72 gfx::ImageSkia bottom_right;
73 };
74
75 //------------------------------------------------------------------------------
76 // class used for maintaining a map of network state and images.
77 class NetworkIconImpl {
78 public:
79 NetworkIconImpl(const std::string& path, IconType icon_type);
80
81 // Determines whether or not the associated network might be dirty and if so
82 // updates and generates the icon. Does nothing if network no longer exists.
83 void Update(const chromeos::NetworkState* network);
84
85 const gfx::ImageSkia& image() const { return image_; }
86
87 private:
88 // Updates |strength_index_| for wireless networks. Returns true if changed.
89 bool UpdateWirelessStrengthIndex(const chromeos::NetworkState* network);
90
91 // Updates the local state for cellular networks. Returns true if changed.
92 bool UpdateCellularState(const chromeos::NetworkState* network);
93
94 // Updates the portal state for wireless networks. Returns true if changed.
95 bool UpdatePortalState(const chromeos::NetworkState* network);
96
97 // Updates the VPN badge. Returns true if changed.
98 bool UpdateVPNBadge();
99
100 // Gets |badges| based on |network| and the current state.
101 void GetBadges(const NetworkState* network, Badges* badges);
102
103 // Gets the appropriate icon and badges and composites the image.
104 void GenerateImage(const chromeos::NetworkState* network);
105
106 // Network path, used for debugging.
107 std::string network_path_;
108
109 // Defines color theme and VPN badging
110 const IconType icon_type_;
111
112 // Cached state of the network when the icon was last generated.
113 std::string state_;
114
115 // Cached strength index of the network when the icon was last generated.
116 int strength_index_;
117
118 // Cached technology badge for the network when the icon was last generated.
119 gfx::ImageSkia technology_badge_;
120
121 // Cached vpn badge for the network when the icon was last generated.
122 gfx::ImageSkia vpn_badge_;
123
124 // Cached roaming state of the network when the icon was last generated.
125 std::string roaming_state_;
126
127 // Cached portal state of the network when the icon was last generated.
128 bool behind_captive_portal_;
129
130 // Generated icon image.
131 gfx::ImageSkia image_;
132
133 DISALLOW_COPY_AND_ASSIGN(NetworkIconImpl);
134 };
135
136 //------------------------------------------------------------------------------
137 // Maintain a static (global) icon map. Note: Icons are never destroyed;
138 // it is assumed that a finite and reasonable number of network icons will be
139 // created during a session.
140
141 typedef std::map<std::string, NetworkIconImpl*> NetworkIconMap;
142
143 NetworkIconMap* GetIconMapInstance(IconType icon_type, bool create) {
144 typedef std::map<IconType, NetworkIconMap*> IconTypeMap;
145 static IconTypeMap* s_icon_map = nullptr;
146 if (s_icon_map == nullptr) {
147 if (!create)
148 return nullptr;
149 s_icon_map = new IconTypeMap;
150 }
151 if (s_icon_map->count(icon_type) == 0) {
152 if (!create)
153 return nullptr;
154 (*s_icon_map)[icon_type] = new NetworkIconMap;
155 }
156 return (*s_icon_map)[icon_type];
157 }
158
159 NetworkIconMap* GetIconMap(IconType icon_type) {
160 return GetIconMapInstance(icon_type, true);
161 }
162
163 void PurgeIconMap(IconType icon_type,
164 const std::set<std::string>& network_paths) {
165 NetworkIconMap* icon_map = GetIconMapInstance(icon_type, false);
166 if (!icon_map)
167 return;
168 for (NetworkIconMap::iterator loop_iter = icon_map->begin();
169 loop_iter != icon_map->end(); ) {
170 NetworkIconMap::iterator cur_iter = loop_iter++;
171 if (network_paths.count(cur_iter->first) == 0) {
172 delete cur_iter->second;
173 icon_map->erase(cur_iter);
174 }
175 }
176 }
177
178 //------------------------------------------------------------------------------
179 // Utilities for generating icon images.
180
181 // 'NONE' will default to ARCS behavior where appropriate (e.g. no network or
182 // if a new type gets added).
183 enum ImageType {
184 ARCS,
185 BARS,
186 NONE
187 };
188
189 // Amount to fade icons while connecting.
190 const double kConnectingImageAlpha = 0.5;
191
192 // Images for strength arcs for wireless networks or strength bars for cellular
193 // networks.
194 const int kNumNetworkImages = 5;
195
196 // Number of discrete images to use for alpha fade animation
197 const int kNumFadeImages = 10;
198
199 SkColor GetDefaultColorForIconType(IconType icon_type) {
200 // TODO(estade): use kTrayIconColor and kMenuIconColor.
201 return icon_type == ICON_TYPE_TRAY ? SK_ColorWHITE : gfx::kChromeIconGrey;
202 }
203
204 bool IconTypeIsDark(IconType icon_type) {
205 return (icon_type != ICON_TYPE_TRAY);
206 }
207
208 bool IconTypeHasVPNBadge(IconType icon_type) {
209 return (icon_type != ICON_TYPE_LIST);
210 }
211
212 // This defines how we assemble a network icon.
213 class NetworkIconImageSource : public gfx::CanvasImageSource {
214 public:
215 NetworkIconImageSource(const gfx::ImageSkia& icon, const Badges& badges)
216 : CanvasImageSource(icon.size(), false), icon_(icon), badges_(badges) {}
217 ~NetworkIconImageSource() override {}
218
219 // TODO(pkotwicz): Figure out what to do when a new image resolution becomes
220 // available.
221 void Draw(gfx::Canvas* canvas) override {
222 canvas->DrawImageInt(icon_, 0, 0);
223
224 if (!badges_.top_left.isNull())
225 canvas->DrawImageInt(badges_.top_left, 0, 0);
226 if (!badges_.top_right.isNull())
227 canvas->DrawImageInt(badges_.top_right,
228 icon_.width() - badges_.top_right.width(), 0);
229 if (!badges_.bottom_left.isNull()) {
230 canvas->DrawImageInt(badges_.bottom_left, 0,
231 icon_.height() - badges_.bottom_left.height());
232 }
233 if (!badges_.bottom_right.isNull()) {
234 canvas->DrawImageInt(badges_.bottom_right,
235 icon_.width() - badges_.bottom_right.width(),
236 icon_.height() - badges_.bottom_right.height());
237 }
238 }
239
240 private:
241 const gfx::ImageSkia icon_;
242 const Badges badges_;
243
244 DISALLOW_COPY_AND_ASSIGN(NetworkIconImageSource);
245 };
246
247 // This defines how we assemble a network icon.
248 class NetworkIconImageSourceMd : public gfx::CanvasImageSource {
249 public:
250 static gfx::ImageSkia CreateImage(const gfx::ImageSkia& icon,
251 const Badges& badges) {
252 auto source = new NetworkIconImageSourceMd(icon, badges);
253 return gfx::ImageSkia(source, source->size());
254 }
255
256 // gfx::CanvasImageSource:
257 void Draw(gfx::Canvas* canvas) override {
258 const int width = size().width();
259 const int height = size().height();
260
261 // The base icon is centered in both dimensions.
262 const int icon_y = (height - icon_.height()) / 2;
263 canvas->DrawImageInt(icon_, (width - icon_.width()) / 2, icon_y);
264
265 // The badges are flush against the edges of the canvas, except at the top,
266 // where the badge is only 1dp higher than the base image.
267 const int top_badge_y = icon_y - 1;
268 if (!badges_.top_left.isNull())
269 canvas->DrawImageInt(badges_.top_left, 0, top_badge_y);
270 if (!badges_.top_right.isNull()) {
271 canvas->DrawImageInt(badges_.top_right, width - badges_.top_right.width(),
272 top_badge_y);
273 }
274 if (!badges_.bottom_left.isNull()) {
275 canvas->DrawImageInt(badges_.bottom_left, 0,
276 height - badges_.bottom_left.height());
277 }
278 if (!badges_.bottom_right.isNull()) {
279 canvas->DrawImageInt(badges_.bottom_right,
280 width - badges_.bottom_right.width(),
281 height - badges_.bottom_right.height());
282 }
283 }
284
285 bool HasRepresentationAtAllScales() const override { return true; }
286
287 private:
288 NetworkIconImageSourceMd(const gfx::ImageSkia& icon, const Badges& badges)
289 : CanvasImageSource(GetSizeForBaseIconSize(icon.size()), false),
290 icon_(icon),
291 badges_(badges) {}
292 ~NetworkIconImageSourceMd() override {}
293
294 static gfx::Size GetSizeForBaseIconSize(const gfx::Size& base_icon_size) {
295 gfx::Size size = base_icon_size;
296 const int badge_offset = base_icon_size.width() == kTrayIconSide
297 ? kTrayIconBadgeOffset
298 : kMenuIconBadgeOffset;
299 size.Enlarge(badge_offset * 2, badge_offset * 2);
300 return size;
301 }
302
303 const gfx::ImageSkia icon_;
304 const Badges badges_;
305
306 DISALLOW_COPY_AND_ASSIGN(NetworkIconImageSourceMd);
307 };
308
309 // Depicts a given signal strength using arcs (e.g. for WiFi connections) or
310 // bars (e.g. for cell connections).
311 class SignalStrengthImageSource : public gfx::CanvasImageSource {
312 public:
313 SignalStrengthImageSource(ImageType image_type,
314 IconType icon_type,
315 int signal_strength)
316 : CanvasImageSource(GetSizeForIconType(icon_type), false),
317 image_type_(image_type),
318 icon_type_(icon_type),
319 color_(GetDefaultColorForIconType(icon_type_)),
320 signal_strength_(signal_strength) {
321 if (image_type_ == NONE)
322 image_type_ = ARCS;
323
324 DCHECK_GE(signal_strength, 0);
325 DCHECK_LT(signal_strength, kNumNetworkImages);
326 }
327 ~SignalStrengthImageSource() override {}
328
329 void set_color(SkColor color) { color_ = color; }
330
331 // gfx::CanvasImageSource:
332 void Draw(gfx::Canvas* canvas) override {
333 if (image_type_ == ARCS)
334 DrawArcs(canvas);
335 else
336 DrawBars(canvas);
337 }
338
339 bool HasRepresentationAtAllScales() const override {
340 return true;
341 }
342
343 private:
344 static gfx::Size GetSizeForIconType(IconType icon_type) {
345 return icon_type == ICON_TYPE_TRAY
346 ? gfx::Size(kTrayIconSide, kTrayIconSide)
347 // TODO(estade): use kMenuIconSize instead of 20.
348 : gfx::Size(20, 20);
349 }
350
351 void DrawArcs(gfx::Canvas* canvas) {
352 gfx::RectF oval_bounds((gfx::Rect(size())));
353 oval_bounds.Inset(gfx::Insets(kIconInset));
354 // Double the width and height. The new midpoint should be the former
355 // bottom center.
356 oval_bounds.Inset(-oval_bounds.width() / 2, 0, -oval_bounds.width() / 2,
357 -oval_bounds.height());
358
359 const SkScalar kAngleAboveHorizontal = 51.f;
360 const SkScalar kStartAngle = 180.f + kAngleAboveHorizontal;
361 const SkScalar kSweepAngle = 180.f - 2 * kAngleAboveHorizontal;
362
363 SkPaint paint;
364 paint.setAntiAlias(true);
365 paint.setStyle(SkPaint::kFill_Style);
366 // Background. Skip drawing for full signal.
367 if (signal_strength_ != kNumNetworkImages - 1) {
368 paint.setColor(SkColorSetA(color_, kBgAlpha));
369 canvas->sk_canvas()->drawArc(gfx::RectFToSkRect(oval_bounds), kStartAngle,
370 kSweepAngle, true, paint);
371 }
372 // Foreground (signal strength).
373 if (signal_strength_ != 0) {
374 paint.setColor(color_);
375 // Percent of the height of the background wedge that we draw the
376 // foreground wedge, indexed by signal strength.
377 static const float kWedgeHeightPercentages[] = {0.f, 0.375f, 0.5833f,
378 0.75f, 1.f};
379 const float wedge_percent = kWedgeHeightPercentages[signal_strength_];
380 oval_bounds.Inset(
381 gfx::InsetsF((oval_bounds.height() / 2) * (1.f - wedge_percent)));
382 canvas->sk_canvas()->drawArc(gfx::RectFToSkRect(oval_bounds), kStartAngle,
383 kSweepAngle, true, paint);
384 }
385 }
386
387 void DrawBars(gfx::Canvas* canvas) {
388 // Undo the canvas's device scaling and round values to the nearest whole
389 // number so we can draw on exact pixel boundaries.
390 const float dsf = canvas->UndoDeviceScaleFactor();
391 auto scale = [dsf](SkScalar dimension) {
392 return std::round(dimension * dsf);
393 };
394
395 // Length of short side of an isosceles right triangle, in dip.
396 const SkScalar kFullTriangleSide =
397 SkIntToScalar(size().width()) - kIconInset * 2;
398
399 auto make_triangle = [scale, kFullTriangleSide](SkScalar side) {
400 SkPath triangle;
401 triangle.moveTo(scale(kIconInset), scale(kIconInset + kFullTriangleSide));
402 triangle.rLineTo(scale(side), 0);
403 triangle.rLineTo(0, -scale(side));
404 triangle.close();
405 return triangle;
406 };
407
408 SkPaint paint;
409 paint.setAntiAlias(true);
410 paint.setStyle(SkPaint::kFill_Style);
411 // Background. Skip drawing for full signal.
412 if (signal_strength_ != kNumNetworkImages - 1) {
413 paint.setColor(SkColorSetA(color_, kBgAlpha));
414 canvas->DrawPath(make_triangle(kFullTriangleSide), paint);
415 }
416 // Foreground (signal strength).
417 if (signal_strength_ != 0) {
418 paint.setColor(color_);
419 // As a percentage of the bg triangle, the length of one of the short
420 // sides of the fg triangle, indexed by signal strength.
421 static const float kTriangleSidePercents[] = {0.f, 0.5f, 0.625f, 0.75f,
422 1.f};
423 canvas->DrawPath(make_triangle(kTriangleSidePercents[signal_strength_] *
424 kFullTriangleSide),
425 paint);
426 }
427 }
428
429 ImageType image_type_;
430 IconType icon_type_;
431 SkColor color_;
432
433 // On a scale of 0 to kNum{Arcs,Bars}Images - 1, how connected we are.
434 int signal_strength_;
435
436 // Padding between outside of icon and edge of the canvas, in dp. This value
437 // stays the same regardless of the canvas size (which depends on
438 // |icon_type_|).
439 static constexpr int kIconInset = 2;
440
441 // TODO(estade): share this alpha with other things in ash (battery, etc.).
442 // See crbug.com/623987 and crbug.com/632827
443 static constexpr int kBgAlpha = 0x4D;
444
445 DISALLOW_COPY_AND_ASSIGN(SignalStrengthImageSource);
446 };
447
448 //------------------------------------------------------------------------------
449 // Utilities for extracting icon images.
450
451 gfx::ImageSkia* BaseImageForType(ImageType image_type, IconType icon_type) {
452 gfx::ImageSkia* image;
453 if (image_type == BARS) {
454 image = ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
455 IconTypeIsDark(icon_type) ? IDR_AURA_UBER_TRAY_NETWORK_BARS_DARK
456 : IDR_AURA_UBER_TRAY_NETWORK_BARS_LIGHT);
457 } else {
458 image = ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
459 IconTypeIsDark(icon_type) ? IDR_AURA_UBER_TRAY_NETWORK_ARCS_DARK
460 : IDR_AURA_UBER_TRAY_NETWORK_ARCS_LIGHT);
461 }
462 return image;
463 }
464
465 ImageType ImageTypeForNetworkType(const std::string& type) {
466 if (type == shill::kTypeWifi)
467 return ARCS;
468 else if (type == shill::kTypeCellular || type == shill::kTypeWimax)
469 return BARS;
470 return NONE;
471 }
472
473 gfx::ImageSkia GetImageForIndex(ImageType image_type,
474 IconType icon_type,
475 int index) {
476 if (UseMd()) {
477 gfx::CanvasImageSource* source =
478 new SignalStrengthImageSource(image_type, icon_type, index);
479 return gfx::ImageSkia(source, source->size());
480 }
481
482 if (index < 0 || index >= kNumNetworkImages)
483 return gfx::ImageSkia();
484 gfx::ImageSkia* images = BaseImageForType(image_type, icon_type);
485 int width = images->width();
486 int height = images->height() / kNumNetworkImages;
487 return gfx::ImageSkiaOperations::ExtractSubset(*images,
488 gfx::Rect(0, index * height, width, height));
489 }
490
491 const gfx::ImageSkia GetDisconnectedImage(IconType icon_type,
492 const std::string& network_type) {
493 DCHECK_NE(shill::kTypeVPN, network_type);
494 ImageType image_type = ImageTypeForNetworkType(network_type);
495 const int disconnected_index = 0;
496 return GetImageForIndex(image_type, icon_type, disconnected_index);
497 }
498
499 gfx::ImageSkia* ConnectingWirelessImage(ImageType image_type,
500 IconType icon_type,
501 double animation) {
502 static const int kImageCount = kNumNetworkImages - 1;
503 static gfx::ImageSkia* s_bars_images_dark[kImageCount];
504 static gfx::ImageSkia* s_bars_images_light[kImageCount];
505 static gfx::ImageSkia* s_arcs_images_dark[kImageCount];
506 static gfx::ImageSkia* s_arcs_images_light[kImageCount];
507 int index = animation * nextafter(static_cast<float>(kImageCount), 0);
508 index = std::max(std::min(index, kImageCount - 1), 0);
509 gfx::ImageSkia** images;
510 bool dark = IconTypeIsDark(icon_type);
511 if (image_type == BARS)
512 images = dark ? s_bars_images_dark : s_bars_images_light;
513 else
514 images = dark ? s_arcs_images_dark : s_arcs_images_light;
515 if (!images[index]) {
516 // Lazily cache images.
517 // TODO(estade): should the alpha be applied in SignalStrengthImageSource?
518 gfx::ImageSkia source = GetImageForIndex(image_type, icon_type, index + 1);
519 images[index] =
520 new gfx::ImageSkia(gfx::ImageSkiaOperations::CreateTransparentImage(
521 source, kConnectingImageAlpha));
522 }
523 return images[index];
524 }
525
526 gfx::ImageSkia ConnectingVpnImage(double animation) {
527 int index = animation * nextafter(static_cast<float>(kNumFadeImages), 0);
528 static gfx::ImageSkia* s_vpn_images[kNumFadeImages];
529 if (!s_vpn_images[index]) {
530 // Lazily cache images.
531 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
532 gfx::ImageSkia* icon = rb.GetImageSkiaNamed(IDR_AURA_UBER_TRAY_NETWORK_VPN);
533 s_vpn_images[index] = new gfx::ImageSkia(
534 gfx::ImageSkiaOperations::CreateTransparentImage(*icon, animation));
535 }
536 return *s_vpn_images[index];
537 }
538
539 gfx::ImageSkia ConnectingVpnBadge(double animation, IconType icon_type) {
540 int index = animation * nextafter(static_cast<float>(kNumFadeImages), 0);
541 static gfx::ImageSkia* s_vpn_badges[kNumFadeImages];
542 if (!s_vpn_badges[index]) {
543 // Lazily cache images.
544 gfx::ImageSkia badge =
545 UseMd() ? gfx::CreateVectorIcon(gfx::VectorIconId::NETWORK_BADGE_VPN,
546 GetDefaultColorForIconType(icon_type))
547 : *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
548 IDR_AURA_UBER_TRAY_NETWORK_VPN_BADGE);
549 s_vpn_badges[index] = new gfx::ImageSkia(
550 gfx::ImageSkiaOperations::CreateTransparentImage(badge, animation));
551 }
552 return *s_vpn_badges[index];
553 }
554
555 int StrengthIndex(int strength) {
556 // Return an index in the range [1, kNumNetworkImages - 1].
557 const float findex = (static_cast<float>(strength) / 100.0f) *
558 nextafter(static_cast<float>(kNumNetworkImages - 1), 0);
559 int index = 1 + static_cast<int>(findex);
560 index = std::max(std::min(index, kNumNetworkImages - 1), 1);
561 return index;
562 }
563
564 gfx::ImageSkia BadgeForNetworkTechnology(const NetworkState* network,
565 IconType icon_type) {
566 const std::string& technology = network->network_technology();
567 if (UseMd()) {
568 gfx::VectorIconId id = gfx::VectorIconId::VECTOR_ICON_NONE;
569 if (technology == shill::kNetworkTechnologyEvdo) {
570 id = gfx::VectorIconId::NETWORK_BADGE_TECHNOLOGY_EVDO;
571 } else if (technology == shill::kNetworkTechnology1Xrtt) {
572 id = gfx::VectorIconId::NETWORK_BADGE_TECHNOLOGY_1X;
573 } else if (technology == shill::kNetworkTechnologyGprs ||
574 technology == shill::kNetworkTechnologyGsm) {
575 id = gfx::VectorIconId::NETWORK_BADGE_TECHNOLOGY_GPRS;
576 } else if (technology == shill::kNetworkTechnologyEdge) {
577 id = gfx::VectorIconId::NETWORK_BADGE_TECHNOLOGY_EDGE;
578 } else if (technology == shill::kNetworkTechnologyUmts) {
579 id = gfx::VectorIconId::NETWORK_BADGE_TECHNOLOGY_3G;
580 } else if (technology == shill::kNetworkTechnologyHspa) {
581 id = gfx::VectorIconId::NETWORK_BADGE_TECHNOLOGY_HSPA;
582 } else if (technology == shill::kNetworkTechnologyHspaPlus) {
583 id = gfx::VectorIconId::NETWORK_BADGE_TECHNOLOGY_HSPA_PLUS;
584 } else if (technology == shill::kNetworkTechnologyLte) {
585 id = gfx::VectorIconId::NETWORK_BADGE_TECHNOLOGY_LTE;
586 } else if (technology == shill::kNetworkTechnologyLteAdvanced) {
587 id = gfx::VectorIconId::NETWORK_BADGE_TECHNOLOGY_LTE_ADVANCED;
588 } else {
589 return gfx::ImageSkia();
590 }
591 return gfx::CreateVectorIcon(id, GetDefaultColorForIconType(icon_type));
592 }
593
594 int id = -1;
595 if (technology == shill::kNetworkTechnologyEvdo) {
596 id = IconTypeIsDark(icon_type) ? IDR_AURA_UBER_TRAY_NETWORK_EVDO_DARK
597 : IDR_AURA_UBER_TRAY_NETWORK_EVDO_LIGHT;
598 } else if (technology == shill::kNetworkTechnology1Xrtt) {
599 id = IDR_AURA_UBER_TRAY_NETWORK_1X;
600 } else if (technology == shill::kNetworkTechnologyGprs) {
601 id = IconTypeIsDark(icon_type) ? IDR_AURA_UBER_TRAY_NETWORK_GPRS_DARK
602 : IDR_AURA_UBER_TRAY_NETWORK_GPRS_LIGHT;
603 } else if (technology == shill::kNetworkTechnologyEdge) {
604 id = IconTypeIsDark(icon_type) ? IDR_AURA_UBER_TRAY_NETWORK_EDGE_DARK
605 : IDR_AURA_UBER_TRAY_NETWORK_EDGE_LIGHT;
606 } else if (technology == shill::kNetworkTechnologyUmts) {
607 id = IconTypeIsDark(icon_type) ? IDR_AURA_UBER_TRAY_NETWORK_3G_DARK
608 : IDR_AURA_UBER_TRAY_NETWORK_3G_LIGHT;
609 } else if (technology == shill::kNetworkTechnologyHspa) {
610 id = IconTypeIsDark(icon_type) ? IDR_AURA_UBER_TRAY_NETWORK_HSPA_DARK
611 : IDR_AURA_UBER_TRAY_NETWORK_HSPA_LIGHT;
612 } else if (technology == shill::kNetworkTechnologyHspaPlus) {
613 id = IconTypeIsDark(icon_type) ? IDR_AURA_UBER_TRAY_NETWORK_HSPA_PLUS_DARK
614 : IDR_AURA_UBER_TRAY_NETWORK_HSPA_PLUS_LIGHT;
615 } else if (technology == shill::kNetworkTechnologyLte) {
616 id = IconTypeIsDark(icon_type) ? IDR_AURA_UBER_TRAY_NETWORK_LTE_DARK
617 : IDR_AURA_UBER_TRAY_NETWORK_LTE_LIGHT;
618 } else if (technology == shill::kNetworkTechnologyLteAdvanced) {
619 id = IconTypeIsDark(icon_type)
620 ? IDR_AURA_UBER_TRAY_NETWORK_LTE_ADVANCED_DARK
621 : IDR_AURA_UBER_TRAY_NETWORK_LTE_ADVANCED_LIGHT;
622 } else if (technology == shill::kNetworkTechnologyGsm) {
623 id = IconTypeIsDark(icon_type) ? IDR_AURA_UBER_TRAY_NETWORK_GPRS_DARK
624 : IDR_AURA_UBER_TRAY_NETWORK_GPRS_LIGHT;
625 } else {
626 return gfx::ImageSkia();
627 }
628 return *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(id);
629 }
630
631 gfx::ImageSkia GetIcon(const NetworkState* network,
632 IconType icon_type,
633 int strength_index) {
634 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
635 if (network->Matches(NetworkTypePattern::Ethernet())) {
636 DCHECK_NE(ICON_TYPE_TRAY, icon_type);
637 return UseMd() ? gfx::CreateVectorIcon(
638 gfx::VectorIconId::NETWORK_ETHERNET,
639 GetDefaultColorForIconType(ICON_TYPE_LIST))
640 : *rb.GetImageSkiaNamed(IDR_AURA_UBER_TRAY_NETWORK_WIRED);
641 } else if (network->Matches(NetworkTypePattern::Wireless())) {
642 DCHECK(strength_index > 0);
643 return GetImageForIndex(ImageTypeForNetworkType(network->type()), icon_type,
644 strength_index);
645 } else if (network->Matches(NetworkTypePattern::VPN())) {
646 DCHECK_NE(ICON_TYPE_TRAY, icon_type);
647 return GetVpnImage();
648 }
649
650 NOTREACHED() << "Request for icon for unsupported type: " << network->type();
651 return gfx::ImageSkia();
652 }
653
654 //------------------------------------------------------------------------------
655 // Get connecting images
656
657 gfx::ImageSkia GetConnectingVpnImage(IconType icon_type) {
658 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
659 const NetworkState* connected_network = nullptr;
660 if (icon_type == ICON_TYPE_TRAY) {
661 connected_network =
662 handler->ConnectedNetworkByType(NetworkTypePattern::NonVirtual());
663 }
664 double animation = NetworkIconAnimation::GetInstance()->GetAnimation();
665
666 gfx::ImageSkia icon;
667 Badges badges;
668 if (connected_network) {
669 icon = GetImageForNetwork(connected_network, icon_type);
670 badges.bottom_left = ConnectingVpnBadge(animation, icon_type);
671 } else {
672 icon = ConnectingVpnImage(animation);
673 }
674 return UseMd() ? NetworkIconImageSourceMd::CreateImage(icon, badges)
675 : gfx::ImageSkia(new NetworkIconImageSource(icon, badges),
676 icon.size());
677 }
678
679 gfx::ImageSkia GetConnectingImage(IconType icon_type,
680 const std::string& network_type) {
681 if (network_type == shill::kTypeVPN)
682 return GetConnectingVpnImage(icon_type);
683
684 ImageType image_type = ImageTypeForNetworkType(network_type);
685 double animation = NetworkIconAnimation::GetInstance()->GetAnimation();
686
687 gfx::ImageSkia* icon = ConnectingWirelessImage(
688 image_type, icon_type, animation);
689 return UseMd() ? NetworkIconImageSourceMd::CreateImage(*icon, Badges())
690 : gfx::ImageSkia(new NetworkIconImageSource(*icon, Badges()),
691 icon->size());
692 }
693
694 } // namespace
695
696 //------------------------------------------------------------------------------
697 // NetworkIconImpl
698
699 NetworkIconImpl::NetworkIconImpl(const std::string& path, IconType icon_type)
700 : network_path_(path),
701 icon_type_(icon_type),
702 strength_index_(-1),
703 behind_captive_portal_(false) {
704 // Default image
705 image_ = GetDisconnectedImage(icon_type, shill::kTypeWifi);
706 }
707
708 void NetworkIconImpl::Update(const NetworkState* network) {
709 DCHECK(network);
710 // Determine whether or not we need to update the icon.
711 bool dirty = image_.isNull();
712
713 // If the network state has changed, the icon needs updating.
714 if (state_ != network->connection_state()) {
715 state_ = network->connection_state();
716 dirty = true;
717 }
718
719 dirty |= UpdatePortalState(network);
720
721 if (network->Matches(NetworkTypePattern::Wireless())) {
722 dirty |= UpdateWirelessStrengthIndex(network);
723 }
724
725 if (network->Matches(NetworkTypePattern::Cellular()))
726 dirty |= UpdateCellularState(network);
727
728 if (IconTypeHasVPNBadge(icon_type_) &&
729 network->Matches(NetworkTypePattern::NonVirtual())) {
730 dirty |= UpdateVPNBadge();
731 }
732
733 if (dirty) {
734 // Set the icon and badges based on the network and generate the image.
735 GenerateImage(network);
736 }
737 }
738
739 bool NetworkIconImpl::UpdateWirelessStrengthIndex(const NetworkState* network) {
740 int index = StrengthIndex(network->signal_strength());
741 if (index != strength_index_) {
742 strength_index_ = index;
743 return true;
744 }
745 return false;
746 }
747
748 bool NetworkIconImpl::UpdateCellularState(const NetworkState* network) {
749 bool dirty = false;
750 const gfx::ImageSkia technology_badge =
751 BadgeForNetworkTechnology(network, icon_type_);
752 if (!technology_badge.BackedBySameObjectAs(technology_badge_)) {
753 technology_badge_ = technology_badge;
754 dirty = true;
755 }
756 std::string roaming_state = network->roaming();
757 if (roaming_state != roaming_state_) {
758 roaming_state_ = roaming_state;
759 dirty = true;
760 }
761 return dirty;
762 }
763
764 bool NetworkIconImpl::UpdatePortalState(const NetworkState* network) {
765 bool behind_captive_portal = false;
766 if (network && chromeos::network_portal_detector::IsInitialized()) {
767 NetworkPortalDetector::CaptivePortalState state =
768 chromeos::network_portal_detector::GetInstance()->GetCaptivePortalState(
769 network->guid());
770 behind_captive_portal =
771 state.status == NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL;
772 }
773
774 if (behind_captive_portal == behind_captive_portal_)
775 return false;
776 behind_captive_portal_ = behind_captive_portal;
777 return true;
778 }
779
780 bool NetworkIconImpl::UpdateVPNBadge() {
781 const NetworkState* vpn = NetworkHandler::Get()->network_state_handler()->
782 ConnectedNetworkByType(NetworkTypePattern::VPN());
783 if (vpn && vpn_badge_.isNull()) {
784 vpn_badge_ =
785 UseMd() ? gfx::CreateVectorIcon(gfx::VectorIconId::NETWORK_BADGE_VPN,
786 GetDefaultColorForIconType(icon_type_))
787 : *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
788 IDR_AURA_UBER_TRAY_NETWORK_VPN_BADGE);
789 return true;
790 }
791 if (!vpn && !vpn_badge_.isNull()) {
792 vpn_badge_ = gfx::ImageSkia();
793 return true;
794 }
795 return false;
796 }
797
798 void NetworkIconImpl::GetBadges(const NetworkState* network, Badges* badges) {
799 DCHECK(network);
800 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
801 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
802
803 const std::string& type = network->type();
804 const SkColor icon_color = GetDefaultColorForIconType(icon_type_);
805 if (type == shill::kTypeWifi) {
806 if (network->security_class() != shill::kSecurityNone &&
807 IconTypeIsDark(icon_type_)) {
808 badges->bottom_right =
809 UseMd()
810 ? gfx::CreateVectorIcon(gfx::VectorIconId::NETWORK_BADGE_SECURE,
811 icon_color)
812 : *rb.GetImageSkiaNamed(IDR_AURA_UBER_TRAY_NETWORK_SECURE_DARK);
813 }
814 } else if (type == shill::kTypeWimax) {
815 technology_badge_ =
816 UseMd()
817 ? gfx::CreateVectorIcon(
818 gfx::VectorIconId::NETWORK_BADGE_TECHNOLOGY_4G, icon_color)
819 : *rb.GetImageSkiaNamed(IconTypeIsDark(icon_type_)
820 ? IDR_AURA_UBER_TRAY_NETWORK_4G_DARK
821 : IDR_AURA_UBER_TRAY_NETWORK_4G_LIGHT);
822 } else if (type == shill::kTypeCellular) {
823 if (network->roaming() == shill::kRoamingStateRoaming) {
824 // For networks that are always in roaming don't show roaming badge.
825 const DeviceState* device =
826 handler->GetDeviceState(network->device_path());
827 LOG_IF(WARNING, !device) << "Could not find device state for "
828 << network->device_path();
829 if (!device || !device->provider_requires_roaming()) {
830 badges->bottom_right =
831 UseMd() ? gfx::CreateVectorIcon(
832 gfx::VectorIconId::NETWORK_BADGE_ROAMING, icon_color)
833 : *rb.GetImageSkiaNamed(
834 IconTypeIsDark(icon_type_)
835 ? IDR_AURA_UBER_TRAY_NETWORK_ROAMING_DARK
836 : IDR_AURA_UBER_TRAY_NETWORK_ROAMING_LIGHT);
837 }
838 }
839 }
840 if (!network->IsConnectingState()) {
841 badges->top_left = technology_badge_;
842 badges->bottom_left = vpn_badge_;
843 }
844
845 if (behind_captive_portal_) {
846 badges->bottom_right =
847 UseMd()
848 ? gfx::CreateVectorIcon(
849 gfx::VectorIconId::NETWORK_BADGE_CAPTIVE_PORTAL, icon_color)
850 : *rb.GetImageSkiaNamed(
851 IconTypeIsDark(icon_type_)
852 ? IDR_AURA_UBER_TRAY_NETWORK_PORTAL_DARK
853 : IDR_AURA_UBER_TRAY_NETWORK_PORTAL_LIGHT);
854 }
855 }
856
857 void NetworkIconImpl::GenerateImage(const NetworkState* network) {
858 DCHECK(network);
859 gfx::ImageSkia icon = GetIcon(network, icon_type_, strength_index_);
860 Badges badges;
861 GetBadges(network, &badges);
862 image_ = UseMd() ? NetworkIconImageSourceMd::CreateImage(icon, badges)
863 : gfx::ImageSkia(new NetworkIconImageSource(icon, badges),
864 icon.size());
865 }
866
867 namespace {
868
869 NetworkIconImpl* FindAndUpdateImageImpl(const NetworkState* network,
870 IconType icon_type) {
871 // Find or add the icon.
872 NetworkIconMap* icon_map = GetIconMap(icon_type);
873 NetworkIconImpl* icon;
874 NetworkIconMap::iterator iter = icon_map->find(network->path());
875 if (iter == icon_map->end()) {
876 icon = new NetworkIconImpl(network->path(), icon_type);
877 icon_map->insert(std::make_pair(network->path(), icon));
878 } else {
879 icon = iter->second;
880 }
881
882 // Update and return the icon's image.
883 icon->Update(network);
884 return icon;
885 }
886
887 } // namespace
888
889 //------------------------------------------------------------------------------
890 // Public interface
891
892 gfx::ImageSkia GetImageForNetwork(const NetworkState* network,
893 IconType icon_type) {
894 DCHECK(network);
895 if (!network->visible())
896 return GetDisconnectedImage(icon_type, network->type());
897
898 if (network->IsConnectingState())
899 return GetConnectingImage(icon_type, network->type());
900
901 NetworkIconImpl* icon = FindAndUpdateImageImpl(network, icon_type);
902 return icon->image();
903 }
904
905 gfx::ImageSkia GetImageForConnectedMobileNetwork() {
906 ImageType image_type = ImageTypeForNetworkType(shill::kTypeWifi);
907 const IconType icon_type = ICON_TYPE_LIST;
908 const int connected_index = kNumNetworkImages - 1;
909 return GetImageForIndex(image_type, icon_type, connected_index);
910 }
911
912 gfx::ImageSkia GetImageForDisconnectedCellNetwork() {
913 return GetDisconnectedImage(ICON_TYPE_LIST, shill::kTypeCellular);
914 }
915
916 gfx::ImageSkia GetImageForNewWifiNetwork(SkColor icon_color,
917 SkColor badge_color) {
918 SignalStrengthImageSource* source =
919 new SignalStrengthImageSource(ImageTypeForNetworkType(shill::kTypeWifi),
920 ICON_TYPE_LIST, kNumNetworkImages - 1);
921 source->set_color(icon_color);
922 gfx::ImageSkia icon = gfx::ImageSkia(source, source->size());
923 Badges badges;
924 badges.bottom_right = gfx::CreateVectorIcon(
925 gfx::VectorIconId::NETWORK_BADGE_ADD_OTHER, badge_color);
926 return NetworkIconImageSourceMd::CreateImage(icon, badges);
927 }
928
929 gfx::ImageSkia GetVpnImage() {
930 return UseMd()
931 ? gfx::CreateVectorIcon(gfx::VectorIconId::NETWORK_VPN,
932 GetDefaultColorForIconType(ICON_TYPE_LIST))
933 : *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
934 IDR_AURA_UBER_TRAY_NETWORK_VPN);
935 }
936
937 base::string16 GetLabelForNetwork(const chromeos::NetworkState* network,
938 IconType icon_type) {
939 DCHECK(network);
940 std::string activation_state = network->activation_state();
941 if (icon_type == ICON_TYPE_LIST) {
942 // Show "<network>: [Connecting|Activating|Reconnecting]..."
943 if (network->IsReconnecting()) {
944 return l10n_util::GetStringFUTF16(
945 IDS_ASH_STATUS_TRAY_NETWORK_LIST_RECONNECTING,
946 base::UTF8ToUTF16(network->name()));
947 }
948 if (network->IsConnectingState()) {
949 return l10n_util::GetStringFUTF16(
950 IDS_ASH_STATUS_TRAY_NETWORK_LIST_CONNECTING,
951 base::UTF8ToUTF16(network->name()));
952 }
953 if (activation_state == shill::kActivationStateActivating) {
954 return l10n_util::GetStringFUTF16(
955 IDS_ASH_STATUS_TRAY_NETWORK_LIST_ACTIVATING,
956 base::UTF8ToUTF16(network->name()));
957 }
958 // Show "Activate <network>" in list view only.
959 if (activation_state == shill::kActivationStateNotActivated ||
960 activation_state == shill::kActivationStatePartiallyActivated) {
961 return l10n_util::GetStringFUTF16(
962 IDS_ASH_STATUS_TRAY_NETWORK_LIST_ACTIVATE,
963 base::UTF8ToUTF16(network->name()));
964 }
965 } else {
966 // Show "[Connected to|Connecting to|Activating|Reconnecting to] <network>"
967 // (non-list view).
968 if (network->IsReconnecting()) {
969 return l10n_util::GetStringFUTF16(
970 IDS_ASH_STATUS_TRAY_NETWORK_RECONNECTING,
971 base::UTF8ToUTF16(network->name()));
972 }
973 if (network->IsConnectedState()) {
974 return l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_NETWORK_CONNECTED,
975 base::UTF8ToUTF16(network->name()));
976 }
977 if (network->IsConnectingState()) {
978 return l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_NETWORK_CONNECTING,
979 base::UTF8ToUTF16(network->name()));
980 }
981 if (activation_state == shill::kActivationStateActivating) {
982 return l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_NETWORK_ACTIVATING,
983 base::UTF8ToUTF16(network->name()));
984 }
985 }
986
987 // Otherwise just show the network name or 'Ethernet'.
988 if (network->Matches(NetworkTypePattern::Ethernet())) {
989 return l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_ETHERNET);
990 } else {
991 return base::UTF8ToUTF16(network->name());
992 }
993 }
994
995 int GetCellularUninitializedMsg() {
996 static base::Time s_uninitialized_state_time;
997 static int s_uninitialized_msg(0);
998
999 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
1000 if (handler->GetTechnologyState(NetworkTypePattern::Mobile())
1001 == NetworkStateHandler::TECHNOLOGY_UNINITIALIZED) {
1002 s_uninitialized_msg = IDS_ASH_STATUS_TRAY_INITIALIZING_CELLULAR;
1003 s_uninitialized_state_time = base::Time::Now();
1004 return s_uninitialized_msg;
1005 } else if (handler->GetScanningByType(NetworkTypePattern::Mobile())) {
1006 s_uninitialized_msg = IDS_ASH_STATUS_TRAY_CELLULAR_SCANNING;
1007 s_uninitialized_state_time = base::Time::Now();
1008 return s_uninitialized_msg;
1009 }
1010 // There can be a delay between leaving the Initializing state and when
1011 // a Cellular device shows up, so keep showing the initializing
1012 // animation for a bit to avoid flashing the disconnect icon.
1013 const int kInitializingDelaySeconds = 1;
1014 base::TimeDelta dtime = base::Time::Now() - s_uninitialized_state_time;
1015 if (dtime.InSeconds() < kInitializingDelaySeconds)
1016 return s_uninitialized_msg;
1017 return 0;
1018 }
1019
1020 void GetDefaultNetworkImageAndLabel(IconType icon_type,
1021 gfx::ImageSkia* image,
1022 base::string16* label,
1023 bool* animating) {
1024 NetworkStateHandler* state_handler =
1025 NetworkHandler::Get()->network_state_handler();
1026 NetworkConnectionHandler* connect_handler =
1027 NetworkHandler::Get()->network_connection_handler();
1028 const NetworkState* connected_network =
1029 state_handler->ConnectedNetworkByType(NetworkTypePattern::NonVirtual());
1030 const NetworkState* connecting_network =
1031 state_handler->ConnectingNetworkByType(NetworkTypePattern::Wireless());
1032 if (!connecting_network && icon_type == ICON_TYPE_TRAY) {
1033 connecting_network =
1034 state_handler->ConnectingNetworkByType(NetworkTypePattern::VPN());
1035 }
1036
1037 const NetworkState* network;
1038 // If we are connecting to a network, and there is either no connected
1039 // network, or the connection was user requested, or shill triggered a
1040 // reconnection, use the connecting network.
1041 if (connecting_network &&
1042 (!connected_network || connecting_network->IsReconnecting() ||
1043 connect_handler->HasConnectingNetwork(connecting_network->path()))) {
1044 network = connecting_network;
1045 } else {
1046 network = connected_network;
1047 }
1048
1049 // Don't show ethernet in the tray
1050 if (icon_type == ICON_TYPE_TRAY && network &&
1051 network->Matches(NetworkTypePattern::Ethernet())) {
1052 *image = gfx::ImageSkia();
1053 *animating = false;
1054 return;
1055 }
1056
1057 if (!network) {
1058 // If no connecting network, check if we are activating a network.
1059 const NetworkState* mobile_network =
1060 state_handler->FirstNetworkByType(NetworkTypePattern::Mobile());
1061 if (mobile_network && (mobile_network->activation_state() ==
1062 shill::kActivationStateActivating)) {
1063 network = mobile_network;
1064 }
1065 }
1066 if (!network) {
1067 // If no connecting network, check for cellular initializing.
1068 int uninitialized_msg = GetCellularUninitializedMsg();
1069 if (uninitialized_msg != 0) {
1070 *image = GetConnectingImage(icon_type, shill::kTypeCellular);
1071 if (label)
1072 *label = l10n_util::GetStringUTF16(uninitialized_msg);
1073 *animating = true;
1074 } else {
1075 // Otherwise show the disconnected wifi icon.
1076 *image = GetDisconnectedImage(icon_type, shill::kTypeWifi);
1077 if (label) {
1078 *label = l10n_util::GetStringUTF16(
1079 IDS_ASH_STATUS_TRAY_NETWORK_NOT_CONNECTED);
1080 }
1081 *animating = false;
1082 }
1083 return;
1084 }
1085 *animating = network->IsConnectingState();
1086 // Get icon and label for connected or connecting network.
1087 *image = GetImageForNetwork(network, icon_type);
1088 if (label)
1089 *label = GetLabelForNetwork(network, icon_type);
1090 }
1091
1092 void PurgeNetworkIconCache() {
1093 NetworkStateHandler::NetworkStateList networks;
1094 NetworkHandler::Get()->network_state_handler()->GetVisibleNetworkList(
1095 &networks);
1096 std::set<std::string> network_paths;
1097 for (NetworkStateHandler::NetworkStateList::iterator iter = networks.begin();
1098 iter != networks.end(); ++iter) {
1099 network_paths.insert((*iter)->path());
1100 }
1101 PurgeIconMap(ICON_TYPE_TRAY, network_paths);
1102 PurgeIconMap(ICON_TYPE_DEFAULT_VIEW, network_paths);
1103 PurgeIconMap(ICON_TYPE_LIST, network_paths);
1104 }
1105
1106 } // namespace network_icon
1107 } // namespace ui
OLDNEW
« no previous file with comments | « ui/chromeos/network/network_icon.h ('k') | ui/chromeos/network/network_icon_animation.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698