Chromium Code Reviews| 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 |