| 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..daf7b680a36c3d75e6999fa02f2f56baa2e5e394 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;
|
| }
|
|
|