Chromium Code Reviews| Index: chrome/browser/browser_theme_provider.cc |
| diff --git a/chrome/browser/browser_theme_provider.cc b/chrome/browser/browser_theme_provider.cc |
| index aceedf13b24b007ed899ae102758690a78143241..5a477723c3100543d19ecf443e83d7e141098ac1 100644 |
| --- a/chrome/browser/browser_theme_provider.cc |
| +++ b/chrome/browser/browser_theme_provider.cc |
| @@ -13,6 +13,7 @@ |
| #include "base/values.h" |
| #include "chrome/browser/browser_list.h" |
| #include "chrome/browser/browser_process.h" |
| +#include "chrome/browser/browser_theme_pack.h" |
| #include "chrome/browser/browser_window.h" |
| #include "chrome/browser/extensions/extensions_service.h" |
| #include "chrome/browser/metrics/user_metrics.h" |
| @@ -36,50 +37,6 @@ |
| #include "app/win_util.h" |
| #endif |
| -// Strings used by themes to identify colors for different parts of our UI. |
| -const char* BrowserThemeProvider::kColorFrame = "frame"; |
| -const char* BrowserThemeProvider::kColorFrameInactive = "frame_inactive"; |
| -const char* BrowserThemeProvider::kColorFrameIncognito = "frame_incognito"; |
| -const char* BrowserThemeProvider::kColorFrameIncognitoInactive = |
| - "frame_incognito_inactive"; |
| -const char* BrowserThemeProvider::kColorToolbar = "toolbar"; |
| -const char* BrowserThemeProvider::kColorTabText = "tab_text"; |
| -const char* BrowserThemeProvider::kColorBackgroundTabText = |
| - "tab_background_text"; |
| -const char* BrowserThemeProvider::kColorBookmarkText = "bookmark_text"; |
| -const char* BrowserThemeProvider::kColorNTPBackground = "ntp_background"; |
| -const char* BrowserThemeProvider::kColorNTPText = "ntp_text"; |
| -const char* BrowserThemeProvider::kColorNTPLink = "ntp_link"; |
| -const char* BrowserThemeProvider::kColorNTPLinkUnderline = "ntp_link_underline"; |
| -const char* BrowserThemeProvider::kColorNTPHeader = "ntp_header"; |
| -const char* BrowserThemeProvider::kColorNTPSection = "ntp_section"; |
| -const char* BrowserThemeProvider::kColorNTPSectionText = "ntp_section_text"; |
| -const char* BrowserThemeProvider::kColorNTPSectionLink = "ntp_section_link"; |
| -const char* BrowserThemeProvider::kColorNTPSectionLinkUnderline = |
| - "ntp_section_link_underline"; |
| -const char* BrowserThemeProvider::kColorControlBackground = |
| - "control_background"; |
| -const char* BrowserThemeProvider::kColorButtonBackground = "button_background"; |
| - |
| -// Strings used by themes to identify tints to apply to different parts of |
| -// our UI. The frame tints apply to the frame color and produce the |
| -// COLOR_FRAME* colors. |
| -const char* BrowserThemeProvider::kTintButtons = "buttons"; |
| -const char* BrowserThemeProvider::kTintFrame = "frame"; |
| -const char* BrowserThemeProvider::kTintFrameInactive = "frame_inactive"; |
| -const char* BrowserThemeProvider::kTintFrameIncognito = "frame_incognito"; |
| -const char* BrowserThemeProvider::kTintFrameIncognitoInactive = |
| - "frame_incognito_inactive"; |
| -const char* BrowserThemeProvider::kTintBackgroundTab = "background_tab"; |
| - |
| -// Strings used by themes to identify miscellaneous numerical properties. |
| -const char* BrowserThemeProvider::kDisplayPropertyNTPAlignment = |
| - "ntp_background_alignment"; |
| -const char* BrowserThemeProvider::kDisplayPropertyNTPTiling = |
| - "ntp_background_repeat"; |
| -const char* BrowserThemeProvider::kDisplayPropertyNTPInverseLogo = |
| - "ntp_logo_alternate"; |
| - |
| // Strings used in alignment properties. |
| const char* BrowserThemeProvider::kAlignmentTop = "top"; |
| const char* BrowserThemeProvider::kAlignmentBottom = "bottom"; |
| @@ -92,68 +49,52 @@ const char* BrowserThemeProvider::kTilingRepeatX = "repeat-x"; |
| const char* BrowserThemeProvider::kTilingRepeatY = "repeat-y"; |
| const char* BrowserThemeProvider::kTilingRepeat = "repeat"; |
| +// Saved default values. |
| +const char* BrowserThemeProvider::kDefaultThemeID = ""; |
| + |
| +namespace { |
| + |
| +SkColor TintForUnderline(SkColor input) { |
| + return SkColorSetA(input, SkColorGetA(input) / 3); |
| +} |
| + |
| // Default colors. |
| -const SkColor BrowserThemeProvider::kDefaultColorFrame = |
| - SkColorSetRGB(77, 139, 217); |
| -const SkColor BrowserThemeProvider::kDefaultColorFrameInactive = |
| - SkColorSetRGB(152, 188, 233); |
| -const SkColor BrowserThemeProvider::kDefaultColorFrameIncognito = |
| - SkColorSetRGB(83, 106, 139); |
| -const SkColor BrowserThemeProvider::kDefaultColorFrameIncognitoInactive = |
| +const SkColor kDefaultColorFrame = SkColorSetRGB(77, 139, 217); |
| +const SkColor kDefaultColorFrameInactive = SkColorSetRGB(152, 188, 233); |
| +const SkColor kDefaultColorFrameIncognito = SkColorSetRGB(83, 106, 139); |
| +const SkColor kDefaultColorFrameIncognitoInactive = |
| SkColorSetRGB(126, 139, 156); |
| -const SkColor BrowserThemeProvider::kDefaultColorToolbar = |
| - SkColorSetRGB(210, 225, 246); |
| -const SkColor BrowserThemeProvider::kDefaultColorTabText = SK_ColorBLACK; |
| -const SkColor BrowserThemeProvider::kDefaultColorBackgroundTabText = |
| - SkColorSetRGB(64, 64, 64); |
| -const SkColor BrowserThemeProvider::kDefaultColorBookmarkText = |
| - SkColorSetRGB(18, 50, 114); |
| +const SkColor kDefaultColorToolbar = SkColorSetRGB(210, 225, 246); |
| +const SkColor kDefaultColorTabText = SK_ColorBLACK; |
| +const SkColor kDefaultColorBackgroundTabText = SkColorSetRGB(64, 64, 64); |
| +const SkColor kDefaultColorBookmarkText = SkColorSetRGB(18, 50, 114); |
| #if defined(OS_WIN) |
| -const SkColor BrowserThemeProvider::kDefaultColorNTPBackground = |
| +const SkColor kDefaultColorNTPBackground = |
| color_utils::GetSysSkColor(COLOR_WINDOW); |
| -const SkColor BrowserThemeProvider::kDefaultColorNTPText = |
| +const SkColor kDefaultColorNTPText = |
| color_utils::GetSysSkColor(COLOR_WINDOWTEXT); |
| -const SkColor BrowserThemeProvider::kDefaultColorNTPLink = |
| +const SkColor kDefaultColorNTPLink = |
| color_utils::GetSysSkColor(COLOR_HOTLIGHT); |
| #else |
| // TODO(beng): source from theme provider. |
| -const SkColor BrowserThemeProvider::kDefaultColorNTPBackground = SK_ColorWHITE; |
| -const SkColor BrowserThemeProvider::kDefaultColorNTPText = SK_ColorBLACK; |
| -const SkColor BrowserThemeProvider::kDefaultColorNTPLink = |
| - SkColorSetRGB(6, 55, 116); |
| +const SkColor kDefaultColorNTPBackground = SK_ColorWHITE; |
| +const SkColor kDefaultColorNTPText = SK_ColorBLACK; |
| +const SkColor kDefaultColorNTPLink = SkColorSetRGB(6, 55, 116); |
| #endif |
| -const SkColor BrowserThemeProvider::kDefaultColorNTPHeader = |
| - SkColorSetRGB(75, 140, 220); |
| -const SkColor BrowserThemeProvider::kDefaultColorNTPSection = |
| - SkColorSetRGB(229, 239, 254); |
| -const SkColor BrowserThemeProvider::kDefaultColorNTPSectionText = SK_ColorBLACK; |
| -const SkColor BrowserThemeProvider::kDefaultColorNTPSectionLink = |
| - SkColorSetRGB(6, 55, 116); |
| -const SkColor BrowserThemeProvider::kDefaultColorControlBackground = |
| - SkColorSetARGB(0, 0, 0, 0); |
| -const SkColor BrowserThemeProvider::kDefaultColorButtonBackground = |
| - SkColorSetARGB(0, 0, 0, 0); |
| +const SkColor kDefaultColorNTPHeader = SkColorSetRGB(75, 140, 220); |
| +const SkColor kDefaultColorNTPSection = SkColorSetRGB(229, 239, 254); |
| +const SkColor kDefaultColorNTPSectionText = SK_ColorBLACK; |
| +const SkColor kDefaultColorNTPSectionLink = SkColorSetRGB(6, 55, 116); |
| +const SkColor kDefaultColorControlBackground = SkColorSetARGB(0, 0, 0, 0); |
| +const SkColor kDefaultColorButtonBackground = SkColorSetARGB(0, 0, 0, 0); |
| // Default tints. |
| -const color_utils::HSL BrowserThemeProvider::kDefaultTintButtons = |
| - { -1, -1, -1 }; |
| -const color_utils::HSL BrowserThemeProvider::kDefaultTintFrame = { -1, -1, -1 }; |
| -const color_utils::HSL BrowserThemeProvider::kDefaultTintFrameInactive = |
| - { -1, -1, 0.75f }; |
| -const color_utils::HSL BrowserThemeProvider::kDefaultTintFrameIncognito = |
| - { -1, 0.2f, 0.35f }; |
| -const color_utils::HSL |
| - BrowserThemeProvider::kDefaultTintFrameIncognitoInactive = |
| - { -1, 0.3f, 0.6f }; |
| -const color_utils::HSL BrowserThemeProvider::kDefaultTintBackgroundTab = |
| - { -1, 0.5, 0.75 }; |
| - |
| -// Saved default values. |
| -const char* BrowserThemeProvider::kDefaultThemeID = ""; |
| - |
| -Lock BrowserThemeProvider::themed_image_cache_lock_; |
| - |
| -namespace { |
| +const color_utils::HSL kDefaultTintButtons = { -1, -1, -1 }; |
| +const color_utils::HSL kDefaultTintFrame = { -1, -1, -1 }; |
| +const color_utils::HSL kDefaultTintFrameInactive = { -1, -1, 0.75f }; |
| +const color_utils::HSL kDefaultTintFrameIncognito = { -1, 0.2f, 0.35f }; |
| +const color_utils::HSL kDefaultTintFrameIncognitoInactive = { -1, 0.3f, 0.6f }; |
| +const color_utils::HSL kDefaultTintBackgroundTab = { -1, 0.5, 0.75 }; |
| // Default display properties. |
| const int kDefaultDisplayPropertyNTPAlignment = |
| @@ -166,35 +107,6 @@ const int kDefaultDisplayPropertyNTPInverseLogo = 0; |
| // OpaqueBrowserFrameView. |
| const int kRestoredTabVerticalOffset = 15; |
| -// The image resources that will be tinted by the 'button' tint value. |
| -const int kToolbarButtonIDs[] = { |
| - IDR_BACK, IDR_BACK_D, IDR_BACK_H, IDR_BACK_P, |
| - IDR_FORWARD, IDR_FORWARD_D, IDR_FORWARD_H, IDR_FORWARD_P, |
| - IDR_RELOAD, IDR_RELOAD_H, IDR_RELOAD_P, |
| - IDR_HOME, IDR_HOME_H, IDR_HOME_P, |
| - IDR_STAR, IDR_STAR_NOBORDER, IDR_STAR_NOBORDER_CENTER, IDR_STAR_D, IDR_STAR_H, |
| - IDR_STAR_P, |
| - IDR_STARRED, IDR_STARRED_NOBORDER, IDR_STARRED_NOBORDER_CENTER, IDR_STARRED_H, |
| - IDR_STARRED_P, |
| - IDR_GO, IDR_GO_NOBORDER, IDR_GO_NOBORDER_CENTER, IDR_GO_H, IDR_GO_P, |
| - IDR_STOP, IDR_STOP_NOBORDER, IDR_STOP_NOBORDER_CENTER, IDR_STOP_H, IDR_STOP_P, |
| - IDR_MENU_BOOKMARK, |
| - IDR_MENU_PAGE, IDR_MENU_PAGE_RTL, |
| - IDR_MENU_CHROME, IDR_MENU_CHROME_RTL, |
| - IDR_MENU_DROPARROW, |
| - IDR_THROBBER, IDR_THROBBER_WAITING, IDR_THROBBER_LIGHT, |
| - IDR_LOCATIONBG |
| -}; |
| - |
| -bool HasButtonImage(int toolbar_button_id) { |
| - static std::map<int, bool> button_images; |
| - if (button_images.empty()) { |
| - for (size_t i = 0; i < arraysize(kToolbarButtonIDs); ++i) |
| - button_images[kToolbarButtonIDs[i]] = true; |
| - } |
| - return button_images.count(toolbar_button_id) > 0; |
| -} |
| - |
| // The image resources we will allow people to theme. |
| const int kThemeableImages[] = { |
| IDR_THEME_FRAME, |
| @@ -222,49 +134,21 @@ bool HasThemeableImage(int themeable_image_id) { |
| return themeable_images.count(themeable_image_id) > 0; |
| } |
| - |
| -class WriteImagesToDiskTask : public Task { |
| +// Writes the theme pack to disk on a separate thread. |
| +class WritePackToDiskTask : public Task { |
| public: |
| - WriteImagesToDiskTask( |
| - const BrowserThemeProvider::ImagesDiskCache& images_disk_cache, |
| - const BrowserThemeProvider::ImageCache& themed_image_cache) : |
| - images_disk_cache_(images_disk_cache), |
| - themed_image_cache_(themed_image_cache) { |
| - } |
| + WritePackToDiskTask(BrowserThemePack* pack, const FilePath& path) |
| + : theme_pack_(pack), pack_path_(path) {} |
| virtual void Run() { |
| - AutoLock lock(BrowserThemeProvider::themed_image_cache_lock_); |
| - for (BrowserThemeProvider::ImagesDiskCache::const_iterator iter( |
| - images_disk_cache_.begin()); iter != images_disk_cache_.end(); |
| - ++iter) { |
| - FilePath image_path = iter->first; |
| - BrowserThemeProvider::ImageCache::const_iterator themed_iter = |
| - themed_image_cache_.find(iter->second); |
| - if (themed_iter != themed_image_cache_.end()) { |
| - SkBitmap* bitmap = themed_iter->second; |
| - std::vector<unsigned char> image_data; |
| - if (!gfx::PNGCodec::EncodeBGRASkBitmap(*bitmap, false, &image_data)) { |
| - NOTREACHED() << "Image file could not be encoded."; |
| - return; |
| - } |
| - const char* image_data_ptr = |
| - reinterpret_cast<const char*>(&image_data[0]); |
| - if (!file_util::WriteFile(image_path, |
| - image_data_ptr, image_data.size())) { |
| - NOTREACHED() << "Image file could not be written to disk."; |
| - return; |
| - } |
| - } else { |
| - NOTREACHED() << "Themed image missing from cache."; |
| - return; |
| - } |
| + if (!theme_pack_->WriteToDisk(pack_path_)) { |
| + NOTREACHED() << "Could not write theme pack to disk"; |
| } |
| } |
| private: |
| - // References to data held in the BrowserThemeProvider. |
| - const BrowserThemeProvider::ImagesDiskCache& images_disk_cache_; |
| - const BrowserThemeProvider::ImageCache& themed_image_cache_; |
| + scoped_refptr<BrowserThemePack> theme_pack_; |
| + FilePath pack_path_; |
| }; |
| } // namespace |
| @@ -275,32 +159,13 @@ bool BrowserThemeProvider::IsThemeableImage(int resource_id) { |
| BrowserThemeProvider::BrowserThemeProvider() |
| : rb_(ResourceBundle::GetSharedInstance()), |
| - profile_(NULL), |
| - process_images_(false) { |
| + profile_(NULL) { |
| // Initialize the themeable image map so we can use it on other threads. |
| HasThemeableImage(0); |
| - resource_names_[IDR_THEME_FRAME] = "theme_frame"; |
| - resource_names_[IDR_THEME_FRAME_INACTIVE] = "theme_frame_inactive"; |
| - resource_names_[IDR_THEME_FRAME_OVERLAY] = "theme_frame_overlay"; |
| - resource_names_[IDR_THEME_FRAME_OVERLAY_INACTIVE] = |
| - "theme_frame_overlay_inactive"; |
| - resource_names_[IDR_THEME_FRAME_INCOGNITO] = "theme_frame_incognito"; |
| - resource_names_[IDR_THEME_FRAME_INCOGNITO_INACTIVE] = |
| - "theme_frame_incognito_inactive"; |
| - resource_names_[IDR_THEME_TAB_BACKGROUND] = "theme_tab_background"; |
| - resource_names_[IDR_THEME_TAB_BACKGROUND_INCOGNITO] = |
| - "theme_tab_background_incognito"; |
| - resource_names_[IDR_THEME_TOOLBAR] = "theme_toolbar"; |
| - resource_names_[IDR_THEME_TAB_BACKGROUND_V] = "theme_tab_background_v"; |
| - resource_names_[IDR_THEME_NTP_BACKGROUND] = "theme_ntp_background"; |
| - resource_names_[IDR_THEME_BUTTON_BACKGROUND] = "theme_button_background"; |
| - resource_names_[IDR_THEME_NTP_ATTRIBUTION] = "theme_ntp_attribution"; |
| - resource_names_[IDR_THEME_WINDOW_CONTROL_BACKGROUND] = |
| - "theme_window_control_background"; |
| } |
| BrowserThemeProvider::~BrowserThemeProvider() { |
| - ClearCaches(); |
| + FreePlatformCaches(); |
|
tony
2009/12/11 19:14:23
I don't think this is going to call the virtual me
Elliot Glaysher
2009/12/11 19:35:38
Good catch. Fixed.
|
| RemoveUnusedThemes(); |
| } |
| @@ -309,120 +174,37 @@ void BrowserThemeProvider::Init(Profile* profile) { |
| DCHECK(CalledOnValidThread()); |
| profile_ = profile; |
| - image_dir_ = profile_->GetPath().Append(chrome::kThemeImagesDirname); |
| - if (!file_util::PathExists(image_dir_)) |
| - file_util::CreateDirectory(image_dir_); |
| - |
| LoadThemePrefs(); |
| } |
| SkBitmap* BrowserThemeProvider::GetBitmapNamed(int id) const { |
| DCHECK(CalledOnValidThread()); |
| - // First check to see if the Skia image is in the themed cache. The themed |
| - // cache is not changed in this method, so it can remain unlocked. |
| - ImageCache::const_iterator themed_iter = themed_image_cache_.find(id); |
| - if (themed_iter != themed_image_cache_.end()) |
| - return themed_iter->second; |
| - |
| - // If Skia image is not in themed cache, check regular cache, and possibly |
| - // generate and store. |
| - ImageCache::const_iterator image_iter = image_cache_.find(id); |
| - if (image_iter != image_cache_.end()) |
| - return image_iter->second; |
| - |
| - scoped_ptr<SkBitmap> result; |
| - |
| - // Try to load the image from the extension. |
| - result.reset(LoadThemeBitmap(id)); |
| - |
| - // If we still don't have an image, load it from resourcebundle. |
| - if (!result.get()) |
| - result.reset(new SkBitmap(*rb_.GetBitmapNamed(id))); |
| - |
| - if (result.get()) { |
| - // If the requested image is part of the toolbar button set, and we have |
| - // a provided tint for that set, tint it appropriately. |
| - if (HasButtonImage(id) && tints_.count(kTintButtons)) { |
| - SkBitmap* tinted = |
| - new SkBitmap(TintBitmap(*result.release(), TINT_BUTTONS)); |
| - result.reset(tinted); |
| - } |
| + SkBitmap* bitmap = NULL; |
| - // We loaded successfully. Cache the bitmap. |
| - image_cache_[id] = result.get(); |
| - return result.release(); |
| - } else { |
| - NOTREACHED() << "Failed to load a requested image"; |
| - return NULL; |
| - } |
| + if (theme_pack_.get()) |
| + bitmap = theme_pack_->GetBitmapNamed(id); |
| + |
| + if (!bitmap) |
| + bitmap = rb_.GetBitmapNamed(id); |
| + |
| + return bitmap; |
| } |
| SkColor BrowserThemeProvider::GetColor(int id) const { |
| DCHECK(CalledOnValidThread()); |
| - // Special-case NTP header - if the color isn't provided, we fall back to |
| - // the section color. |
| - if (id == COLOR_NTP_HEADER) { |
| - ColorMap::const_iterator color_iter = colors_.find(kColorNTPHeader); |
| - if (color_iter != colors_.end()) |
| - return color_iter->second; |
| - color_iter = colors_.find(kColorNTPSection); |
| - return (color_iter == colors_.end()) ? |
| - GetDefaultColor(id) : color_iter->second; |
| - } |
| - |
| - // Special case the underline colors to use semi transparent in case not |
| - // defined. |
| - if (id == COLOR_NTP_SECTION_LINK_UNDERLINE) { |
| - ColorMap::const_iterator color_iter = |
| - colors_.find(kColorNTPSectionLinkUnderline); |
| - if (color_iter != colors_.end()) |
| - return color_iter->second; |
| - SkColor color_section_link = GetColor(COLOR_NTP_SECTION_LINK); |
| - return SkColorSetA(color_section_link, SkColorGetA(color_section_link) / 3); |
| - } |
| + SkColor color; |
| + if (theme_pack_.get() && theme_pack_->GetColor(id, &color)) |
| + return color; |
| - if (id == COLOR_NTP_LINK_UNDERLINE) { |
| - ColorMap::const_iterator color_iter = colors_.find(kColorNTPLinkUnderline); |
| - if (color_iter != colors_.end()) |
| - return color_iter->second; |
| - SkColor color_link = GetColor(COLOR_NTP_LINK); |
| - return SkColorSetA(color_link, SkColorGetA(color_link) / 3); |
| - } |
| - |
| - // TODO(glen): Figure out if we need to tint these. http://crbug.com/11578 |
| - ColorMap::const_iterator color_iter = colors_.find(GetColorKey(id)); |
| - return (color_iter == colors_.end()) ? |
| - GetDefaultColor(id) : color_iter->second; |
| + return GetDefaultColor(id); |
| } |
| bool BrowserThemeProvider::GetDisplayProperty(int id, int* result) const { |
| - switch (id) { |
| - case NTP_BACKGROUND_ALIGNMENT: { |
| - DisplayPropertyMap::const_iterator display_iter = |
| - display_properties_.find(kDisplayPropertyNTPAlignment); |
| - *result = (display_iter == display_properties_.end()) ? |
| - kDefaultDisplayPropertyNTPAlignment : display_iter->second; |
| - return true; |
| - } |
| - case NTP_BACKGROUND_TILING: { |
| - DisplayPropertyMap::const_iterator display_iter = |
| - display_properties_.find(kDisplayPropertyNTPTiling); |
| - *result = (display_iter == display_properties_.end()) ? |
| - kDefaultDisplayPropertyNTPTiling : display_iter->second; |
| - return true; |
| - } |
| - case NTP_LOGO_ALTERNATE: { |
| - DisplayPropertyMap::const_iterator display_iter = |
| - display_properties_.find(kDisplayPropertyNTPInverseLogo); |
| - *result = (display_iter == display_properties_.end()) ? |
| - kDefaultDisplayPropertyNTPInverseLogo : display_iter->second; |
| - return true; |
| - } |
| - default: |
| - NOTREACHED() << "Unknown property requested"; |
| - } |
| + if (theme_pack_.get()) |
| + return theme_pack_->GetDisplayProperty(id, result); |
| + |
| return false; |
| } |
| @@ -440,15 +222,10 @@ bool BrowserThemeProvider::HasCustomImage(int id) const { |
| if (!HasThemeableImage(id)) |
| return false; |
| - // A custom image = base name is NOT equal to resource name. See note in |
| - // SaveThemeBitmap describing the process by which an original image is |
| - // tagged. |
| - ImageMap::const_iterator images_iter = images_.find(id); |
| - ResourceNameMap::const_iterator names_iter = resource_names_.find(id); |
| - if ((images_iter == images_.end()) || (names_iter == resource_names_.end())) |
| - return false; |
| - return !EndsWith(UTF8ToWide(images_iter->second), |
| - UTF8ToWide(names_iter->second), false); |
| + if (theme_pack_) |
| + return theme_pack_->HasCustomImage(id); |
| + |
| + return false; |
| } |
| RefCountedMemory* BrowserThemeProvider::GetRawData(int id) const { |
| @@ -458,57 +235,25 @@ RefCountedMemory* BrowserThemeProvider::GetRawData(int id) const { |
| if (id == IDR_PRODUCT_LOGO && ntp_alternate != 0) |
| id = IDR_PRODUCT_LOGO_WHITE; |
| - RawDataMap::const_iterator data_iter = raw_data_.find(id); |
| - if (data_iter != raw_data_.end()) |
| - return data_iter->second; |
| - |
| - RefCountedMemory* data = ReadThemeFileData(id); |
| + RefCountedMemory* data = NULL; |
| + if (theme_pack_.get()) |
| + data = theme_pack_->GetRawData(id); |
| if (!data) |
| data = rb_.LoadDataResourceBytes(id); |
| - if (!data) |
| - return NULL; |
| - raw_data_[id] = data; |
| return data; |
| } |
| void BrowserThemeProvider::SetTheme(Extension* extension) { |
| // Clear our image cache. |
| - ClearCaches(); |
| + FreePlatformCaches(); |
| DCHECK(extension); |
| DCHECK(extension->IsTheme()); |
| - SetImageData(extension->GetThemeImages(), |
| - extension->path()); |
| - SetColorData(extension->GetThemeColors()); |
| - SetTintData(extension->GetThemeTints()); |
| - |
| - // Drop out to default theme if the theme data is empty. |
| - if (images_.empty() && colors_.empty() && tints_.empty()) { |
| - UseDefaultTheme(); |
| - return; |
| - } |
| - |
| - SetDisplayPropertyData(extension->GetThemeDisplayProperties()); |
| - raw_data_.clear(); |
| - SaveImageData(extension->GetThemeImages()); |
| - SaveColorData(); |
| - SaveTintData(); |
| - SaveDisplayPropertyData(); |
| + BuildFromExtension(extension); |
| SaveThemeID(extension->id()); |
| - // Process all images when we first set theme. |
| - process_images_ = true; |
| - |
| - GenerateFrameColors(); |
| - if (ShouldTintFrames()) { |
| - AutoLock lock(themed_image_cache_lock_); |
| - GenerateFrameImages(); |
| - GenerateTabImages(); |
| - } |
| - |
| - WriteImagesToDisk(); |
| NotifyThemeChanged(); |
| UserMetrics::RecordAction("Themes_Installed", profile_); |
| } |
| @@ -543,36 +288,6 @@ std::string BrowserThemeProvider::GetThemeID() const { |
| return WideToUTF8(id); |
| } |
| -RefCountedMemory* BrowserThemeProvider::ReadThemeFileData(int id) const { |
| - ImageMap::const_iterator images_iter = images_.find(id); |
| - if (images_iter != images_.end()) { |
| - // First check to see if we have a registered theme extension and whether |
| - // it can handle this resource. |
| -#if defined(OS_WIN) |
| - FilePath path = FilePath(UTF8ToWide(images_iter->second)); |
| -#else |
| - FilePath path = FilePath(images_iter->second); |
| -#endif |
| - if (!path.empty()) { |
| - net::FileStream file; |
| - int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ; |
| - if (file.Open(path, flags) == net::OK) { |
| - int64 avail = file.Available(); |
| - if (avail > 0 && avail < INT_MAX) { |
| - size_t size = static_cast<size_t>(avail); |
| - std::vector<unsigned char> raw_data; |
| - raw_data.resize(size); |
| - char* data = reinterpret_cast<char*>(&(raw_data.front())); |
| - if (file.ReadUntilComplete(data, size) == avail) |
| - return RefCountedBytes::TakeVector(&raw_data); |
| - } |
| - } |
| - } |
| - } |
| - |
| - return NULL; |
| -} |
| - |
| // static |
| std::string BrowserThemeProvider::AlignmentToString(int alignment) { |
| // Convert from an AlignmentProperty back into a string. |
| @@ -646,313 +361,8 @@ int BrowserThemeProvider::StringToTiling(const std::string& tiling) { |
| return BrowserThemeProvider::NO_REPEAT; |
| } |
| -void BrowserThemeProvider::SetColor(const char* key, const SkColor& color) { |
| - colors_[key] = color; |
| -} |
| - |
| -void BrowserThemeProvider::SetTint(const char* key, |
| - const color_utils::HSL& tint) { |
| - tints_[key] = tint; |
| -} |
| - |
| -color_utils::HSL BrowserThemeProvider::GetTint(int id) const { |
| - DCHECK(CalledOnValidThread()); |
| - |
| - TintMap::const_iterator tint_iter = tints_.find(GetTintKey(id)); |
| - return (tint_iter == tints_.end()) ? GetDefaultTint(id) : tint_iter->second; |
| -} |
| - |
| -void BrowserThemeProvider::GenerateFrameColors() { |
| - // Generate any secondary frame colors that weren't provided. |
| - SkColor frame = GetColor(COLOR_FRAME); |
| - |
| - if (!colors_.count(kColorFrame)) |
| - colors_[kColorFrame] = HSLShift(frame, GetTint(TINT_FRAME)); |
| - if (!colors_.count(kColorFrameInactive)) { |
| - colors_[kColorFrameInactive] = |
| - HSLShift(frame, GetTint(TINT_FRAME_INACTIVE)); |
| - } |
| - if (!colors_.count(kColorFrameIncognito)) { |
| - colors_[kColorFrameIncognito] = |
| - HSLShift(frame, GetTint(TINT_FRAME_INCOGNITO)); |
| - } |
| - if (!colors_.count(kColorFrameIncognitoInactive)) { |
| - colors_[kColorFrameIncognitoInactive] = |
| - HSLShift(frame, GetTint(TINT_FRAME_INCOGNITO_INACTIVE)); |
| - } |
| -} |
| - |
| -void BrowserThemeProvider::GenerateFrameImages() const { |
| - // A map of frame image IDs to the tints for those ids. |
| - typedef std::map<int, int> FrameTintMap; |
| - static FrameTintMap frame_tints; |
| - if (frame_tints.empty()) { |
| - frame_tints[IDR_THEME_FRAME] = TINT_FRAME; |
| - frame_tints[IDR_THEME_FRAME_INACTIVE] = TINT_FRAME_INACTIVE; |
| - frame_tints[IDR_THEME_FRAME_OVERLAY] = TINT_FRAME; |
| - frame_tints[IDR_THEME_FRAME_OVERLAY_INACTIVE] = TINT_FRAME_INACTIVE; |
| - frame_tints[IDR_THEME_FRAME_INCOGNITO] = TINT_FRAME_INCOGNITO; |
| - frame_tints[IDR_THEME_FRAME_INCOGNITO_INACTIVE] = |
| - TINT_FRAME_INCOGNITO_INACTIVE; |
| - } |
| - |
| - for (FrameTintMap::const_iterator iter(frame_tints.begin()); |
| - iter != frame_tints.end(); ++iter) { |
| - int id = iter->first; |
| - scoped_ptr<SkBitmap> frame; |
| - // If there's no frame image provided for the specified id, then load |
| - // the default provided frame. If that's not provided, skip this whole |
| - // thing and just use the default images. |
| - int base_id; |
| - std::string resource_name; |
| - |
| - // If we've already processed the images for this theme, they're all |
| - // waiting on disk -- just load them in. |
| - if (!process_images_) { |
| - frame.reset(LoadThemeBitmap(id)); |
| - if (frame.get()) |
| - themed_image_cache_[id] = new SkBitmap(*frame.get()); |
| - } else { |
| - resource_name = resource_names_.find(id)->second; |
| - if (id == IDR_THEME_FRAME_INCOGNITO_INACTIVE) { |
| - base_id = HasCustomImage(IDR_THEME_FRAME_INCOGNITO) ? |
| - IDR_THEME_FRAME_INCOGNITO : IDR_THEME_FRAME; |
| - } else if (id == IDR_THEME_FRAME_OVERLAY_INACTIVE) { |
| - base_id = IDR_THEME_FRAME_OVERLAY; |
| - } else if (id == IDR_THEME_FRAME_INACTIVE) { |
| - base_id = IDR_THEME_FRAME; |
| - } else if (id == IDR_THEME_FRAME_INCOGNITO && |
| - !HasCustomImage(IDR_THEME_FRAME_INCOGNITO)) { |
| - base_id = IDR_THEME_FRAME; |
| - } else { |
| - base_id = id; |
| - } |
| - |
| - if (HasCustomImage(id)) { |
| - frame.reset(LoadThemeBitmap(id)); |
| - } else if (base_id != id && HasCustomImage(base_id)) { |
| - frame.reset(LoadThemeBitmap(base_id)); |
| - } else if (base_id == IDR_THEME_FRAME_OVERLAY && |
| - HasCustomImage(IDR_THEME_FRAME)) { |
| - // If there is no theme overlay, don't tint the default frame, |
| - // because it will overwrite the custom frame image when we cache and |
| - // reload from disk. |
| - frame.reset(NULL); |
| - } else { |
| - // If the theme doesn't specify an image, then apply the tint to |
| - // the default frame. |
| - frame.reset(new SkBitmap(*rb_.GetBitmapNamed(IDR_THEME_FRAME))); |
| - } |
| - |
| - if (frame.get()) { |
| - SkBitmap* tinted = new SkBitmap(TintBitmap(*frame, iter->second)); |
| - themed_image_cache_[id] = tinted; |
| - SaveThemeBitmap(resource_name, id); |
| - } |
| - } |
| - } |
| -} |
| - |
| -void BrowserThemeProvider::GenerateTabImages() const { |
| - GenerateTabBackgroundBitmap(IDR_THEME_TAB_BACKGROUND); |
| - GenerateTabBackgroundBitmap(IDR_THEME_TAB_BACKGROUND_INCOGNITO); |
| -} |
| - |
| -void BrowserThemeProvider::ClearAllThemeData() { |
| - // Clear our image cache. |
| - ClearCaches(); |
| - |
| - images_.clear(); |
| - colors_.clear(); |
| - tints_.clear(); |
| - display_properties_.clear(); |
| - raw_data_.clear(); |
| - |
| - SaveImageData(NULL); |
| - SaveColorData(); |
| - SaveTintData(); |
| - SaveDisplayPropertyData(); |
| - SaveThemeID(kDefaultThemeID); |
| -} |
| - |
| -void BrowserThemeProvider::LoadThemePrefs() { |
| - process_images_ = false; |
| - PrefService* prefs = profile_->GetPrefs(); |
| - |
| - // TODO(glen): Figure out if any custom prefs were loaded, and if so UMA-log |
| - // the fact that a theme was loaded. |
| - if (!prefs->HasPrefPath(prefs::kCurrentThemeImages) && |
| - !prefs->HasPrefPath(prefs::kCurrentThemeColors) && |
| - !prefs->HasPrefPath(prefs::kCurrentThemeTints)) |
| - return; |
| - |
| - // Our prefs already have the extension path baked in, so we don't need to |
| - // provide it. |
| - SetImageData(prefs->GetMutableDictionary(prefs::kCurrentThemeImages), |
| - FilePath()); |
| - SetColorData(prefs->GetMutableDictionary(prefs::kCurrentThemeColors)); |
| - SetTintData(prefs->GetMutableDictionary(prefs::kCurrentThemeTints)); |
| - SetDisplayPropertyData( |
| - prefs->GetMutableDictionary(prefs::kCurrentThemeDisplayProperties)); |
| - |
| - // If we're not loading the frame from the cached image dir, we are using an |
| - // old preferences file, or the processed images were not saved correctly. |
| - // Force image reprocessing and caching. |
| - ImageMap::const_iterator images_iter = images_.find(IDR_THEME_FRAME); |
| - if (images_iter != images_.end()) { |
| -#if defined(OS_WIN) |
| - FilePath cache_path = FilePath(UTF8ToWide(images_iter->second)); |
| -#else |
| - FilePath cache_path = FilePath(images_iter->second); |
| -#endif |
| - process_images_ = !file_util::ContainsPath(image_dir_, cache_path); |
| - } |
| - |
| - GenerateFrameColors(); |
| - // Scope for AutoLock on themed_image_cache. |
| - { |
| - AutoLock lock(themed_image_cache_lock_); |
| - GenerateFrameImages(); |
| - GenerateTabImages(); |
| - } |
| - |
| - if (process_images_) { |
| - WriteImagesToDisk(); |
| - UserMetrics::RecordAction("Migrated noncached to cached theme.", profile_); |
| - } |
| - UserMetrics::RecordAction("Themes_loaded", profile_); |
| -} |
| - |
| -void BrowserThemeProvider::NotifyThemeChanged() { |
| - // Redraw! |
| - NotificationService* service = NotificationService::current(); |
| - service->Notify(NotificationType::BROWSER_THEME_CHANGED, |
| - Source<BrowserThemeProvider>(this), |
| - NotificationService::NoDetails()); |
| -} |
| - |
| -SkBitmap* BrowserThemeProvider::LoadThemeBitmap(int id) const { |
| - DCHECK(CalledOnValidThread()); |
| - |
| - if (!HasThemeableImage(id)) |
| - return NULL; |
| - |
| - scoped_refptr<RefCountedMemory> raw_data; |
| - |
| - // We special case images related to the NTP so we first try raw data. Why? |
| - // Because the DOMUI stuff uses that interface to return raw PNG data instead |
| - // of the normal theme interface which returns SkBitmaps. GetRawData() also |
| - // caches the PNG data so it opens new tab pages faster. If we didn't try and |
| - // otherwise we would be loading big images twice, once through GetRawData() |
| - // and once here. Ouch. So either we prime the GetRawData() cache for when |
| - // DOMUIThemeSource requests our image, or we take advantage of the already |
| - // loaded data, saving a trip to disk. |
| - if (id == IDR_THEME_NTP_BACKGROUND) |
| - raw_data = GetRawData(id); |
| - |
| - if (!raw_data) |
| - raw_data = ReadThemeFileData(id); |
| - |
| - if (raw_data) { |
| - // Decode the PNG. |
| - SkBitmap bitmap; |
| - if (!gfx::PNGCodec::Decode(raw_data->front(), raw_data->size(), |
| - &bitmap)) { |
| - NOTREACHED() << "Unable to decode theme image resource " << id; |
| - return NULL; |
| - } |
| - |
| - return new SkBitmap(bitmap); |
| - } else { |
| - // TODO(glen): File no-longer exists, we're out of date. We should |
| - // clear the theme (or maybe just the pref that points to this |
| - // image). |
| - return NULL; |
| - } |
| -} |
| - |
| -void BrowserThemeProvider::SaveThemeBitmap(std::string resource_name, |
| - int id) const { |
| - DCHECK(CalledOnValidThread()); |
| - if (!themed_image_cache_.count(id)) { |
| - NOTREACHED(); |
| - return; |
| - } |
| - |
| - // The images_ directory, at this point, contains only the custom images |
| - // provided by the extension. We tag these images "_original" in the prefs |
| - // file so we can distinguish them from images which have been generated and |
| - // saved to disk by the theme caching process (WriteImagesToDisk). This way, |
| - // when we call HasCustomImage, we can check for the "_original" tag to see |
| - // whether an image was originally provided by the extension, or saved |
| - // in the caching process. |
| - if (images_.count(id)) |
| - resource_name.append("_original"); |
| - |
| -#if defined(OS_WIN) |
| - FilePath image_path = image_dir_.Append(UTF8ToWide(resource_name)); |
| -#elif defined(OS_POSIX) |
| - FilePath image_path = image_dir_.Append(resource_name); |
| -#endif |
| - |
| - images_disk_cache_[image_path] = id; |
| -} |
| - |
| -#if defined(OS_WIN) |
| -void BrowserThemeProvider::FreePlatformCaches() { |
| - // Views (Skia) has no platform image cache to clear. |
| -} |
| -#endif |
| - |
| -SkBitmap* BrowserThemeProvider::GenerateTabBackgroundBitmapImpl(int id) const { |
| - int base_id = (id == IDR_THEME_TAB_BACKGROUND) ? |
| - IDR_THEME_FRAME : IDR_THEME_FRAME_INCOGNITO; |
| - // According to Miranda, it is safe to read from the themed_image_cache_ here |
| - // because we only lock to write on the UI thread, and we only lock to read |
| - // on the cache writing thread. |
| - ImageCache::const_iterator themed_iter = themed_image_cache_.find(base_id); |
| - if (themed_iter == themed_image_cache_.end()) |
| - return NULL; |
| - |
| - SkBitmap bg_tint = TintBitmap(*(themed_iter->second), TINT_BACKGROUND_TAB); |
| - int vertical_offset = HasCustomImage(id) ? kRestoredTabVerticalOffset : 0; |
| - SkBitmap* bg_tab = new SkBitmap(SkBitmapOperations::CreateTiledBitmap( |
| - bg_tint, 0, vertical_offset, bg_tint.width(), bg_tint.height())); |
| - |
| - // If they've provided a custom image, overlay it. |
| - if (HasCustomImage(id)) { |
| - SkBitmap* overlay = LoadThemeBitmap(id); |
| - if (overlay) { |
| - SkCanvas canvas(*bg_tab); |
| - for (int x = 0; x < bg_tab->width(); x += overlay->width()) |
| - canvas.drawBitmap(*overlay, static_cast<SkScalar>(x), 0, NULL); |
| - } |
| - } |
| - |
| - return bg_tab; |
| -} |
| - |
| -const std::string BrowserThemeProvider::GetTintKey(int id) const { |
| - switch (id) { |
| - case TINT_FRAME: |
| - return kTintFrame; |
| - case TINT_FRAME_INACTIVE: |
| - return kTintFrameInactive; |
| - case TINT_FRAME_INCOGNITO: |
| - return kTintFrameIncognito; |
| - case TINT_FRAME_INCOGNITO_INACTIVE: |
| - return kTintFrameIncognitoInactive; |
| - case TINT_BUTTONS: |
| - return kTintButtons; |
| - case TINT_BACKGROUND_TAB: |
| - return kTintBackgroundTab; |
| - default: |
| - NOTREACHED() << "Unknown tint requested"; |
| - return ""; |
| - } |
| -} |
| - |
| -color_utils::HSL BrowserThemeProvider::GetDefaultTint(int id) const { |
| +// static |
| +color_utils::HSL BrowserThemeProvider::GetDefaultTint(int id) { |
| switch (id) { |
| case TINT_FRAME: |
| return kDefaultTintFrame; |
| @@ -972,53 +382,8 @@ color_utils::HSL BrowserThemeProvider::GetDefaultTint(int id) const { |
| } |
| } |
| -const std::string BrowserThemeProvider::GetColorKey(int id) const { |
| - switch (id) { |
| - case COLOR_FRAME: |
| - return kColorFrame; |
| - case COLOR_FRAME_INACTIVE: |
| - return kColorFrameInactive; |
| - case COLOR_FRAME_INCOGNITO: |
| - return kColorFrameIncognito; |
| - case COLOR_FRAME_INCOGNITO_INACTIVE: |
| - return kColorFrameIncognitoInactive; |
| - case COLOR_TOOLBAR: |
| - return kColorToolbar; |
| - case COLOR_TAB_TEXT: |
| - return kColorTabText; |
| - case COLOR_BACKGROUND_TAB_TEXT: |
| - return kColorBackgroundTabText; |
| - case COLOR_BOOKMARK_TEXT: |
| - return kColorBookmarkText; |
| - case COLOR_NTP_BACKGROUND: |
| - return kColorNTPBackground; |
| - case COLOR_NTP_TEXT: |
| - return kColorNTPText; |
| - case COLOR_NTP_LINK: |
| - return kColorNTPLink; |
| - case COLOR_NTP_LINK_UNDERLINE: |
| - return kColorNTPLinkUnderline; |
| - case COLOR_NTP_HEADER: |
| - return kColorNTPHeader; |
| - case COLOR_NTP_SECTION: |
| - return kColorNTPSection; |
| - case COLOR_NTP_SECTION_TEXT: |
| - return kColorNTPSectionText; |
| - case COLOR_NTP_SECTION_LINK: |
| - return kColorNTPSectionLink; |
| - case COLOR_NTP_SECTION_LINK_UNDERLINE: |
| - return kColorNTPSectionLinkUnderline; |
| - case COLOR_CONTROL_BACKGROUND: |
| - return kColorControlBackground; |
| - case COLOR_BUTTON_BACKGROUND: |
| - return kColorButtonBackground; |
| - default: |
| - NOTREACHED() << "Unknown color requested"; |
| - return ""; |
| - } |
| -} |
| - |
| -SkColor BrowserThemeProvider::GetDefaultColor(int id) const { |
| +// static |
| +SkColor BrowserThemeProvider::GetDefaultColor(int id) { |
| switch (id) { |
| case COLOR_FRAME: |
| return kDefaultColorFrame; |
| @@ -1042,6 +407,8 @@ SkColor BrowserThemeProvider::GetDefaultColor(int id) const { |
| return kDefaultColorNTPText; |
| case COLOR_NTP_LINK: |
| return kDefaultColorNTPLink; |
| + case COLOR_NTP_LINK_UNDERLINE: |
| + return TintForUnderline(kDefaultColorNTPLink); |
| case COLOR_NTP_HEADER: |
| return kDefaultColorNTPHeader; |
| case COLOR_NTP_SECTION: |
| @@ -1050,6 +417,8 @@ SkColor BrowserThemeProvider::GetDefaultColor(int id) const { |
| return kDefaultColorNTPSectionText; |
| case COLOR_NTP_SECTION_LINK: |
| return kDefaultColorNTPSectionLink; |
| + case COLOR_NTP_SECTION_LINK_UNDERLINE: |
| + return TintForUnderline(kDefaultColorNTPSectionLink); |
| case COLOR_CONTROL_BACKGROUND: |
| return kDefaultColorControlBackground; |
| case COLOR_BUTTON_BACKGROUND: |
| @@ -1060,289 +429,97 @@ SkColor BrowserThemeProvider::GetDefaultColor(int id) const { |
| } |
| } |
| -SkBitmap BrowserThemeProvider::TintBitmap(const SkBitmap& bitmap, |
| - int hsl_id) const { |
| - return SkBitmapOperations::CreateHSLShiftedBitmap(bitmap, GetTint(hsl_id)); |
| -} |
| - |
| -void BrowserThemeProvider::SetImageData(DictionaryValue* images_value, |
| - FilePath images_path) { |
| - images_.clear(); |
| - |
| - if (!images_value) |
| - return; |
| - |
| - for (DictionaryValue::key_iterator iter(images_value->begin_keys()); |
| - iter != images_value->end_keys(); ++iter) { |
| - std::string val; |
| - if (images_value->GetStringWithoutPathExpansion(*iter, &val)) { |
| - int id = ThemeResourcesUtil::GetId(WideToUTF8(*iter)); |
| - if (id != -1) { |
| - if (!images_path.empty()) { |
| - images_[id] = |
| - WideToUTF8(images_path.AppendASCII(val).ToWStringHack()); |
| - resource_names_[id] = WideToASCII(*iter); |
| - } else { |
| - images_[id] = val; |
| - } |
| - } |
| - } |
| - } |
| -} |
| - |
| -void BrowserThemeProvider::SetColorData(DictionaryValue* colors_value) { |
| - colors_.clear(); |
| +color_utils::HSL BrowserThemeProvider::GetTint(int id) const { |
| + DCHECK(CalledOnValidThread()); |
| - if (!colors_value) |
| - return; |
| + color_utils::HSL hsl; |
| + if (theme_pack_.get() && theme_pack_->GetTint(id, &hsl)) |
| + return hsl; |
| - for (DictionaryValue::key_iterator iter(colors_value->begin_keys()); |
| - iter != colors_value->end_keys(); ++iter) { |
| - ListValue* color_list; |
| - if (colors_value->GetListWithoutPathExpansion(*iter, &color_list) && |
| - ((color_list->GetSize() == 3) || (color_list->GetSize() == 4))) { |
| - int r, g, b; |
| - color_list->GetInteger(0, &r); |
| - color_list->GetInteger(1, &g); |
| - color_list->GetInteger(2, &b); |
| - if (color_list->GetSize() == 4) { |
| - double alpha; |
| - int alpha_int; |
| - if (color_list->GetReal(3, &alpha)) { |
| - colors_[WideToUTF8(*iter)] = |
| - SkColorSetARGB(static_cast<int>(alpha * 255), r, g, b); |
| - } else if (color_list->GetInteger(3, &alpha_int) && |
| - (alpha_int == 0 || alpha_int == 1)) { |
| - colors_[WideToUTF8(*iter)] = |
| - SkColorSetARGB(alpha_int ? 255 : 0, r, g, b); |
| - } |
| - } else { |
| - colors_[WideToUTF8(*iter)] = SkColorSetRGB(r, g, b); |
| - } |
| - } |
| - } |
| + return GetDefaultTint(id); |
| } |
| -void BrowserThemeProvider::SetTintData(DictionaryValue* tints_value) { |
| - tints_.clear(); |
| - |
| - if (!tints_value) |
| - return; |
| +void BrowserThemeProvider::ClearAllThemeData() { |
| + // Clear our image cache. |
| + FreePlatformCaches(); |
| + theme_pack_ = NULL; |
| - for (DictionaryValue::key_iterator iter(tints_value->begin_keys()); |
| - iter != tints_value->end_keys(); ++iter) { |
| - ListValue* tint_list; |
| - if (tints_value->GetListWithoutPathExpansion(*iter, &tint_list) && |
| - (tint_list->GetSize() == 3)) { |
| - color_utils::HSL hsl = { -1, -1, -1 }; |
| - int value = 0; |
| - if (!tint_list->GetReal(0, &hsl.h) && tint_list->GetInteger(0, &value)) |
| - hsl.h = value; |
| - if (!tint_list->GetReal(1, &hsl.s) && tint_list->GetInteger(1, &value)) |
| - hsl.s = value; |
| - if (!tint_list->GetReal(2, &hsl.l) && tint_list->GetInteger(2, &value)) |
| - hsl.l = value; |
| - |
| - tints_[WideToUTF8(*iter)] = hsl; |
| - } |
| - } |
| + profile_->GetPrefs()->ClearPref(prefs::kCurrentThemePackFilename); |
| + SaveThemeID(kDefaultThemeID); |
| } |
| -void BrowserThemeProvider::SetDisplayPropertyData( |
| - DictionaryValue* display_properties_value) { |
| - display_properties_.clear(); |
| +void BrowserThemeProvider::LoadThemePrefs() { |
| + PrefService* prefs = profile_->GetPrefs(); |
| - if (!display_properties_value) |
| - return; |
| + std::string current_id = GetThemeID(); |
| + if (current_id != kDefaultThemeID) { |
| + bool loaded_pack = false; |
| - for (DictionaryValue::key_iterator iter( |
| - display_properties_value->begin_keys()); |
| - iter != display_properties_value->end_keys(); ++iter) { |
| - // New tab page alignment and background tiling. |
| - if (base::strcasecmp(WideToUTF8(*iter).c_str(), |
| - kDisplayPropertyNTPAlignment) == 0) { |
| - std::string val; |
| - if (display_properties_value->GetStringWithoutPathExpansion(*iter, |
| - &val)) { |
| - display_properties_[kDisplayPropertyNTPAlignment] = |
| - StringToAlignment(val); |
| - } |
| - } else if (base::strcasecmp(WideToUTF8(*iter).c_str(), |
| - kDisplayPropertyNTPTiling) == 0) { |
| - std::string val; |
| - if (display_properties_value->GetStringWithoutPathExpansion(*iter, &val)) |
| - display_properties_[kDisplayPropertyNTPTiling] = StringToTiling(val); |
| + // If we don't have a file pack, we're updating from an old version. |
| + FilePath path = prefs->GetFilePath(prefs::kCurrentThemePackFilename); |
| + if (path != FilePath()) { |
| + theme_pack_ = BrowserThemePack::BuildFromDataPack(path, current_id); |
| + loaded_pack = theme_pack_.get() != NULL; |
| } |
| - if (base::strcasecmp(WideToUTF8(*iter).c_str(), |
| - kDisplayPropertyNTPInverseLogo) == 0) { |
| - int val = 0; |
| - if (display_properties_value->GetIntegerWithoutPathExpansion(*iter, &val)) |
| - display_properties_[kDisplayPropertyNTPInverseLogo] = val; |
| - } |
| - } |
| -} |
| -SkBitmap* BrowserThemeProvider::GenerateTabBackgroundBitmap(int id) const { |
| - if (id == IDR_THEME_TAB_BACKGROUND || |
| - id == IDR_THEME_TAB_BACKGROUND_INCOGNITO) { |
| - // The requested image is a background tab. Get a frame to create the |
| - // tab against. As themes don't use the glass frame, we don't have to |
| - // worry about compositing them together, as our default theme provides |
| - // the necessary bitmaps. |
| - if (!process_images_) { |
| - scoped_ptr<SkBitmap> frame; |
| - frame.reset(LoadThemeBitmap(id)); |
| - if (frame.get()) |
| - themed_image_cache_[id] = new SkBitmap(*frame.get()); |
| + if (loaded_pack) { |
| + UserMetrics::RecordAction("Themes.Loaded", profile_); |
| } else { |
| - SkBitmap* bg_tab = GenerateTabBackgroundBitmapImpl(id); |
| - |
| - if (bg_tab) { |
| - std::string resource_name((id == IDR_THEME_TAB_BACKGROUND) ? |
| - "theme_tab_background" : "theme_tab_background_incognito"); |
| - themed_image_cache_[id] = bg_tab; |
| - SaveThemeBitmap(resource_name, id); |
| - return bg_tab; |
| - } |
| - } |
| - } |
| - return NULL; |
| -} |
| - |
| -void BrowserThemeProvider::SaveImageData(DictionaryValue* images_value) const { |
| - // Save our images data. |
| - DictionaryValue* pref_images = |
| - profile_->GetPrefs()->GetMutableDictionary(prefs::kCurrentThemeImages); |
| - pref_images->Clear(); |
| - |
| - if (!images_value) |
| - return; |
| - |
| - for (DictionaryValue::key_iterator iter(images_value->begin_keys()); |
| - iter != images_value->end_keys(); ++iter) { |
| - std::string val; |
| - if (images_value->GetStringWithoutPathExpansion(*iter, &val)) { |
| - int id = ThemeResourcesUtil::GetId(WideToUTF8(*iter)); |
| - if (id != -1) { |
| - pref_images->SetWithoutPathExpansion(*iter, |
| - Value::CreateStringValue(images_.find(id)->second)); |
| + // TODO(erg): We need to pop up a dialog informing the user that their |
| + // theme is being migrated. |
| + ExtensionsService* service = profile_->GetExtensionsService(); |
| + if (service) { |
| + Extension* extension = service->GetExtensionById(current_id, false); |
| + if (extension) { |
| + DLOG(ERROR) << "Migrating theme"; |
| + BuildFromExtension(extension); |
| + UserMetrics::RecordAction("Themes.Migrated", profile_); |
| + } else { |
| + DLOG(ERROR) << "Theme is mysteriously gone."; |
| + ClearAllThemeData(); |
| + UserMetrics::RecordAction("Themes.Gone", profile_); |
| + } |
| } |
| } |
| } |
| } |
| -void BrowserThemeProvider::SaveColorData() const { |
| - // Save our color data. |
| - DictionaryValue* pref_colors = |
| - profile_->GetPrefs()->GetMutableDictionary(prefs::kCurrentThemeColors); |
| - pref_colors->Clear(); |
| - |
| - if (colors_.empty()) |
| - return; |
| - |
| - for (ColorMap::const_iterator iter(colors_.begin()); iter != colors_.end(); |
| - ++iter) { |
| - SkColor rgba = iter->second; |
| - ListValue* rgb_list = new ListValue(); |
| - rgb_list->Set(0, Value::CreateIntegerValue(SkColorGetR(rgba))); |
| - rgb_list->Set(1, Value::CreateIntegerValue(SkColorGetG(rgba))); |
| - rgb_list->Set(2, Value::CreateIntegerValue(SkColorGetB(rgba))); |
| - if (SkColorGetA(rgba) != 255) |
| - rgb_list->Set(3, Value::CreateRealValue(SkColorGetA(rgba) / 255.0)); |
| - pref_colors->Set(UTF8ToWide(iter->first), rgb_list); |
| - } |
| -} |
| - |
| -void BrowserThemeProvider::SaveTintData() const { |
| - // Save our tint data. |
| - DictionaryValue* pref_tints = |
| - profile_->GetPrefs()->GetMutableDictionary(prefs::kCurrentThemeTints); |
| - pref_tints->Clear(); |
| - |
| - if (tints_.empty()) |
| - return; |
| - |
| - for (TintMap::const_iterator iter(tints_.begin()); iter != tints_.end(); |
| - ++iter) { |
| - color_utils::HSL hsl = iter->second; |
| - ListValue* hsl_list = new ListValue(); |
| - hsl_list->Set(0, Value::CreateRealValue(hsl.h)); |
| - hsl_list->Set(1, Value::CreateRealValue(hsl.s)); |
| - hsl_list->Set(2, Value::CreateRealValue(hsl.l)); |
| - pref_tints->Set(UTF8ToWide(iter->first), hsl_list); |
| - } |
| +void BrowserThemeProvider::NotifyThemeChanged() { |
| + // Redraw! |
| + NotificationService* service = NotificationService::current(); |
| + service->Notify(NotificationType::BROWSER_THEME_CHANGED, |
| + Source<BrowserThemeProvider>(this), |
| + NotificationService::NoDetails()); |
| } |
| -void BrowserThemeProvider::SaveDisplayPropertyData() const { |
| - // Save our display property data. |
| - DictionaryValue* pref_display_properties = |
| - profile_->GetPrefs()-> |
| - GetMutableDictionary(prefs::kCurrentThemeDisplayProperties); |
| - pref_display_properties->Clear(); |
| - |
| - if (display_properties_.empty()) |
| - return; |
| - |
| - for (DisplayPropertyMap::const_iterator iter(display_properties_.begin()); |
| - iter != display_properties_.end(); ++iter) { |
| - if (base::strcasecmp(iter->first.c_str(), |
| - kDisplayPropertyNTPAlignment) == 0) { |
| - pref_display_properties->SetString(UTF8ToWide(iter->first), |
| - AlignmentToString(iter->second)); |
| - } else if (base::strcasecmp(iter->first.c_str(), |
| - kDisplayPropertyNTPTiling) == 0) { |
| - pref_display_properties->SetString(UTF8ToWide(iter->first), |
| - TilingToString(iter->second)); |
| - } |
| - if (base::strcasecmp(iter->first.c_str(), |
| - kDisplayPropertyNTPInverseLogo) == 0) { |
| - pref_display_properties->SetInteger(UTF8ToWide(iter->first), |
| - iter->second); |
| - } |
| - } |
| +#if defined(OS_WIN) |
| +void BrowserThemeProvider::FreePlatformCaches() { |
| + // Views (Skia) has no platform image cache to clear. |
| } |
| +#endif |
| -void BrowserThemeProvider::SaveCachedImageData() const { |
| - DictionaryValue* pref_images = |
| - profile_->GetPrefs()->GetMutableDictionary(prefs::kCurrentThemeImages); |
| - |
| - for (ImagesDiskCache::const_iterator it(images_disk_cache_.begin()); |
| - it != images_disk_cache_.end(); ++it) { |
| - std::wstring disk_path = it->first.ToWStringHack(); |
| - std::string pref_name = resource_names_.find(it->second)->second; |
| - pref_images->SetString(UTF8ToWide(pref_name), WideToUTF8(disk_path)); |
| - } |
| - profile_->GetPrefs()->ScheduleSavePersistentPrefs(); |
| +void BrowserThemeProvider::SavePackName(const FilePath& pack_path) { |
| + profile_->GetPrefs()->SetFilePath( |
| + prefs::kCurrentThemePackFilename, pack_path); |
| } |
| void BrowserThemeProvider::SaveThemeID(const std::string& id) { |
| profile_->GetPrefs()->SetString(prefs::kCurrentThemeID, UTF8ToWide(id)); |
| } |
| -void BrowserThemeProvider::ClearCaches() { |
| - FreePlatformCaches(); |
| - STLDeleteValues(&image_cache_); |
| - |
| - // Scope for AutoLock on themed_image_cache. |
| - { |
| - AutoLock lock(themed_image_cache_lock_); |
| - STLDeleteValues(&themed_image_cache_); |
| +void BrowserThemeProvider::BuildFromExtension(Extension* extension) { |
| + scoped_refptr<BrowserThemePack> pack = |
| + BrowserThemePack::BuildFromExtension(extension); |
| + if (!pack.get()) { |
| + NOTREACHED() << "Could not load theme."; |
| + return; |
| } |
| - images_disk_cache_.clear(); |
| -} |
| - |
| -void BrowserThemeProvider::WriteImagesToDisk() const { |
| - g_browser_process->file_thread()->message_loop()->PostTask(FROM_HERE, |
| - new WriteImagesToDiskTask(images_disk_cache_, themed_image_cache_)); |
| - SaveCachedImageData(); |
| -} |
| + // Write the packed file to disk. |
| + FilePath pack_path = extension->path().Append(chrome::kThemePackFilename); |
| + ChromeThread::PostTask(ChromeThread::IO, FROM_HERE, |
| + new WritePackToDiskTask(pack, pack_path)); |
| -bool BrowserThemeProvider::ShouldTintFrames() const { |
| - return (HasCustomImage(IDR_THEME_FRAME) || |
| - tints_.count(GetTintKey(TINT_BACKGROUND_TAB)) || |
| - tints_.count(GetTintKey(TINT_FRAME)) || |
| - tints_.count(GetTintKey(TINT_FRAME_INACTIVE)) || |
| - tints_.count(GetTintKey(TINT_FRAME_INCOGNITO)) || |
| - tints_.count(GetTintKey(TINT_FRAME_INCOGNITO_INACTIVE))); |
| + SavePackName(pack_path); |
| + theme_pack_ = pack; |
| } |