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