12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/chromeos/network/network_icon.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/network/device_state.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chromeos/network/network_connection_handler.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/network/network_state.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/network/network_state_handler.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chromeos/network/portal_detector/network_portal_detector.h"
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "grit/ui_chromeos_resources.h"
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "grit/ui_chromeos_strings.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
1846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/base/webui/web_ui_util.h"
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/chromeos/network/network_icon_animation.h"
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/chromeos/network/network_icon_animation_observer.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/canvas.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/image/image_skia_operations.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/image/image_skia_source.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/rect.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/size_conversions.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using chromeos::DeviceState;
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)using chromeos::NetworkConnectionHandler;
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using chromeos::NetworkHandler;
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdochusing chromeos::NetworkPortalDetector;
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using chromeos::NetworkState;
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using chromeos::NetworkStateHandler;
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using chromeos::NetworkTypePattern;
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace ui {
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace network_icon {
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Struct to pass icon badges to NetworkIconImageSource.
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct Badges {
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Badges()
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : top_left(NULL),
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        top_right(NULL),
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        bottom_left(NULL),
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        bottom_right(NULL) {
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const gfx::ImageSkia* top_left;
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const gfx::ImageSkia* top_right;
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const gfx::ImageSkia* bottom_left;
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const gfx::ImageSkia* bottom_right;
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// class used for maintaining a map of network state and images.
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class NetworkIconImpl {
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  NetworkIconImpl(const std::string& path, IconType icon_type);
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Determines whether or not the associated network might be dirty and if so
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // updates and generates the icon. Does nothing if network no longer exists.
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Update(const chromeos::NetworkState* network);
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Returns the cached image url for |image_| based on |scale_factor|.
6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const std::string& GetImageUrl(float scale_factor);
6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const gfx::ImageSkia& image() const { return image_; }
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  typedef std::map<float, std::string> ImageUrlMap;
7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Updates |strength_index_| for wireless networks. Returns true if changed.
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool UpdateWirelessStrengthIndex(const chromeos::NetworkState* network);
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Updates the local state for cellular networks. Returns true if changed.
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool UpdateCellularState(const chromeos::NetworkState* network);
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Updates the portal state for wireless networks. Returns true if changed.
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool UpdatePortalState(const chromeos::NetworkState* network);
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Updates the VPN badge. Returns true if changed.
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool UpdateVPNBadge();
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Gets |badges| based on |network| and the current state.
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void GetBadges(const NetworkState* network, Badges* badges);
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Gets the appropriate icon and badges and composites the image.
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void GenerateImage(const chromeos::NetworkState* network);
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Network path, used for debugging.
9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  std::string network_path_;
9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Defines color theme and VPN badging
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const IconType icon_type_;
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Cached state of the network when the icon was last generated.
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string state_;
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Cached strength index of the network when the icon was last generated.
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int strength_index_;
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Cached technology badge for the network when the icon was last generated.
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const gfx::ImageSkia* technology_badge_;
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Cached vpn badge for the network when the icon was last generated.
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const gfx::ImageSkia* vpn_badge_;
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Cached roaming state of the network when the icon was last generated.
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string roaming_state_;
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Cached portal state of the network when the icon was last generated.
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool behind_captive_portal_;
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Generated icon image.
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::ImageSkia image_;
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Map of cached image urls by scale factor. Cleared whenever image_ is
11946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // generated.
12046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ImageUrlMap image_urls_;
12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NetworkIconImpl);
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Maintain a static (global) icon map. Note: Icons are never destroyed;
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// it is assumed that a finite and reasonable number of network icons will be
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// created during a session.
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef std::map<std::string, NetworkIconImpl*> NetworkIconMap;
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)NetworkIconMap* GetIconMapInstance(IconType icon_type, bool create) {
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef std::map<IconType, NetworkIconMap*> IconTypeMap;
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static IconTypeMap* s_icon_map = NULL;
1357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (s_icon_map == NULL) {
1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (!create)
1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return NULL;
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    s_icon_map = new IconTypeMap;
1397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
1407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (s_icon_map->count(icon_type) == 0) {
1417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (!create)
1427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return NULL;
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*s_icon_map)[icon_type] = new NetworkIconMap;
1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (*s_icon_map)[icon_type];
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)NetworkIconMap* GetIconMap(IconType icon_type) {
1497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return GetIconMapInstance(icon_type, true);
1507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void PurgeIconMap(IconType icon_type,
1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                  const std::set<std::string>& network_paths) {
1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  NetworkIconMap* icon_map = GetIconMapInstance(icon_type, false);
1557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!icon_map)
1567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
1577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  for (NetworkIconMap::iterator loop_iter = icon_map->begin();
1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)       loop_iter != icon_map->end(); ) {
1597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    NetworkIconMap::iterator cur_iter = loop_iter++;
1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (network_paths.count(cur_iter->first) == 0) {
1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      delete cur_iter->second;
1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      icon_map->erase(cur_iter);
1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
1657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Utilities for generating icon images.
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 'NONE' will default to ARCS behavior where appropriate (e.g. no network or
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// if a new type gets added).
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)enum ImageType {
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ARCS,
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BARS,
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NONE
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Amount to fade icons while connecting.
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const double kConnectingImageAlpha = 0.5;
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Images for strength bars for wired networks.
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kNumBarsImages = 5;
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Imagaes for strength arcs for wireless networks.
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kNumArcsImages = 5;
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Number of discrete images to use for alpha fade animation
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kNumFadeImages = 10;
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Classes for generating scaled images.
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const SkBitmap GetEmptyBitmap(const gfx::Size pixel_size) {
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef std::pair<int, int> SizeKey;
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef std::map<SizeKey, SkBitmap> SizeBitmapMap;
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static SizeBitmapMap* s_empty_bitmaps = new SizeBitmapMap;
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SizeKey key(pixel_size.width(), pixel_size.height());
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SizeBitmapMap::iterator iter = s_empty_bitmaps->find(key);
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (iter != s_empty_bitmaps->end())
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return iter->second;
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkBitmap empty;
205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  empty.allocN32Pixels(key.first, key.second);
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  empty.eraseARGB(0, 0, 0, 0);
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  (*s_empty_bitmaps)[key] = empty;
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return empty;
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class EmptyImageSource: public gfx::ImageSkiaSource {
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit EmptyImageSource(const gfx::Size& size)
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : size_(size) {
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  virtual gfx::ImageSkiaRep GetImageForScale(float scale) OVERRIDE {
21868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    gfx::Size pixel_size = gfx::ToFlooredSize(gfx::ScaleSize(size_, scale));
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SkBitmap empty_bitmap = GetEmptyBitmap(pixel_size);
22068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return gfx::ImageSkiaRep(empty_bitmap, scale);
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
22268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const gfx::Size size_;
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(EmptyImageSource);
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This defines how we assemble a network icon.
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class NetworkIconImageSource : public gfx::ImageSkiaSource {
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NetworkIconImageSource(const gfx::ImageSkia& icon, const Badges& badges)
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : icon_(icon),
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        badges_(badges) {
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~NetworkIconImageSource() {}
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(pkotwicz): Figure out what to do when a new image resolution becomes
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // available.
24068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  virtual gfx::ImageSkiaRep GetImageForScale(float scale) OVERRIDE {
24168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    gfx::ImageSkiaRep icon_rep = icon_.GetRepresentation(scale);
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (icon_rep.is_null())
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return gfx::ImageSkiaRep();
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Canvas canvas(icon_rep, false);
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (badges_.top_left)
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      canvas.DrawImageInt(*badges_.top_left, 0, 0);
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (badges_.top_right)
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      canvas.DrawImageInt(*badges_.top_right,
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          icon_.width() - badges_.top_right->width(), 0);
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (badges_.bottom_left) {
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      canvas.DrawImageInt(*badges_.bottom_left,
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          0, icon_.height() - badges_.bottom_left->height());
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (badges_.bottom_right) {
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      canvas.DrawImageInt(*badges_.bottom_right,
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          icon_.width() - badges_.bottom_right->width(),
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          icon_.height() - badges_.bottom_right->height());
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return canvas.ExtractImageRep();
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const gfx::ImageSkia icon_;
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Badges badges_;
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NetworkIconImageSource);
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Utilities for extracting icon images.
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// A struct used for caching image urls.
27346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)struct ImageIdForNetworkType {
27446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ImageIdForNetworkType(IconType icon_type,
27546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        const std::string& network_type,
27646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        float scale_factor) :
27746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      icon_type(icon_type),
27846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      network_type(network_type),
27946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      scale_factor(scale_factor) {}
28046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool operator<(const ImageIdForNetworkType& other) const {
28146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (icon_type != other.icon_type)
28246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      return icon_type < other.icon_type;
28346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (network_type != other.network_type)
28446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      return network_type < other.network_type;
28546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return scale_factor < other.scale_factor;
28646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
28746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  IconType icon_type;
28846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  std::string network_type;
28946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  float scale_factor;
29046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)};
29146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
29246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)typedef std::map<ImageIdForNetworkType, std::string> ImageIdUrlMap;
29346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IconTypeIsDark(IconType icon_type) {
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (icon_type != ICON_TYPE_TRAY);
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IconTypeHasVPNBadge(IconType icon_type) {
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (icon_type != ICON_TYPE_LIST);
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int NumImagesForType(ImageType type) {
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (type == BARS) ? kNumBarsImages : kNumArcsImages;
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::ImageSkia* BaseImageForType(ImageType image_type, IconType icon_type) {
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::ImageSkia* image;
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (image_type == BARS) {
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    image =  ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IconTypeIsDark(icon_type) ?
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IDR_AURA_UBER_TRAY_NETWORK_BARS_DARK :
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IDR_AURA_UBER_TRAY_NETWORK_BARS_LIGHT);
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    image =  ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IconTypeIsDark(icon_type) ?
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IDR_AURA_UBER_TRAY_NETWORK_ARCS_DARK :
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IDR_AURA_UBER_TRAY_NETWORK_ARCS_LIGHT);
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return image;
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ImageType ImageTypeForNetworkType(const std::string& type) {
32368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (type == shill::kTypeWifi)
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return ARCS;
32568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  else if (type == shill::kTypeCellular || type == shill::kTypeWimax)
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return BARS;
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return NONE;
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::ImageSkia GetImageForIndex(ImageType image_type,
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                IconType icon_type,
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                int index) {
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int num_images = NumImagesForType(image_type);
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (index < 0 || index >= num_images)
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return gfx::ImageSkia();
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::ImageSkia* images = BaseImageForType(image_type, icon_type);
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int width = images->width();
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int height = images->height() / num_images;
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return gfx::ImageSkiaOperations::ExtractSubset(*images,
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(0, index * height, width, height));
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const gfx::ImageSkia GetConnectedImage(IconType icon_type,
34446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                       const std::string& network_type) {
34546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (network_type == shill::kTypeVPN) {
346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        IDR_AURA_UBER_TRAY_NETWORK_VPN);
348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
34946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ImageType image_type = ImageTypeForNetworkType(network_type);
350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const int connected_index = NumImagesForType(image_type) - 1;
351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return GetImageForIndex(image_type, icon_type, connected_index);
352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
35446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const gfx::ImageSkia GetDisconnectedImage(IconType icon_type,
35546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                          const std::string& network_type) {
35646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (network_type == shill::kTypeVPN) {
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Note: same as connected image, shouldn't normally be seen.
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IDR_AURA_UBER_TRAY_NETWORK_VPN);
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
36146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ImageType image_type = ImageTypeForNetworkType(network_type);
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int disconnected_index = 0;
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetImageForIndex(image_type, icon_type, disconnected_index);
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::ImageSkia* ConnectingWirelessImage(ImageType image_type,
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        IconType icon_type,
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        double animation) {
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static gfx::ImageSkia* s_bars_images_dark[kNumBarsImages - 1];
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static gfx::ImageSkia* s_bars_images_light[kNumBarsImages - 1];
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static gfx::ImageSkia* s_arcs_images_dark[kNumArcsImages - 1];
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static gfx::ImageSkia* s_arcs_images_light[kNumArcsImages - 1];
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int image_count = NumImagesForType(image_type) - 1;
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int index = animation * nextafter(static_cast<float>(image_count), 0);
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  index = std::max(std::min(index, image_count - 1), 0);
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::ImageSkia** images;
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool dark = IconTypeIsDark(icon_type);
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (image_type == BARS)
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    images = dark ? s_bars_images_dark : s_bars_images_light;
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    images = dark ? s_arcs_images_dark : s_arcs_images_light;
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!images[index]) {
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Lazily cache images.
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::ImageSkia source = GetImageForIndex(image_type, icon_type, index + 1);
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    images[index] = new gfx::ImageSkia(
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::ImageSkiaOperations::CreateBlendedImage(
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            gfx::ImageSkia(new EmptyImageSource(source.size()), source.size()),
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            source,
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            kConnectingImageAlpha));
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return images[index];
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::ImageSkia* ConnectingVpnImage(double animation) {
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int index = animation * nextafter(static_cast<float>(kNumFadeImages), 0);
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static gfx::ImageSkia* s_vpn_images[kNumFadeImages];
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!s_vpn_images[index]) {
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Lazily cache images.
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::ImageSkia* icon = rb.GetImageSkiaNamed(IDR_AURA_UBER_TRAY_NETWORK_VPN);
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    s_vpn_images[index] = new gfx::ImageSkia(
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::ImageSkiaOperations::CreateBlendedImage(
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            gfx::ImageSkia(new EmptyImageSource(icon->size()), icon->size()),
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            *icon,
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            animation));
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return s_vpn_images[index];
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::ImageSkia* ConnectingVpnBadge(double animation) {
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int index = animation * nextafter(static_cast<float>(kNumFadeImages), 0);
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static gfx::ImageSkia* s_vpn_badges[kNumFadeImages];
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!s_vpn_badges[index]) {
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Lazily cache images.
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::ImageSkia* icon =
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rb.GetImageSkiaNamed(IDR_AURA_UBER_TRAY_NETWORK_WIRED);  // For size
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::ImageSkia* badge =
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rb.GetImageSkiaNamed(IDR_AURA_UBER_TRAY_NETWORK_VPN_BADGE);
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    s_vpn_badges[index] = new gfx::ImageSkia(
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::ImageSkiaOperations::CreateBlendedImage(
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            gfx::ImageSkia(new EmptyImageSource(icon->size()), icon->size()),
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            *badge,
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            animation));
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return s_vpn_badges[index];
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int StrengthIndex(int strength, int count) {
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Return an index in the range [1, count-1].
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const float findex = (static_cast<float>(strength) / 100.0f) *
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      nextafter(static_cast<float>(count - 1), 0);
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int index = 1 + static_cast<int>(findex);
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  index = std::max(std::min(index, count - 1), 1);
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return index;
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int GetStrengthIndex(const NetworkState* network) {
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ImageType image_type = ImageTypeForNetworkType(network->type());
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (image_type == ARCS)
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return StrengthIndex(network->signal_strength(), kNumArcsImages);
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (image_type == BARS)
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return StrengthIndex(network->signal_strength(), kNumBarsImages);
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return 0;
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const gfx::ImageSkia* BadgeForNetworkTechnology(const NetworkState* network,
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                IconType icon_type) {
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int kUnknownBadgeType = -1;
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int id = kUnknownBadgeType;
451a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  const std::string& technology = network->network_technology();
45268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (technology == shill::kNetworkTechnologyEvdo) {
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    id = IconTypeIsDark(icon_type) ?
454ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        IDR_AURA_UBER_TRAY_NETWORK_EVDO_DARK :
455ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        IDR_AURA_UBER_TRAY_NETWORK_EVDO_LIGHT;
45668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  } else if (technology == shill::kNetworkTechnology1Xrtt) {
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    id = IDR_AURA_UBER_TRAY_NETWORK_1X;
45868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  } else if (technology == shill::kNetworkTechnologyGprs) {
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    id = IconTypeIsDark(icon_type) ?
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IDR_AURA_UBER_TRAY_NETWORK_GPRS_DARK :
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IDR_AURA_UBER_TRAY_NETWORK_GPRS_LIGHT;
46268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  } else if (technology == shill::kNetworkTechnologyEdge) {
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    id = IconTypeIsDark(icon_type) ?
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IDR_AURA_UBER_TRAY_NETWORK_EDGE_DARK :
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IDR_AURA_UBER_TRAY_NETWORK_EDGE_LIGHT;
46668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  } else if (technology == shill::kNetworkTechnologyUmts) {
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    id = IconTypeIsDark(icon_type) ?
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IDR_AURA_UBER_TRAY_NETWORK_3G_DARK :
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IDR_AURA_UBER_TRAY_NETWORK_3G_LIGHT;
47068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  } else if (technology == shill::kNetworkTechnologyHspa) {
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    id = IconTypeIsDark(icon_type) ?
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IDR_AURA_UBER_TRAY_NETWORK_HSPA_DARK :
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IDR_AURA_UBER_TRAY_NETWORK_HSPA_LIGHT;
47468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  } else if (technology == shill::kNetworkTechnologyHspaPlus) {
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    id = IconTypeIsDark(icon_type) ?
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IDR_AURA_UBER_TRAY_NETWORK_HSPA_PLUS_DARK :
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IDR_AURA_UBER_TRAY_NETWORK_HSPA_PLUS_LIGHT;
47868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  } else if (technology == shill::kNetworkTechnologyLte) {
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    id = IconTypeIsDark(icon_type) ?
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IDR_AURA_UBER_TRAY_NETWORK_LTE_DARK :
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IDR_AURA_UBER_TRAY_NETWORK_LTE_LIGHT;
48268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  } else if (technology == shill::kNetworkTechnologyLteAdvanced) {
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    id = IconTypeIsDark(icon_type) ?
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IDR_AURA_UBER_TRAY_NETWORK_LTE_ADVANCED_DARK :
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IDR_AURA_UBER_TRAY_NETWORK_LTE_ADVANCED_LIGHT;
48668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  } else if (technology == shill::kNetworkTechnologyGsm) {
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    id = IconTypeIsDark(icon_type) ?
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IDR_AURA_UBER_TRAY_NETWORK_GPRS_DARK :
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IDR_AURA_UBER_TRAY_NETWORK_GPRS_LIGHT;
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (id == kUnknownBadgeType)
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(id);
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const gfx::ImageSkia* BadgeForVPN(IconType icon_type) {
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      IDR_AURA_UBER_TRAY_NETWORK_VPN_BADGE);
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::ImageSkia GetIcon(const NetworkState* network,
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       IconType icon_type,
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       int strength_index) {
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
50658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (network->Matches(NetworkTypePattern::Ethernet())) {
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return *rb.GetImageSkiaNamed(IDR_AURA_UBER_TRAY_NETWORK_WIRED);
50858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  } else if (network->Matches(NetworkTypePattern::Wireless())) {
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(strength_index > 0);
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return GetImageForIndex(
51158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        ImageTypeForNetworkType(network->type()), icon_type, strength_index);
51258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  } else if (network->Matches(NetworkTypePattern::VPN())) {
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return *rb.GetImageSkiaNamed(IDR_AURA_UBER_TRAY_NETWORK_VPN);
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
51558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    LOG(WARNING) << "Request for icon for unsupported type: "
51658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 << network->type();
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return *rb.GetImageSkiaNamed(IDR_AURA_UBER_TRAY_NETWORK_WIRED);
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Get connecting images
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::ImageSkia GetConnectingVpnImage(IconType icon_type) {
52590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const NetworkState* connected_network = NULL;
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (icon_type == ICON_TYPE_TRAY) {
52858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    connected_network =
52958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        handler->ConnectedNetworkByType(NetworkTypePattern::NonVirtual());
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  double animation = NetworkIconAnimation::GetInstance()->GetAnimation();
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (connected_network) {
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::ImageSkia icon = GetImageForNetwork(connected_network, icon_type);
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Badges badges;
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    badges.bottom_left = ConnectingVpnBadge(animation);
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return gfx::ImageSkia(
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new NetworkIconImageSource(icon, badges), icon.size());
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::ImageSkia* icon = ConnectingVpnImage(animation);
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return gfx::ImageSkia(
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new NetworkIconImageSource(*icon, Badges()), icon->size());
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
54646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)gfx::ImageSkia GetConnectingImage(IconType icon_type,
54746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  const std::string& network_type) {
54868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (network_type == shill::kTypeVPN)
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return GetConnectingVpnImage(icon_type);
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ImageType image_type = ImageTypeForNetworkType(network_type);
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  double animation = NetworkIconAnimation::GetInstance()->GetAnimation();
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::ImageSkia* icon = ConnectingWirelessImage(
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      image_type, icon_type, animation);
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return gfx::ImageSkia(
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new NetworkIconImageSource(*icon, Badges()), icon->size());
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
56046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)std::string GetConnectingImageUrl(IconType icon_type,
56146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  const std::string& network_type,
56246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  float scale_factor) {
56346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Caching the connecting image is complicated and we will never draw more
56446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // than a few per frame, so just generate the image url each time.
56546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  gfx::ImageSkia image = GetConnectingImage(icon_type, network_type);
56646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  gfx::ImageSkiaRep image_rep = image.GetRepresentation(scale_factor);
56746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return webui::GetBitmapDataUrl(image_rep.sk_bitmap());
56846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
56946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// NetworkIconImpl
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
57546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)NetworkIconImpl::NetworkIconImpl(const std::string& path, IconType icon_type)
57646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    : network_path_(path),
57746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      icon_type_(icon_type),
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      strength_index_(-1),
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      technology_badge_(NULL),
580a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      vpn_badge_(NULL),
581a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      behind_captive_portal_(false) {
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Default image
58346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  image_ = GetDisconnectedImage(icon_type, shill::kTypeWifi);
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NetworkIconImpl::Update(const NetworkState* network) {
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(network);
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Determine whether or not we need to update the icon.
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool dirty = image_.isNull();
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If the network state has changed, the icon needs updating.
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state_ != network->connection_state()) {
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    state_ = network->connection_state();
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dirty = true;
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
597a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  dirty |= UpdatePortalState(network);
598a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
599a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (network->Matches(NetworkTypePattern::Wireless())) {
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dirty |= UpdateWirelessStrengthIndex(network);
601a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
60358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (network->Matches(NetworkTypePattern::Cellular()))
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dirty |= UpdateCellularState(network);
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
60658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (IconTypeHasVPNBadge(icon_type_) &&
60758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      network->Matches(NetworkTypePattern::NonVirtual())) {
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dirty |= UpdateVPNBadge();
60958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (dirty) {
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Set the icon and badges based on the network and generate the image.
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GenerateImage(network);
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NetworkIconImpl::UpdateWirelessStrengthIndex(const NetworkState* network) {
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int index = GetStrengthIndex(network);
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (index != strength_index_) {
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    strength_index_ = index;
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NetworkIconImpl::UpdateCellularState(const NetworkState* network) {
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool dirty = false;
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const gfx::ImageSkia* technology_badge =
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BadgeForNetworkTechnology(network, icon_type_);
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (technology_badge != technology_badge_) {
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    technology_badge_ = technology_badge;
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dirty = true;
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string roaming_state = network->roaming();
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (roaming_state != roaming_state_) {
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    roaming_state_ = roaming_state;
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dirty = true;
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return dirty;
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
642a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool NetworkIconImpl::UpdatePortalState(const NetworkState* network) {
643a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool behind_captive_portal = false;
6445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (network && NetworkPortalDetector::IsInitialized()) {
645116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    NetworkPortalDetector::CaptivePortalState state =
646116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        NetworkPortalDetector::Get()->GetCaptivePortalState(network->guid());
647a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    behind_captive_portal =
648116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        state.status == NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL;
649a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
650a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
651a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (behind_captive_portal == behind_captive_portal_)
652a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
653a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  behind_captive_portal_ = behind_captive_portal;
654a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return true;
655a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
656a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NetworkIconImpl::UpdateVPNBadge() {
65890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const NetworkState* vpn = NetworkHandler::Get()->network_state_handler()->
65958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      ConnectedNetworkByType(NetworkTypePattern::VPN());
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (vpn && vpn_badge_ == NULL) {
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    vpn_badge_ = BadgeForVPN(icon_type_);
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (!vpn && vpn_badge_ != NULL) {
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    vpn_badge_ = NULL;
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NetworkIconImpl::GetBadges(const NetworkState* network, Badges* badges) {
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(network);
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
67390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::string& type = network->type();
67668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (type == shill::kTypeWifi) {
67768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (network->security() != shill::kSecurityNone &&
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IconTypeIsDark(icon_type_)) {
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      badges->bottom_right = rb.GetImageSkiaNamed(
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          IDR_AURA_UBER_TRAY_NETWORK_SECURE_DARK);
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
68268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  } else if (type == shill::kTypeWimax) {
683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    technology_badge_ = rb.GetImageSkiaNamed(
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IconTypeIsDark(icon_type_) ?
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IDR_AURA_UBER_TRAY_NETWORK_4G_DARK :
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IDR_AURA_UBER_TRAY_NETWORK_4G_LIGHT);
68768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  } else if (type == shill::kTypeCellular) {
68868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (network->roaming() == shill::kRoamingStateRoaming) {
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // For networks that are always in roaming don't show roaming badge.
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const DeviceState* device =
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          handler->GetDeviceState(network->device_path());
69258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      LOG_IF(WARNING, !device) << "Could not find device state for "
69358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                               << network->device_path();
69458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      if (!device || !device->provider_requires_roaming()) {
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        badges->bottom_right = rb.GetImageSkiaNamed(
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            IconTypeIsDark(icon_type_) ?
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            IDR_AURA_UBER_TRAY_NETWORK_ROAMING_DARK :
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            IDR_AURA_UBER_TRAY_NETWORK_ROAMING_LIGHT);
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!network->IsConnectingState()) {
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    badges->top_left = technology_badge_;
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    badges->bottom_left = vpn_badge_;
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
706a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
707a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (behind_captive_portal_) {
708a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    gfx::ImageSkia* badge = rb.GetImageSkiaNamed(
709a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       IconTypeIsDark(icon_type_) ?
710a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       IDR_AURA_UBER_TRAY_NETWORK_PORTAL_DARK :
711a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       IDR_AURA_UBER_TRAY_NETWORK_PORTAL_LIGHT);
712a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    badges->bottom_right = badge;
713a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NetworkIconImpl::GenerateImage(const NetworkState* network) {
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(network);
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::ImageSkia icon = GetIcon(network, icon_type_, strength_index_);
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Badges badges;
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetBadges(network, &badges);
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  image_ = gfx::ImageSkia(
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new NetworkIconImageSource(icon, badges), icon.size());
72346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  image_urls_.clear();
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const std::string& NetworkIconImpl::GetImageUrl(float scale_factor) {
72746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ImageUrlMap::iterator iter = image_urls_.find(scale_factor);
72846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (iter != image_urls_.end())
72946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return iter->second;
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  VLOG(2) << "Generating bitmap URL for: " << network_path_;
73246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  gfx::ImageSkiaRep image_rep = image_.GetRepresentation(scale_factor);
73346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  iter = image_urls_.insert(std::make_pair(
73446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      scale_factor, webui::GetBitmapDataUrl(image_rep.sk_bitmap()))).first;
73546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return iter->second;
73646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
73746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
73846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace {
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
74046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)NetworkIconImpl* FindAndUpdateImageImpl(const NetworkState* network,
74146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                        IconType icon_type) {
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Find or add the icon.
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NetworkIconMap* icon_map = GetIconMap(icon_type);
7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NetworkIconImpl* icon;
7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NetworkIconMap::iterator iter = icon_map->find(network->path());
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (iter == icon_map->end()) {
74746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    icon = new NetworkIconImpl(network->path(), icon_type);
7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    icon_map->insert(std::make_pair(network->path(), icon));
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    icon = iter->second;
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Update and return the icon's image.
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  icon->Update(network);
75546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return icon;
75646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
75746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
75846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}  // namespace
75946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
76046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)//------------------------------------------------------------------------------
76146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Public interface
76246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
76346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)gfx::ImageSkia GetImageForNetwork(const NetworkState* network,
76446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  IconType icon_type) {
76546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(network);
766f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!network->visible())
767f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return GetDisconnectedImage(icon_type, network->type());
768f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
76946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (network->IsConnectingState())
77046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return GetConnectingImage(icon_type, network->type());
77146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
77246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  NetworkIconImpl* icon = FindAndUpdateImageImpl(network, icon_type);
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return icon->image();
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
77646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)std::string GetImageUrlForNetwork(const NetworkState* network,
77746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  IconType icon_type,
77846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  float scale_factor) {
77946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(network);
78046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Handle connecting icons.
78146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (network->IsConnectingState())
78246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return GetConnectingImageUrl(icon_type, network->type(), scale_factor);
78346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
78446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  NetworkIconImpl* icon = FindAndUpdateImageImpl(network, icon_type);
78546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return icon->GetImageUrl(scale_factor);
78646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
78746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
788868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)gfx::ImageSkia GetImageForConnectedNetwork(IconType icon_type,
789868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           const std::string& network_type) {
79046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return GetConnectedImage(icon_type, network_type);
791868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
792868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::ImageSkia GetImageForConnectingNetwork(IconType icon_type,
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            const std::string& network_type) {
79546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return GetConnectingImage(icon_type, network_type);
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::ImageSkia GetImageForDisconnectedNetwork(IconType icon_type,
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              const std::string& network_type) {
80046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return GetDisconnectedImage(icon_type, network_type);
80146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
80246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
803c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)base::string16 GetLabelForNetwork(const chromeos::NetworkState* network,
804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  IconType icon_type) {
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(network);
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string activation_state = network->activation_state();
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (icon_type == ICON_TYPE_LIST) {
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Show "<network>: [Connecting|Activating]..."
8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (network->IsConnectingState()) {
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return l10n_util::GetStringFUTF16(
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          IDS_ASH_STATUS_TRAY_NETWORK_LIST_CONNECTING,
8125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::UTF8ToUTF16(network->name()));
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
81468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (activation_state == shill::kActivationStateActivating) {
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return l10n_util::GetStringFUTF16(
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          IDS_ASH_STATUS_TRAY_NETWORK_LIST_ACTIVATING,
8175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::UTF8ToUTF16(network->name()));
8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Show "Activate <network>" in list view only.
82068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (activation_state == shill::kActivationStateNotActivated ||
82168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        activation_state == shill::kActivationStatePartiallyActivated) {
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return l10n_util::GetStringFUTF16(
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          IDS_ASH_STATUS_TRAY_NETWORK_LIST_ACTIVATE,
8245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::UTF8ToUTF16(network->name()));
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Show "[Connected to|Connecting to|Activating] <network>" (non-list view).
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (network->IsConnectedState()) {
8295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_NETWORK_CONNECTED,
8305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                        base::UTF8ToUTF16(network->name()));
8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (network->IsConnectingState()) {
8335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_NETWORK_CONNECTING,
8345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                        base::UTF8ToUTF16(network->name()));
8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
83668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (activation_state == shill::kActivationStateActivating) {
8375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_NETWORK_ACTIVATING,
8385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                        base::UTF8ToUTF16(network->name()));
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Otherwise just show the network name or 'Ethernet'.
84358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (network->Matches(NetworkTypePattern::Ethernet())) {
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_ETHERNET);
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
8465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return base::UTF8ToUTF16(network->name());
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int GetCellularUninitializedMsg() {
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static base::Time s_uninitialized_state_time;
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static int s_uninitialized_msg(0);
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
85490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
85558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (handler->GetTechnologyState(NetworkTypePattern::Mobile())
856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      == NetworkStateHandler::TECHNOLOGY_UNINITIALIZED) {
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    s_uninitialized_msg = IDS_ASH_STATUS_TRAY_INITIALIZING_CELLULAR;
8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    s_uninitialized_state_time = base::Time::Now();
8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return s_uninitialized_msg;
86058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  } else if (handler->GetScanningByType(NetworkTypePattern::Mobile())) {
8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    s_uninitialized_msg = IDS_ASH_STATUS_TRAY_CELLULAR_SCANNING;
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    s_uninitialized_state_time = base::Time::Now();
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return s_uninitialized_msg;
8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // There can be a delay between leaving the Initializing state and when
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // a Cellular device shows up, so keep showing the initializing
8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // animation for a bit to avoid flashing the disconnect icon.
8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int kInitializingDelaySeconds = 1;
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeDelta dtime = base::Time::Now() - s_uninitialized_state_time;
8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (dtime.InSeconds() < kInitializingDelaySeconds)
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return s_uninitialized_msg;
8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return 0;
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
875868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void GetDefaultNetworkImageAndLabel(IconType icon_type,
876868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                    gfx::ImageSkia* image,
877868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                    base::string16* label,
878868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                    bool* animating) {
879868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NetworkStateHandler* state_handler =
880868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      NetworkHandler::Get()->network_state_handler();
881868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NetworkConnectionHandler* connect_handler =
882868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      NetworkHandler::Get()->network_connection_handler();
883868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const NetworkState* connected_network =
88458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      state_handler->ConnectedNetworkByType(NetworkTypePattern::NonVirtual());
885868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const NetworkState* connecting_network =
88658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      state_handler->ConnectingNetworkByType(NetworkTypePattern::Wireless());
887868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!connecting_network && icon_type == ICON_TYPE_TRAY) {
888868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    connecting_network =
88958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        state_handler->ConnectingNetworkByType(NetworkTypePattern::VPN());
890868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
891868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
892868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const NetworkState* network;
893868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // If we are connecting to a network, and there is either no connected
894868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // network, or the connection was user requested, use the connecting
895868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // network.
896868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (connecting_network &&
897868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      (!connected_network ||
898868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       connect_handler->HasConnectingNetwork(connecting_network->path()))) {
899868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    network = connecting_network;
900868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else {
901868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    network = connected_network;
902868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
903868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
904868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Don't show ethernet in the tray
90558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (icon_type == ICON_TYPE_TRAY && network &&
90658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      network->Matches(NetworkTypePattern::Ethernet())) {
907868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    *image = gfx::ImageSkia();
908868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    *animating = false;
909868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
910868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
911868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
912868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!network) {
913868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // If no connecting network, check if we are activating a network.
91458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const NetworkState* mobile_network =
91558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        state_handler->FirstNetworkByType(NetworkTypePattern::Mobile());
916868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (mobile_network && (mobile_network->activation_state() ==
91768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                           shill::kActivationStateActivating)) {
918868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      network = mobile_network;
919868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
920868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
921868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!network) {
922868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // If no connecting network, check for cellular initializing.
923868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int uninitialized_msg = GetCellularUninitializedMsg();
924868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (uninitialized_msg != 0) {
92568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      *image = GetImageForConnectingNetwork(icon_type, shill::kTypeCellular);
926868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (label)
927868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        *label = l10n_util::GetStringUTF16(uninitialized_msg);
928868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      *animating = true;
929868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else {
930868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // Otherwise show the disconnected wifi icon.
93168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      *image = GetImageForDisconnectedNetwork(icon_type, shill::kTypeWifi);
932868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (label) {
933868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        *label = l10n_util::GetStringUTF16(
934868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            IDS_ASH_STATUS_TRAY_NETWORK_NOT_CONNECTED);
935868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      }
936868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      *animating = false;
937868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
938868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
939868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
940868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  *animating = network->IsConnectingState();
941868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Get icon and label for connected or connecting network.
942868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  *image = GetImageForNetwork(network, icon_type);
943868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (label)
944868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    *label = GetLabelForNetwork(network, icon_type);
945868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
946868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
9477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void PurgeNetworkIconCache() {
9487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  NetworkStateHandler::NetworkStateList networks;
949f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  NetworkHandler::Get()->network_state_handler()->GetVisibleNetworkList(
950f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      &networks);
9517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::set<std::string> network_paths;
9527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  for (NetworkStateHandler::NetworkStateList::iterator iter = networks.begin();
9537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)       iter != networks.end(); ++iter) {
9547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    network_paths.insert((*iter)->path());
9557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
9567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  PurgeIconMap(ICON_TYPE_TRAY, network_paths);
9577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  PurgeIconMap(ICON_TYPE_DEFAULT_VIEW, network_paths);
9587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  PurgeIconMap(ICON_TYPE_LIST, network_paths);
9597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
9607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace network_icon
962116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace ui
963