OLD | NEW |
---|---|
(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 "ash/system/chromeos/network/network_icon.h" | |
6 | |
7 #include "ash/shell.h" | |
8 #include "base/observer_list.h" | |
9 #include "chromeos/network/device_state.h" | |
10 #include "chromeos/network/network_state.h" | |
11 #include "chromeos/network/network_state_handler.h" | |
12 #include "grit/ash_resources.h" | |
13 #include "third_party/cros_system_api/dbus/service_constants.h" | |
14 #include "ui/base/animation/animation_delegate.h" | |
15 #include "ui/base/animation/throb_animation.h" | |
16 #include "ui/base/resource/resource_bundle.h" | |
17 #include "ui/gfx/canvas.h" | |
18 #include "ui/gfx/image/image_skia_operations.h" | |
19 #include "ui/gfx/image/image_skia_source.h" | |
20 #include "ui/gfx/rect.h" | |
21 #include "ui/gfx/size_conversions.h" | |
22 | |
23 using chromeos::DeviceState; | |
24 using chromeos::NetworkStateHandler; | |
25 using chromeos::NetworkState; | |
26 | |
27 namespace ash { | |
28 namespace network_icon { | |
29 | |
30 //------------------------------------------------------------------------------ | |
31 // NetworkIcon class declaration | |
32 | |
33 class NetworkIcon { | |
gauravsh
2012/11/27 20:48:09
Is there a reason why this is not declared in netw
stevenjb
2012/11/27 22:19:19
network_icon.h defines the network_icon namespace.
| |
34 public: | |
35 NetworkIcon(const std::string& service_path, ResourceColorTheme color); | |
36 | |
37 // Determines whether or not the associated network might be dirty and if so | |
38 // updates and generates the icon. Does nothing if network no longer exists. | |
39 void Update(const chromeos::NetworkState* network); | |
40 | |
41 const gfx::ImageSkia& image() const { return image_; } | |
42 | |
43 private: | |
44 // Updates |strength_index_| for wireless networks. Returns true if changed. | |
45 bool UpdateWirelessStrengthIndex(const chromeos::NetworkState* network); | |
46 | |
47 // Updates the local state for cellular networks. Returns true if changed. | |
48 bool UpdateCellularState(const chromeos::NetworkState* network); | |
49 | |
50 // Gets the appropriate icon and badges and composites the image. | |
51 void GenerateImage(const chromeos::NetworkState* network); | |
52 | |
53 // Service path for the network this icon is associated with. | |
54 std::string service_path_; | |
55 | |
56 // Color theme for the icon. | |
57 ResourceColorTheme color_; | |
58 | |
59 // Cached state of the network when the icon was last generated. | |
60 std::string state_; | |
61 | |
62 // Cached strength index of the network when the icon was last generated. | |
63 int strength_index_; | |
64 | |
65 // Cached technology badge for the network when the icon was last generated. | |
66 const gfx::ImageSkia* technology_badge_; | |
67 | |
68 // Cached roaming state of the network when the icon was last generated. | |
69 std::string roaming_state_; | |
70 | |
71 // Generated icon image. | |
72 gfx::ImageSkia image_; | |
73 | |
74 DISALLOW_COPY_AND_ASSIGN(NetworkIcon); | |
75 }; | |
76 | |
77 namespace { | |
78 | |
79 //------------------------------------------------------------------------------ | |
80 // Utilities for generating icon images. | |
81 | |
82 enum ImageType { | |
83 ARCS = 0, | |
84 BARS | |
85 }; | |
86 | |
87 struct Badges { | |
88 Badges() | |
89 : top_left(NULL), | |
90 top_right(NULL), | |
91 bottom_left(NULL), | |
92 bottom_right(NULL) { | |
93 } | |
94 const gfx::ImageSkia* top_left; | |
95 const gfx::ImageSkia* top_right; | |
96 const gfx::ImageSkia* bottom_left; | |
97 const gfx::ImageSkia* bottom_right; | |
98 }; | |
99 | |
100 // Animation cycle length. | |
101 const int kThrobDurationMs = 750; | |
102 | |
103 // Amount to fade icons while connecting. | |
104 const double kConnectingImageAlpha = 0.5; | |
105 | |
106 // Images for strength bars for wired networks. | |
107 const int kNumBarsImages = 5; | |
108 gfx::ImageSkia* kBarsImagesAnimatingDark[kNumBarsImages - 1]; | |
109 gfx::ImageSkia* kBarsImagesAnimatingLight[kNumBarsImages - 1]; | |
110 | |
111 // Imagaes for strength arcs for wireless networks. | |
112 const int kNumArcsImages = 5; | |
113 gfx::ImageSkia* kArcsImagesAnimatingDark[kNumArcsImages - 1]; | |
114 gfx::ImageSkia* kArcsImagesAnimatingLight[kNumArcsImages - 1]; | |
115 | |
116 //------------------------------------------------------------------------------ | |
117 // Classes for generating scaled images. | |
118 | |
119 const SkBitmap GetEmptyBitmap(const gfx::Size pixel_size) { | |
120 typedef std::pair<int, int> SizeKey; | |
121 typedef std::map<SizeKey, SkBitmap> SizeBitmapMap; | |
122 static SizeBitmapMap* s_empty_bitmaps = new SizeBitmapMap; | |
123 | |
124 SizeKey key(pixel_size.width(), pixel_size.height()); | |
125 | |
126 SizeBitmapMap::iterator iter = s_empty_bitmaps->find(key); | |
127 if (iter != s_empty_bitmaps->end()) | |
128 return iter->second; | |
129 | |
130 SkBitmap empty; | |
131 empty.setConfig(SkBitmap::kARGB_8888_Config, key.first, key.second); | |
132 empty.allocPixels(); | |
133 empty.eraseARGB(0, 0, 0, 0); | |
134 (*s_empty_bitmaps)[key] = empty; | |
135 return empty; | |
136 } | |
137 | |
138 class EmptyImageSource: public gfx::ImageSkiaSource { | |
139 public: | |
140 explicit EmptyImageSource(const gfx::Size& size) | |
141 : size_(size) { | |
142 } | |
143 | |
144 virtual gfx::ImageSkiaRep GetImageForScale( | |
145 ui::ScaleFactor scale_factor) OVERRIDE { | |
146 gfx::Size pixel_size = gfx::ToFlooredSize( | |
147 gfx::ScaleSize(size_, ui::GetScaleFactorScale(scale_factor))); | |
148 SkBitmap empty_bitmap = GetEmptyBitmap(pixel_size); | |
149 return gfx::ImageSkiaRep(empty_bitmap, scale_factor); | |
150 } | |
151 private: | |
152 const gfx::Size size_; | |
153 | |
154 DISALLOW_COPY_AND_ASSIGN(EmptyImageSource); | |
155 }; | |
156 | |
157 // This defines how we assemble a network icon. | |
158 class NetworkIconImageSource : public gfx::ImageSkiaSource { | |
159 public: | |
160 NetworkIconImageSource(const gfx::ImageSkia& icon, const Badges& badges) | |
161 : icon_(icon), | |
162 badges_(badges) { | |
163 } | |
164 virtual ~NetworkIconImageSource() {} | |
165 | |
166 // TODO(pkotwicz): Figure out what to do when a new image resolution becomes | |
167 // available. | |
168 virtual gfx::ImageSkiaRep GetImageForScale( | |
169 ui::ScaleFactor scale_factor) OVERRIDE { | |
170 gfx::ImageSkiaRep icon_rep = icon_.GetRepresentation(scale_factor); | |
171 if (icon_rep.is_null()) | |
172 return gfx::ImageSkiaRep(); | |
173 gfx::Canvas canvas(icon_rep, false); | |
174 if (badges_.top_left) | |
175 canvas.DrawImageInt(*badges_.top_left, 0, 0); | |
176 if (badges_.top_right) | |
177 canvas.DrawImageInt(*badges_.top_right, | |
178 icon_.width() - badges_.top_right->width(), 0); | |
179 if (badges_.bottom_left) { | |
180 canvas.DrawImageInt(*badges_.bottom_left, | |
181 0, icon_.height() - badges_.bottom_left->height()); | |
182 } | |
183 if (badges_.bottom_right) { | |
184 canvas.DrawImageInt(*badges_.bottom_right, | |
185 icon_.width() - badges_.bottom_right->width(), | |
186 icon_.height() - badges_.bottom_right->height()); | |
187 } | |
188 return canvas.ExtractImageRep(); | |
189 } | |
190 | |
191 private: | |
192 const gfx::ImageSkia icon_; | |
193 const Badges badges_; | |
194 | |
195 DISALLOW_COPY_AND_ASSIGN(NetworkIconImageSource); | |
196 }; | |
197 | |
198 //------------------------------------------------------------------------------ | |
199 // Utilities for extracting icon images. | |
200 | |
201 int NumImagesForType(ImageType type) { | |
202 return (type == ARCS) ? kNumArcsImages : kNumBarsImages; | |
203 } | |
204 | |
205 gfx::ImageSkia** ImageListForType(ImageType type, | |
206 ResourceColorTheme color) { | |
207 gfx::ImageSkia** images; | |
208 if (type == ARCS) { | |
209 images = (color == COLOR_DARK) ? | |
210 kArcsImagesAnimatingDark : kArcsImagesAnimatingLight; | |
211 } else { | |
212 images = (color == COLOR_DARK) ? | |
213 kBarsImagesAnimatingDark : kBarsImagesAnimatingLight; | |
214 } | |
215 return images; | |
216 } | |
217 | |
218 gfx::ImageSkia* BaseImageForType(ImageType type, | |
219 ResourceColorTheme color) { | |
220 gfx::ImageSkia* image; | |
221 if (type == ARCS) { | |
222 image = ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | |
223 color == COLOR_DARK ? | |
224 IDR_AURA_UBER_TRAY_NETWORK_ARCS_DARK : | |
225 IDR_AURA_UBER_TRAY_NETWORK_ARCS_LIGHT); | |
226 } else { | |
227 image = ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | |
228 color == COLOR_DARK ? | |
229 IDR_AURA_UBER_TRAY_NETWORK_BARS_DARK : | |
230 IDR_AURA_UBER_TRAY_NETWORK_BARS_LIGHT); | |
231 } | |
232 return image; | |
233 } | |
234 | |
235 gfx::ImageSkia GetImageForIndex(ImageType type, | |
236 ResourceColorTheme color, | |
237 int index) { | |
238 int num_images = NumImagesForType(type); | |
239 if (index < 0 || index >= num_images) | |
240 return gfx::ImageSkia(); | |
241 gfx::ImageSkia* images = BaseImageForType(type, color); | |
242 int width = images->width(); | |
243 int height = images->height() / num_images; | |
244 return gfx::ImageSkiaOperations::ExtractSubset(*images, | |
245 gfx::Rect(0, index * height, width, height)); | |
246 } | |
247 | |
248 const gfx::ImageSkia GetDisconnectedImage(ResourceColorTheme color) { | |
249 return GetImageForIndex(ARCS, color, 0); | |
250 } | |
251 | |
252 int StrengthIndex(int strength, int count) { | |
253 // Return an index in the range [1, count-1]. | |
254 const float findex = (static_cast<float>(strength) / 100.0f) * | |
255 nextafter(static_cast<float>(count - 1), 0); | |
256 int index = 1 + static_cast<int>(findex); | |
257 index = std::max(std::min(index, count - 1), 1); | |
258 return index; | |
259 } | |
260 | |
261 int GetStrengthIndex(const NetworkState* network) { | |
262 if (network->type() == flimflam::kTypeWifi) { | |
263 return StrengthIndex(network->signal_strength(), kNumArcsImages); | |
264 } else if (network->type() == flimflam::kTypeWimax) { | |
265 return StrengthIndex(network->signal_strength(), kNumBarsImages); | |
266 } else if (network->type() == flimflam::kTypeCellular) { | |
267 return StrengthIndex(network->signal_strength(), kNumBarsImages); | |
268 } | |
269 return 0; | |
270 } | |
271 | |
272 const gfx::ImageSkia* BadgeForNetworkTechnology(const NetworkState* network, | |
273 ResourceColorTheme color) { | |
274 const int kUnknownBadgeType = -1; | |
275 int id = kUnknownBadgeType; | |
276 if (network->technology() == flimflam::kNetworkTechnologyEvdo) { | |
277 id = (color == COLOR_DARK) ? | |
278 IDR_AURA_UBER_TRAY_NETWORK_3G_DARK : | |
279 IDR_AURA_UBER_TRAY_NETWORK_3G_LIGHT; | |
280 } else if (network->technology() == flimflam::kNetworkTechnology1Xrtt) { | |
281 id = IDR_AURA_UBER_TRAY_NETWORK_1X; | |
282 } else if (network->technology() == flimflam::kNetworkTechnologyGprs) { | |
283 id = IDR_AURA_UBER_TRAY_NETWORK_GPRS; | |
284 } else if (network->technology() == flimflam::kNetworkTechnologyEdge) { | |
285 id = (color == COLOR_DARK) ? | |
286 IDR_AURA_UBER_TRAY_NETWORK_EDGE_DARK : | |
287 IDR_AURA_UBER_TRAY_NETWORK_EDGE_LIGHT; | |
288 } else if (network->technology() == flimflam::kNetworkTechnologyUmts) { | |
289 id = (color == COLOR_DARK) ? | |
290 IDR_AURA_UBER_TRAY_NETWORK_3G_DARK : | |
291 IDR_AURA_UBER_TRAY_NETWORK_3G_LIGHT; | |
292 } else if (network->technology() == flimflam::kNetworkTechnologyHspa) { | |
293 id = IDR_AURA_UBER_TRAY_NETWORK_HSPA; | |
294 } else if (network->technology() == flimflam::kNetworkTechnologyHspaPlus) { | |
295 id = IDR_AURA_UBER_TRAY_NETWORK_HSPA_PLUS; | |
296 } else if (network->technology() == flimflam::kNetworkTechnologyLte) { | |
297 id = IDR_AURA_UBER_TRAY_NETWORK_LTE; | |
298 } else if (network->technology() == flimflam::kNetworkTechnologyLteAdvanced) { | |
299 id = IDR_AURA_UBER_TRAY_NETWORK_LTE_ADVANCED; | |
300 } else if (network->technology() == flimflam::kNetworkTechnologyGsm) { | |
301 id = IDR_AURA_UBER_TRAY_NETWORK_GPRS; | |
302 } | |
303 if (id == kUnknownBadgeType) | |
304 return NULL; | |
305 else | |
306 return ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(id); | |
307 } | |
308 | |
309 gfx::ImageSkia GetIcon(const NetworkState* network, | |
310 ResourceColorTheme color, | |
311 int strength_index) { | |
312 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | |
313 const std::string& type = network->type(); | |
314 if (type == flimflam::kTypeEthernet) { | |
315 return *rb.GetImageSkiaNamed(IDR_AURA_UBER_TRAY_NETWORK_WIRED); | |
316 } else if (type == flimflam::kTypeWifi) { | |
317 DCHECK(strength_index > 0); | |
318 return GetImageForIndex(ARCS, color, strength_index); | |
319 } else if (type == flimflam::kTypeWimax) { | |
320 DCHECK(strength_index > 0); | |
321 return GetImageForIndex(BARS, color, strength_index); | |
322 } else if (type == flimflam::kTypeCellular) { | |
323 DCHECK(strength_index > 0); | |
324 return GetImageForIndex(BARS, color, strength_index); | |
325 } else if (type == flimflam::kTypeVPN) { | |
326 return *rb.GetImageSkiaNamed(IDR_AURA_UBER_TRAY_NETWORK_VPN); | |
327 } else { | |
328 LOG(WARNING) << "Request for icon for unsupported type: " << type; | |
329 return *rb.GetImageSkiaNamed(IDR_AURA_UBER_TRAY_NETWORK_WIRED); | |
330 } | |
331 } | |
332 | |
333 void GetBadges(const NetworkState* network, | |
334 ResourceColorTheme color, | |
335 Badges* badges) { | |
336 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | |
337 chromeos::NetworkStateHandler* handler = chromeos::NetworkStateHandler::Get(); | |
338 | |
339 bool use_dark_icons = color == COLOR_DARK; | |
340 const std::string& type = network->type(); | |
341 if (type == flimflam::kTypeWifi) { | |
342 if (network->security() != flimflam::kSecurityNone && use_dark_icons) { | |
343 badges->bottom_right = rb.GetImageSkiaNamed( | |
344 IDR_AURA_UBER_TRAY_NETWORK_SECURE_DARK); | |
345 } | |
346 } else if (type == flimflam::kTypeWimax) { | |
347 badges->top_left = rb.GetImageSkiaNamed( | |
348 use_dark_icons ? | |
349 IDR_AURA_UBER_TRAY_NETWORK_4G_DARK : | |
350 IDR_AURA_UBER_TRAY_NETWORK_4G_LIGHT); | |
351 } else if (type == flimflam::kTypeCellular) { | |
352 if (network->roaming() == flimflam::kRoamingStateRoaming) { | |
353 // For networks that are always in roaming don't show roaming badge. | |
354 const DeviceState* device = | |
355 handler->GetDeviceState(network->device_path()); | |
356 if (!device->provider_requires_roaming()) { | |
357 badges->bottom_right = rb.GetImageSkiaNamed( | |
358 use_dark_icons ? | |
359 IDR_AURA_UBER_TRAY_NETWORK_ROAMING_DARK : | |
360 IDR_AURA_UBER_TRAY_NETWORK_ROAMING_LIGHT); | |
361 } | |
362 } | |
363 if (!network->IsConnectingState()) { | |
364 badges->top_left = BadgeForNetworkTechnology(network, color); | |
365 } | |
366 } | |
367 } | |
368 | |
369 //------------------------------------------------------------------------------ | |
370 // Handle connecting images | |
371 | |
372 class ConnectingAnimation : public ui::AnimationDelegate { | |
373 public: | |
374 ConnectingAnimation() | |
375 : ALLOW_THIS_IN_INITIALIZER_LIST(animation_(this)) { | |
376 // Set up the animation throbber. | |
377 animation_.SetThrobDuration(kThrobDurationMs); | |
378 animation_.SetTweenType(ui::Tween::LINEAR); | |
379 } | |
380 | |
381 virtual ~ConnectingAnimation() {} | |
382 | |
383 // ui::AnimationDelegate implementation. | |
384 virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE { | |
385 if (animation == &animation_) { | |
386 FOR_EACH_OBSERVER(AnimationObserver, observers_, NetworkIconChanged()); | |
387 } | |
388 } | |
389 | |
390 double GetAnimation() { | |
391 if (!animation_.is_animating()) { | |
392 animation_.Reset(); | |
393 animation_.StartThrobbing(-1 /*throb indefinitely*/); | |
394 return 0; | |
395 } | |
396 return animation_.GetCurrentValue(); | |
397 } | |
398 | |
399 void AddObserver(AnimationObserver* observer) { | |
400 observers_.AddObserver(observer); | |
401 } | |
402 | |
403 void RemoveObserver(AnimationObserver* observer) { | |
404 observers_.RemoveObserver(observer); | |
405 if (observers_.size() == 0) | |
406 animation_.Stop(); | |
407 } | |
408 | |
409 private: | |
410 ui::ThrobAnimation animation_; | |
411 ObserverList<AnimationObserver> observers_; | |
412 }; | |
413 | |
414 ConnectingAnimation* GetConnectingAnimation() { | |
415 static ConnectingAnimation* s_connecting_animation = | |
416 new ConnectingAnimation(); | |
417 return s_connecting_animation; | |
418 } | |
419 | |
420 gfx::ImageSkia GetConnectingImage(const std::string& type, | |
421 ResourceColorTheme color) { | |
422 ImageType image_type = (type == flimflam::kTypeWifi) ? ARCS : BARS; | |
423 int image_count = NumImagesForType(image_type) - 1; | |
424 gfx::ImageSkia** images = ImageListForType(image_type, color); | |
425 double animation = GetConnectingAnimation()->GetAnimation(); | |
426 int index = animation * nextafter(static_cast<float>(image_count), 0); | |
427 index = std::max(std::min(index, image_count - 1), 0); | |
428 | |
429 // Lazily cache images. | |
430 if (!images[index]) { | |
431 gfx::ImageSkia source = GetImageForIndex(image_type, color, index + 1); | |
432 images[index] = new gfx::ImageSkia( | |
433 gfx::ImageSkiaOperations::CreateBlendedImage( | |
434 gfx::ImageSkia(new EmptyImageSource(source.size()), source.size()), | |
435 source, | |
436 kConnectingImageAlpha)); | |
437 } | |
438 gfx::ImageSkia& icon = *images[index]; | |
439 return gfx::ImageSkia( | |
440 new NetworkIconImageSource(icon, Badges()), icon.size()); | |
441 } | |
442 | |
443 | |
444 //------------------------------------------------------------------------------ | |
445 // Maintain a static (global) icon map. Note: Icons are never destroyed; | |
446 // it is assumed that a finite and reasonable number of network icons will be | |
447 // created during a session. | |
448 | |
449 typedef std::map<std::string, NetworkIcon*> NetworkIconMap; | |
450 | |
451 NetworkIconMap* GetIconMap(ResourceColorTheme color) { | |
452 if (color == COLOR_DARK) { | |
453 static NetworkIconMap* s_icon_map_dark = NULL; | |
454 if (s_icon_map_dark == NULL) | |
455 s_icon_map_dark = new NetworkIconMap; | |
456 return s_icon_map_dark; | |
457 } else { | |
458 static NetworkIconMap* s_icon_map_light = NULL; | |
459 if (s_icon_map_light == NULL) | |
460 s_icon_map_light = new NetworkIconMap; | |
461 return s_icon_map_light; | |
462 } | |
463 } | |
464 | |
465 } // namespace | |
466 | |
467 //------------------------------------------------------------------------------ | |
468 // NetworkIcon | |
469 | |
470 NetworkIcon::NetworkIcon(const std::string& service_path, | |
471 ResourceColorTheme color) | |
472 : service_path_(service_path), | |
473 color_(color), | |
474 strength_index_(-1), | |
475 technology_badge_(NULL) { | |
476 // Default image | |
477 image_ = GetDisconnectedImage(color); | |
478 } | |
479 | |
480 void NetworkIcon::Update(const NetworkState* network) { | |
481 // Determine whether or not we need to update the icon. | |
482 bool dirty = image_.isNull(); | |
483 | |
484 // If the network state has changed, the icon needs updating. | |
485 if (state_ != network->state()) { | |
486 state_ = network->state(); | |
487 dirty = true; | |
488 } | |
489 | |
490 const std::string& type = network->type(); | |
491 if (type != flimflam::kTypeEthernet) | |
492 dirty |= UpdateWirelessStrengthIndex(network); | |
493 | |
494 if (type == flimflam::kTypeCellular) | |
495 dirty |= UpdateCellularState(network); | |
496 | |
497 if (dirty) { | |
498 // Set the icon and badges based on the network and generate the image. | |
499 GenerateImage(network); | |
500 } | |
501 } | |
502 | |
503 bool NetworkIcon::UpdateWirelessStrengthIndex(const NetworkState* network) { | |
504 int index = GetStrengthIndex(network); | |
505 if (index != strength_index_) { | |
506 strength_index_ = index; | |
507 return true; | |
508 } | |
509 return false; | |
510 } | |
511 | |
512 bool NetworkIcon::UpdateCellularState(const NetworkState* network) { | |
513 bool dirty = false; | |
514 const gfx::ImageSkia* technology_badge = | |
515 BadgeForNetworkTechnology(network, color_); | |
516 if (technology_badge != technology_badge_) { | |
517 technology_badge_ = technology_badge; | |
518 dirty = true; | |
519 } | |
520 std::string roaming_state = network->roaming(); | |
521 if (roaming_state != roaming_state_) { | |
522 roaming_state_ = roaming_state; | |
523 dirty = true; | |
524 } | |
525 return dirty; | |
526 } | |
527 | |
528 void NetworkIcon::GenerateImage(const NetworkState* network) { | |
529 gfx::ImageSkia icon = GetIcon(network, color_, strength_index_); | |
530 Badges badges; | |
531 GetBadges(network, color_, &badges); | |
532 image_ = gfx::ImageSkia( | |
533 new NetworkIconImageSource(icon, badges), icon.size()); | |
534 } | |
535 | |
536 //------------------------------------------------------------------------------ | |
537 // Public interface | |
538 | |
539 gfx::ImageSkia GetImageForNetwork(const NetworkState* network, | |
540 ResourceColorTheme color, | |
541 AnimationObserver* observer) { | |
542 if (network->IsConnectingState()) { | |
543 if (observer) | |
544 GetConnectingAnimation()->AddObserver(observer); | |
545 return GetConnectingImage(network->type(), color); | |
546 } | |
547 // Not connecting, remove observer. | |
548 if (observer) | |
549 GetConnectingAnimation()->RemoveObserver(observer); | |
550 | |
551 NetworkIconMap* icon_map = GetIconMap(color); | |
552 | |
553 // Find or add the icon. | |
554 NetworkIcon* icon; | |
555 NetworkIconMap::iterator iter = icon_map->find(network->path()); | |
556 if (iter == icon_map->end()) { | |
557 icon = new NetworkIcon(network->path(), color); | |
558 icon_map->insert(std::make_pair(network->path(), icon)); | |
559 } else { | |
560 icon = iter->second; | |
561 } | |
562 | |
563 // Update and return the icon's image. | |
564 icon->Update(network); | |
565 return icon->image(); | |
566 } | |
567 | |
568 } // namespace network_icon | |
569 } // namespace ash | |
OLD | NEW |