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