Index: ash/system/chromeos/network/network_icon.cc |
diff --git a/ash/system/chromeos/network/network_icon.cc b/ash/system/chromeos/network/network_icon.cc |
index 73abc8456412a6f6b083abb1b2bd33ca6dcce0de..a7323851084ee4792ce28f1fc1ad1ab477a86676 100644 |
--- a/ash/system/chromeos/network/network_icon.cc |
+++ b/ash/system/chromeos/network/network_icon.cc |
@@ -18,6 +18,7 @@ |
#include "third_party/cros_system_api/dbus/service_constants.h" |
#include "ui/base/l10n/l10n_util.h" |
#include "ui/base/resource/resource_bundle.h" |
+#include "ui/base/webui/web_ui_util.h" |
#include "ui/gfx/canvas.h" |
#include "ui/gfx/image/image_skia_operations.h" |
#include "ui/gfx/image/image_skia_source.h" |
@@ -55,15 +56,20 @@ struct Badges { |
// class used for maintaining a map of network state and images. |
class NetworkIconImpl { |
public: |
- explicit NetworkIconImpl(IconType icon_type); |
+ NetworkIconImpl(const std::string& path, IconType icon_type); |
// Determines whether or not the associated network might be dirty and if so |
// updates and generates the icon. Does nothing if network no longer exists. |
void Update(const chromeos::NetworkState* network); |
+ // Returns the cached image url for |image_| based on |scale_factor|. |
+ const std::string& GetImageUrl(float scale_factor); |
+ |
const gfx::ImageSkia& image() const { return image_; } |
private: |
+ typedef std::map<float, std::string> ImageUrlMap; |
+ |
// Updates |strength_index_| for wireless networks. Returns true if changed. |
bool UpdateWirelessStrengthIndex(const chromeos::NetworkState* network); |
@@ -82,6 +88,9 @@ class NetworkIconImpl { |
// Gets the appropriate icon and badges and composites the image. |
void GenerateImage(const chromeos::NetworkState* network); |
+ // Network path, used for debugging. |
+ std::string network_path_; |
+ |
// Defines color theme and VPN badging |
const IconType icon_type_; |
@@ -106,6 +115,10 @@ class NetworkIconImpl { |
// Generated icon image. |
gfx::ImageSkia image_; |
+ // Map of cached image urls by scale factor. Cleared whenever image_ is |
+ // generated. |
+ ImageUrlMap image_urls_; |
+ |
DISALLOW_COPY_AND_ASSIGN(NetworkIconImpl); |
}; |
@@ -257,6 +270,28 @@ class NetworkIconImageSource : public gfx::ImageSkiaSource { |
//------------------------------------------------------------------------------ |
// Utilities for extracting icon images. |
+// A struct used for caching image urls. |
+struct ImageIdForNetworkType { |
+ ImageIdForNetworkType(IconType icon_type, |
+ const std::string& network_type, |
+ float scale_factor) : |
+ icon_type(icon_type), |
+ network_type(network_type), |
+ scale_factor(scale_factor) {} |
+ bool operator<(const ImageIdForNetworkType& other) const { |
+ if (icon_type != other.icon_type) |
+ return icon_type < other.icon_type; |
+ if (network_type != other.network_type) |
+ return network_type < other.network_type; |
+ return scale_factor < other.scale_factor; |
+ } |
+ IconType icon_type; |
+ std::string network_type; |
+ float scale_factor; |
+}; |
+ |
+typedef std::map<ImageIdForNetworkType, std::string> ImageIdUrlMap; |
+ |
bool IconTypeIsDark(IconType icon_type) { |
return (icon_type != ICON_TYPE_TRAY); |
} |
@@ -306,29 +341,49 @@ gfx::ImageSkia GetImageForIndex(ImageType image_type, |
gfx::Rect(0, index * height, width, height)); |
} |
-const gfx::ImageSkia GetConnectedImage(const std::string& type, |
- IconType icon_type) { |
- if (type == shill::kTypeVPN) { |
+const gfx::ImageSkia GetConnectedImage(IconType icon_type, |
+ const std::string& network_type) { |
+ if (network_type == shill::kTypeVPN) { |
return *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
IDR_AURA_UBER_TRAY_NETWORK_VPN); |
} |
- ImageType image_type = ImageTypeForNetworkType(type); |
+ ImageType image_type = ImageTypeForNetworkType(network_type); |
const int connected_index = NumImagesForType(image_type) - 1; |
return GetImageForIndex(image_type, icon_type, connected_index); |
} |
-const gfx::ImageSkia GetDisconnectedImage(const std::string& type, |
- IconType icon_type) { |
- if (type == shill::kTypeVPN) { |
+const gfx::ImageSkia GetDisconnectedImage(IconType icon_type, |
+ const std::string& network_type) { |
+ if (network_type == shill::kTypeVPN) { |
// Note: same as connected image, shouldn't normally be seen. |
return *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
IDR_AURA_UBER_TRAY_NETWORK_VPN); |
} |
- ImageType image_type = ImageTypeForNetworkType(type); |
+ ImageType image_type = ImageTypeForNetworkType(network_type); |
const int disconnected_index = 0; |
return GetImageForIndex(image_type, icon_type, disconnected_index); |
} |
+const std::string& GetDisconnectedImageUrl(IconType icon_type, |
+ const std::string& network_type, |
+ float scale_factor) { |
+ static ImageIdUrlMap* s_image_url_map = NULL; |
+ if (s_image_url_map == NULL) |
+ s_image_url_map = new ImageIdUrlMap; |
+ |
+ ImageIdForNetworkType key(icon_type, network_type, scale_factor); |
+ ImageIdUrlMap::iterator iter = s_image_url_map->find(key); |
+ if (iter != s_image_url_map->end()) |
+ return iter->second; |
+ |
+ VLOG(2) << "Generating disconnected bitmap URL for: " << network_type; |
+ gfx::ImageSkia image = GetDisconnectedImage(icon_type, network_type); |
+ gfx::ImageSkiaRep image_rep = image.GetRepresentation(scale_factor); |
+ iter = s_image_url_map->insert(std::make_pair( |
+ key, webui::GetBitmapDataUrl(image_rep.sk_bitmap()))).first; |
+ return iter->second; |
+} |
+ |
gfx::ImageSkia* ConnectingWirelessImage(ImageType image_type, |
IconType icon_type, |
double animation) { |
@@ -509,8 +564,8 @@ gfx::ImageSkia GetConnectingVpnImage(IconType icon_type) { |
} |
} |
-gfx::ImageSkia GetConnectingImage(const std::string& network_type, |
- IconType icon_type) { |
+gfx::ImageSkia GetConnectingImage(IconType icon_type, |
+ const std::string& network_type) { |
if (network_type == shill::kTypeVPN) |
return GetConnectingVpnImage(icon_type); |
@@ -523,19 +578,30 @@ gfx::ImageSkia GetConnectingImage(const std::string& network_type, |
new NetworkIconImageSource(*icon, Badges()), icon->size()); |
} |
+std::string GetConnectingImageUrl(IconType icon_type, |
+ const std::string& network_type, |
+ float scale_factor) { |
+ // Caching the connecting image is complicated and we will never draw more |
+ // than a few per frame, so just generate the image url each time. |
+ gfx::ImageSkia image = GetConnectingImage(icon_type, network_type); |
+ gfx::ImageSkiaRep image_rep = image.GetRepresentation(scale_factor); |
+ return webui::GetBitmapDataUrl(image_rep.sk_bitmap()); |
+} |
+ |
} // namespace |
//------------------------------------------------------------------------------ |
// NetworkIconImpl |
-NetworkIconImpl::NetworkIconImpl(IconType icon_type) |
- : icon_type_(icon_type), |
+NetworkIconImpl::NetworkIconImpl(const std::string& path, IconType icon_type) |
+ : network_path_(path), |
+ icon_type_(icon_type), |
strength_index_(-1), |
technology_badge_(NULL), |
vpn_badge_(NULL), |
behind_captive_portal_(false) { |
// Default image |
- image_ = GetDisconnectedImage(shill::kTypeWifi, icon_type); |
+ image_ = GetDisconnectedImage(icon_type, shill::kTypeWifi); |
} |
void NetworkIconImpl::Update(const NetworkState* network) { |
@@ -674,24 +740,31 @@ void NetworkIconImpl::GenerateImage(const NetworkState* network) { |
GetBadges(network, &badges); |
image_ = gfx::ImageSkia( |
new NetworkIconImageSource(icon, badges), icon.size()); |
+ image_urls_.clear(); |
} |
-//------------------------------------------------------------------------------ |
-// Public interface |
+const std::string& NetworkIconImpl::GetImageUrl(float scale_factor) { |
+ ImageUrlMap::iterator iter = image_urls_.find(scale_factor); |
+ if (iter != image_urls_.end()) |
+ return iter->second; |
-gfx::ImageSkia GetImageForNetwork(const NetworkState* network, |
- IconType icon_type) { |
- DCHECK(network); |
- // Handle connecting icons. |
- if (network->IsConnectingState()) |
- return GetConnectingImage(network->type(), icon_type); |
+ VLOG(2) << "Generating bitmap URL for: " << network_path_; |
+ gfx::ImageSkiaRep image_rep = image_.GetRepresentation(scale_factor); |
+ iter = image_urls_.insert(std::make_pair( |
+ scale_factor, webui::GetBitmapDataUrl(image_rep.sk_bitmap()))).first; |
+ return iter->second; |
+} |
+ |
+namespace { |
+NetworkIconImpl* FindAndUpdateImageImpl(const NetworkState* network, |
+ IconType icon_type) { |
// Find or add the icon. |
NetworkIconMap* icon_map = GetIconMap(icon_type); |
NetworkIconImpl* icon; |
NetworkIconMap::iterator iter = icon_map->find(network->path()); |
if (iter == icon_map->end()) { |
- icon = new NetworkIconImpl(icon_type); |
+ icon = new NetworkIconImpl(network->path(), icon_type); |
icon_map->insert(std::make_pair(network->path(), icon)); |
} else { |
icon = iter->second; |
@@ -699,22 +772,56 @@ gfx::ImageSkia GetImageForNetwork(const NetworkState* network, |
// Update and return the icon's image. |
icon->Update(network); |
+ return icon; |
+} |
+ |
+} // namespace |
+ |
+//------------------------------------------------------------------------------ |
+// Public interface |
+ |
+gfx::ImageSkia GetImageForNetwork(const NetworkState* network, |
+ IconType icon_type) { |
+ DCHECK(network); |
+ // Handle connecting icons. |
+ if (network->IsConnectingState()) |
+ return GetConnectingImage(icon_type, network->type()); |
+ |
+ NetworkIconImpl* icon = FindAndUpdateImageImpl(network, icon_type); |
return icon->image(); |
} |
+std::string GetImageUrlForNetwork(const NetworkState* network, |
+ IconType icon_type, |
+ float scale_factor) { |
+ DCHECK(network); |
+ // Handle connecting icons. |
+ if (network->IsConnectingState()) |
+ return GetConnectingImageUrl(icon_type, network->type(), scale_factor); |
+ |
+ NetworkIconImpl* icon = FindAndUpdateImageImpl(network, icon_type); |
+ return icon->GetImageUrl(scale_factor); |
+} |
+ |
gfx::ImageSkia GetImageForConnectedNetwork(IconType icon_type, |
const std::string& network_type) { |
- return GetConnectedImage(network_type, icon_type); |
+ return GetConnectedImage(icon_type, network_type); |
} |
gfx::ImageSkia GetImageForConnectingNetwork(IconType icon_type, |
const std::string& network_type) { |
- return GetConnectingImage(network_type, icon_type); |
+ return GetConnectingImage(icon_type, network_type); |
} |
gfx::ImageSkia GetImageForDisconnectedNetwork(IconType icon_type, |
const std::string& network_type) { |
- return GetDisconnectedImage(network_type, icon_type); |
+ return GetDisconnectedImage(icon_type, network_type); |
+} |
+ |
+std::string GetImageUrlForDisconnectedNetwork(IconType icon_type, |
+ const std::string& network_type, |
+ float scale_factor) { |
+ return GetDisconnectedImageUrl(icon_type, network_type, scale_factor); |
} |
base::string16 GetLabelForNetwork(const chromeos::NetworkState* network, |