diff options
Diffstat (limited to 'chrome/browser/browser_theme_provider.cc')
-rw-r--r-- | chrome/browser/browser_theme_provider.cc | 1118 |
1 files changed, 156 insertions, 962 deletions
diff --git a/chrome/browser/browser_theme_provider.cc b/chrome/browser/browser_theme_provider.cc index aceedf1..daf7b68 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(); RemoveUnusedThemes(); } @@ -309,121 +174,38 @@ 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); - } - - 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); - } + SkColor color; + if (theme_pack_.get() && theme_pack_->GetColor(id, &color)) + return color; - // 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"; - } - return false; + if (theme_pack_.get()) + return theme_pack_->GetDisplayProperty(id, result); + + return GetDefaultDisplayProperty(id, result); } bool BrowserThemeProvider::ShouldUseNativeFrame() const { @@ -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,114 @@ 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; - } - } - } +// static +bool BrowserThemeProvider::GetDefaultDisplayProperty(int id, int* result) { + switch (id) { + case NTP_BACKGROUND_ALIGNMENT: + *result = kDefaultDisplayPropertyNTPAlignment; + return true; + case NTP_BACKGROUND_TILING: + *result = kDefaultDisplayPropertyNTPTiling; + return true; + case NTP_LOGO_ALTERNATE: + *result = kDefaultDisplayPropertyNTPInverseLogo; + return true; } + + return false; } -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 (base::strcasecmp(WideToUTF8(*iter).c_str(), - kDisplayPropertyNTPInverseLogo) == 0) { - int val = 0; - if (display_properties_value->GetIntegerWithoutPathExpansion(*iter, &val)) - display_properties_[kDisplayPropertyNTPInverseLogo] = 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; } - } -} -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; } |