diff options
author | stevenjb@chromium.org <stevenjb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-06 20:00:22 +0000 |
---|---|---|
committer | stevenjb@chromium.org <stevenjb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-06 20:00:22 +0000 |
commit | 42dbdaa6943939486e36e8ded5eb26f2419eeee3 (patch) | |
tree | 6c34fc9787a1a2355ca8a12039a32c6cb3608842 | |
parent | 25af6ecf9c3f9aee202698b81676474065b612ce (diff) | |
download | chromium_src-42dbdaa6943939486e36e8ded5eb26f2419eeee3.zip chromium_src-42dbdaa6943939486e36e8ded5eb26f2419eeee3.tar.gz chromium_src-42dbdaa6943939486e36e8ded5eb26f2419eeee3.tar.bz2 |
Cache network icon urls
Encoding icons to urls for WebUI is expensive enough that we should
do some basic caching to avoid redundant encoding calls.
BUG=336385
Review URL: https://codereview.chromium.org/314183002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@275504 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ash/system/chromeos/network/network_icon.cc | 159 | ||||
-rw-r--r-- | ash/system/chromeos/network/network_icon.h | 13 | ||||
-rw-r--r-- | chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc | 19 |
3 files changed, 153 insertions, 38 deletions
diff --git a/ash/system/chromeos/network/network_icon.cc b/ash/system/chromeos/network/network_icon.cc index 73abc84..a732385 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, diff --git a/ash/system/chromeos/network/network_icon.h b/ash/system/chromeos/network/network_icon.h index 1f9b2c7..4974de7 100644 --- a/ash/system/chromeos/network/network_icon.h +++ b/ash/system/chromeos/network/network_icon.h @@ -34,6 +34,13 @@ ASH_EXPORT gfx::ImageSkia GetImageForNetwork( const chromeos::NetworkState* network, IconType icon_type); +// Similar to GetImageForNetwork but returns the cached image url based on +// |scale_factor| instead. +ASH_EXPORT std::string GetImageUrlForNetwork( + const chromeos::NetworkState* network, + IconType icon_type, + float scale_factor); + // Gets the fulls strength image for a connected network type. ASH_EXPORT gfx::ImageSkia GetImageForConnectedNetwork( IconType icon_type, @@ -49,6 +56,12 @@ ASH_EXPORT gfx::ImageSkia GetImageForDisconnectedNetwork( IconType icon_type, const std::string& network_type); +// Gets a url representing the image for a disconnected network type. +ASH_EXPORT std::string GetImageUrlForDisconnectedNetwork( + IconType icon_type, + const std::string& network_type, + float scale_factor); + // Returns the label for |network| based on |icon_type|. |network| can be NULL. ASH_EXPORT base::string16 GetLabelForNetwork( const chromeos::NetworkState* network, diff --git a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc index f3312cd..82ffaa5 100644 --- a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc +++ b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc @@ -312,13 +312,8 @@ bool HasPolicyForNetwork(const NetworkState* network, } void SetCommonNetworkInfo(const ManagedState* state, - const gfx::ImageSkia& icon, - float icon_scale_factor, + const std::string& icon_url, base::DictionaryValue* network_info) { - gfx::ImageSkiaRep image_rep = - icon.GetRepresentation(icon_scale_factor); - std::string icon_url = - icon.isNull() ? "" : webui::GetBitmapDataUrl(image_rep.sk_bitmap()); network_info->SetString(kNetworkInfoKeyIconURL, icon_url); std::string name = state->name(); @@ -347,9 +342,9 @@ base::DictionaryValue* BuildNetworkDictionary( network_info->SetBoolean(kNetworkInfoKeyPolicyManaged, HasPolicyForNetwork(network, profile_prefs)); - gfx::ImageSkia icon = ash::network_icon::GetImageForNetwork( - network, ash::network_icon::ICON_TYPE_LIST); - SetCommonNetworkInfo(network, icon, icon_scale_factor, network_info.get()); + std::string icon_url = ash::network_icon::GetImageUrlForNetwork( + network, ash::network_icon::ICON_TYPE_LIST, icon_scale_factor); + SetCommonNetworkInfo(network, icon_url, network_info.get()); return network_info.release(); } @@ -364,9 +359,9 @@ base::DictionaryValue* BuildFavoriteDictionary( network_info->SetBoolean(kNetworkInfoKeyPolicyManaged, HasPolicyForFavorite(favorite, profile_prefs)); - gfx::ImageSkia icon = ash::network_icon::GetImageForDisconnectedNetwork( - ash::network_icon::ICON_TYPE_LIST, favorite->type()); - SetCommonNetworkInfo(favorite, icon, icon_scale_factor, network_info.get()); + std::string icon_url = ash::network_icon::GetImageUrlForDisconnectedNetwork( + ash::network_icon::ICON_TYPE_LIST, favorite->type(), icon_scale_factor); + SetCommonNetworkInfo(favorite, icon_url, network_info.get()); return network_info.release(); } |