From b071b6c6801bc5a0d2cdb174a200a85f201ce7c0 Mon Sep 17 00:00:00 2001 From: "evan@chromium.org" Date: Wed, 25 Aug 2010 20:28:03 +0000 Subject: Move theme files in chrome/browser/ into a themes/ subdir. Rename (and resort) every #include. BUG=50548 TEST=compiles Review URL: http://codereview.chromium.org/3173043 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@57375 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome/browser/browser_theme_pack.cc | 1043 -------------------- chrome/browser/browser_theme_pack.h | 226 ----- chrome/browser/browser_theme_pack_unittest.cc | 428 -------- chrome/browser/browser_theme_provider.cc | 609 ------------ chrome/browser/browser_theme_provider.h | 275 ------ chrome/browser/browser_theme_provider_gtk.cc | 73 -- chrome/browser/browser_theme_provider_mac.mm | 317 ------ chrome/browser/browser_theme_provider_unittest.cc | 51 - .../chromeos/frame/normal_browser_frame_view.cc | 2 +- chrome/browser/cocoa/background_gradient_view.mm | 2 +- chrome/browser/cocoa/bookmark_bar_controller.mm | 2 +- .../cocoa/bookmark_bar_folder_controller.mm | 5 +- chrome/browser/cocoa/bookmark_bar_toolbar_view.mm | 2 +- .../cocoa/bookmark_bar_toolbar_view_unittest.mm | 2 +- chrome/browser/cocoa/bookmark_bar_view.mm | 2 +- chrome/browser/cocoa/browser_frame_view.mm | 2 +- chrome/browser/cocoa/browser_window_controller.mm | 18 +- .../cocoa/browser_window_controller_private.mm | 2 +- chrome/browser/cocoa/bubble_view.mm | 2 +- chrome/browser/cocoa/chrome_browser_window.mm | 2 +- chrome/browser/cocoa/download_item_cell.mm | 2 +- chrome/browser/cocoa/download_item_controller.mm | 2 +- chrome/browser/cocoa/download_shelf_controller.mm | 4 +- chrome/browser/cocoa/download_shelf_view.mm | 2 +- chrome/browser/cocoa/fullscreen_window.mm | 2 +- chrome/browser/cocoa/gradient_button_cell.mm | 2 +- chrome/browser/cocoa/infobar_gradient_view.mm | 2 +- chrome/browser/cocoa/styled_text_field_cell.mm | 2 +- chrome/browser/cocoa/tab_controller.mm | 2 +- chrome/browser/cocoa/tab_strip_view.mm | 4 +- chrome/browser/cocoa/tab_view.mm | 2 +- chrome/browser/cocoa/toolbar_controller.mm | 2 +- chrome/browser/debugger/devtools_window.cc | 2 +- chrome/browser/dom_ui/dom_ui.cc | 2 +- chrome/browser/dom_ui/dom_ui_theme_source.cc | 2 +- .../browser/dom_ui/dom_ui_theme_source_unittest.cc | 2 +- chrome/browser/dom_ui/ntp_resource_cache.cc | 2 +- chrome/browser/extensions/extension_host.cc | 6 +- .../extensions/theme_installed_infobar_delegate.cc | 2 +- chrome/browser/gtk/browser_toolbar_gtk.cc | 4 +- chrome/browser/gtk/browser_window_gtk.cc | 2 +- chrome/browser/gtk/gtk_theme_provider.h | 2 +- .../browser/gtk/notifications/balloon_view_gtk.cc | 2 +- chrome/browser/gtk/tabs/dragged_tab_gtk.cc | 2 +- chrome/browser/gtk/tabs/tab_strip_gtk.cc | 2 +- chrome/browser/ntp_background_util.cc | 2 +- chrome/browser/profile.cc | 2 +- chrome/browser/profile_impl.cc | 12 +- chrome/browser/sync/glue/theme_change_processor.cc | 2 +- chrome/browser/sync/glue/theme_model_associator.cc | 2 +- chrome/browser/themes/browser_theme_pack.cc | 1043 ++++++++++++++++++++ chrome/browser/themes/browser_theme_pack.h | 226 +++++ .../browser/themes/browser_theme_pack_unittest.cc | 428 ++++++++ chrome/browser/themes/browser_theme_provider.cc | 609 ++++++++++++ chrome/browser/themes/browser_theme_provider.h | 275 ++++++ .../browser/themes/browser_theme_provider_gtk.cc | 73 ++ .../browser/themes/browser_theme_provider_mac.mm | 317 ++++++ .../themes/browser_theme_provider_unittest.cc | 51 + .../views/bookmark_bar_instructions_view.cc | 2 +- chrome/browser/views/bookmark_bar_view.cc | 2 +- chrome/browser/views/browser_actions_container.cc | 8 +- chrome/browser/views/detachable_toolbar_view.cc | 2 +- chrome/browser/views/download_item_view.cc | 2 +- chrome/browser/views/download_shelf_view.cc | 2 +- chrome/browser/views/find_bar_view.cc | 4 +- chrome/browser/views/frame/browser_frame_gtk.cc | 2 +- chrome/browser/views/frame/browser_frame_win.cc | 2 +- chrome/browser/views/frame/browser_view.cc | 2 +- .../views/frame/glass_browser_frame_view.cc | 2 +- .../views/frame/opaque_browser_frame_view.cc | 2 +- chrome/browser/views/notifications/balloon_view.cc | 2 +- chrome/browser/views/status_bubble_views.cc | 2 +- chrome/browser/views/tabs/tab.cc | 2 +- chrome/browser/views/tabs/tab_strip.cc | 2 +- chrome/browser/views/theme_background.cc | 2 +- chrome/browser/views/toolbar_view.cc | 4 +- 76 files changed, 3107 insertions(+), 3106 deletions(-) delete mode 100644 chrome/browser/browser_theme_pack.cc delete mode 100644 chrome/browser/browser_theme_pack.h delete mode 100644 chrome/browser/browser_theme_pack_unittest.cc delete mode 100644 chrome/browser/browser_theme_provider.cc delete mode 100644 chrome/browser/browser_theme_provider.h delete mode 100644 chrome/browser/browser_theme_provider_gtk.cc delete mode 100644 chrome/browser/browser_theme_provider_mac.mm delete mode 100644 chrome/browser/browser_theme_provider_unittest.cc create mode 100644 chrome/browser/themes/browser_theme_pack.cc create mode 100644 chrome/browser/themes/browser_theme_pack.h create mode 100644 chrome/browser/themes/browser_theme_pack_unittest.cc create mode 100644 chrome/browser/themes/browser_theme_provider.cc create mode 100644 chrome/browser/themes/browser_theme_provider.h create mode 100644 chrome/browser/themes/browser_theme_provider_gtk.cc create mode 100644 chrome/browser/themes/browser_theme_provider_mac.mm create mode 100644 chrome/browser/themes/browser_theme_provider_unittest.cc (limited to 'chrome/browser') diff --git a/chrome/browser/browser_theme_pack.cc b/chrome/browser/browser_theme_pack.cc deleted file mode 100644 index 082f1a8..0000000 --- a/chrome/browser/browser_theme_pack.cc +++ /dev/null @@ -1,1043 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/browser_theme_pack.h" - -#include "app/resource_bundle.h" -#include "base/data_pack.h" -#include "base/stl_util-inl.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/browser_theme_provider.h" -#include "chrome/browser/chrome_thread.h" -#include "gfx/codec/png_codec.h" -#include "gfx/skbitmap_operations.h" -#include "grit/app_resources.h" -#include "grit/theme_resources.h" -#include "net/base/file_stream.h" -#include "net/base/net_errors.h" -#include "third_party/skia/include/core/SkCanvas.h" - -namespace { - -// Version number of the current theme pack. We just throw out and rebuild -// theme packs that aren't int-equal to this. -const int kThemePackVersion = 15; - -// IDs that are in the DataPack won't clash with the positive integer -// int32_t. kHeaderID should always have the maximum value because we want the -// "header" to be written last. That way we can detect whether the pack was -// successfully written and ignore and regenerate if it was only partially -// written (i.e. chrome crashed on a different thread while writing the pack). -const int kHeaderID = UINT_MAX - 1; -const int kTintsID = UINT_MAX - 2; -const int kColorsID = UINT_MAX - 3; -const int kDisplayPropertiesID = UINT_MAX - 4; -const int kSourceImagesID = UINT_MAX - 5; - -// Static size of the tint/color/display property arrays that are mmapped. -const int kTintArraySize = 6; -const int kColorArraySize = 19; -const int kDisplayPropertySize = 3; - -// The sum of kFrameBorderThickness and kNonClientRestoredExtraThickness from -// OpaqueBrowserFrameView. -const int kRestoredTabVerticalOffset = 15; - -// Persistent constants for the main images that we need. These have the same -// names as their IDR_* counterparts but these values will always stay the -// same. -const int PRS_THEME_FRAME = 1; -const int PRS_THEME_FRAME_INACTIVE = 2; -const int PRS_THEME_FRAME_INCOGNITO = 3; -const int PRS_THEME_FRAME_INCOGNITO_INACTIVE = 4; -const int PRS_THEME_TOOLBAR = 5; -const int PRS_THEME_TAB_BACKGROUND = 6; -const int PRS_THEME_TAB_BACKGROUND_INCOGNITO = 7; -const int PRS_THEME_TAB_BACKGROUND_V = 8; -const int PRS_THEME_NTP_BACKGROUND = 9; -const int PRS_THEME_FRAME_OVERLAY = 10; -const int PRS_THEME_FRAME_OVERLAY_INACTIVE = 11; -const int PRS_THEME_BUTTON_BACKGROUND = 12; -const int PRS_THEME_NTP_ATTRIBUTION = 13; -const int PRS_THEME_WINDOW_CONTROL_BACKGROUND = 14; - -struct PersistingImagesTable { - // A non-changing integer ID meant to be saved in theme packs. This ID must - // not change between versions of chrome. - int persistent_id; - - // The IDR that depends on the whims of GRIT and therefore changes whenever - // someone adds a new resource. - int idr_id; - - // String to check for when parsing theme manifests or NULL if this isn't - // supposed to be changeable by the user. - const char* key; -}; - -// IDR_* resource names change whenever new resources are added; use persistent -// IDs when storing to a cached pack. -PersistingImagesTable kPersistingImages[] = { - { PRS_THEME_FRAME, IDR_THEME_FRAME, - "theme_frame" }, - { PRS_THEME_FRAME_INACTIVE, IDR_THEME_FRAME_INACTIVE, - "theme_frame_inactive" }, - { PRS_THEME_FRAME_INCOGNITO, IDR_THEME_FRAME_INCOGNITO, - "theme_frame_incognito" }, - { PRS_THEME_FRAME_INCOGNITO_INACTIVE, IDR_THEME_FRAME_INCOGNITO_INACTIVE, - "theme_frame_incognito_inactive" }, - { PRS_THEME_TOOLBAR, IDR_THEME_TOOLBAR, - "theme_toolbar" }, - { PRS_THEME_TAB_BACKGROUND, IDR_THEME_TAB_BACKGROUND, - "theme_tab_background" }, - { PRS_THEME_TAB_BACKGROUND_INCOGNITO, IDR_THEME_TAB_BACKGROUND_INCOGNITO, - "theme_tab_background_incognito" }, - { PRS_THEME_TAB_BACKGROUND_V, IDR_THEME_TAB_BACKGROUND_V, - "theme_tab_background_v"}, - { PRS_THEME_NTP_BACKGROUND, IDR_THEME_NTP_BACKGROUND, - "theme_ntp_background" }, - { PRS_THEME_FRAME_OVERLAY, IDR_THEME_FRAME_OVERLAY, - "theme_frame_overlay" }, - { PRS_THEME_FRAME_OVERLAY_INACTIVE, IDR_THEME_FRAME_OVERLAY_INACTIVE, - "theme_frame_overlay_inactive" }, - { PRS_THEME_BUTTON_BACKGROUND, IDR_THEME_BUTTON_BACKGROUND, - "theme_button_background" }, - { PRS_THEME_NTP_ATTRIBUTION, IDR_THEME_NTP_ATTRIBUTION, - "theme_ntp_attribution" }, - { PRS_THEME_WINDOW_CONTROL_BACKGROUND, IDR_THEME_WINDOW_CONTROL_BACKGROUND, - "theme_window_control_background"}, - - // The rest of these entries have no key because they can't be overridden - // from the json manifest. - { 15, IDR_BACK, NULL }, - { 16, IDR_BACK_D, NULL }, - { 17, IDR_BACK_H, NULL }, - { 18, IDR_BACK_P, NULL }, - { 19, IDR_FORWARD, NULL }, - { 20, IDR_FORWARD_D, NULL }, - { 21, IDR_FORWARD_H, NULL }, - { 22, IDR_FORWARD_P, NULL }, - { 23, IDR_HOME, NULL }, - { 24, IDR_HOME_H, NULL }, - { 25, IDR_HOME_P, NULL }, - { 26, IDR_RELOAD, NULL }, - { 27, IDR_RELOAD_H, NULL }, - { 28, IDR_RELOAD_P, NULL }, - { 29, IDR_STOP, NULL }, - { 30, IDR_STOP_D, NULL }, - { 31, IDR_STOP_H, NULL }, - { 32, IDR_STOP_P, NULL }, - { 33, IDR_LOCATIONBG_C, NULL }, - { 34, IDR_LOCATIONBG_L, NULL }, - { 35, IDR_LOCATIONBG_R, NULL }, - { 36, IDR_BROWSER_ACTIONS_OVERFLOW, NULL }, - { 37, IDR_BROWSER_ACTIONS_OVERFLOW_H, NULL }, - { 38, IDR_BROWSER_ACTIONS_OVERFLOW_P, NULL }, - { 39, IDR_TOOLS, NULL }, - { 40, IDR_TOOLS_H, NULL }, - { 41, IDR_TOOLS_P, NULL }, - { 42, IDR_MENU_DROPARROW, NULL }, - { 43, IDR_THROBBER, NULL }, - { 44, IDR_THROBBER_WAITING, NULL }, - { 45, IDR_THROBBER_LIGHT, NULL }, -}; - -int GetPersistentIDByName(const std::string& key) { - for (size_t i = 0; i < arraysize(kPersistingImages); ++i) { - if (kPersistingImages[i].key != NULL && - base::strcasecmp(key.c_str(), kPersistingImages[i].key) == 0) { - return kPersistingImages[i].persistent_id; - } - } - - return -1; -} - -int GetPersistentIDByIDR(int idr) { - for (size_t i = 0; i < arraysize(kPersistingImages); ++i) { - if (kPersistingImages[i].idr_id == idr) { - return kPersistingImages[i].persistent_id; - } - } - - return -1; -} - -struct StringToIntTable { - const char* key; - int id; -}; - -// Strings used by themes to identify tints in the JSON. -StringToIntTable kTintTable[] = { - { "buttons", BrowserThemeProvider::TINT_BUTTONS }, - { "frame", BrowserThemeProvider::TINT_FRAME }, - { "frame_inactive", BrowserThemeProvider::TINT_FRAME_INACTIVE }, - { "frame_incognito", BrowserThemeProvider::TINT_FRAME_INCOGNITO }, - { "frame_incognito_inactive", - BrowserThemeProvider::TINT_FRAME_INCOGNITO_INACTIVE }, - { "background_tab", BrowserThemeProvider::TINT_BACKGROUND_TAB }, - { NULL, 0 } -}; - -// Strings used by themes to identify colors in the JSON. -StringToIntTable kColorTable[] = { - { "frame", BrowserThemeProvider::COLOR_FRAME }, - { "frame_inactive", BrowserThemeProvider::COLOR_FRAME_INACTIVE }, - { "frame_incognito", BrowserThemeProvider::COLOR_FRAME_INCOGNITO }, - { "frame_incognito_inactive", - BrowserThemeProvider::COLOR_FRAME_INCOGNITO_INACTIVE }, - { "toolbar", BrowserThemeProvider::COLOR_TOOLBAR }, - { "tab_text", BrowserThemeProvider::COLOR_TAB_TEXT }, - { "tab_background_text", BrowserThemeProvider::COLOR_BACKGROUND_TAB_TEXT }, - { "bookmark_text", BrowserThemeProvider::COLOR_BOOKMARK_TEXT }, - { "ntp_background", BrowserThemeProvider::COLOR_NTP_BACKGROUND }, - { "ntp_text", BrowserThemeProvider::COLOR_NTP_TEXT }, - { "ntp_link", BrowserThemeProvider::COLOR_NTP_LINK }, - { "ntp_link_underline", BrowserThemeProvider::COLOR_NTP_LINK_UNDERLINE }, - { "ntp_header", BrowserThemeProvider::COLOR_NTP_HEADER }, - { "ntp_section", BrowserThemeProvider::COLOR_NTP_SECTION }, - { "ntp_section_text", BrowserThemeProvider::COLOR_NTP_SECTION_TEXT }, - { "ntp_section_link", BrowserThemeProvider::COLOR_NTP_SECTION_LINK }, - { "ntp_section_link_underline", - BrowserThemeProvider::COLOR_NTP_SECTION_LINK_UNDERLINE }, - { "control_background", BrowserThemeProvider::COLOR_CONTROL_BACKGROUND }, - { "button_background", BrowserThemeProvider::COLOR_BUTTON_BACKGROUND }, - { NULL, 0 } -}; - -// Strings used by themes to identify display properties keys in JSON. -StringToIntTable kDisplayProperties[] = { - { "ntp_background_alignment", - BrowserThemeProvider::NTP_BACKGROUND_ALIGNMENT }, - { "ntp_background_repeat", BrowserThemeProvider::NTP_BACKGROUND_TILING }, - { "ntp_logo_alternate", BrowserThemeProvider::NTP_LOGO_ALTERNATE }, - { NULL, 0 } -}; - -// Strings used by the tiling values in JSON. -StringToIntTable kTilingStrings[] = { - { "no-repeat", BrowserThemeProvider::NO_REPEAT }, - { "repeat-x", BrowserThemeProvider::REPEAT_X }, - { "repeat-y", BrowserThemeProvider::REPEAT_Y }, - { "repeat", BrowserThemeProvider::REPEAT }, - { NULL, 0 } -}; - -int GetIntForString(const std::string& key, StringToIntTable* table) { - for (int i = 0; table[i].key != NULL; ++i) { - if (base::strcasecmp(key.c_str(), table[i].key) == 0) { - return table[i].id; - } - } - - return -1; -} - -struct IntToIntTable { - int key; - int value; -}; - -// Mapping used in GenerateFrameImages() to associate frame images with the -// tint ID that should maybe be applied to it. -IntToIntTable kFrameTintMap[] = { - { PRS_THEME_FRAME, BrowserThemeProvider::TINT_FRAME }, - { PRS_THEME_FRAME_INACTIVE, BrowserThemeProvider::TINT_FRAME_INACTIVE }, - { PRS_THEME_FRAME_OVERLAY, BrowserThemeProvider::TINT_FRAME }, - { PRS_THEME_FRAME_OVERLAY_INACTIVE, - BrowserThemeProvider::TINT_FRAME_INACTIVE }, - { PRS_THEME_FRAME_INCOGNITO, BrowserThemeProvider::TINT_FRAME_INCOGNITO }, - { PRS_THEME_FRAME_INCOGNITO_INACTIVE, - BrowserThemeProvider::TINT_FRAME_INCOGNITO_INACTIVE } -}; - -// Mapping used in GenerateTabBackgroundImages() to associate what frame image -// goes with which tab background. -IntToIntTable kTabBackgroundMap[] = { - { PRS_THEME_TAB_BACKGROUND, PRS_THEME_FRAME }, - { PRS_THEME_TAB_BACKGROUND_INCOGNITO, PRS_THEME_FRAME_INCOGNITO } -}; - -// A list of images that don't need tinting or any other modification and can -// be byte-copied directly into the finished DataPack. This should contain the -// persistent IDs for all themeable image IDs that aren't in kFrameTintMap or -// kTabBackgroundMap. -const int kPreloadIDs[] = { - PRS_THEME_TOOLBAR, - PRS_THEME_NTP_BACKGROUND, - PRS_THEME_BUTTON_BACKGROUND, - PRS_THEME_NTP_ATTRIBUTION, - PRS_THEME_WINDOW_CONTROL_BACKGROUND -}; - -// Returns a piece of memory with the contents of the file |path|. -RefCountedMemory* ReadFileData(const FilePath& path) { - 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(avail); - std::vector raw_data; - raw_data.resize(size); - char* data = reinterpret_cast(&(raw_data.front())); - if (file.ReadUntilComplete(data, size) == avail) - return RefCountedBytes::TakeVector(&raw_data); - } - } - } - - return NULL; -} - -// Does error checking for invalid incoming data while trying to read an -// floating point value. -bool ValidRealValue(ListValue* tint_list, int index, double* out) { - if (tint_list->GetReal(index, out)) - return true; - - int value = 0; - if (tint_list->GetInteger(index, &value)) { - *out = value; - return true; - } - - return false; -} - -} // namespace - -BrowserThemePack::~BrowserThemePack() { - if (!data_pack_.get()) { - delete header_; - delete [] tints_; - delete [] colors_; - delete [] display_properties_; - delete [] source_images_; - } - - STLDeleteValues(&prepared_images_); - STLDeleteValues(&loaded_images_); -} - -// static -BrowserThemePack* BrowserThemePack::BuildFromExtension(Extension* extension) { - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); - DCHECK(extension); - DCHECK(extension->is_theme()); - - BrowserThemePack* pack = new BrowserThemePack; - pack->BuildHeader(extension); - pack->BuildTintsFromJSON(extension->GetThemeTints()); - pack->BuildColorsFromJSON(extension->GetThemeColors()); - pack->BuildDisplayPropertiesFromJSON(extension->GetThemeDisplayProperties()); - - // Builds the images. (Image building is dependent on tints). - FilePathMap file_paths; - pack->ParseImageNamesFromJSON(extension->GetThemeImages(), - extension->path(), - &file_paths); - pack->BuildSourceImagesArray(file_paths); - - if (!pack->LoadRawBitmapsTo(file_paths, &pack->prepared_images_)) - return NULL; - - pack->GenerateFrameImages(&pack->prepared_images_); - -#if !defined(OS_MACOSX) - // OSX uses its own special buttons that are PDFs that do odd sorts of vector - // graphics tricks. Other platforms use bitmaps and we must pre-tint them. - pack->GenerateTintedButtons( - pack->GetTintInternal(BrowserThemeProvider::TINT_BUTTONS), - &pack->prepared_images_); -#endif - - pack->GenerateTabBackgroundImages(&pack->prepared_images_); - - // The BrowserThemePack is now in a consistent state. - return pack; -} - -// static -scoped_refptr BrowserThemePack::BuildFromDataPack( - FilePath path, const std::string& expected_id) { - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); - scoped_refptr pack = new BrowserThemePack; - pack->data_pack_.reset(new base::DataPack); - - if (!pack->data_pack_->Load(path)) { - LOG(ERROR) << "Failed to load theme data pack."; - return NULL; - } - - base::StringPiece pointer; - if (!pack->data_pack_->GetStringPiece(kHeaderID, &pointer)) - return NULL; - pack->header_ = reinterpret_cast(const_cast( - pointer.data())); - - if (pack->header_->version != kThemePackVersion) { - DLOG(ERROR) << "BuildFromDataPack failure! Version mismatch!"; - return NULL; - } - // TODO(erg): Check endianess once DataPack works on the other endian. - std::string theme_id(reinterpret_cast(pack->header_->theme_id), - Extension::kIdSize); - std::string truncated_id = expected_id.substr(0, Extension::kIdSize); - if (theme_id != truncated_id) { - DLOG(ERROR) << "Wrong id: " << theme_id << " vs " << expected_id; - return NULL; - } - - if (!pack->data_pack_->GetStringPiece(kTintsID, &pointer)) - return NULL; - pack->tints_ = reinterpret_cast(const_cast( - pointer.data())); - - if (!pack->data_pack_->GetStringPiece(kColorsID, &pointer)) - return NULL; - pack->colors_ = - reinterpret_cast(const_cast(pointer.data())); - - if (!pack->data_pack_->GetStringPiece(kDisplayPropertiesID, &pointer)) - return NULL; - pack->display_properties_ = reinterpret_cast( - const_cast(pointer.data())); - - if (!pack->data_pack_->GetStringPiece(kSourceImagesID, &pointer)) - return NULL; - pack->source_images_ = reinterpret_cast( - const_cast(pointer.data())); - - return pack; -} - -bool BrowserThemePack::WriteToDisk(FilePath path) const { - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); - // Add resources for each of the property arrays. - RawDataForWriting resources; - resources[kHeaderID] = base::StringPiece( - reinterpret_cast(header_), sizeof(BrowserThemePackHeader)); - resources[kTintsID] = base::StringPiece( - reinterpret_cast(tints_), sizeof(TintEntry[kTintArraySize])); - resources[kColorsID] = base::StringPiece( - reinterpret_cast(colors_), - sizeof(ColorPair[kColorArraySize])); - resources[kDisplayPropertiesID] = base::StringPiece( - reinterpret_cast(display_properties_), - sizeof(DisplayPropertyPair[kDisplayPropertySize])); - - int source_count = 1; - int* end = source_images_; - for (; *end != -1 ; end++) - source_count++; - resources[kSourceImagesID] = base::StringPiece( - reinterpret_cast(source_images_), - source_count * sizeof(*source_images_)); - - AddRawImagesTo(image_memory_, &resources); - - RawImages reencoded_images; - RepackImages(prepared_images_, &reencoded_images); - AddRawImagesTo(reencoded_images, &resources); - - return base::DataPack::WritePack(path, resources); -} - -bool BrowserThemePack::GetTint(int id, color_utils::HSL* hsl) const { - if (tints_) { - for (int i = 0; i < kTintArraySize; ++i) { - if (tints_[i].id == id) { - hsl->h = tints_[i].h; - hsl->s = tints_[i].s; - hsl->l = tints_[i].l; - return true; - } - } - } - - return false; -} - -bool BrowserThemePack::GetColor(int id, SkColor* color) const { - if (colors_) { - for (int i = 0; i < kColorArraySize; ++i) { - if (colors_[i].id == id) { - *color = colors_[i].color; - return true; - } - } - } - - return false; -} - -bool BrowserThemePack::GetDisplayProperty(int id, int* result) const { - if (display_properties_) { - for (int i = 0; i < kDisplayPropertySize; ++i) { - if (display_properties_[i].id == id) { - *result = display_properties_[i].property; - return true; - } - } - } - - return false; -} - -SkBitmap* BrowserThemePack::GetBitmapNamed(int idr_id) const { - int prs_id = GetPersistentIDByIDR(idr_id); - if (prs_id == -1) - return NULL; - - // Check our cache of prepared images, first. - ImageCache::const_iterator image_iter = prepared_images_.find(prs_id); - if (image_iter != prepared_images_.end()) - return image_iter->second; - - // Check if we've already loaded this image. - image_iter = loaded_images_.find(prs_id); - if (image_iter != loaded_images_.end()) - return image_iter->second; - - scoped_refptr memory; - if (data_pack_.get()) { - memory = data_pack_->GetStaticMemory(prs_id); - } else { - RawImages::const_iterator it = image_memory_.find(prs_id); - if (it != image_memory_.end()) { - memory = it->second; - } - } - - if (memory.get()) { - // Decode the PNG. - SkBitmap bitmap; - if (!gfx::PNGCodec::Decode(memory->front(), memory->size(), - &bitmap)) { - NOTREACHED() << "Unable to decode theme image resource " << idr_id - << " from saved DataPack."; - return NULL; - } - - SkBitmap* ret = new SkBitmap(bitmap); - loaded_images_[prs_id] = ret; - - return ret; - } - - return NULL; -} - -RefCountedMemory* BrowserThemePack::GetRawData(int idr_id) const { - RefCountedMemory* memory = NULL; - int prs_id = GetPersistentIDByIDR(idr_id); - - if (prs_id != -1) { - if (data_pack_.get()) { - memory = data_pack_->GetStaticMemory(prs_id); - } else { - RawImages::const_iterator it = image_memory_.find(prs_id); - if (it != image_memory_.end()) { - memory = it->second; - } - } - } - - return memory; -} - -bool BrowserThemePack::HasCustomImage(int idr_id) const { - int prs_id = GetPersistentIDByIDR(idr_id); - if (prs_id == -1) - return false; - - int* img = source_images_; - for (; *img != -1; ++img) { - if (*img == prs_id) - return true; - } - - return false; -} - -// private: - -BrowserThemePack::BrowserThemePack() - : header_(NULL), - tints_(NULL), - colors_(NULL), - display_properties_(NULL), - source_images_(NULL) { -} - -void BrowserThemePack::BuildHeader(Extension* extension) { - header_ = new BrowserThemePackHeader; - header_->version = kThemePackVersion; - - // TODO(erg): Need to make this endian safe on other computers. Prerequisite - // is that base::DataPack removes this same check. -#if defined(__BYTE_ORDER) - // Linux check - COMPILE_ASSERT(__BYTE_ORDER == __LITTLE_ENDIAN, - datapack_assumes_little_endian); -#elif defined(__BIG_ENDIAN__) - // Mac check - #error DataPack assumes little endian -#endif - header_->little_endian = 1; - - const std::string& id = extension->id(); - memcpy(header_->theme_id, id.c_str(), Extension::kIdSize); -} - -void BrowserThemePack::BuildTintsFromJSON(DictionaryValue* tints_value) { - tints_ = new TintEntry[kTintArraySize]; - for (int i = 0; i < kTintArraySize; ++i) { - tints_[i].id = -1; - tints_[i].h = -1; - tints_[i].s = -1; - tints_[i].l = -1; - } - - if (!tints_value) - return; - - // Parse the incoming data from |tints_value| into an intermediary structure. - std::map temp_tints; - for (DictionaryValue::key_iterator iter(tints_value->begin_keys()); - iter != tints_value->end_keys(); ++iter) { - ListValue* tint_list; - if (tints_value->GetList(*iter, &tint_list) && - (tint_list->GetSize() == 3)) { - color_utils::HSL hsl = { -1, -1, -1 }; - - if (ValidRealValue(tint_list, 0, &hsl.h) && - ValidRealValue(tint_list, 1, &hsl.s) && - ValidRealValue(tint_list, 2, &hsl.l)) { - int id = GetIntForString(*iter, kTintTable); - if (id != -1) { - temp_tints[id] = hsl; - } - } - } - } - - // Copy data from the intermediary data structure to the array. - int count = 0; - for (std::map::const_iterator it = - temp_tints.begin(); it != temp_tints.end() && count < kTintArraySize; - ++it, ++count) { - tints_[count].id = it->first; - tints_[count].h = it->second.h; - tints_[count].s = it->second.s; - tints_[count].l = it->second.l; - } -} - -void BrowserThemePack::BuildColorsFromJSON(DictionaryValue* colors_value) { - colors_ = new ColorPair[kColorArraySize]; - for (int i = 0; i < kColorArraySize; ++i) { - colors_[i].id = -1; - colors_[i].color = SkColorSetRGB(0, 0, 0); - } - - std::map temp_colors; - if (colors_value) - ReadColorsFromJSON(colors_value, &temp_colors); - GenerateMissingColors(&temp_colors); - - // Copy data from the intermediary data structure to the array. - int count = 0; - for (std::map::const_iterator it = temp_colors.begin(); - it != temp_colors.end() && count < kColorArraySize; ++it, ++count) { - colors_[count].id = it->first; - colors_[count].color = it->second; - } -} - -void BrowserThemePack::ReadColorsFromJSON( - DictionaryValue* colors_value, - std::map* temp_colors) { - // Parse the incoming data from |colors_value| into an intermediary structure. - for (DictionaryValue::key_iterator iter(colors_value->begin_keys()); - iter != colors_value->end_keys(); ++iter) { - ListValue* color_list; - if (colors_value->GetList(*iter, &color_list) && - ((color_list->GetSize() == 3) || (color_list->GetSize() == 4))) { - SkColor color = SK_ColorWHITE; - int r, g, b; - if (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)) { - color = SkColorSetARGB(static_cast(alpha * 255), r, g, b); - } else if (color_list->GetInteger(3, &alpha_int) && - (alpha_int == 0 || alpha_int == 1)) { - color = SkColorSetARGB(alpha_int ? 255 : 0, r, g, b); - } else { - // Invalid entry for part 4. - continue; - } - } else { - color = SkColorSetRGB(r, g, b); - } - - int id = GetIntForString(*iter, kColorTable); - if (id != -1) { - (*temp_colors)[id] = color; - } - } - } - } -} - -void BrowserThemePack::GenerateMissingColors( - std::map* colors) { - // Generate link colors, if missing. (See GetColor()). - if (!colors->count(BrowserThemeProvider::COLOR_NTP_HEADER) && - colors->count(BrowserThemeProvider::COLOR_NTP_SECTION)) { - (*colors)[BrowserThemeProvider::COLOR_NTP_HEADER] = - (*colors)[BrowserThemeProvider::COLOR_NTP_SECTION]; - } - - if (!colors->count(BrowserThemeProvider::COLOR_NTP_SECTION_LINK_UNDERLINE) && - colors->count(BrowserThemeProvider::COLOR_NTP_SECTION_LINK)) { - SkColor color_section_link = - (*colors)[BrowserThemeProvider::COLOR_NTP_SECTION_LINK]; - (*colors)[BrowserThemeProvider::COLOR_NTP_SECTION_LINK_UNDERLINE] = - SkColorSetA(color_section_link, SkColorGetA(color_section_link) / 3); - } - - if (!colors->count(BrowserThemeProvider::COLOR_NTP_LINK_UNDERLINE) && - colors->count(BrowserThemeProvider::COLOR_NTP_LINK)) { - SkColor color_link = (*colors)[BrowserThemeProvider::COLOR_NTP_LINK]; - (*colors)[BrowserThemeProvider::COLOR_NTP_LINK_UNDERLINE] = - SkColorSetA(color_link, SkColorGetA(color_link) / 3); - } - - // Generate frame colors, if missing. (See GenerateFrameColors()). - SkColor frame; - std::map::const_iterator it = - colors->find(BrowserThemeProvider::COLOR_FRAME); - if (it != colors->end()) { - frame = it->second; - } else { - frame = BrowserThemeProvider::GetDefaultColor( - BrowserThemeProvider::COLOR_FRAME); - } - - if (!colors->count(BrowserThemeProvider::COLOR_FRAME)) { - (*colors)[BrowserThemeProvider::COLOR_FRAME] = - HSLShift(frame, GetTintInternal(BrowserThemeProvider::TINT_FRAME)); - } - if (!colors->count(BrowserThemeProvider::COLOR_FRAME_INACTIVE)) { - (*colors)[BrowserThemeProvider::COLOR_FRAME_INACTIVE] = - HSLShift(frame, GetTintInternal( - BrowserThemeProvider::TINT_FRAME_INACTIVE)); - } - if (!colors->count(BrowserThemeProvider::COLOR_FRAME_INCOGNITO)) { - (*colors)[BrowserThemeProvider::COLOR_FRAME_INCOGNITO] = - HSLShift(frame, GetTintInternal( - BrowserThemeProvider::TINT_FRAME_INCOGNITO)); - } - if (!colors->count(BrowserThemeProvider::COLOR_FRAME_INCOGNITO_INACTIVE)) { - (*colors)[BrowserThemeProvider::COLOR_FRAME_INCOGNITO_INACTIVE] = - HSLShift(frame, GetTintInternal( - BrowserThemeProvider::TINT_FRAME_INCOGNITO_INACTIVE)); - } -} - -void BrowserThemePack::BuildDisplayPropertiesFromJSON( - DictionaryValue* display_properties_value) { - display_properties_ = new DisplayPropertyPair[kDisplayPropertySize]; - for (int i = 0; i < kDisplayPropertySize; ++i) { - display_properties_[i].id = -1; - display_properties_[i].property = 0; - } - - if (!display_properties_value) - return; - - std::map temp_properties; - for (DictionaryValue::key_iterator iter( - display_properties_value->begin_keys()); - iter != display_properties_value->end_keys(); ++iter) { - int property_id = GetIntForString(*iter, kDisplayProperties); - switch (property_id) { - case BrowserThemeProvider::NTP_BACKGROUND_ALIGNMENT: { - std::string val; - if (display_properties_value->GetString(*iter, &val)) { - temp_properties[BrowserThemeProvider::NTP_BACKGROUND_ALIGNMENT] = - BrowserThemeProvider::StringToAlignment(val); - } - break; - } - case BrowserThemeProvider::NTP_BACKGROUND_TILING: { - std::string val; - if (display_properties_value->GetString(*iter, &val)) { - temp_properties[BrowserThemeProvider::NTP_BACKGROUND_TILING] = - GetIntForString(val, kTilingStrings); - } - break; - } - case BrowserThemeProvider::NTP_LOGO_ALTERNATE: { - int val = 0; - if (display_properties_value->GetInteger(*iter, &val)) - temp_properties[BrowserThemeProvider::NTP_LOGO_ALTERNATE] = val; - break; - } - } - } - - // Copy data from the intermediary data structure to the array. - int count = 0; - for (std::map::const_iterator it = temp_properties.begin(); - it != temp_properties.end() && count < kDisplayPropertySize; - ++it, ++count) { - display_properties_[count].id = it->first; - display_properties_[count].property = it->second; - } -} - -void BrowserThemePack::ParseImageNamesFromJSON( - DictionaryValue* images_value, - FilePath images_path, - FilePathMap* file_paths) const { - 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->GetString(*iter, &val)) { - int id = GetPersistentIDByName(*iter); - if (id != -1) - (*file_paths)[id] = images_path.AppendASCII(val); - } - } -} - -void BrowserThemePack::BuildSourceImagesArray(const FilePathMap& file_paths) { - std::vector ids; - for (FilePathMap::const_iterator it = file_paths.begin(); - it != file_paths.end(); ++it) { - ids.push_back(it->first); - } - - source_images_ = new int[ids.size() + 1]; - std::copy(ids.begin(), ids.end(), source_images_); - source_images_[ids.size()] = -1; -} - -bool BrowserThemePack::LoadRawBitmapsTo( - const FilePathMap& file_paths, - ImageCache* raw_bitmaps) { - for (FilePathMap::const_iterator it = file_paths.begin(); - it != file_paths.end(); ++it) { - scoped_refptr raw_data(ReadFileData(it->second)); - if (!raw_data.get()) { - LOG(ERROR) << "Could not load theme image"; - return false; - } - - int id = it->first; - - // Some images need to go directly into |image_memory_|. No modification is - // necessary or desirable. - bool is_copyable = false; - for (size_t i = 0; i < arraysize(kPreloadIDs); ++i) { - if (kPreloadIDs[i] == id) { - is_copyable = true; - break; - } - } - - if (is_copyable) { - image_memory_[id] = raw_data; - } else if (raw_data.get() && raw_data->size()) { - // Decode the PNG. - SkBitmap bitmap; - if (gfx::PNGCodec::Decode(raw_data->front(), raw_data->size(), - &bitmap)) { - (*raw_bitmaps)[it->first] = new SkBitmap(bitmap); - } else { - NOTREACHED() << "Unable to decode theme image resource " << it->first; - } - } - } - - return true; -} - -void BrowserThemePack::GenerateFrameImages(ImageCache* bitmaps) const { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - - // Create all the output bitmaps in a separate cache and move them back into - // the input bitmaps because there can be name collisions. - ImageCache temp_output; - - for (size_t i = 0; i < arraysize(kFrameTintMap); ++i) { - int prs_id = kFrameTintMap[i].key; - scoped_ptr 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 prs_base_id; - - if (prs_id == PRS_THEME_FRAME_INCOGNITO_INACTIVE) { - prs_base_id = bitmaps->count(PRS_THEME_FRAME_INCOGNITO) ? - PRS_THEME_FRAME_INCOGNITO : PRS_THEME_FRAME; - } else if (prs_id == PRS_THEME_FRAME_OVERLAY_INACTIVE) { - prs_base_id = PRS_THEME_FRAME_OVERLAY; - } else if (prs_id == PRS_THEME_FRAME_INACTIVE) { - prs_base_id = PRS_THEME_FRAME; - } else if (prs_id == PRS_THEME_FRAME_INCOGNITO && - !bitmaps->count(PRS_THEME_FRAME_INCOGNITO)) { - prs_base_id = PRS_THEME_FRAME; - } else { - prs_base_id = prs_id; - } - - if (bitmaps->count(prs_id)) { - frame.reset(new SkBitmap(*(*bitmaps)[prs_id])); - } else if (prs_base_id != prs_id && bitmaps->count(prs_base_id)) { - frame.reset(new SkBitmap(*(*bitmaps)[prs_base_id])); - } else if (prs_base_id == PRS_THEME_FRAME_OVERLAY && - bitmaps->count(PRS_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()) { - temp_output[prs_id] = new SkBitmap( - SkBitmapOperations::CreateHSLShiftedBitmap( - *frame, GetTintInternal(kFrameTintMap[i].value))); - } - } - - MergeImageCaches(temp_output, bitmaps); -} - -void BrowserThemePack::GenerateTintedButtons( - color_utils::HSL button_tint, - ImageCache* processed_bitmaps) const { - if (button_tint.h != -1 || button_tint.s != -1 || button_tint.l != -1) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - const std::set& idr_ids = - BrowserThemeProvider::GetTintableToolbarButtons(); - for (std::set::const_iterator it = idr_ids.begin(); - it != idr_ids.end(); ++it) { - int prs_id = GetPersistentIDByIDR(*it); - DCHECK(prs_id > 0); - - // Fetch the image by IDR... - scoped_ptr button(new SkBitmap(*rb.GetBitmapNamed(*it))); - - // but save a version with the persistent ID. - (*processed_bitmaps)[prs_id] = new SkBitmap( - SkBitmapOperations::CreateHSLShiftedBitmap(*button, button_tint)); - } - } -} - -void BrowserThemePack::GenerateTabBackgroundImages(ImageCache* bitmaps) const { - ImageCache temp_output; - for (size_t i = 0; i < arraysize(kTabBackgroundMap); ++i) { - int prs_id = kTabBackgroundMap[i].key; - int prs_base_id = kTabBackgroundMap[i].value; - - // We only need to generate the background tab images if we were provided - // with a PRS_THEME_FRAME. - ImageCache::const_iterator it = bitmaps->find(prs_base_id); - if (it != bitmaps->end()) { - SkBitmap bg_tint = SkBitmapOperations::CreateHSLShiftedBitmap( - *(it->second), GetTintInternal( - BrowserThemeProvider::TINT_BACKGROUND_TAB)); - int vertical_offset = bitmaps->count(prs_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. - ImageCache::const_iterator overlay_it = bitmaps->find(prs_id); - if (overlay_it != bitmaps->end()) { - SkBitmap* overlay = overlay_it->second; - SkCanvas canvas(*bg_tab); - for (int x = 0; x < bg_tab->width(); x += overlay->width()) - canvas.drawBitmap(*overlay, static_cast(x), 0, NULL); - } - - temp_output[prs_id] = bg_tab; - } - } - - MergeImageCaches(temp_output, bitmaps); -} - -void BrowserThemePack::RepackImages(const ImageCache& images, - RawImages* reencoded_images) const { - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); - for (ImageCache::const_iterator it = images.begin(); - it != images.end(); ++it) { - std::vector image_data; - if (!gfx::PNGCodec::EncodeBGRASkBitmap(*(it->second), false, &image_data)) { - NOTREACHED() << "Image file for resource " << it->first - << " could not be encoded."; - } else { - (*reencoded_images)[it->first] = RefCountedBytes::TakeVector(&image_data); - } - } -} - -void BrowserThemePack::MergeImageCaches( - const ImageCache& source, ImageCache* destination) const { - - for (ImageCache::const_iterator it = source.begin(); it != source.end(); - ++it) { - ImageCache::const_iterator bitmap_it = destination->find(it->first); - if (bitmap_it != destination->end()) - delete bitmap_it->second; - - (*destination)[it->first] = it->second; - } -} - -void BrowserThemePack::AddRawImagesTo(const RawImages& images, - RawDataForWriting* out) const { - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); - for (RawImages::const_iterator it = images.begin(); it != images.end(); - ++it) { - (*out)[it->first] = base::StringPiece( - reinterpret_cast(it->second->front()), it->second->size()); - } -} - -color_utils::HSL BrowserThemePack::GetTintInternal(int id) const { - if (tints_) { - for (int i = 0; i < kTintArraySize; ++i) { - if (tints_[i].id == id) { - color_utils::HSL hsl; - hsl.h = tints_[i].h; - hsl.s = tints_[i].s; - hsl.l = tints_[i].l; - return hsl; - } - } - } - - return BrowserThemeProvider::GetDefaultTint(id); -} diff --git a/chrome/browser/browser_theme_pack.h b/chrome/browser/browser_theme_pack.h deleted file mode 100644 index c5b20eb..0000000 --- a/chrome/browser/browser_theme_pack.h +++ /dev/null @@ -1,226 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_BROWSER_THEME_PACK_H_ -#define CHROME_BROWSER_BROWSER_THEME_PACK_H_ -#pragma once - -#include -#include - -#include "base/basictypes.h" -#include "base/scoped_ptr.h" -#include "base/ref_counted.h" -#include "gfx/color_utils.h" -#include "chrome/common/extensions/extension.h" - -namespace base { -class DataPack; -} -class DictionaryValue; -class FilePath; -class RefCountedMemory; - -// An optimized representation of a theme, backed by a mmapped DataPack. -// -// The idea is to pre-process all images (tinting, compositing, etc) at theme -// install time, save all the PNG-ified data into an mmappable file so we don't -// suffer multiple file system access times, therefore solving two of the -// problems with the previous implementation. -// -// A note on const-ness. All public, non-static methods are const. We do this -// because once we've constructed a BrowserThemePack through the -// BuildFromExtension() interface, we WriteToDisk() on a thread other than the -// UI thread that consumes a BrowserThemePack. There is no locking; thread -// safety between the writing thread and the UI thread is ensured by having the -// data be immutable. -class BrowserThemePack : public base::RefCountedThreadSafe { - public: - ~BrowserThemePack(); - - // Builds the theme pack from all data from |extension|. This is often done - // on a separate thread as it takes so long. This can fail and return NULL in - // the case where the theme has invalid data. - static BrowserThemePack* BuildFromExtension(Extension* extension); - - // Builds the theme pack from a previously performed WriteToDisk(). This - // operation should be relatively fast, as it should be an mmap() and some - // pointer swizzling. Returns NULL on any error attempting to read |path|. - static scoped_refptr BuildFromDataPack( - FilePath path, const std::string& expected_id); - - // Builds a data pack on disk at |path| for future quick loading by - // BuildFromDataPack(). Often (but not always) called from the file thread; - // implementation should be threadsafe because neither thread will write to - // |image_memory_| and the worker thread will keep a reference to prevent - // destruction. - bool WriteToDisk(FilePath path) const; - - // If this theme specifies data for the corresponding |id|, return true and - // write the corresponding value to the output parameter. These functions - // don't return the default data. These methods should only be called from - // the UI thread. (But this isn't enforced because of unit tests). - bool GetTint(int id, color_utils::HSL* hsl) const; - bool GetColor(int id, SkColor* color) const; - bool GetDisplayProperty(int id, int* result) const; - - // Returns a bitmap if we have a custom image for |id|, otherwise NULL. Note - // that this is separate from HasCustomImage() which returns whether a custom - // image |id| was included in the unprocessed theme and is used as a proxy - // for making layout decisions in the interface. - SkBitmap* GetBitmapNamed(int id) const; - - // Returns the raw PNG encoded data for IDR_THEME_NTP_*. This method is only - // supposed to work for the NTP attribution and background resources. - RefCountedMemory* GetRawData(int id) const; - - // Whether this theme provides an image for |id|. - bool HasCustomImage(int id) const; - - private: - friend class BrowserThemePackTest; - - // Cached images. We cache all retrieved and generated bitmaps and keep - // track of the pointers. We own these and will delete them when we're done - // using them. - typedef std::map ImageCache; - - // The raw PNG memory associated with a certain id. - typedef std::map > RawImages; - - // The type passed to base::DataPack::WritePack. - typedef std::map RawDataForWriting; - - // An association between an id and the FilePath that has the image data. - typedef std::map FilePathMap; - - // Default. Everything is empty. - BrowserThemePack(); - - // Builds a header ready to write to disk. - void BuildHeader(Extension* extension); - - // Transforms the JSON tint values into their final versions in the |tints_| - // array. - void BuildTintsFromJSON(DictionaryValue* tints_value); - - // Transforms the JSON color values into their final versions in the - // |colors_| array and also fills in unspecified colors based on tint values. - void BuildColorsFromJSON(DictionaryValue* color_value); - - // Implementation details of BuildColorsFromJSON(). - void ReadColorsFromJSON(DictionaryValue* colors_value, - std::map* temp_colors); - void GenerateMissingColors(std::map* temp_colors); - - // Transforms the JSON display properties into |display_properties_|. - void BuildDisplayPropertiesFromJSON(DictionaryValue* display_value); - - // Parses the image names out of an extension. - void ParseImageNamesFromJSON(DictionaryValue* images_value, - FilePath images_path, - FilePathMap* file_paths) const; - - // Creates the data for |source_images_| from |file_paths|. - void BuildSourceImagesArray(const FilePathMap& file_paths); - - // Loads the unmodified bitmaps packed in the extension to SkBitmaps. Returns - // true if all images loaded. - bool LoadRawBitmapsTo(const FilePathMap& file_paths, - ImageCache* raw_bitmaps); - - // Creates tinted and composited frame images. Source and destination is - // |bitmaps|. - void GenerateFrameImages(ImageCache* bitmaps) const; - - // Generates button images tinted with |button_tint| and places them in - // processed_bitmaps. - void GenerateTintedButtons(color_utils::HSL button_tint, - ImageCache* processed_bitmaps) const; - - // Generates the semi-transparent tab background images, putting the results - // in |bitmaps|. Must be called after GenerateFrameImages(). - void GenerateTabBackgroundImages(ImageCache* bitmaps) const; - - // Takes all the SkBitmaps in |images|, encodes them as PNGs and places - // them in |reencoded_images|. - void RepackImages(const ImageCache& images, - RawImages* reencoded_images) const; - - // Takes all images in |source| and puts them in |destination|, freeing any - // image already in |destination| that |source| would overwrite. - void MergeImageCaches(const ImageCache& source, - ImageCache* destination) const; - - // Changes the RefCountedMemory based |images| into StringPiece data in |out|. - void AddRawImagesTo(const RawImages& images, RawDataForWriting* out) const; - - // Retrieves the tint OR the default tint. Unlike the public interface, we - // always need to return a reasonable tint here, instead of partially - // querying if the tint exists. - color_utils::HSL GetTintInternal(int id) const; - - // Data pack, if we have one. - scoped_ptr data_pack_; - - // All structs written to disk need to be packed; no alignment tricks here, - // please. -#pragma pack(push,1) - // Header that is written to disk. - struct BrowserThemePackHeader { - // Numeric version to make sure we're compatible in the future. - int32 version; - - // 1 if little_endian. 0 if big_endian. On mismatch, abort load. - int32 little_endian; - - // theme_id without NULL terminator. - uint8 theme_id[16]; - } *header_; - - // The remaining structs represent individual entries in an array. For the - // following three structs, BrowserThemePack will either allocate an array or - // will point directly to mmapped data. - struct TintEntry { - int32 id; - double h; - double s; - double l; - } *tints_; - - struct ColorPair { - int32 id; - SkColor color; - } *colors_; - - struct DisplayPropertyPair { - int32 id; - int32 property; - } *display_properties_; - - // A list of included source images. A pointer to a -1 terminated array of - // our persistent IDs. - int* source_images_; -#pragma pack(pop) - - // References to raw PNG data. This map isn't touched when |data_pack_| is - // non-NULL; |image_memory_| is only filled during BuildFromExtension(). Any - // image data that needs to be written to the DataPack during WriteToDisk() - // needs to be in |image_memory_|. - RawImages image_memory_; - - // An immutable cache of images generated in BuildFromExtension(). When this - // BrowserThemePack is generated from BuildFromDataPack(), this cache is - // empty. We separate the images from the images loaded from disk so that - // WriteToDisk()'s implementation doesn't need locks. There should be no IDs - // in |image_memory_| that are in |prepared_images_| or vice versa. - ImageCache prepared_images_; - - // Loaded images. These are loaded from |image_memory_| or the |data_pack_|. - mutable ImageCache loaded_images_; - - DISALLOW_COPY_AND_ASSIGN(BrowserThemePack); -}; - -#endif // CHROME_BROWSER_BROWSER_THEME_PACK_H_ diff --git a/chrome/browser/browser_theme_pack_unittest.cc b/chrome/browser/browser_theme_pack_unittest.cc deleted file mode 100644 index eaeba79..0000000 --- a/chrome/browser/browser_theme_pack_unittest.cc +++ /dev/null @@ -1,428 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/browser_theme_pack.h" - -#include "base/file_util.h" -#include "base/json/json_reader.h" -#include "base/message_loop.h" -#include "base/path_service.h" -#include "base/scoped_temp_dir.h" -#include "base/values.h" -#include "chrome/browser/browser_theme_provider.h" -#include "chrome/browser/chrome_thread.h" -#include "chrome/common/chrome_paths.h" -#include "chrome/common/json_value_serializer.h" -#include "gfx/color_utils.h" -#include "grit/theme_resources.h" -#include "testing/gtest/include/gtest/gtest.h" - -class BrowserThemePackTest : public ::testing::Test { - public: - BrowserThemePackTest() - : message_loop(), - fake_ui_thread(ChromeThread::UI, &message_loop), - fake_file_thread(ChromeThread::FILE, &message_loop), - theme_pack_(new BrowserThemePack) { - } - - // Transformation for link underline colors. - SkColor BuildThirdOpacity(SkColor color_link) { - return SkColorSetA(color_link, SkColorGetA(color_link) / 3); - } - - void GenerateDefaultFrameColor(std::map* colors, - int color, int tint) { - (*colors)[color] = HSLShift( - BrowserThemeProvider::GetDefaultColor( - BrowserThemeProvider::COLOR_FRAME), - BrowserThemeProvider::GetDefaultTint(tint)); - } - - // Returns a mapping from each COLOR_* constant to the default value for this - // constant. Callers get this map, and then modify expected values and then - // run the resulting thing through VerifyColorMap(). - std::map GetDefaultColorMap() { - std::map colors; - for (int i = BrowserThemeProvider::COLOR_FRAME; - i <= BrowserThemeProvider::COLOR_BUTTON_BACKGROUND; ++i) { - colors[i] = BrowserThemeProvider::GetDefaultColor(i); - } - - GenerateDefaultFrameColor(&colors, BrowserThemeProvider::COLOR_FRAME, - BrowserThemeProvider::TINT_FRAME); - GenerateDefaultFrameColor(&colors, - BrowserThemeProvider::COLOR_FRAME_INACTIVE, - BrowserThemeProvider::TINT_FRAME_INACTIVE); - GenerateDefaultFrameColor(&colors, - BrowserThemeProvider::COLOR_FRAME_INCOGNITO, - BrowserThemeProvider::TINT_FRAME_INCOGNITO); - GenerateDefaultFrameColor( - &colors, - BrowserThemeProvider::COLOR_FRAME_INCOGNITO_INACTIVE, - BrowserThemeProvider::TINT_FRAME_INCOGNITO_INACTIVE); - - return colors; - } - - void VerifyColorMap(const std::map& color_map) { - for (std::map::const_iterator it = color_map.begin(); - it != color_map.end(); ++it) { - SkColor color = BrowserThemeProvider::GetDefaultColor(it->first); - theme_pack_->GetColor(it->first, &color); - EXPECT_EQ(it->second, color) << "Color id = " << it->first; - } - } - - void LoadColorJSON(const std::string& json) { - scoped_ptr value(base::JSONReader::Read(json, false)); - ASSERT_TRUE(value->IsType(Value::TYPE_DICTIONARY)); - LoadColorDictionary(static_cast(value.get())); - } - - void LoadColorDictionary(DictionaryValue* value) { - theme_pack_->BuildColorsFromJSON(value); - } - - void LoadTintJSON(const std::string& json) { - scoped_ptr value(base::JSONReader::Read(json, false)); - ASSERT_TRUE(value->IsType(Value::TYPE_DICTIONARY)); - LoadTintDictionary(static_cast(value.get())); - } - - void LoadTintDictionary(DictionaryValue* value) { - theme_pack_->BuildTintsFromJSON(value); - } - - void LoadDisplayPropertiesJSON(const std::string& json) { - scoped_ptr value(base::JSONReader::Read(json, false)); - ASSERT_TRUE(value->IsType(Value::TYPE_DICTIONARY)); - LoadDisplayPropertiesDictionary(static_cast(value.get())); - } - - void LoadDisplayPropertiesDictionary(DictionaryValue* value) { - theme_pack_->BuildDisplayPropertiesFromJSON(value); - } - - void ParseImageNamesJSON(const std::string& json, - std::map* out_file_paths) { - scoped_ptr value(base::JSONReader::Read(json, false)); - ASSERT_TRUE(value->IsType(Value::TYPE_DICTIONARY)); - ParseImageNamesDictionary(static_cast(value.get()), - out_file_paths); - } - - void ParseImageNamesDictionary(DictionaryValue* value, - std::map* out_file_paths) { - theme_pack_->ParseImageNamesFromJSON(value, FilePath(), out_file_paths); - - // Build the source image list for HasCustomImage(). - theme_pack_->BuildSourceImagesArray(*out_file_paths); - } - - bool LoadRawBitmapsTo(const std::map& out_file_paths) { - return theme_pack_->LoadRawBitmapsTo(out_file_paths, - &theme_pack_->prepared_images_); - } - - FilePath GetStarGazingPath() { - FilePath test_path; - if (!PathService::Get(chrome::DIR_TEST_DATA, &test_path)) { - NOTREACHED(); - return test_path; - } - - test_path = test_path.AppendASCII("profiles"); - test_path = test_path.AppendASCII("complex_theme"); - test_path = test_path.AppendASCII("Default"); - test_path = test_path.AppendASCII("Extensions"); - test_path = test_path.AppendASCII("mblmlcbknbnfebdfjnolmcapmdofhmme"); - test_path = test_path.AppendASCII("1.1"); - return FilePath(test_path); - } - - // Verifies the data in star gazing. We do this multiple times for different - // BrowserThemePack objects to make sure it works in generated and mmapped - // mode correctly. - void VerifyStarGazing(BrowserThemePack* pack) { - // First check that values we know exist, exist. - SkColor color; - EXPECT_TRUE(pack->GetColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT, - &color)); - EXPECT_EQ(SK_ColorBLACK, color); - - EXPECT_TRUE(pack->GetColor(BrowserThemeProvider::COLOR_NTP_BACKGROUND, - &color)); - EXPECT_EQ(SkColorSetRGB(57, 137, 194), color); - - color_utils::HSL expected = { 0.6, 0.553, 0.5 }; - color_utils::HSL actual; - EXPECT_TRUE(pack->GetTint(BrowserThemeProvider::TINT_BUTTONS, &actual)); - EXPECT_DOUBLE_EQ(expected.h, actual.h); - EXPECT_DOUBLE_EQ(expected.s, actual.s); - EXPECT_DOUBLE_EQ(expected.l, actual.l); - - int val; - EXPECT_TRUE(pack->GetDisplayProperty( - BrowserThemeProvider::NTP_BACKGROUND_ALIGNMENT, &val)); - EXPECT_EQ(BrowserThemeProvider::ALIGN_TOP, val); - - // The stargazing theme defines the following images: - EXPECT_TRUE(pack->HasCustomImage(IDR_THEME_BUTTON_BACKGROUND)); - EXPECT_TRUE(pack->HasCustomImage(IDR_THEME_FRAME)); - EXPECT_TRUE(pack->HasCustomImage(IDR_THEME_NTP_BACKGROUND)); - EXPECT_TRUE(pack->HasCustomImage(IDR_THEME_TAB_BACKGROUND)); - EXPECT_TRUE(pack->HasCustomImage(IDR_THEME_TOOLBAR)); - EXPECT_TRUE(pack->HasCustomImage(IDR_THEME_WINDOW_CONTROL_BACKGROUND)); - - // Here are a few images that we shouldn't expect because even though - // they're included in the theme pack, they were autogenerated and - // therefore shouldn't show up when calling HasCustomImage(). - EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_FRAME_INACTIVE)); - EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_FRAME_INCOGNITO)); - EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_FRAME_INCOGNITO_INACTIVE)); - EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_TAB_BACKGROUND_INCOGNITO)); - - // Make sure we don't have phantom data. - EXPECT_FALSE(pack->GetColor(BrowserThemeProvider::COLOR_CONTROL_BACKGROUND, - &color)); - EXPECT_FALSE(pack->GetTint(BrowserThemeProvider::TINT_FRAME, &actual)); - } - - MessageLoop message_loop; - ChromeThread fake_ui_thread; - ChromeThread fake_file_thread; - - scoped_refptr theme_pack_; -}; - - -TEST_F(BrowserThemePackTest, DeriveUnderlineLinkColor) { - // If we specify a link color, but don't specify the underline color, the - // theme provider should create one. - std::string color_json = "{ \"ntp_link\": [128, 128, 128]," - " \"ntp_section_link\": [128, 128, 128] }"; - LoadColorJSON(color_json); - - std::map colors = GetDefaultColorMap(); - SkColor link_color = SkColorSetRGB(128, 128, 128); - colors[BrowserThemeProvider::COLOR_NTP_LINK] = link_color; - colors[BrowserThemeProvider::COLOR_NTP_LINK_UNDERLINE] = - BuildThirdOpacity(link_color); - colors[BrowserThemeProvider::COLOR_NTP_SECTION_LINK] = link_color; - colors[BrowserThemeProvider::COLOR_NTP_SECTION_LINK_UNDERLINE] = - BuildThirdOpacity(link_color); - - VerifyColorMap(colors); -} - -TEST_F(BrowserThemePackTest, ProvideUnderlineLinkColor) { - // If we specify the underline color, it shouldn't try to generate one. - std::string color_json = "{ \"ntp_link\": [128, 128, 128]," - " \"ntp_link_underline\": [255, 255, 255]," - " \"ntp_section_link\": [128, 128, 128]," - " \"ntp_section_link_underline\": [255, 255, 255]" - "}"; - LoadColorJSON(color_json); - - std::map colors = GetDefaultColorMap(); - SkColor link_color = SkColorSetRGB(128, 128, 128); - SkColor underline_color = SkColorSetRGB(255, 255, 255); - colors[BrowserThemeProvider::COLOR_NTP_LINK] = link_color; - colors[BrowserThemeProvider::COLOR_NTP_LINK_UNDERLINE] = underline_color; - colors[BrowserThemeProvider::COLOR_NTP_SECTION_LINK] = link_color; - colors[BrowserThemeProvider::COLOR_NTP_SECTION_LINK_UNDERLINE] = - underline_color; - - VerifyColorMap(colors); -} - -TEST_F(BrowserThemePackTest, UseSectionColorAsNTPHeader) { - std::string color_json = "{ \"ntp_section\": [190, 190, 190] }"; - LoadColorJSON(color_json); - - std::map colors = GetDefaultColorMap(); - SkColor ntp_color = SkColorSetRGB(190, 190, 190); - colors[BrowserThemeProvider::COLOR_NTP_HEADER] = ntp_color; - colors[BrowserThemeProvider::COLOR_NTP_SECTION] = ntp_color; - VerifyColorMap(colors); -} - -TEST_F(BrowserThemePackTest, ProvideNtpHeaderColor) { - std::string color_json = "{ \"ntp_header\": [120, 120, 120], " - " \"ntp_section\": [190, 190, 190] }"; - LoadColorJSON(color_json); - - std::map colors = GetDefaultColorMap(); - SkColor ntp_header = SkColorSetRGB(120, 120, 120); - SkColor ntp_section = SkColorSetRGB(190, 190, 190); - colors[BrowserThemeProvider::COLOR_NTP_HEADER] = ntp_header; - colors[BrowserThemeProvider::COLOR_NTP_SECTION] = ntp_section; - VerifyColorMap(colors); -} - -TEST_F(BrowserThemePackTest, CanReadTints) { - std::string tint_json = "{ \"buttons\": [ 0.5, 0.5, 0.5 ] }"; - LoadTintJSON(tint_json); - - color_utils::HSL expected = { 0.5, 0.5, 0.5 }; - color_utils::HSL actual = { -1, -1, -1 }; - EXPECT_TRUE(theme_pack_->GetTint( - BrowserThemeProvider::TINT_BUTTONS, &actual)); - EXPECT_DOUBLE_EQ(expected.h, actual.h); - EXPECT_DOUBLE_EQ(expected.s, actual.s); - EXPECT_DOUBLE_EQ(expected.l, actual.l); -} - -TEST_F(BrowserThemePackTest, CanReadDisplayProperties) { - std::string json = "{ \"ntp_background_alignment\": \"bottom\", " - " \"ntp_background_repeat\": \"repeat-x\", " - " \"ntp_logo_alternate\": 0 }"; - LoadDisplayPropertiesJSON(json); - - int out_val; - EXPECT_TRUE(theme_pack_->GetDisplayProperty( - BrowserThemeProvider::NTP_BACKGROUND_ALIGNMENT, &out_val)); - EXPECT_EQ(BrowserThemeProvider::ALIGN_BOTTOM, out_val); - - EXPECT_TRUE(theme_pack_->GetDisplayProperty( - BrowserThemeProvider::NTP_BACKGROUND_TILING, &out_val)); - EXPECT_EQ(BrowserThemeProvider::REPEAT_X, out_val); - - EXPECT_TRUE(theme_pack_->GetDisplayProperty( - BrowserThemeProvider::NTP_LOGO_ALTERNATE, &out_val)); - EXPECT_EQ(0, out_val); -} - -TEST_F(BrowserThemePackTest, CanParsePaths) { - std::string path_json = "{ \"theme_button_background\": \"one\", " - " \"theme_toolbar\": \"two\" }"; - std::map out_file_paths; - ParseImageNamesJSON(path_json, &out_file_paths); - - EXPECT_EQ(2u, out_file_paths.size()); - // "12" and "5" are internal constants to BrowserThemePack and are - // PRS_THEME_BUTTON_BACKGROUND and PRS_THEME_TOOLBAR, but they are - // implementation details that shouldn't be exported. - EXPECT_TRUE(FilePath(FILE_PATH_LITERAL("one")) == out_file_paths[12]); - EXPECT_TRUE(FilePath(FILE_PATH_LITERAL("two")) == out_file_paths[5]); -} - -TEST_F(BrowserThemePackTest, InvalidPathNames) { - std::string path_json = "{ \"wrong\": [1], " - " \"theme_button_background\": \"one\", " - " \"not_a_thing\": \"blah\" }"; - std::map out_file_paths; - ParseImageNamesJSON(path_json, &out_file_paths); - - // We should have only parsed one valid path out of that mess above. - EXPECT_EQ(1u, out_file_paths.size()); -} - -TEST_F(BrowserThemePackTest, InvalidColors) { - std::string invalid_color = "{ \"toolbar\": [\"dog\", \"cat\", [12]], " - " \"sound\": \"woof\" }"; - LoadColorJSON(invalid_color); - std::map colors = GetDefaultColorMap(); - VerifyColorMap(colors); -} - -TEST_F(BrowserThemePackTest, InvalidTints) { - std::string invalid_tints = "{ \"buttons\": [ \"dog\", \"cat\", [\"x\"]], " - " \"invalid\": \"entry\" }"; - LoadTintJSON(invalid_tints); - - // We shouldn't have a buttons tint, as it was invalid. - color_utils::HSL actual = { -1, -1, -1 }; - EXPECT_FALSE(theme_pack_->GetTint(BrowserThemeProvider::TINT_BUTTONS, - &actual)); -} - -TEST_F(BrowserThemePackTest, InvalidDisplayProperties) { - std::string invalid_properties = "{ \"ntp_background_alignment\": [15], " - " \"junk\": [15.3] }"; - LoadDisplayPropertiesJSON(invalid_properties); - - int out_val; - EXPECT_FALSE(theme_pack_->GetDisplayProperty( - BrowserThemeProvider::NTP_BACKGROUND_ALIGNMENT, &out_val)); -} - -// These three tests should just not cause a segmentation fault. -TEST_F(BrowserThemePackTest, NullPaths) { - std::map out_file_paths; - ParseImageNamesDictionary(NULL, &out_file_paths); -} - -TEST_F(BrowserThemePackTest, NullTints) { - LoadTintDictionary(NULL); -} - -TEST_F(BrowserThemePackTest, NullColors) { - LoadColorDictionary(NULL); -} - -TEST_F(BrowserThemePackTest, NullDisplayProperties) { - LoadDisplayPropertiesDictionary(NULL); -} - -TEST_F(BrowserThemePackTest, TestHasCustomImage) { - // HasCustomImage should only return true for images that exist in the - // extension and not for autogenerated images. - std::string images = "{ \"theme_frame\": \"one\" }"; - std::map out_file_paths; - ParseImageNamesJSON(images, &out_file_paths); - - EXPECT_TRUE(theme_pack_->HasCustomImage(IDR_THEME_FRAME)); - EXPECT_FALSE(theme_pack_->HasCustomImage(IDR_THEME_FRAME_INCOGNITO)); -} - -TEST_F(BrowserThemePackTest, TestNonExistantImages) { - std::string images = "{ \"theme_frame\": \"does_not_exist\" }"; - std::map out_file_paths; - ParseImageNamesJSON(images, &out_file_paths); - - EXPECT_FALSE(LoadRawBitmapsTo(out_file_paths)); -} - -// TODO(erg): This test should actually test more of the built resources from -// the extension data, but for now, exists so valgrind can test some of the -// tricky memory stuff that BrowserThemePack does. -TEST_F(BrowserThemePackTest, CanBuildAndReadPack) { - ScopedTempDir dir; - ASSERT_TRUE(dir.CreateUniqueTempDir()); - FilePath file = dir.path().Append(FILE_PATH_LITERAL("data.pak")); - - // Part 1: Build the pack from an extension. - { - FilePath star_gazing_path = GetStarGazingPath(); - Extension extension(star_gazing_path); - - FilePath manifest_path = - star_gazing_path.AppendASCII("manifest.json"); - std::string error; - JSONFileValueSerializer serializer(manifest_path); - scoped_ptr valid_value( - static_cast(serializer.Deserialize(NULL, &error))); - EXPECT_EQ("", error); - ASSERT_TRUE(valid_value.get()); - ASSERT_TRUE(extension.InitFromValue(*valid_value, true, &error)); - ASSERT_EQ("", error); - - scoped_refptr pack = - BrowserThemePack::BuildFromExtension(&extension); - ASSERT_TRUE(pack.get()); - ASSERT_TRUE(pack->WriteToDisk(file)); - VerifyStarGazing(pack.get()); - } - - // Part 2: Try to read back the data pack that we just wrote to disk. - { - scoped_refptr pack = - BrowserThemePack::BuildFromDataPack( - file, "mblmlcbknbnfebdfjnolmcapmdofhmme"); - ASSERT_TRUE(pack.get()); - VerifyStarGazing(pack.get()); - } -} diff --git a/chrome/browser/browser_theme_provider.cc b/chrome/browser/browser_theme_provider.cc deleted file mode 100644 index 4964bdd..0000000 --- a/chrome/browser/browser_theme_provider.cc +++ /dev/null @@ -1,609 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/browser_theme_provider.h" - -#include "app/resource_bundle.h" -#include "base/utf_string_conversions.h" -#include "base/string_util.h" -#include "chrome/browser/browser_theme_pack.h" -#include "chrome/browser/extensions/extensions_service.h" -#include "chrome/browser/metrics/user_metrics.h" -#include "chrome/browser/profile.h" -#include "chrome/common/chrome_constants.h" -#include "chrome/common/notification_service.h" -#include "chrome/common/notification_type.h" -#include "chrome/common/pref_names.h" -#include "grit/app_resources.h" -#include "grit/theme_resources.h" - -#if defined(OS_WIN) -#include "app/win_util.h" -#endif - -// Strings used in alignment properties. -const char* BrowserThemeProvider::kAlignmentTop = "top"; -const char* BrowserThemeProvider::kAlignmentBottom = "bottom"; -const char* BrowserThemeProvider::kAlignmentLeft = "left"; -const char* BrowserThemeProvider::kAlignmentRight = "right"; - -// Strings used in background tiling repetition properties. -const char* BrowserThemeProvider::kTilingNoRepeat = "no-repeat"; -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 kDefaultColorFrame = SkColorSetRGB(66, 116, 201); -const SkColor kDefaultColorFrameInactive = SkColorSetRGB(161, 182, 228); -const SkColor kDefaultColorFrameIncognito = SkColorSetRGB(83, 106, 139); -const SkColor kDefaultColorFrameIncognitoInactive = - SkColorSetRGB(126, 139, 156); -#if defined(OS_MACOSX) -const SkColor kDefaultColorToolbar = SkColorSetRGB(230, 230, 230); -#else -const SkColor kDefaultColorToolbar = SkColorSetRGB(223, 223, 223); -#endif -const SkColor kDefaultColorTabText = SK_ColorBLACK; -#if defined(OS_MACOSX) -const SkColor kDefaultColorBackgroundTabText = SK_ColorBLACK; -const SkColor kDefaultColorBookmarkText = SK_ColorBLACK; -#else -const SkColor kDefaultColorBackgroundTabText = SkColorSetRGB(64, 64, 64); -const SkColor kDefaultColorBookmarkText = SkColorSetRGB(18, 50, 114); -#endif -#if defined(OS_WIN) -const SkColor kDefaultColorNTPBackground = - color_utils::GetSysSkColor(COLOR_WINDOW); -const SkColor kDefaultColorNTPText = - color_utils::GetSysSkColor(COLOR_WINDOWTEXT); -const SkColor kDefaultColorNTPLink = - color_utils::GetSysSkColor(COLOR_HOTLIGHT); -#else -// TODO(beng): source from theme provider. -const SkColor kDefaultColorNTPBackground = SK_ColorWHITE; -const SkColor kDefaultColorNTPText = SK_ColorBLACK; -const SkColor kDefaultColorNTPLink = SkColorSetRGB(6, 55, 116); -#endif -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); -#if defined(OS_MACOSX) -const SkColor kDefaultColorToolbarButtonStroke = SkColorSetARGB(75, 81, 81, 81); -const SkColor kDefaultColorToolbarButtonStrokeInactive = - SkColorSetARGB(75, 99, 99, 99); -const SkColor kDefaultColorToolbarBezel = SkColorSetRGB(247, 247, 247); -const SkColor kDefaultColorToolbarStroke = SkColorSetRGB(103, 103, 103); -const SkColor kDefaultColorToolbarStrokeInactive = SkColorSetRGB(123, 123, 123); -#endif - -// Default tints. -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 = - BrowserThemeProvider::ALIGN_BOTTOM; -const int kDefaultDisplayPropertyNTPTiling = - BrowserThemeProvider::NO_REPEAT; -const int kDefaultDisplayPropertyNTPInverseLogo = 0; - -// The sum of kFrameBorderThickness and kNonClientRestoredExtraThickness from -// OpaqueBrowserFrameView. -const int kRestoredTabVerticalOffset = 15; - -// The image resources we will allow people to theme. -const int kThemeableImages[] = { - IDR_THEME_FRAME, - IDR_THEME_FRAME_INACTIVE, - IDR_THEME_FRAME_INCOGNITO, - IDR_THEME_FRAME_INCOGNITO_INACTIVE, - IDR_THEME_TOOLBAR, - IDR_THEME_TAB_BACKGROUND, - IDR_THEME_TAB_BACKGROUND_INCOGNITO, - IDR_THEME_TAB_BACKGROUND_V, - IDR_THEME_NTP_BACKGROUND, - IDR_THEME_FRAME_OVERLAY, - IDR_THEME_FRAME_OVERLAY_INACTIVE, - IDR_THEME_BUTTON_BACKGROUND, - IDR_THEME_NTP_ATTRIBUTION, - IDR_THEME_WINDOW_CONTROL_BACKGROUND -}; - -bool HasThemeableImage(int themeable_image_id) { - static std::set themeable_images; - if (themeable_images.empty()) { - themeable_images.insert( - kThemeableImages, kThemeableImages + arraysize(kThemeableImages)); - } - return themeable_images.count(themeable_image_id) > 0; -} - -// The image resources that will be tinted by the 'button' tint value. -// If you change this list, you must increment the version number in -// browser_theme_pack.cc, and you should assign persistent IDs to the -// data table at the start of said file or else tinted versions of -// these resources will not be created. -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_HOME, IDR_HOME_H, IDR_HOME_P, - IDR_RELOAD, IDR_RELOAD_H, IDR_RELOAD_P, - IDR_STOP, IDR_STOP_D, IDR_STOP_H, IDR_STOP_P, - IDR_LOCATIONBG_C, IDR_LOCATIONBG_L, IDR_LOCATIONBG_R, - IDR_BROWSER_ACTIONS_OVERFLOW, IDR_BROWSER_ACTIONS_OVERFLOW_H, - IDR_BROWSER_ACTIONS_OVERFLOW_P, - IDR_TOOLS, IDR_TOOLS_H, IDR_TOOLS_P, - IDR_MENU_DROPARROW, - IDR_THROBBER, IDR_THROBBER_WAITING, IDR_THROBBER_LIGHT, -}; - -// Writes the theme pack to disk on a separate thread. -class WritePackToDiskTask : public Task { - public: - WritePackToDiskTask(BrowserThemePack* pack, const FilePath& path) - : theme_pack_(pack), pack_path_(path) {} - - virtual void Run() { - if (!theme_pack_->WriteToDisk(pack_path_)) { - NOTREACHED() << "Could not write theme pack to disk"; - } - } - - private: - scoped_refptr theme_pack_; - FilePath pack_path_; -}; - -} // namespace - -bool BrowserThemeProvider::IsThemeableImage(int resource_id) { - return HasThemeableImage(resource_id); -} - -BrowserThemeProvider::BrowserThemeProvider() - : rb_(ResourceBundle::GetSharedInstance()), - profile_(NULL), - number_of_infobars_(0) { - // Initialize the themeable image map so we can use it on other threads. - HasThemeableImage(0); -} - -BrowserThemeProvider::~BrowserThemeProvider() { - FreePlatformCaches(); - - RemoveUnusedThemes(); -} - -void BrowserThemeProvider::Init(Profile* profile) { - DCHECK(CalledOnValidThread()); - profile_ = profile; - - LoadThemePrefs(); -} - -SkBitmap* BrowserThemeProvider::GetBitmapNamed(int id) const { - DCHECK(CalledOnValidThread()); - - SkBitmap* bitmap = 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()); - - SkColor color; - if (theme_pack_.get() && theme_pack_->GetColor(id, &color)) - return color; - - return GetDefaultColor(id); -} - -bool BrowserThemeProvider::GetDisplayProperty(int id, int* result) const { - if (theme_pack_.get()) - return theme_pack_->GetDisplayProperty(id, result); - - return GetDefaultDisplayProperty(id, result); -} - -bool BrowserThemeProvider::ShouldUseNativeFrame() const { - if (HasCustomImage(IDR_THEME_FRAME)) - return false; -#if defined(OS_WIN) - return win_util::ShouldUseVistaFrame(); -#else - return false; -#endif -} - -bool BrowserThemeProvider::HasCustomImage(int id) const { - if (!HasThemeableImage(id)) - return false; - - if (theme_pack_) - return theme_pack_->HasCustomImage(id); - - return false; -} - -RefCountedMemory* BrowserThemeProvider::GetRawData(int id) const { - // Check to see whether we should substitute some images. - int ntp_alternate; - GetDisplayProperty(NTP_LOGO_ALTERNATE, &ntp_alternate); - if (id == IDR_PRODUCT_LOGO && ntp_alternate != 0) - id = IDR_PRODUCT_LOGO_WHITE; - - RefCountedMemory* data = NULL; - if (theme_pack_.get()) - data = theme_pack_->GetRawData(id); - if (!data) - data = rb_.LoadDataResourceBytes(id); - - return data; -} - -void BrowserThemeProvider::SetTheme(Extension* extension) { - // Clear our image cache. - FreePlatformCaches(); - - DCHECK(extension); - DCHECK(extension->is_theme()); - - BuildFromExtension(extension); - SaveThemeID(extension->id()); - - NotifyThemeChanged(extension); - UserMetrics::RecordAction(UserMetricsAction("Themes_Installed"), profile_); -} - -void BrowserThemeProvider::RemoveUnusedThemes() { - if (!profile_) - return; - ExtensionsService* service = profile_->GetExtensionsService(); - if (!service) - return; - std::string current_theme = GetThemeID(); - std::vector remove_list; - const ExtensionList* extensions = service->extensions(); - for (ExtensionList::const_iterator it = extensions->begin(); - it != extensions->end(); ++it) { - if ((*it)->is_theme() && (*it)->id() != current_theme) { - remove_list.push_back((*it)->id()); - } - } - for (size_t i = 0; i < remove_list.size(); ++i) - service->UninstallExtension(remove_list[i], false); -} - -void BrowserThemeProvider::UseDefaultTheme() { - ClearAllThemeData(); - NotifyThemeChanged(NULL); - UserMetrics::RecordAction(UserMetricsAction("Themes_Reset"), profile_); -} - -bool BrowserThemeProvider::UsingDefaultTheme() { - return GetThemeID() == BrowserThemeProvider::kDefaultThemeID; -} - -std::string BrowserThemeProvider::GetThemeID() const { - return profile_->GetPrefs()->GetString(prefs::kCurrentThemeID); -} - -// static -std::string BrowserThemeProvider::AlignmentToString(int alignment) { - // Convert from an AlignmentProperty back into a string. - std::string vertical_string; - std::string horizontal_string; - - if (alignment & BrowserThemeProvider::ALIGN_TOP) - vertical_string = kAlignmentTop; - else if (alignment & BrowserThemeProvider::ALIGN_BOTTOM) - vertical_string = kAlignmentBottom; - - if (alignment & BrowserThemeProvider::ALIGN_LEFT) - horizontal_string = kAlignmentLeft; - else if (alignment & BrowserThemeProvider::ALIGN_RIGHT) - horizontal_string = kAlignmentRight; - - if (vertical_string.empty()) - return horizontal_string; - if (horizontal_string.empty()) - return vertical_string; - return vertical_string + " " + horizontal_string; -} - -// static -int BrowserThemeProvider::StringToAlignment(const std::string& alignment) { - std::vector split; - SplitStringAlongWhitespace(UTF8ToWide(alignment), &split); - - int alignment_mask = 0; - for (std::vector::iterator alignments(split.begin()); - alignments != split.end(); ++alignments) { - std::string comp = WideToUTF8(*alignments); - const char* component = comp.c_str(); - - if (base::strcasecmp(component, kAlignmentTop) == 0) - alignment_mask |= BrowserThemeProvider::ALIGN_TOP; - else if (base::strcasecmp(component, kAlignmentBottom) == 0) - alignment_mask |= BrowserThemeProvider::ALIGN_BOTTOM; - - if (base::strcasecmp(component, kAlignmentLeft) == 0) - alignment_mask |= BrowserThemeProvider::ALIGN_LEFT; - else if (base::strcasecmp(component, kAlignmentRight) == 0) - alignment_mask |= BrowserThemeProvider::ALIGN_RIGHT; - } - return alignment_mask; -} - -// static -std::string BrowserThemeProvider::TilingToString(int tiling) { - // Convert from a TilingProperty back into a string. - if (tiling == BrowserThemeProvider::REPEAT_X) - return kTilingRepeatX; - if (tiling == BrowserThemeProvider::REPEAT_Y) - return kTilingRepeatY; - if (tiling == BrowserThemeProvider::REPEAT) - return kTilingRepeat; - return kTilingNoRepeat; -} - -// static -int BrowserThemeProvider::StringToTiling(const std::string& tiling) { - const char* component = tiling.c_str(); - - if (base::strcasecmp(component, kTilingRepeatX) == 0) - return BrowserThemeProvider::REPEAT_X; - if (base::strcasecmp(component, kTilingRepeatY) == 0) - return BrowserThemeProvider::REPEAT_Y; - if (base::strcasecmp(component, kTilingRepeat) == 0) - return BrowserThemeProvider::REPEAT; - // NO_REPEAT is the default choice. - return BrowserThemeProvider::NO_REPEAT; -} - -// static -color_utils::HSL BrowserThemeProvider::GetDefaultTint(int id) { - switch (id) { - case TINT_FRAME: - return kDefaultTintFrame; - case TINT_FRAME_INACTIVE: - return kDefaultTintFrameInactive; - case TINT_FRAME_INCOGNITO: - return kDefaultTintFrameIncognito; - case TINT_FRAME_INCOGNITO_INACTIVE: - return kDefaultTintFrameIncognitoInactive; - case TINT_BUTTONS: - return kDefaultTintButtons; - case TINT_BACKGROUND_TAB: - return kDefaultTintBackgroundTab; - default: - color_utils::HSL result = {-1, -1, -1}; - return result; - } -} - -// static -SkColor BrowserThemeProvider::GetDefaultColor(int id) { - switch (id) { - case COLOR_FRAME: - return kDefaultColorFrame; - case COLOR_FRAME_INACTIVE: - return kDefaultColorFrameInactive; - case COLOR_FRAME_INCOGNITO: - return kDefaultColorFrameIncognito; - case COLOR_FRAME_INCOGNITO_INACTIVE: - return kDefaultColorFrameIncognitoInactive; - case COLOR_TOOLBAR: - return kDefaultColorToolbar; - case COLOR_TAB_TEXT: - return kDefaultColorTabText; - case COLOR_BACKGROUND_TAB_TEXT: - return kDefaultColorBackgroundTabText; - case COLOR_BOOKMARK_TEXT: - return kDefaultColorBookmarkText; - case COLOR_NTP_BACKGROUND: - return kDefaultColorNTPBackground; - case COLOR_NTP_TEXT: - 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: - return kDefaultColorNTPSection; - case COLOR_NTP_SECTION_TEXT: - 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: - return kDefaultColorButtonBackground; -#if defined(OS_MACOSX) - case COLOR_TOOLBAR_BUTTON_STROKE: - return kDefaultColorToolbarButtonStroke; - case COLOR_TOOLBAR_BUTTON_STROKE_INACTIVE: - return kDefaultColorToolbarButtonStrokeInactive; - case COLOR_TOOLBAR_BEZEL: - return kDefaultColorToolbarBezel; - case COLOR_TOOLBAR_STROKE: - return kDefaultColorToolbarStroke; - case COLOR_TOOLBAR_STROKE_INACTIVE: - return kDefaultColorToolbarStrokeInactive; -#endif - default: - // Return a debugging red color. - return 0xffff0000; - } -} - -// 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; -} - -// static -const std::set& BrowserThemeProvider::GetTintableToolbarButtons() { - static std::set button_set; - if (button_set.empty()) { - button_set = std::set( - kToolbarButtonIDs, - kToolbarButtonIDs + arraysize(kToolbarButtonIDs)); - } - - return button_set; -} - -color_utils::HSL BrowserThemeProvider::GetTint(int id) const { - DCHECK(CalledOnValidThread()); - - color_utils::HSL hsl; - if (theme_pack_.get() && theme_pack_->GetTint(id, &hsl)) - return hsl; - - return GetDefaultTint(id); -} - -void BrowserThemeProvider::ClearAllThemeData() { - // Clear our image cache. - FreePlatformCaches(); - theme_pack_ = NULL; - - profile_->GetPrefs()->ClearPref(prefs::kCurrentThemePackFilename); - SaveThemeID(kDefaultThemeID); -} - -void BrowserThemeProvider::LoadThemePrefs() { - PrefService* prefs = profile_->GetPrefs(); - - std::string current_id = GetThemeID(); - if (current_id != kDefaultThemeID) { - bool loaded_pack = false; - - // If we don't have a file pack, we're updating from an old version. - FilePath path = prefs->GetFilePath(prefs::kCurrentThemePackFilename); - if (path != FilePath()) { - theme_pack_ = BrowserThemePack::BuildFromDataPack(path, current_id); - loaded_pack = theme_pack_.get() != NULL; - } - - if (loaded_pack) { - UserMetrics::RecordAction(UserMetricsAction("Themes.Loaded"), profile_); - } else { - // 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(UserMetricsAction("Themes.Migrated"), - profile_); - } else { - DLOG(ERROR) << "Theme is mysteriously gone."; - ClearAllThemeData(); - UserMetrics::RecordAction(UserMetricsAction("Themes.Gone"), profile_); - } - } - } - } -} - -void BrowserThemeProvider::NotifyThemeChanged(Extension* extension) { - LOG(INFO) << "Sending BROWSER_THEME_CHANGED"; - // Redraw! - NotificationService* service = NotificationService::current(); - service->Notify(NotificationType::BROWSER_THEME_CHANGED, - Source(this), - Details(extension)); -#if defined(OS_MACOSX) - NotifyPlatformThemeChanged(); -#endif // OS_MACOSX -} - -#if defined(OS_WIN) -void BrowserThemeProvider::FreePlatformCaches() { - // Views (Skia) has no platform image cache to clear. -} -#endif - -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, id); -} - -void BrowserThemeProvider::BuildFromExtension(Extension* extension) { - scoped_refptr pack = - BrowserThemePack::BuildFromExtension(extension); - if (!pack.get()) { - // TODO(erg): We've failed to install the theme; perhaps we should tell the - // user? http://crbug.com/34780 - LOG(ERROR) << "Could not load theme."; - return; - } - - // Write the packed file to disk. - FilePath pack_path = extension->path().Append(chrome::kThemePackFilename); - ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE, - new WritePackToDiskTask(pack, pack_path)); - - SavePackName(pack_path); - theme_pack_ = pack; -} - -void BrowserThemeProvider::OnInfobarDisplayed() { - number_of_infobars_++; -} - -void BrowserThemeProvider::OnInfobarDestroyed() { - number_of_infobars_--; - - if (number_of_infobars_ == 0) - RemoveUnusedThemes(); -} diff --git a/chrome/browser/browser_theme_provider.h b/chrome/browser/browser_theme_provider.h deleted file mode 100644 index 9381ae2..0000000 --- a/chrome/browser/browser_theme_provider.h +++ /dev/null @@ -1,275 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_BROWSER_THEME_PROVIDER_H_ -#define CHROME_BROWSER_BROWSER_THEME_PROVIDER_H_ -#pragma once - -#include -#include -#include - -#include "app/theme_provider.h" -#include "base/non_thread_safe.h" -#include "base/ref_counted.h" - -namespace color_utils { - struct HSL; -} - -class BrowserThemePack; -class BrowserThemeProviderTest; -class Extension; -class FilePath; -class Profile; -class ResourceBundle; - -#ifdef __OBJC__ -@class NSString; -// Sent whenever the browser theme changes. Object => NSValue wrapping the -// BrowserThemeProvider that changed. -extern "C" NSString* const kBrowserThemeDidChangeNotification; -#endif // __OBJC__ - -class BrowserThemeProvider : public NonThreadSafe, - public ThemeProvider { - public: - // Public constants used in BrowserThemeProvider and its subclasses: - - // Strings used in alignment properties. - static const char* kAlignmentTop; - static const char* kAlignmentBottom; - static const char* kAlignmentLeft; - static const char* kAlignmentRight; - - // Strings used in tiling properties. - static const char* kTilingNoRepeat; - static const char* kTilingRepeatX; - static const char* kTilingRepeatY; - static const char* kTilingRepeat; - - static const char* kDefaultThemeID; - - // Returns true if the image is themeable. Safe to call on any thread. - static bool IsThemeableImage(int resource_id); - - BrowserThemeProvider(); - virtual ~BrowserThemeProvider(); - - enum { - COLOR_FRAME, - COLOR_FRAME_INACTIVE, - COLOR_FRAME_INCOGNITO, - COLOR_FRAME_INCOGNITO_INACTIVE, - COLOR_TOOLBAR, - COLOR_TAB_TEXT, - COLOR_BACKGROUND_TAB_TEXT, - COLOR_BOOKMARK_TEXT, - COLOR_NTP_BACKGROUND, - COLOR_NTP_TEXT, - COLOR_NTP_LINK, - COLOR_NTP_LINK_UNDERLINE, - COLOR_NTP_HEADER, - COLOR_NTP_SECTION, - COLOR_NTP_SECTION_TEXT, - COLOR_NTP_SECTION_LINK, - COLOR_NTP_SECTION_LINK_UNDERLINE, - COLOR_CONTROL_BACKGROUND, - COLOR_BUTTON_BACKGROUND, - TINT_BUTTONS, - TINT_FRAME, - TINT_FRAME_INACTIVE, - TINT_FRAME_INCOGNITO, - TINT_FRAME_INCOGNITO_INACTIVE, - TINT_BACKGROUND_TAB, - NTP_BACKGROUND_ALIGNMENT, - NTP_BACKGROUND_TILING, - NTP_LOGO_ALTERNATE -#if defined(OS_MACOSX) - , - COLOR_TOOLBAR_BEZEL = 1000, - COLOR_TOOLBAR_STROKE, - COLOR_TOOLBAR_STROKE_INACTIVE, - COLOR_TOOLBAR_BUTTON_STROKE, - COLOR_TOOLBAR_BUTTON_STROKE_INACTIVE, - GRADIENT_FRAME_INCOGNITO, - GRADIENT_FRAME_INCOGNITO_INACTIVE, - GRADIENT_TOOLBAR, - GRADIENT_TOOLBAR_INACTIVE, - GRADIENT_TOOLBAR_BUTTON, - GRADIENT_TOOLBAR_BUTTON_INACTIVE, - GRADIENT_TOOLBAR_BUTTON_PRESSED, - GRADIENT_TOOLBAR_BUTTON_PRESSED_INACTIVE -#endif // OS_MACOSX - }; - - // A bitfield mask for alignments. - typedef enum { - ALIGN_CENTER = 0x0, - ALIGN_LEFT = 0x1, - ALIGN_TOP = 0x2, - ALIGN_RIGHT = 0x4, - ALIGN_BOTTOM = 0x8, - } AlignmentMasks; - - // Background tiling choices. - typedef enum { - NO_REPEAT = 0, - REPEAT_X = 1, - REPEAT_Y = 2, - REPEAT = 3 - } Tiling; - - // ThemeProvider implementation. - virtual void Init(Profile* profile); - virtual SkBitmap* GetBitmapNamed(int id) const; - virtual SkColor GetColor(int id) const; - virtual bool GetDisplayProperty(int id, int* result) const; - virtual bool ShouldUseNativeFrame() const; - virtual bool HasCustomImage(int id) const; - virtual RefCountedMemory* GetRawData(int id) const; -#if defined(TOOLKIT_USES_GTK) - // GdkPixbufs returned by GetPixbufNamed and GetRTLEnabledPixbufNamed are - // shared instances owned by the theme provider and should not be freed. - virtual GdkPixbuf* GetPixbufNamed(int id) const; - virtual GdkPixbuf* GetRTLEnabledPixbufNamed(int id) const; -#elif defined(OS_MACOSX) - virtual NSImage* GetNSImageNamed(int id, bool allow_default) const; - virtual NSColor* GetNSImageColorNamed(int id, bool allow_default) const; - virtual NSColor* GetNSColor(int id, bool allow_default) const; - virtual NSColor* GetNSColorTint(int id, bool allow_default) const; - virtual NSGradient* GetNSGradient(int id) const; -#endif - - // Set the current theme to the theme defined in |extension|. - virtual void SetTheme(Extension* extension); - - // Reset the theme to default. - virtual void UseDefaultTheme(); - - // Set the current theme to the native theme. On some platforms, the native - // theme is the default theme. - virtual void SetNativeTheme() { UseDefaultTheme(); } - - // Whether we're using the chrome default theme. Virtual so linux can check - // if we're using the GTK theme. - virtual bool UsingDefaultTheme(); - - // Gets the id of the last installed theme. (The theme may have been further - // locally customized.) - std::string GetThemeID() const; - - // This class needs to keep track of the number of theme infobars so that we - // clean up unused themes. - void OnInfobarDisplayed(); - - // Decrements the number of theme infobars. If the last infobar has been - // destroyed, uninstalls all themes that aren't the currently selected. - void OnInfobarDestroyed(); - - // Convert a bitfield alignment into a string like "top left". Public so that - // it can be used to generate CSS values. Takes a bitfield of AlignmentMasks. - static std::string AlignmentToString(int alignment); - - // Parse alignments from something like "top left" into a bitfield of - // AlignmentMasks - static int StringToAlignment(const std::string& alignment); - - // Convert a tiling value into a string like "no-repeat". Public - // so that it can be used to generate CSS values. Takes a Tiling. - static std::string TilingToString(int tiling); - - // Parse tiling values from something like "no-repeat" into a Tiling value. - static int StringToTiling(const std::string& tiling); - - // Returns the default tint for the given tint |id| TINT_* enum value. - static color_utils::HSL GetDefaultTint(int id); - - // Returns the default color for the given color |id| COLOR_* enum value. - static SkColor GetDefaultColor(int id); - - // Returns true and sets |result| to the requested default property, if |id| - // is valid. - static bool GetDefaultDisplayProperty(int id, int* result); - - // Returns the set of IDR_* resources that should be tinted. - static const std::set& GetTintableToolbarButtons(); - - // Save the images to be written to disk, mapping file path to id. - typedef std::map ImagesDiskCache; - - protected: - // Get the specified tint - |id| is one of the TINT_* enum values. - color_utils::HSL GetTint(int id) const; - - // Clears all the override fields and saves the dictionary. - virtual void ClearAllThemeData(); - - // Load theme data from preferences. - virtual void LoadThemePrefs(); - - // Let all the browser views know that themes have changed. - // extension is NULL iff the theme is being set to the - // default/system theme. - virtual void NotifyThemeChanged(Extension* extension); - -#if defined(OS_MACOSX) - // Let all the browser views know that themes have changed in a platform way. - virtual void NotifyPlatformThemeChanged(); -#endif // OS_MACOSX - - // Clears the platform-specific caches. Do not call directly; it's called - // from ClearCaches(). - virtual void FreePlatformCaches(); - - Profile* profile() { return profile_; } - - private: - friend class BrowserThemeProviderTest; - - // Saves the filename of the cached theme pack. - void SavePackName(const FilePath& pack_path); - - // Save the id of the last theme installed. - void SaveThemeID(const std::string& id); - - // Implementation of SetTheme() (and the fallback from LoadThemePrefs() in - // case we don't have a theme pack). - void BuildFromExtension(Extension* extension); - - // Remove preference values for themes that are no longer in use. - void RemoveUnusedThemes(); - -#if defined(TOOLKIT_USES_GTK) - // Loads an image and flips it horizontally if |rtl_enabled| is true. - GdkPixbuf* GetPixbufImpl(int id, bool rtl_enabled) const; -#endif - -#if defined(TOOLKIT_USES_GTK) - typedef std::map GdkPixbufMap; - mutable GdkPixbufMap gdk_pixbufs_; -#elif defined(OS_MACOSX) - typedef std::map NSImageMap; - mutable NSImageMap nsimage_cache_; - - // The bool member of the pair is whether the color is a default color. - typedef std::map > NSColorMap; - mutable NSColorMap nscolor_cache_; - - typedef std::map NSGradientMap; - mutable NSGradientMap nsgradient_cache_; -#endif - - ResourceBundle& rb_; - Profile* profile_; - - scoped_refptr theme_pack_; - - // The number of infobars currently displayed. - int number_of_infobars_; - - DISALLOW_COPY_AND_ASSIGN(BrowserThemeProvider); -}; - -#endif // CHROME_BROWSER_BROWSER_THEME_PROVIDER_H_ diff --git a/chrome/browser/browser_theme_provider_gtk.cc b/chrome/browser/browser_theme_provider_gtk.cc deleted file mode 100644 index 8052086..0000000 --- a/chrome/browser/browser_theme_provider_gtk.cc +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/browser_theme_provider.h" - -#include - -#include "base/i18n/rtl.h" -#include "base/logging.h" -#include "gfx/gtk_util.h" -#include "third_party/skia/include/core/SkBitmap.h" - -GdkPixbuf* BrowserThemeProvider::GetPixbufNamed(int id) const { - return GetPixbufImpl(id, false); -} - -GdkPixbuf* BrowserThemeProvider::GetRTLEnabledPixbufNamed(int id) const { - return GetPixbufImpl(id, true); -} - -GdkPixbuf* BrowserThemeProvider::GetPixbufImpl(int id, bool rtl_enabled) const { - DCHECK(CalledOnValidThread()); - // Use the negative |resource_id| for the key for BIDI-aware images. - int key = rtl_enabled ? -id : id; - - // Check to see if we already have the pixbuf in the cache. - GdkPixbufMap::const_iterator pixbufs_iter = gdk_pixbufs_.find(key); - if (pixbufs_iter != gdk_pixbufs_.end()) - return pixbufs_iter->second; - - SkBitmap* bitmap = GetBitmapNamed(id); - GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(bitmap); - - // We loaded successfully. Cache the pixbuf. - if (pixbuf) { - if (base::i18n::IsRTL() && rtl_enabled) { - GdkPixbuf* original_pixbuf = pixbuf; - pixbuf = gdk_pixbuf_flip(pixbuf, TRUE); - g_object_unref(original_pixbuf); - } - - gdk_pixbufs_[key] = pixbuf; - return pixbuf; - } - - // We failed to retrieve the bitmap, show a debugging red square. - LOG(WARNING) << "Unable to load GdkPixbuf with id " << id; - NOTREACHED(); // Want to assert in debug mode. - - static GdkPixbuf* empty_bitmap = NULL; - if (!empty_bitmap) { - // The placeholder bitmap is bright red so people notice the problem. - // This bitmap will be leaked, but this code should never be hit. - scoped_ptr skia_bitmap(new SkBitmap()); - skia_bitmap->setConfig(SkBitmap::kARGB_8888_Config, 32, 32); - skia_bitmap->allocPixels(); - skia_bitmap->eraseARGB(255, 255, 0, 0); - empty_bitmap = gfx::GdkPixbufFromSkBitmap(skia_bitmap.get()); - } - return empty_bitmap; -} - -void BrowserThemeProvider::FreePlatformCaches() { - DCHECK(CalledOnValidThread()); - - // Free GdkPixbufs. - for (GdkPixbufMap::iterator i = gdk_pixbufs_.begin(); - i != gdk_pixbufs_.end(); i++) { - g_object_unref(i->second); - } - gdk_pixbufs_.clear(); -} diff --git a/chrome/browser/browser_theme_provider_mac.mm b/chrome/browser/browser_theme_provider_mac.mm deleted file mode 100644 index edac255..0000000 --- a/chrome/browser/browser_theme_provider_mac.mm +++ /dev/null @@ -1,317 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/browser_theme_provider.h" - -#import - -#include "base/logging.h" -#include "chrome/browser/browser_theme_pack.h" -#include "gfx/color_utils.h" -#include "skia/ext/skia_utils_mac.h" -#import "third_party/GTM/AppKit/GTMNSColor+Luminance.h" - -NSString* const kBrowserThemeDidChangeNotification = - @"BrowserThemeDidChangeNotification"; - -namespace { - -void HSLToHSB(const color_utils::HSL& hsl, CGFloat* h, CGFloat* s, CGFloat* b) { - SkColor color = color_utils::HSLToSkColor(hsl, 255); // alpha doesn't matter - SkScalar hsv[3]; - SkColorToHSV(color, hsv); - - *h = SkScalarToDouble(hsv[0]) / 360.0; - *s = SkScalarToDouble(hsv[1]); - *b = SkScalarToDouble(hsv[2]); -} - -} - -NSImage* BrowserThemeProvider::GetNSImageNamed(int id, - bool allow_default) const { - DCHECK(CalledOnValidThread()); - - if (!allow_default && !HasCustomImage(id)) - return nil; - - // Check to see if we already have the image in the cache. - NSImageMap::const_iterator nsimage_iter = nsimage_cache_.find(id); - if (nsimage_iter != nsimage_cache_.end()) - return nsimage_iter->second; - - // Why don't we load the file directly into the image instead of the whole - // SkBitmap > native conversion? - // - For consistency with other platforms. - // - To get the generated tinted images. - SkBitmap* bitmap = GetBitmapNamed(id); - NSImage* nsimage = gfx::SkBitmapToNSImage(*bitmap); - - // We loaded successfully. Cache the image. - if (nsimage) { - nsimage_cache_[id] = [nsimage retain]; - return nsimage; - } - - // We failed to retrieve the bitmap, show a debugging red square. - LOG(WARNING) << "Unable to load NSImage with id " << id; - NOTREACHED(); // Want to assert in debug mode. - - static NSImage* empty_image = NULL; - if (!empty_image) { - // The placeholder image is bright red so people notice the problem. This - // image will be leaked, but this code should never be hit. - NSRect image_rect = NSMakeRect(0, 0, 32, 32); - empty_image = [[NSImage alloc] initWithSize:image_rect.size]; - [empty_image lockFocus]; - [[NSColor redColor] set]; - NSRectFill(image_rect); - [empty_image unlockFocus]; - } - - return empty_image; -} - -NSColor* BrowserThemeProvider::GetNSImageColorNamed(int id, - bool allow_default) const { - DCHECK(CalledOnValidThread()); - - // Check to see if we already have the color in the cache. - NSColorMap::const_iterator nscolor_iter = nscolor_cache_.find(id); - if (nscolor_iter != nscolor_cache_.end()) { - bool cached_is_default = nscolor_iter->second.second; - if (!cached_is_default || allow_default) - return nscolor_iter->second.first; - } - - NSImage* image = GetNSImageNamed(id, allow_default); - if (!image) - return nil; - NSColor* image_color = [NSColor colorWithPatternImage:image]; - - // We loaded successfully. Cache the color. - if (image_color) { - nscolor_cache_[id] = std::make_pair([image_color retain], - !HasCustomImage(id)); - } - - return image_color; -} - -NSColor* BrowserThemeProvider::GetNSColor(int id, - bool allow_default) const { - DCHECK(CalledOnValidThread()); - - // Check to see if we already have the color in the cache. - NSColorMap::const_iterator nscolor_iter = nscolor_cache_.find(id); - if (nscolor_iter != nscolor_cache_.end()) { - bool cached_is_default = nscolor_iter->second.second; - if (!cached_is_default || allow_default) - return nscolor_iter->second.first; - } - - bool is_default = false; - SkColor sk_color; - if (theme_pack_.get() && theme_pack_->GetColor(id, &sk_color)) { - is_default = false; - } else { - is_default = true; - sk_color = GetDefaultColor(id); - } - - if (is_default && !allow_default) - return nil; - - NSColor* color = [NSColor - colorWithCalibratedRed:SkColorGetR(sk_color)/255.0 - green:SkColorGetG(sk_color)/255.0 - blue:SkColorGetB(sk_color)/255.0 - alpha:SkColorGetA(sk_color)/255.0]; - - // We loaded successfully. Cache the color. - if (color) - nscolor_cache_[id] = std::make_pair([color retain], is_default); - - return color; -} - -NSColor* BrowserThemeProvider::GetNSColorTint(int id, - bool allow_default) const { - DCHECK(CalledOnValidThread()); - - // Check to see if we already have the color in the cache. - NSColorMap::const_iterator nscolor_iter = nscolor_cache_.find(id); - if (nscolor_iter != nscolor_cache_.end()) { - bool cached_is_default = nscolor_iter->second.second; - if (!cached_is_default || allow_default) - return nscolor_iter->second.first; - } - - bool is_default = false; - color_utils::HSL tint; - if (theme_pack_.get() && theme_pack_->GetTint(id, &tint)) { - is_default = false; - } else { - is_default = true; - tint = GetDefaultTint(id); - } - - if (is_default && !allow_default) - return nil; - - NSColor* tint_color = nil; - if (tint.h == -1 && tint.s == -1 && tint.l == -1) { - tint_color = [NSColor blackColor]; - } else { - CGFloat hue, saturation, brightness; - HSLToHSB(tint, &hue, &saturation, &brightness); - - tint_color = [NSColor colorWithCalibratedHue:hue - saturation:saturation - brightness:brightness - alpha:1.0]; - } - - // We loaded successfully. Cache the color. - if (tint_color) - nscolor_cache_[id] = std::make_pair([tint_color retain], is_default); - - return tint_color; -} - -NSGradient* BrowserThemeProvider::GetNSGradient(int id) const { - DCHECK(CalledOnValidThread()); - - // Check to see if we already have the gradient in the cache. - NSGradientMap::const_iterator nsgradient_iter = nsgradient_cache_.find(id); - if (nsgradient_iter != nsgradient_cache_.end()) - return nsgradient_iter->second; - - NSGradient* gradient = nil; - - // Note that we are not leaking when we assign a retained object to - // |gradient|; in all cases we cache it before we return. - switch (id) { - case GRADIENT_FRAME_INCOGNITO: - case GRADIENT_FRAME_INCOGNITO_INACTIVE: { - // TODO(avi): can we simplify this? - BOOL active = id == GRADIENT_FRAME_INCOGNITO; - NSColor* base_color = [NSColor colorWithCalibratedRed:83/255.0 - green:108.0/255.0 - blue:140/255.0 - alpha:1.0]; - - NSColor *start_color = - [base_color gtm_colorAdjustedFor:GTMColorationBaseMidtone - faded:!active]; - NSColor *end_color = - [base_color gtm_colorAdjustedFor:GTMColorationBaseShadow - faded:!active]; - - if (!active) { - start_color = [start_color gtm_colorByAdjustingLuminance:0.1 - saturation:0.5]; - end_color = [end_color gtm_colorByAdjustingLuminance:0.1 - saturation:0.5]; - } - - gradient = [[NSGradient alloc] initWithStartingColor:start_color - endingColor:end_color]; - break; - } - - case GRADIENT_TOOLBAR: - case GRADIENT_TOOLBAR_INACTIVE: { - NSColor* base_color = [NSColor colorWithCalibratedWhite:0.2 alpha:1.0]; - BOOL faded = (id == GRADIENT_TOOLBAR_INACTIVE ) || - (id == GRADIENT_TOOLBAR_BUTTON_INACTIVE); - NSColor* start_color = - [base_color gtm_colorAdjustedFor:GTMColorationLightHighlight - faded:faded]; - NSColor* mid_color = - [base_color gtm_colorAdjustedFor:GTMColorationLightMidtone - faded:faded]; - NSColor* end_color = - [base_color gtm_colorAdjustedFor:GTMColorationLightShadow - faded:faded]; - NSColor* glow_color = - [base_color gtm_colorAdjustedFor:GTMColorationLightPenumbra - faded:faded]; - - gradient = - [[NSGradient alloc] initWithColorsAndLocations:start_color, 0.0, - mid_color, 0.25, - end_color, 0.5, - glow_color, 0.75, - nil]; - break; - } - - case GRADIENT_TOOLBAR_BUTTON: - case GRADIENT_TOOLBAR_BUTTON_INACTIVE: { - NSColor* start_color = [NSColor colorWithCalibratedWhite:1.0 alpha:0.0]; - NSColor* end_color = [NSColor colorWithCalibratedWhite:1.0 alpha:0.3]; - gradient = [[NSGradient alloc] initWithStartingColor:start_color - endingColor:end_color]; - break; - } - case GRADIENT_TOOLBAR_BUTTON_PRESSED: - case GRADIENT_TOOLBAR_BUTTON_PRESSED_INACTIVE: { - NSColor* base_color = [NSColor colorWithCalibratedWhite:0.5 alpha:1.0]; - BOOL faded = id == GRADIENT_TOOLBAR_BUTTON_PRESSED_INACTIVE; - NSColor* start_color = - [base_color gtm_colorAdjustedFor:GTMColorationBaseShadow - faded:faded]; - NSColor* end_color = - [base_color gtm_colorAdjustedFor:GTMColorationBaseMidtone - faded:faded]; - - gradient = [[NSGradient alloc] initWithStartingColor:start_color - endingColor:end_color]; - break; - } - default: - LOG(WARNING) << "Gradient request with unknown id " << id; - NOTREACHED(); // Want to assert in debug mode. - break; - } - - // We loaded successfully. Cache the gradient. - if (gradient) - nsgradient_cache_[id] = gradient; // created retained - - return gradient; -} - -// Let all the browser views know that themes have changed in a platform way. -void BrowserThemeProvider::NotifyPlatformThemeChanged() { - NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter]; - [defaultCenter postNotificationName:kBrowserThemeDidChangeNotification - object:[NSValue valueWithPointer:this]]; -} - -void BrowserThemeProvider::FreePlatformCaches() { - DCHECK(CalledOnValidThread()); - - // Free images. - for (NSImageMap::iterator i = nsimage_cache_.begin(); - i != nsimage_cache_.end(); i++) { - [i->second release]; - } - nsimage_cache_.clear(); - - // Free colors. - for (NSColorMap::iterator i = nscolor_cache_.begin(); - i != nscolor_cache_.end(); i++) { - [i->second.first release]; - } - nscolor_cache_.clear(); - - // Free gradients. - for (NSGradientMap::iterator i = nsgradient_cache_.begin(); - i != nsgradient_cache_.end(); i++) { - [i->second release]; - } - nsgradient_cache_.clear(); -} diff --git a/chrome/browser/browser_theme_provider_unittest.cc b/chrome/browser/browser_theme_provider_unittest.cc deleted file mode 100644 index e5f7235..0000000 --- a/chrome/browser/browser_theme_provider_unittest.cc +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/browser_theme_provider.h" - -#include "testing/gtest/include/gtest/gtest.h" -#include "base/json/json_reader.h" - -TEST(BrowserThemeProviderTest, AlignmentConversion) { - // Verify that we get out what we put in. - std::string top_left = "top left"; - int alignment = BrowserThemeProvider::StringToAlignment(top_left); - EXPECT_EQ(BrowserThemeProvider::ALIGN_TOP | BrowserThemeProvider::ALIGN_LEFT, - alignment); - EXPECT_EQ(top_left, BrowserThemeProvider::AlignmentToString(alignment)); - - alignment = BrowserThemeProvider::StringToAlignment("top"); - EXPECT_EQ(BrowserThemeProvider::ALIGN_TOP, alignment); - EXPECT_EQ("top", BrowserThemeProvider::AlignmentToString(alignment)); - - alignment = BrowserThemeProvider::StringToAlignment("left"); - EXPECT_EQ(BrowserThemeProvider::ALIGN_LEFT, alignment); - EXPECT_EQ("left", BrowserThemeProvider::AlignmentToString(alignment)); - - alignment = BrowserThemeProvider::StringToAlignment("right"); - EXPECT_EQ(BrowserThemeProvider::ALIGN_RIGHT, alignment); - EXPECT_EQ("right", BrowserThemeProvider::AlignmentToString(alignment)); - - alignment = BrowserThemeProvider::StringToAlignment("righttopbottom"); - EXPECT_EQ(BrowserThemeProvider::ALIGN_CENTER, alignment); - EXPECT_EQ("", BrowserThemeProvider::AlignmentToString(alignment)); -} - -TEST(BrowserThemeProviderTest, AlignmentConversionInput) { - // Verify that we output in an expected format. - int alignment = BrowserThemeProvider::StringToAlignment("right bottom"); - EXPECT_EQ("bottom right", BrowserThemeProvider::AlignmentToString(alignment)); - - // Verify that bad strings don't cause explosions. - alignment = BrowserThemeProvider::StringToAlignment("new zealand"); - EXPECT_EQ("", BrowserThemeProvider::AlignmentToString(alignment)); - - // Verify that bad strings don't cause explosions. - alignment = BrowserThemeProvider::StringToAlignment("new zealand top"); - EXPECT_EQ("top", BrowserThemeProvider::AlignmentToString(alignment)); - - // Verify that bad strings don't cause explosions. - alignment = BrowserThemeProvider::StringToAlignment("new zealandtop"); - EXPECT_EQ("", BrowserThemeProvider::AlignmentToString(alignment)); -} diff --git a/chrome/browser/chromeos/frame/normal_browser_frame_view.cc b/chrome/browser/chromeos/frame/normal_browser_frame_view.cc index 2878eae..cd3f208 100644 --- a/chrome/browser/chromeos/frame/normal_browser_frame_view.cc +++ b/chrome/browser/chromeos/frame/normal_browser_frame_view.cc @@ -9,8 +9,8 @@ #include "app/theme_provider.h" #include "base/command_line.h" #include "base/compiler_specific.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/browser/views/frame/browser_frame.h" #include "chrome/browser/views/frame/browser_view.h" #include "chrome/browser/views/tabs/tab_strip.h" diff --git a/chrome/browser/cocoa/background_gradient_view.mm b/chrome/browser/cocoa/background_gradient_view.mm index 7dd93b6..9910412 100644 --- a/chrome/browser/cocoa/background_gradient_view.mm +++ b/chrome/browser/cocoa/background_gradient_view.mm @@ -4,8 +4,8 @@ #include "chrome/browser/cocoa/background_gradient_view.h" -#import "chrome/browser/browser_theme_provider.h" #import "chrome/browser/cocoa/themed_window.h" +#import "chrome/browser/themes/browser_theme_provider.h" #include "grit/theme_resources.h" #define kToolbarTopOffset 12 diff --git a/chrome/browser/cocoa/bookmark_bar_controller.mm b/chrome/browser/cocoa/bookmark_bar_controller.mm index 14fdecb..245f599 100644 --- a/chrome/browser/cocoa/bookmark_bar_controller.mm +++ b/chrome/browser/cocoa/bookmark_bar_controller.mm @@ -12,7 +12,6 @@ #include "chrome/browser/bookmarks/bookmark_utils.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_list.h" -#import "chrome/browser/browser_theme_provider.h" #import "chrome/browser/cocoa/background_gradient_view.h" #import "chrome/browser/cocoa/bookmark_bar_bridge.h" #import "chrome/browser/cocoa/bookmark_bar_constants.h" @@ -41,6 +40,7 @@ #include "chrome/browser/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tab_contents/tab_contents_view.h" +#import "chrome/browser/themes/browser_theme_provider.h" #include "chrome/common/pref_names.h" #include "grit/app_resources.h" #include "grit/generated_resources.h" diff --git a/chrome/browser/cocoa/bookmark_bar_folder_controller.mm b/chrome/browser/cocoa/bookmark_bar_folder_controller.mm index ddd0670..34cfd20 100644 --- a/chrome/browser/cocoa/bookmark_bar_folder_controller.mm +++ b/chrome/browser/cocoa/bookmark_bar_folder_controller.mm @@ -3,20 +3,21 @@ // found in the LICENSE file. #import "chrome/browser/cocoa/bookmark_bar_folder_controller.h" + #include "base/mac_util.h" #include "base/nsimage_cache_mac.h" #include "base/sys_string_conversions.h" #include "chrome/browser/bookmarks/bookmark_model.h" #include "chrome/browser/bookmarks/bookmark_utils.h" -#import "chrome/browser/browser_theme_provider.h" #import "chrome/browser/cocoa/bookmark_bar_constants.h" // namespace bookmarks #import "chrome/browser/cocoa/bookmark_bar_controller.h" // namespace bookmarks -#import "chrome/browser/cocoa/bookmark_bar_folder_view.h" #import "chrome/browser/cocoa/bookmark_bar_folder_button_cell.h" #import "chrome/browser/cocoa/bookmark_bar_folder_hover_state.h" +#import "chrome/browser/cocoa/bookmark_bar_folder_view.h" #import "chrome/browser/cocoa/bookmark_folder_target.h" #import "chrome/browser/cocoa/browser_window_controller.h" #import "chrome/browser/cocoa/event_utils.h" +#import "chrome/browser/themes/browser_theme_provider.h" namespace { diff --git a/chrome/browser/cocoa/bookmark_bar_toolbar_view.mm b/chrome/browser/cocoa/bookmark_bar_toolbar_view.mm index 9f50222..f2c8494 100644 --- a/chrome/browser/cocoa/bookmark_bar_toolbar_view.mm +++ b/chrome/browser/cocoa/bookmark_bar_toolbar_view.mm @@ -6,12 +6,12 @@ #include "app/theme_provider.h" #include "gfx/rect.h" -#include "chrome/browser/browser_theme_provider.h" #import "chrome/browser/cocoa/bookmark_bar_constants.h" #import "chrome/browser/cocoa/bookmark_bar_controller.h" #import "chrome/browser/cocoa/browser_window_controller.h" #import "chrome/browser/cocoa/themed_window.h" #include "chrome/browser/ntp_background_util.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "gfx/canvas_skia_paint.h" const CGFloat kBorderRadius = 3.0; diff --git a/chrome/browser/cocoa/bookmark_bar_toolbar_view_unittest.mm b/chrome/browser/cocoa/bookmark_bar_toolbar_view_unittest.mm index eaf3a34..0b5a1cc 100644 --- a/chrome/browser/cocoa/bookmark_bar_toolbar_view_unittest.mm +++ b/chrome/browser/cocoa/bookmark_bar_toolbar_view_unittest.mm @@ -6,10 +6,10 @@ #include "app/theme_provider.h" #include "base/scoped_nsobject.h" -#include "chrome/browser/browser_theme_provider.h" #import "chrome/browser/cocoa/bookmark_bar_controller.h" #import "chrome/browser/cocoa/bookmark_bar_toolbar_view.h" #import "chrome/browser/cocoa/cocoa_test_helper.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "grit/theme_resources.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/cocoa/bookmark_bar_view.mm b/chrome/browser/cocoa/bookmark_bar_view.mm index 2098521..63e3c3c 100644 --- a/chrome/browser/cocoa/bookmark_bar_view.mm +++ b/chrome/browser/cocoa/bookmark_bar_view.mm @@ -5,12 +5,12 @@ #import "chrome/browser/cocoa/bookmark_bar_view.h" #include "chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h" -#import "chrome/browser/browser_theme_provider.h" #import "chrome/browser/cocoa/bookmark_bar_controller.h" #import "chrome/browser/cocoa/bookmark_button.h" #import "chrome/browser/cocoa/bookmark_folder_target.h" #import "chrome/browser/cocoa/themed_window.h" #import "chrome/browser/cocoa/view_id_util.h" +#import "chrome/browser/themes/browser_theme_provider.h" #import "third_party/mozilla/NSPasteboard+Utils.h" @interface BookmarkBarView (Private) diff --git a/chrome/browser/cocoa/browser_frame_view.mm b/chrome/browser/cocoa/browser_frame_view.mm index dfc8003..1c07ab8 100644 --- a/chrome/browser/cocoa/browser_frame_view.mm +++ b/chrome/browser/cocoa/browser_frame_view.mm @@ -9,9 +9,9 @@ #include "base/logging.h" #include "base/scoped_nsautorelease_pool.h" -#import "chrome/browser/browser_theme_provider.h" #import "chrome/browser/cocoa/chrome_browser_window.h" #import "chrome/browser/cocoa/themed_window.h" +#import "chrome/browser/themes/browser_theme_provider.h" #include "grit/theme_resources.h" static const CGFloat kBrowserFrameViewPaintHeight = 60.0; diff --git a/chrome/browser/cocoa/browser_window_controller.mm b/chrome/browser/cocoa/browser_window_controller.mm index d9373a8..0e18570 100644 --- a/chrome/browser/cocoa/browser_window_controller.mm +++ b/chrome/browser/cocoa/browser_window_controller.mm @@ -14,15 +14,9 @@ #import "base/scoped_nsobject.h" #include "base/sys_string_conversions.h" #include "chrome/app/chrome_dll_resource.h" // IDC_* +#include "chrome/browser/bookmarks/bookmark_editor.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_list.h" -#include "chrome/browser/browser_theme_provider.h" -#include "chrome/browser/dock_info.h" -#include "chrome/browser/encoding_menu_controller.h" -#include "chrome/browser/location_bar.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/window_sizer.h" -#include "chrome/browser/bookmarks/bookmark_editor.h" #import "chrome/browser/cocoa/background_gradient_view.h" #import "chrome/browser/cocoa/bookmark_bar_controller.h" #import "chrome/browser/cocoa/bookmark_editor_controller.h" @@ -31,8 +25,8 @@ #import "chrome/browser/cocoa/download_shelf_controller.h" #import "chrome/browser/cocoa/event_utils.h" #import "chrome/browser/cocoa/fast_resize_view.h" -#import "chrome/browser/cocoa/find_bar_cocoa_controller.h" #import "chrome/browser/cocoa/find_bar_bridge.h" +#import "chrome/browser/cocoa/find_bar_cocoa_controller.h" #import "chrome/browser/cocoa/focus_tracker.h" #import "chrome/browser/cocoa/fullscreen_controller.h" #import "chrome/browser/cocoa/fullscreen_window.h" @@ -41,18 +35,24 @@ #import "chrome/browser/cocoa/sad_tab_controller.h" #import "chrome/browser/cocoa/status_bubble_mac.h" #import "chrome/browser/cocoa/tab_contents_controller.h" -#import "chrome/browser/cocoa/tab_strip_model_observer_bridge.h" #import "chrome/browser/cocoa/tab_strip_controller.h" +#import "chrome/browser/cocoa/tab_strip_model_observer_bridge.h" #import "chrome/browser/cocoa/tab_strip_view.h" #import "chrome/browser/cocoa/tab_view.h" #import "chrome/browser/cocoa/tabpose_window.h" #import "chrome/browser/cocoa/toolbar_controller.h" +#include "chrome/browser/dock_info.h" +#include "chrome/browser/encoding_menu_controller.h" +#include "chrome/browser/location_bar.h" +#include "chrome/browser/profile.h" #include "chrome/browser/renderer_host/render_widget_host_view.h" #include "chrome/browser/sync/profile_sync_service.h" #include "chrome/browser/sync/sync_ui_util_mac.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tab_contents/tab_contents_view_mac.h" #include "chrome/browser/tabs/tab_strip_model.h" +#include "chrome/browser/themes/browser_theme_provider.h" +#include "chrome/browser/window_sizer.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" diff --git a/chrome/browser/cocoa/browser_window_controller_private.mm b/chrome/browser/cocoa/browser_window_controller_private.mm index c4615d5..dcb73da 100644 --- a/chrome/browser/cocoa/browser_window_controller_private.mm +++ b/chrome/browser/cocoa/browser_window_controller_private.mm @@ -9,7 +9,6 @@ #include "chrome/browser/browser.h" #include "chrome/browser/browser_list.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_theme_provider.h" #import "chrome/browser/cocoa/chrome_browser_window.h" #import "chrome/browser/cocoa/fast_resize_view.h" #import "chrome/browser/cocoa/find_bar_cocoa_controller.h" @@ -24,6 +23,7 @@ #include "chrome/browser/renderer_host/render_widget_host_view.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tab_contents/tab_contents_view.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/common/pref_names.h" namespace { diff --git a/chrome/browser/cocoa/bubble_view.mm b/chrome/browser/cocoa/bubble_view.mm index 9c5f569..e7815b8 100644 --- a/chrome/browser/cocoa/bubble_view.mm +++ b/chrome/browser/cocoa/bubble_view.mm @@ -4,8 +4,8 @@ #import "chrome/browser/cocoa/bubble_view.h" -#include "chrome/browser/browser_theme_provider.h" #import "chrome/browser/cocoa/themed_window.h" +#include "chrome/browser/themes/browser_theme_provider.h" #import "third_party/GTM/AppKit/GTMNSBezierPath+RoundRect.h" #import "third_party/GTM/AppKit/GTMNSColor+Luminance.h" diff --git a/chrome/browser/cocoa/chrome_browser_window.mm b/chrome/browser/cocoa/chrome_browser_window.mm index 25826a3..9e0df76 100644 --- a/chrome/browser/cocoa/chrome_browser_window.mm +++ b/chrome/browser/cocoa/chrome_browser_window.mm @@ -5,13 +5,13 @@ #import "chrome/browser/cocoa/chrome_browser_window.h" #include "base/logging.h" -#include "chrome/browser/browser_theme_provider.h" #import "chrome/browser/cocoa/browser_frame_view.h" #import "chrome/browser/cocoa/browser_window_controller.h" #import "chrome/browser/cocoa/tab_strip_controller.h" #import "chrome/browser/cocoa/themed_window.h" #include "chrome/browser/global_keyboard_shortcuts_mac.h" #import "chrome/browser/renderer_host/render_widget_host_view_mac.h" +#include "chrome/browser/themes/browser_theme_provider.h" namespace { // Size of the gradient. Empirically determined so that the gradient looks diff --git a/chrome/browser/cocoa/download_item_cell.mm b/chrome/browser/cocoa/download_item_cell.mm index 1338615..935108f 100644 --- a/chrome/browser/cocoa/download_item_cell.mm +++ b/chrome/browser/cocoa/download_item_cell.mm @@ -8,7 +8,6 @@ #include "app/text_elider.h" #include "base/mac_util.h" #include "base/sys_string_conversions.h" -#import "chrome/browser/browser_theme_provider.h" #import "chrome/browser/cocoa/download_item_cell.h" #import "chrome/browser/cocoa/image_utils.h" #import "chrome/browser/cocoa/themed_window.h" @@ -16,6 +15,7 @@ #include "chrome/browser/download/download_item_model.h" #include "chrome/browser/download/download_manager.h" #include "chrome/browser/download/download_util.h" +#import "chrome/browser/themes/browser_theme_provider.h" #include "gfx/canvas_skia_paint.h" #include "grit/theme_resources.h" #import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h" diff --git a/chrome/browser/cocoa/download_item_controller.mm b/chrome/browser/cocoa/download_item_controller.mm index 86cab8d..e13fc74 100644 --- a/chrome/browser/cocoa/download_item_controller.mm +++ b/chrome/browser/cocoa/download_item_controller.mm @@ -12,7 +12,6 @@ #include "base/string_util.h" #include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" -#import "chrome/browser/browser_theme_provider.h" #import "chrome/browser/cocoa/download_item_button.h" #import "chrome/browser/cocoa/download_item_cell.h" #include "chrome/browser/cocoa/download_item_mac.h" @@ -23,6 +22,7 @@ #include "chrome/browser/download/download_item_model.h" #include "chrome/browser/download/download_shelf.h" #include "chrome/browser/download/download_util.h" +#import "chrome/browser/themes/browser_theme_provider.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" #include "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" diff --git a/chrome/browser/cocoa/download_shelf_controller.mm b/chrome/browser/cocoa/download_shelf_controller.mm index e0095ba..715fcfa 100644 --- a/chrome/browser/cocoa/download_shelf_controller.mm +++ b/chrome/browser/cocoa/download_shelf_controller.mm @@ -9,10 +9,9 @@ #include "base/mac_util.h" #include "base/sys_string_conversions.h" #include "chrome/browser/browser.h" -#include "chrome/browser/browser_theme_provider.h" #import "chrome/browser/cocoa/animatable_view.h" -#import "chrome/browser/cocoa/browser_window_controller.h" #include "chrome/browser/cocoa/browser_window_cocoa.h" +#import "chrome/browser/cocoa/browser_window_controller.h" #include "chrome/browser/cocoa/download_item_controller.h" #include "chrome/browser/cocoa/download_shelf_mac.h" #import "chrome/browser/cocoa/download_shelf_view.h" @@ -20,6 +19,7 @@ #include "chrome/browser/download/download_item.h" #include "chrome/browser/download/download_manager.h" #include "chrome/browser/profile.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" #import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h" diff --git a/chrome/browser/cocoa/download_shelf_view.mm b/chrome/browser/cocoa/download_shelf_view.mm index bd43cf5..b382037 100644 --- a/chrome/browser/cocoa/download_shelf_view.mm +++ b/chrome/browser/cocoa/download_shelf_view.mm @@ -5,9 +5,9 @@ #import "chrome/browser/cocoa/download_shelf_view.h" #include "base/scoped_nsobject.h" -#include "chrome/browser/browser_theme_provider.h" #import "chrome/browser/cocoa/themed_window.h" #import "chrome/browser/cocoa/view_id_util.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "grit/theme_resources.h" @implementation DownloadShelfView diff --git a/chrome/browser/cocoa/fullscreen_window.mm b/chrome/browser/cocoa/fullscreen_window.mm index 4fd2be1..15c2ee8 100644 --- a/chrome/browser/cocoa/fullscreen_window.mm +++ b/chrome/browser/cocoa/fullscreen_window.mm @@ -5,8 +5,8 @@ #import "chrome/browser/cocoa/fullscreen_window.h" #include "base/mac_util.h" -#include "chrome/browser/browser_theme_provider.h" #import "chrome/browser/cocoa/themed_window.h" +#include "chrome/browser/themes/browser_theme_provider.h" @implementation FullscreenWindow diff --git a/chrome/browser/cocoa/gradient_button_cell.mm b/chrome/browser/cocoa/gradient_button_cell.mm index ed8408e..d5b40b9 100644 --- a/chrome/browser/cocoa/gradient_button_cell.mm +++ b/chrome/browser/cocoa/gradient_button_cell.mm @@ -6,9 +6,9 @@ #include "base/logging.h" #import "base/scoped_nsobject.h" -#import "chrome/browser/browser_theme_provider.h" #import "chrome/browser/cocoa/image_utils.h" #import "chrome/browser/cocoa/themed_window.h" +#import "chrome/browser/themes/browser_theme_provider.h" #include "grit/theme_resources.h" #import "third_party/GTM/AppKit/GTMNSColor+Luminance.h" diff --git a/chrome/browser/cocoa/infobar_gradient_view.mm b/chrome/browser/cocoa/infobar_gradient_view.mm index 1dc0b7c..180a286 100644 --- a/chrome/browser/cocoa/infobar_gradient_view.mm +++ b/chrome/browser/cocoa/infobar_gradient_view.mm @@ -5,8 +5,8 @@ #include "chrome/browser/cocoa/infobar_gradient_view.h" #include "base/scoped_nsobject.h" -#import "chrome/browser/browser_theme_provider.h" #import "chrome/browser/cocoa/themed_window.h" +#import "chrome/browser/themes/browser_theme_provider.h" namespace { diff --git a/chrome/browser/cocoa/styled_text_field_cell.mm b/chrome/browser/cocoa/styled_text_field_cell.mm index 5a3415a..43a2a39 100644 --- a/chrome/browser/cocoa/styled_text_field_cell.mm +++ b/chrome/browser/cocoa/styled_text_field_cell.mm @@ -6,8 +6,8 @@ #include "app/resource_bundle.h" #include "base/logging.h" -#include "chrome/browser/browser_theme_provider.h" #import "chrome/browser/cocoa/themed_window.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "gfx/font.h" #include "grit/theme_resources.h" diff --git a/chrome/browser/cocoa/tab_controller.mm b/chrome/browser/cocoa/tab_controller.mm index 040f9d6..9e5403c 100644 --- a/chrome/browser/cocoa/tab_controller.mm +++ b/chrome/browser/cocoa/tab_controller.mm @@ -4,12 +4,12 @@ #include "app/l10n_util_mac.h" #include "base/mac_util.h" -#import "chrome/browser/browser_theme_provider.h" #import "chrome/browser/cocoa/menu_controller.h" #import "chrome/browser/cocoa/tab_controller.h" #import "chrome/browser/cocoa/tab_controller_target.h" #import "chrome/browser/cocoa/tab_view.h" #import "chrome/browser/cocoa/themed_window.h" +#import "chrome/browser/themes/browser_theme_provider.h" #import "chrome/common/extensions/extension.h" #include "grit/generated_resources.h" diff --git a/chrome/browser/cocoa/tab_strip_view.mm b/chrome/browser/cocoa/tab_strip_view.mm index 8f4ce26..1e0daf8 100644 --- a/chrome/browser/cocoa/tab_strip_view.mm +++ b/chrome/browser/cocoa/tab_strip_view.mm @@ -4,12 +4,12 @@ #import "chrome/browser/cocoa/tab_strip_view.h" +#include "base/logging.h" #include "base/mac_util.h" -#include "chrome/browser/browser_theme_provider.h" #import "chrome/browser/cocoa/browser_window_controller.h" #import "chrome/browser/cocoa/tab_strip_controller.h" #import "chrome/browser/cocoa/view_id_util.h" -#include "base/logging.h" +#include "chrome/browser/themes/browser_theme_provider.h" @implementation TabStripView diff --git a/chrome/browser/cocoa/tab_view.mm b/chrome/browser/cocoa/tab_view.mm index 8afb68c..e2d7d49 100644 --- a/chrome/browser/cocoa/tab_view.mm +++ b/chrome/browser/cocoa/tab_view.mm @@ -8,11 +8,11 @@ #import "base/mac_util.h" #include "base/nsimage_cache_mac.h" #include "base/scoped_cftyperef.h" -#include "chrome/browser/browser_theme_provider.h" #import "chrome/browser/cocoa/tab_controller.h" #import "chrome/browser/cocoa/tab_window_controller.h" #import "chrome/browser/cocoa/themed_window.h" #import "chrome/browser/cocoa/view_id_util.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "grit/theme_resources.h" namespace { diff --git a/chrome/browser/cocoa/toolbar_controller.mm b/chrome/browser/cocoa/toolbar_controller.mm index 57b0e38..edbdcbd 100644 --- a/chrome/browser/cocoa/toolbar_controller.mm +++ b/chrome/browser/cocoa/toolbar_controller.mm @@ -17,7 +17,6 @@ #include "chrome/app/chrome_dll_resource.h" #include "chrome/browser/autocomplete/autocomplete_edit_view.h" #include "chrome/browser/browser.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/browser_window.h" #import "chrome/browser/cocoa/accelerators_cocoa.h" #import "chrome/browser/cocoa/back_forward_menu_controller.h" @@ -40,6 +39,7 @@ #include "chrome/browser/profile.h" #include "chrome/browser/search_engines/template_url_model.h" #include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/browser/toolbar_model.h" #include "chrome/browser/upgrade_detector.h" #include "chrome/browser/wrench_menu_model.h" diff --git a/chrome/browser/debugger/devtools_window.cc b/chrome/browser/debugger/devtools_window.cc index d0d4e80..f2f8b36 100644 --- a/chrome/browser/debugger/devtools_window.cc +++ b/chrome/browser/debugger/devtools_window.cc @@ -10,7 +10,6 @@ #include "chrome/browser/browser.h" #include "chrome/browser/browser_list.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/browser_window.h" #include "chrome/browser/debugger/devtools_manager.h" #include "chrome/browser/debugger/devtools_window.h" @@ -24,6 +23,7 @@ #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tab_contents/tab_contents_view.h" #include "chrome/browser/tabs/tab_strip_model.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/common/bindings_policy.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" diff --git a/chrome/browser/dom_ui/dom_ui.cc b/chrome/browser/dom_ui/dom_ui.cc index c9e9c88..0ecc7ae 100644 --- a/chrome/browser/dom_ui/dom_ui.cc +++ b/chrome/browser/dom_ui/dom_ui.cc @@ -10,11 +10,11 @@ #include "base/string_number_conversions.h" #include "base/utf_string_conversions.h" #include "base/values.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/profile.h" #include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tab_contents/tab_contents_view.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/common/bindings_policy.h" #include "chrome/common/render_messages.h" #include "chrome/common/render_messages_params.h" diff --git a/chrome/browser/dom_ui/dom_ui_theme_source.cc b/chrome/browser/dom_ui/dom_ui_theme_source.cc index e2ecbdf..d2a91ba0ae 100644 --- a/chrome/browser/dom_ui/dom_ui_theme_source.cc +++ b/chrome/browser/dom_ui/dom_ui_theme_source.cc @@ -8,11 +8,11 @@ #include "app/theme_provider.h" #include "base/message_loop.h" #include "base/ref_counted_memory.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/chrome_thread.h" #include "chrome/browser/dom_ui/ntp_resource_cache.h" #include "chrome/browser/profile.h" #include "chrome/browser/resources_util.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/common/url_constants.h" #include "googleurl/src/gurl.h" diff --git a/chrome/browser/dom_ui/dom_ui_theme_source_unittest.cc b/chrome/browser/dom_ui/dom_ui_theme_source_unittest.cc index e3ceeef..54888b1 100644 --- a/chrome/browser/dom_ui/dom_ui_theme_source_unittest.cc +++ b/chrome/browser/dom_ui/dom_ui_theme_source_unittest.cc @@ -3,10 +3,10 @@ // found in the LICENSE file. #include "base/ref_counted_memory.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/chrome_thread.h" #include "chrome/browser/dom_ui/dom_ui_theme_source.h" #include "chrome/browser/profile.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/common/url_constants.h" #include "chrome/test/testing_profile.h" #include "grit/theme_resources.h" diff --git a/chrome/browser/dom_ui/ntp_resource_cache.cc b/chrome/browser/dom_ui/ntp_resource_cache.cc index 15a2016..bcef31d 100644 --- a/chrome/browser/dom_ui/ntp_resource_cache.cc +++ b/chrome/browser/dom_ui/ntp_resource_cache.cc @@ -18,12 +18,12 @@ #include "base/string_number_conversions.h" #include "base/utf_string_conversions.h" #include "base/values.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/chrome_thread.h" #include "chrome/browser/dom_ui/chrome_url_data_manager.h" #include "chrome/browser/google_util.h" #include "chrome/browser/pref_service.h" #include "chrome/browser/profile.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_constants.h" diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc index c7964b6..1f26277 100644 --- a/chrome/browser/extensions/extension_host.cc +++ b/chrome/browser/extensions/extension_host.cc @@ -15,7 +15,6 @@ #include "chrome/browser/browser.h" #include "chrome/browser/browser_list.h" #include "chrome/browser/browser_shutdown.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/browsing_instance.h" #include "chrome/browser/debugger/devtools_manager.h" #include "chrome/browser/dom_ui/dom_ui_factory.h" @@ -28,24 +27,25 @@ #include "chrome/browser/platform_util.h" #include "chrome/browser/pref_service.h" #include "chrome/browser/profile.h" -#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/renderer_host/render_process_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/renderer_host/render_widget_host.h" #include "chrome/browser/renderer_host/render_widget_host_view.h" #include "chrome/browser/renderer_host/site_instance.h" #include "chrome/browser/renderer_preferences_util.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tab_contents/tab_contents_view.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/common/bindings_policy.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/common/native_web_keyboard_event.h" #include "chrome/common/notification_service.h" #include "chrome/common/pref_names.h" -#include "chrome/common/view_types.h" #include "chrome/common/render_messages.h" #include "chrome/common/render_messages_params.h" #include "chrome/common/url_constants.h" +#include "chrome/common/view_types.h" #include "grit/browser_resources.h" #include "grit/generated_resources.h" #include "webkit/glue/context_menu.h" diff --git a/chrome/browser/extensions/theme_installed_infobar_delegate.cc b/chrome/browser/extensions/theme_installed_infobar_delegate.cc index 4fb501d..6d00c22 100644 --- a/chrome/browser/extensions/theme_installed_infobar_delegate.cc +++ b/chrome/browser/extensions/theme_installed_infobar_delegate.cc @@ -9,10 +9,10 @@ #include "app/l10n_util.h" #include "app/resource_bundle.h" #include "base/utf_string_conversions.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/notification_service.h" #include "grit/generated_resources.h" diff --git a/chrome/browser/gtk/browser_toolbar_gtk.cc b/chrome/browser/gtk/browser_toolbar_gtk.cc index a28abed..3f50b49 100644 --- a/chrome/browser/gtk/browser_toolbar_gtk.cc +++ b/chrome/browser/gtk/browser_toolbar_gtk.cc @@ -4,9 +4,9 @@ #include "chrome/browser/gtk/browser_toolbar_gtk.h" +#include #include #include -#include #include "app/gtk_dnd_util.h" #include "app/l10n_util.h" @@ -19,7 +19,6 @@ #include "base/singleton.h" #include "chrome/app/chrome_dll_resource.h" #include "chrome/browser/browser.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/encoding_menu_controller.h" #include "chrome/browser/gtk/accelerators_gtk.h" #include "chrome/browser/gtk/back_forward_button_gtk.h" @@ -39,6 +38,7 @@ #include "chrome/browser/pref_service.h" #include "chrome/browser/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/browser/upgrade_detector.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/notification_details.h" diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index c9950ff..934a04c 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -28,7 +28,6 @@ #include "chrome/browser/browser.h" #include "chrome/browser/browser_list.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/debugger/devtools_window.h" #include "chrome/browser/download/download_item_model.h" #include "chrome/browser/download/download_manager.h" @@ -74,6 +73,7 @@ #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tab_contents/tab_contents_view.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/browser/window_sizer.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/native_web_keyboard_event.h" diff --git a/chrome/browser/gtk/gtk_theme_provider.h b/chrome/browser/gtk/gtk_theme_provider.h index c78aaa3..33b1ec2 100644 --- a/chrome/browser/gtk/gtk_theme_provider.h +++ b/chrome/browser/gtk/gtk_theme_provider.h @@ -12,8 +12,8 @@ #include "app/gtk_integers.h" #include "app/gtk_signal.h" #include "base/scoped_ptr.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/gtk/owned_widget_gtk.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/common/notification_observer.h" #include "gfx/color_utils.h" diff --git a/chrome/browser/gtk/notifications/balloon_view_gtk.cc b/chrome/browser/gtk/notifications/balloon_view_gtk.cc index f447c75..717a560 100644 --- a/chrome/browser/gtk/notifications/balloon_view_gtk.cc +++ b/chrome/browser/gtk/notifications/balloon_view_gtk.cc @@ -15,7 +15,6 @@ #include "base/message_loop.h" #include "base/string_util.h" #include "chrome/browser/browser_list.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/browser_window.h" #include "chrome/browser/extensions/extension_host.h" #include "chrome/browser/extensions/extension_process_manager.h" @@ -32,6 +31,7 @@ #include "chrome/browser/profile.h" #include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/renderer_host/render_widget_host_view.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/notification_details.h" #include "chrome/common/notification_service.h" diff --git a/chrome/browser/gtk/tabs/dragged_tab_gtk.cc b/chrome/browser/gtk/tabs/dragged_tab_gtk.cc index 96aae10..27a1846 100644 --- a/chrome/browser/gtk/tabs/dragged_tab_gtk.cc +++ b/chrome/browser/gtk/tabs/dragged_tab_gtk.cc @@ -10,7 +10,6 @@ #include "app/x11_util.h" #include "base/i18n/rtl.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/gtk/gtk_util.h" #include "chrome/browser/gtk/tabs/tab_renderer_gtk.h" #include "chrome/browser/profile.h" @@ -18,6 +17,7 @@ #include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tabs/tab_strip_model.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "gfx/gtk_util.h" #include "third_party/skia/include/core/SkShader.h" diff --git a/chrome/browser/gtk/tabs/tab_strip_gtk.cc b/chrome/browser/gtk/tabs/tab_strip_gtk.cc index 696896f8..0f29263 100644 --- a/chrome/browser/gtk/tabs/tab_strip_gtk.cc +++ b/chrome/browser/gtk/tabs/tab_strip_gtk.cc @@ -12,7 +12,6 @@ #include "base/i18n/rtl.h" #include "base/string_util.h" #include "chrome/browser/autocomplete/autocomplete.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/gtk/browser_window_gtk.h" #include "chrome/browser/gtk/custom_button.h" #include "chrome/browser/gtk/gtk_theme_provider.h" @@ -20,6 +19,7 @@ #include "chrome/browser/gtk/tabs/dragged_tab_controller_gtk.h" #include "chrome/browser/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/common/notification_service.h" #include "chrome/common/notification_type.h" #include "gfx/gtk_util.h" diff --git a/chrome/browser/ntp_background_util.cc b/chrome/browser/ntp_background_util.cc index b36ce9f..b3926d5 100644 --- a/chrome/browser/ntp_background_util.cc +++ b/chrome/browser/ntp_background_util.cc @@ -5,7 +5,7 @@ #include "chrome/browser/ntp_background_util.h" #include "base/logging.h" -#include "chrome/browser/browser_theme_provider.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "gfx/canvas.h" #include "gfx/rect.h" #include "gfx/skia_util.h" diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc index 116b645..15a4641 100644 --- a/chrome/browser/profile.cc +++ b/chrome/browser/profile.cc @@ -14,7 +14,6 @@ #include "chrome/browser/background_contents_service.h" #include "chrome/browser/browser_list.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/chrome_thread.h" #include "chrome/browser/download/download_manager.h" #include "chrome/browser/find_bar_state.h" @@ -23,6 +22,7 @@ #include "chrome/browser/notifications/desktop_notification_service.h" #include "chrome/browser/ssl/ssl_host_state.h" #include "chrome/browser/sync/profile_sync_service.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" diff --git a/chrome/browser/profile_impl.cc b/chrome/browser/profile_impl.cc index 4d976d0..55a3f76 100644 --- a/chrome/browser/profile_impl.cc +++ b/chrome/browser/profile_impl.cc @@ -22,7 +22,6 @@ #include "chrome/browser/browser_list.h" #include "chrome/browser/browser_prefs.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/chrome_thread.h" #include "chrome/browser/dom_ui/ntp_resource_cache.h" #include "chrome/browser/download/download_manager.h" @@ -36,8 +35,6 @@ #include "chrome/browser/find_bar_state.h" #include "chrome/browser/geolocation/geolocation_content_settings_map.h" #include "chrome/browser/geolocation/geolocation_permission_context.h" -#include "chrome/browser/spellcheck_host.h" -#include "chrome/browser/transport_security_persister.h" #include "chrome/browser/history/history.h" #include "chrome/browser/history/top_sites.h" #include "chrome/browser/host_content_settings_map.h" @@ -56,16 +53,19 @@ #include "chrome/browser/search_engines/template_url_model.h" #include "chrome/browser/sessions/session_service.h" #include "chrome/browser/sessions/tab_restore_service.h" +#include "chrome/browser/spellcheck_host.h" #include "chrome/browser/ssl/ssl_host_state.h" #include "chrome/browser/status_icons/status_tray.h" -#include "chrome/browser/sync/profile_sync_service.h" #include "chrome/browser/sync/profile_sync_factory_impl.h" +#include "chrome/browser/sync/profile_sync_service.h" #include "chrome/browser/tabs/pinned_tab_service.h" +#include "chrome/browser/themes/browser_theme_provider.h" +#include "chrome/browser/transport_security_persister.h" #include "chrome/browser/user_style_sheet_watcher.h" -#include "chrome/browser/visitedlink_master.h" #include "chrome/browser/visitedlink_event_listener.h" -#include "chrome/browser/webdata/web_data_service.h" +#include "chrome/browser/visitedlink_master.h" #include "chrome/browser/web_resource/web_resource_service.h" +#include "chrome/browser/webdata/web_data_service.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" diff --git a/chrome/browser/sync/glue/theme_change_processor.cc b/chrome/browser/sync/glue/theme_change_processor.cc index 58c3df3..bdf5e47 100644 --- a/chrome/browser/sync/glue/theme_change_processor.cc +++ b/chrome/browser/sync/glue/theme_change_processor.cc @@ -5,11 +5,11 @@ #include "chrome/browser/sync/glue/theme_change_processor.h" #include "base/logging.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/profile.h" #include "chrome/browser/sync/engine/syncapi.h" #include "chrome/browser/sync/glue/theme_util.h" #include "chrome/browser/sync/protocol/theme_specifics.pb.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/notification_details.h" #include "chrome/common/notification_source.h" diff --git a/chrome/browser/sync/glue/theme_model_associator.cc b/chrome/browser/sync/glue/theme_model_associator.cc index 3936f62..2dd02c2 100644 --- a/chrome/browser/sync/glue/theme_model_associator.cc +++ b/chrome/browser/sync/glue/theme_model_associator.cc @@ -7,12 +7,12 @@ #include "base/basictypes.h" #include "base/logging.h" #include "base/utf_string_conversions.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/sync/engine/syncapi.h" #include "chrome/browser/sync/glue/sync_backend_host.h" #include "chrome/browser/sync/glue/theme_util.h" #include "chrome/browser/sync/profile_sync_service.h" #include "chrome/browser/sync/protocol/theme_specifics.pb.h" +#include "chrome/browser/themes/browser_theme_provider.h" namespace browser_sync { diff --git a/chrome/browser/themes/browser_theme_pack.cc b/chrome/browser/themes/browser_theme_pack.cc new file mode 100644 index 0000000..1934700 --- /dev/null +++ b/chrome/browser/themes/browser_theme_pack.cc @@ -0,0 +1,1043 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/themes/browser_theme_pack.h" + +#include "app/resource_bundle.h" +#include "base/data_pack.h" +#include "base/stl_util-inl.h" +#include "base/string_util.h" +#include "base/utf_string_conversions.h" +#include "chrome/browser/chrome_thread.h" +#include "chrome/browser/themes/browser_theme_provider.h" +#include "gfx/codec/png_codec.h" +#include "gfx/skbitmap_operations.h" +#include "grit/app_resources.h" +#include "grit/theme_resources.h" +#include "net/base/file_stream.h" +#include "net/base/net_errors.h" +#include "third_party/skia/include/core/SkCanvas.h" + +namespace { + +// Version number of the current theme pack. We just throw out and rebuild +// theme packs that aren't int-equal to this. +const int kThemePackVersion = 15; + +// IDs that are in the DataPack won't clash with the positive integer +// int32_t. kHeaderID should always have the maximum value because we want the +// "header" to be written last. That way we can detect whether the pack was +// successfully written and ignore and regenerate if it was only partially +// written (i.e. chrome crashed on a different thread while writing the pack). +const int kHeaderID = UINT_MAX - 1; +const int kTintsID = UINT_MAX - 2; +const int kColorsID = UINT_MAX - 3; +const int kDisplayPropertiesID = UINT_MAX - 4; +const int kSourceImagesID = UINT_MAX - 5; + +// Static size of the tint/color/display property arrays that are mmapped. +const int kTintArraySize = 6; +const int kColorArraySize = 19; +const int kDisplayPropertySize = 3; + +// The sum of kFrameBorderThickness and kNonClientRestoredExtraThickness from +// OpaqueBrowserFrameView. +const int kRestoredTabVerticalOffset = 15; + +// Persistent constants for the main images that we need. These have the same +// names as their IDR_* counterparts but these values will always stay the +// same. +const int PRS_THEME_FRAME = 1; +const int PRS_THEME_FRAME_INACTIVE = 2; +const int PRS_THEME_FRAME_INCOGNITO = 3; +const int PRS_THEME_FRAME_INCOGNITO_INACTIVE = 4; +const int PRS_THEME_TOOLBAR = 5; +const int PRS_THEME_TAB_BACKGROUND = 6; +const int PRS_THEME_TAB_BACKGROUND_INCOGNITO = 7; +const int PRS_THEME_TAB_BACKGROUND_V = 8; +const int PRS_THEME_NTP_BACKGROUND = 9; +const int PRS_THEME_FRAME_OVERLAY = 10; +const int PRS_THEME_FRAME_OVERLAY_INACTIVE = 11; +const int PRS_THEME_BUTTON_BACKGROUND = 12; +const int PRS_THEME_NTP_ATTRIBUTION = 13; +const int PRS_THEME_WINDOW_CONTROL_BACKGROUND = 14; + +struct PersistingImagesTable { + // A non-changing integer ID meant to be saved in theme packs. This ID must + // not change between versions of chrome. + int persistent_id; + + // The IDR that depends on the whims of GRIT and therefore changes whenever + // someone adds a new resource. + int idr_id; + + // String to check for when parsing theme manifests or NULL if this isn't + // supposed to be changeable by the user. + const char* key; +}; + +// IDR_* resource names change whenever new resources are added; use persistent +// IDs when storing to a cached pack. +PersistingImagesTable kPersistingImages[] = { + { PRS_THEME_FRAME, IDR_THEME_FRAME, + "theme_frame" }, + { PRS_THEME_FRAME_INACTIVE, IDR_THEME_FRAME_INACTIVE, + "theme_frame_inactive" }, + { PRS_THEME_FRAME_INCOGNITO, IDR_THEME_FRAME_INCOGNITO, + "theme_frame_incognito" }, + { PRS_THEME_FRAME_INCOGNITO_INACTIVE, IDR_THEME_FRAME_INCOGNITO_INACTIVE, + "theme_frame_incognito_inactive" }, + { PRS_THEME_TOOLBAR, IDR_THEME_TOOLBAR, + "theme_toolbar" }, + { PRS_THEME_TAB_BACKGROUND, IDR_THEME_TAB_BACKGROUND, + "theme_tab_background" }, + { PRS_THEME_TAB_BACKGROUND_INCOGNITO, IDR_THEME_TAB_BACKGROUND_INCOGNITO, + "theme_tab_background_incognito" }, + { PRS_THEME_TAB_BACKGROUND_V, IDR_THEME_TAB_BACKGROUND_V, + "theme_tab_background_v"}, + { PRS_THEME_NTP_BACKGROUND, IDR_THEME_NTP_BACKGROUND, + "theme_ntp_background" }, + { PRS_THEME_FRAME_OVERLAY, IDR_THEME_FRAME_OVERLAY, + "theme_frame_overlay" }, + { PRS_THEME_FRAME_OVERLAY_INACTIVE, IDR_THEME_FRAME_OVERLAY_INACTIVE, + "theme_frame_overlay_inactive" }, + { PRS_THEME_BUTTON_BACKGROUND, IDR_THEME_BUTTON_BACKGROUND, + "theme_button_background" }, + { PRS_THEME_NTP_ATTRIBUTION, IDR_THEME_NTP_ATTRIBUTION, + "theme_ntp_attribution" }, + { PRS_THEME_WINDOW_CONTROL_BACKGROUND, IDR_THEME_WINDOW_CONTROL_BACKGROUND, + "theme_window_control_background"}, + + // The rest of these entries have no key because they can't be overridden + // from the json manifest. + { 15, IDR_BACK, NULL }, + { 16, IDR_BACK_D, NULL }, + { 17, IDR_BACK_H, NULL }, + { 18, IDR_BACK_P, NULL }, + { 19, IDR_FORWARD, NULL }, + { 20, IDR_FORWARD_D, NULL }, + { 21, IDR_FORWARD_H, NULL }, + { 22, IDR_FORWARD_P, NULL }, + { 23, IDR_HOME, NULL }, + { 24, IDR_HOME_H, NULL }, + { 25, IDR_HOME_P, NULL }, + { 26, IDR_RELOAD, NULL }, + { 27, IDR_RELOAD_H, NULL }, + { 28, IDR_RELOAD_P, NULL }, + { 29, IDR_STOP, NULL }, + { 30, IDR_STOP_D, NULL }, + { 31, IDR_STOP_H, NULL }, + { 32, IDR_STOP_P, NULL }, + { 33, IDR_LOCATIONBG_C, NULL }, + { 34, IDR_LOCATIONBG_L, NULL }, + { 35, IDR_LOCATIONBG_R, NULL }, + { 36, IDR_BROWSER_ACTIONS_OVERFLOW, NULL }, + { 37, IDR_BROWSER_ACTIONS_OVERFLOW_H, NULL }, + { 38, IDR_BROWSER_ACTIONS_OVERFLOW_P, NULL }, + { 39, IDR_TOOLS, NULL }, + { 40, IDR_TOOLS_H, NULL }, + { 41, IDR_TOOLS_P, NULL }, + { 42, IDR_MENU_DROPARROW, NULL }, + { 43, IDR_THROBBER, NULL }, + { 44, IDR_THROBBER_WAITING, NULL }, + { 45, IDR_THROBBER_LIGHT, NULL }, +}; + +int GetPersistentIDByName(const std::string& key) { + for (size_t i = 0; i < arraysize(kPersistingImages); ++i) { + if (kPersistingImages[i].key != NULL && + base::strcasecmp(key.c_str(), kPersistingImages[i].key) == 0) { + return kPersistingImages[i].persistent_id; + } + } + + return -1; +} + +int GetPersistentIDByIDR(int idr) { + for (size_t i = 0; i < arraysize(kPersistingImages); ++i) { + if (kPersistingImages[i].idr_id == idr) { + return kPersistingImages[i].persistent_id; + } + } + + return -1; +} + +struct StringToIntTable { + const char* key; + int id; +}; + +// Strings used by themes to identify tints in the JSON. +StringToIntTable kTintTable[] = { + { "buttons", BrowserThemeProvider::TINT_BUTTONS }, + { "frame", BrowserThemeProvider::TINT_FRAME }, + { "frame_inactive", BrowserThemeProvider::TINT_FRAME_INACTIVE }, + { "frame_incognito", BrowserThemeProvider::TINT_FRAME_INCOGNITO }, + { "frame_incognito_inactive", + BrowserThemeProvider::TINT_FRAME_INCOGNITO_INACTIVE }, + { "background_tab", BrowserThemeProvider::TINT_BACKGROUND_TAB }, + { NULL, 0 } +}; + +// Strings used by themes to identify colors in the JSON. +StringToIntTable kColorTable[] = { + { "frame", BrowserThemeProvider::COLOR_FRAME }, + { "frame_inactive", BrowserThemeProvider::COLOR_FRAME_INACTIVE }, + { "frame_incognito", BrowserThemeProvider::COLOR_FRAME_INCOGNITO }, + { "frame_incognito_inactive", + BrowserThemeProvider::COLOR_FRAME_INCOGNITO_INACTIVE }, + { "toolbar", BrowserThemeProvider::COLOR_TOOLBAR }, + { "tab_text", BrowserThemeProvider::COLOR_TAB_TEXT }, + { "tab_background_text", BrowserThemeProvider::COLOR_BACKGROUND_TAB_TEXT }, + { "bookmark_text", BrowserThemeProvider::COLOR_BOOKMARK_TEXT }, + { "ntp_background", BrowserThemeProvider::COLOR_NTP_BACKGROUND }, + { "ntp_text", BrowserThemeProvider::COLOR_NTP_TEXT }, + { "ntp_link", BrowserThemeProvider::COLOR_NTP_LINK }, + { "ntp_link_underline", BrowserThemeProvider::COLOR_NTP_LINK_UNDERLINE }, + { "ntp_header", BrowserThemeProvider::COLOR_NTP_HEADER }, + { "ntp_section", BrowserThemeProvider::COLOR_NTP_SECTION }, + { "ntp_section_text", BrowserThemeProvider::COLOR_NTP_SECTION_TEXT }, + { "ntp_section_link", BrowserThemeProvider::COLOR_NTP_SECTION_LINK }, + { "ntp_section_link_underline", + BrowserThemeProvider::COLOR_NTP_SECTION_LINK_UNDERLINE }, + { "control_background", BrowserThemeProvider::COLOR_CONTROL_BACKGROUND }, + { "button_background", BrowserThemeProvider::COLOR_BUTTON_BACKGROUND }, + { NULL, 0 } +}; + +// Strings used by themes to identify display properties keys in JSON. +StringToIntTable kDisplayProperties[] = { + { "ntp_background_alignment", + BrowserThemeProvider::NTP_BACKGROUND_ALIGNMENT }, + { "ntp_background_repeat", BrowserThemeProvider::NTP_BACKGROUND_TILING }, + { "ntp_logo_alternate", BrowserThemeProvider::NTP_LOGO_ALTERNATE }, + { NULL, 0 } +}; + +// Strings used by the tiling values in JSON. +StringToIntTable kTilingStrings[] = { + { "no-repeat", BrowserThemeProvider::NO_REPEAT }, + { "repeat-x", BrowserThemeProvider::REPEAT_X }, + { "repeat-y", BrowserThemeProvider::REPEAT_Y }, + { "repeat", BrowserThemeProvider::REPEAT }, + { NULL, 0 } +}; + +int GetIntForString(const std::string& key, StringToIntTable* table) { + for (int i = 0; table[i].key != NULL; ++i) { + if (base::strcasecmp(key.c_str(), table[i].key) == 0) { + return table[i].id; + } + } + + return -1; +} + +struct IntToIntTable { + int key; + int value; +}; + +// Mapping used in GenerateFrameImages() to associate frame images with the +// tint ID that should maybe be applied to it. +IntToIntTable kFrameTintMap[] = { + { PRS_THEME_FRAME, BrowserThemeProvider::TINT_FRAME }, + { PRS_THEME_FRAME_INACTIVE, BrowserThemeProvider::TINT_FRAME_INACTIVE }, + { PRS_THEME_FRAME_OVERLAY, BrowserThemeProvider::TINT_FRAME }, + { PRS_THEME_FRAME_OVERLAY_INACTIVE, + BrowserThemeProvider::TINT_FRAME_INACTIVE }, + { PRS_THEME_FRAME_INCOGNITO, BrowserThemeProvider::TINT_FRAME_INCOGNITO }, + { PRS_THEME_FRAME_INCOGNITO_INACTIVE, + BrowserThemeProvider::TINT_FRAME_INCOGNITO_INACTIVE } +}; + +// Mapping used in GenerateTabBackgroundImages() to associate what frame image +// goes with which tab background. +IntToIntTable kTabBackgroundMap[] = { + { PRS_THEME_TAB_BACKGROUND, PRS_THEME_FRAME }, + { PRS_THEME_TAB_BACKGROUND_INCOGNITO, PRS_THEME_FRAME_INCOGNITO } +}; + +// A list of images that don't need tinting or any other modification and can +// be byte-copied directly into the finished DataPack. This should contain the +// persistent IDs for all themeable image IDs that aren't in kFrameTintMap or +// kTabBackgroundMap. +const int kPreloadIDs[] = { + PRS_THEME_TOOLBAR, + PRS_THEME_NTP_BACKGROUND, + PRS_THEME_BUTTON_BACKGROUND, + PRS_THEME_NTP_ATTRIBUTION, + PRS_THEME_WINDOW_CONTROL_BACKGROUND +}; + +// Returns a piece of memory with the contents of the file |path|. +RefCountedMemory* ReadFileData(const FilePath& path) { + 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(avail); + std::vector raw_data; + raw_data.resize(size); + char* data = reinterpret_cast(&(raw_data.front())); + if (file.ReadUntilComplete(data, size) == avail) + return RefCountedBytes::TakeVector(&raw_data); + } + } + } + + return NULL; +} + +// Does error checking for invalid incoming data while trying to read an +// floating point value. +bool ValidRealValue(ListValue* tint_list, int index, double* out) { + if (tint_list->GetReal(index, out)) + return true; + + int value = 0; + if (tint_list->GetInteger(index, &value)) { + *out = value; + return true; + } + + return false; +} + +} // namespace + +BrowserThemePack::~BrowserThemePack() { + if (!data_pack_.get()) { + delete header_; + delete [] tints_; + delete [] colors_; + delete [] display_properties_; + delete [] source_images_; + } + + STLDeleteValues(&prepared_images_); + STLDeleteValues(&loaded_images_); +} + +// static +BrowserThemePack* BrowserThemePack::BuildFromExtension(Extension* extension) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + DCHECK(extension); + DCHECK(extension->is_theme()); + + BrowserThemePack* pack = new BrowserThemePack; + pack->BuildHeader(extension); + pack->BuildTintsFromJSON(extension->GetThemeTints()); + pack->BuildColorsFromJSON(extension->GetThemeColors()); + pack->BuildDisplayPropertiesFromJSON(extension->GetThemeDisplayProperties()); + + // Builds the images. (Image building is dependent on tints). + FilePathMap file_paths; + pack->ParseImageNamesFromJSON(extension->GetThemeImages(), + extension->path(), + &file_paths); + pack->BuildSourceImagesArray(file_paths); + + if (!pack->LoadRawBitmapsTo(file_paths, &pack->prepared_images_)) + return NULL; + + pack->GenerateFrameImages(&pack->prepared_images_); + +#if !defined(OS_MACOSX) + // OSX uses its own special buttons that are PDFs that do odd sorts of vector + // graphics tricks. Other platforms use bitmaps and we must pre-tint them. + pack->GenerateTintedButtons( + pack->GetTintInternal(BrowserThemeProvider::TINT_BUTTONS), + &pack->prepared_images_); +#endif + + pack->GenerateTabBackgroundImages(&pack->prepared_images_); + + // The BrowserThemePack is now in a consistent state. + return pack; +} + +// static +scoped_refptr BrowserThemePack::BuildFromDataPack( + FilePath path, const std::string& expected_id) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + scoped_refptr pack = new BrowserThemePack; + pack->data_pack_.reset(new base::DataPack); + + if (!pack->data_pack_->Load(path)) { + LOG(ERROR) << "Failed to load theme data pack."; + return NULL; + } + + base::StringPiece pointer; + if (!pack->data_pack_->GetStringPiece(kHeaderID, &pointer)) + return NULL; + pack->header_ = reinterpret_cast(const_cast( + pointer.data())); + + if (pack->header_->version != kThemePackVersion) { + DLOG(ERROR) << "BuildFromDataPack failure! Version mismatch!"; + return NULL; + } + // TODO(erg): Check endianess once DataPack works on the other endian. + std::string theme_id(reinterpret_cast(pack->header_->theme_id), + Extension::kIdSize); + std::string truncated_id = expected_id.substr(0, Extension::kIdSize); + if (theme_id != truncated_id) { + DLOG(ERROR) << "Wrong id: " << theme_id << " vs " << expected_id; + return NULL; + } + + if (!pack->data_pack_->GetStringPiece(kTintsID, &pointer)) + return NULL; + pack->tints_ = reinterpret_cast(const_cast( + pointer.data())); + + if (!pack->data_pack_->GetStringPiece(kColorsID, &pointer)) + return NULL; + pack->colors_ = + reinterpret_cast(const_cast(pointer.data())); + + if (!pack->data_pack_->GetStringPiece(kDisplayPropertiesID, &pointer)) + return NULL; + pack->display_properties_ = reinterpret_cast( + const_cast(pointer.data())); + + if (!pack->data_pack_->GetStringPiece(kSourceImagesID, &pointer)) + return NULL; + pack->source_images_ = reinterpret_cast( + const_cast(pointer.data())); + + return pack; +} + +bool BrowserThemePack::WriteToDisk(FilePath path) const { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); + // Add resources for each of the property arrays. + RawDataForWriting resources; + resources[kHeaderID] = base::StringPiece( + reinterpret_cast(header_), sizeof(BrowserThemePackHeader)); + resources[kTintsID] = base::StringPiece( + reinterpret_cast(tints_), sizeof(TintEntry[kTintArraySize])); + resources[kColorsID] = base::StringPiece( + reinterpret_cast(colors_), + sizeof(ColorPair[kColorArraySize])); + resources[kDisplayPropertiesID] = base::StringPiece( + reinterpret_cast(display_properties_), + sizeof(DisplayPropertyPair[kDisplayPropertySize])); + + int source_count = 1; + int* end = source_images_; + for (; *end != -1 ; end++) + source_count++; + resources[kSourceImagesID] = base::StringPiece( + reinterpret_cast(source_images_), + source_count * sizeof(*source_images_)); + + AddRawImagesTo(image_memory_, &resources); + + RawImages reencoded_images; + RepackImages(prepared_images_, &reencoded_images); + AddRawImagesTo(reencoded_images, &resources); + + return base::DataPack::WritePack(path, resources); +} + +bool BrowserThemePack::GetTint(int id, color_utils::HSL* hsl) const { + if (tints_) { + for (int i = 0; i < kTintArraySize; ++i) { + if (tints_[i].id == id) { + hsl->h = tints_[i].h; + hsl->s = tints_[i].s; + hsl->l = tints_[i].l; + return true; + } + } + } + + return false; +} + +bool BrowserThemePack::GetColor(int id, SkColor* color) const { + if (colors_) { + for (int i = 0; i < kColorArraySize; ++i) { + if (colors_[i].id == id) { + *color = colors_[i].color; + return true; + } + } + } + + return false; +} + +bool BrowserThemePack::GetDisplayProperty(int id, int* result) const { + if (display_properties_) { + for (int i = 0; i < kDisplayPropertySize; ++i) { + if (display_properties_[i].id == id) { + *result = display_properties_[i].property; + return true; + } + } + } + + return false; +} + +SkBitmap* BrowserThemePack::GetBitmapNamed(int idr_id) const { + int prs_id = GetPersistentIDByIDR(idr_id); + if (prs_id == -1) + return NULL; + + // Check our cache of prepared images, first. + ImageCache::const_iterator image_iter = prepared_images_.find(prs_id); + if (image_iter != prepared_images_.end()) + return image_iter->second; + + // Check if we've already loaded this image. + image_iter = loaded_images_.find(prs_id); + if (image_iter != loaded_images_.end()) + return image_iter->second; + + scoped_refptr memory; + if (data_pack_.get()) { + memory = data_pack_->GetStaticMemory(prs_id); + } else { + RawImages::const_iterator it = image_memory_.find(prs_id); + if (it != image_memory_.end()) { + memory = it->second; + } + } + + if (memory.get()) { + // Decode the PNG. + SkBitmap bitmap; + if (!gfx::PNGCodec::Decode(memory->front(), memory->size(), + &bitmap)) { + NOTREACHED() << "Unable to decode theme image resource " << idr_id + << " from saved DataPack."; + return NULL; + } + + SkBitmap* ret = new SkBitmap(bitmap); + loaded_images_[prs_id] = ret; + + return ret; + } + + return NULL; +} + +RefCountedMemory* BrowserThemePack::GetRawData(int idr_id) const { + RefCountedMemory* memory = NULL; + int prs_id = GetPersistentIDByIDR(idr_id); + + if (prs_id != -1) { + if (data_pack_.get()) { + memory = data_pack_->GetStaticMemory(prs_id); + } else { + RawImages::const_iterator it = image_memory_.find(prs_id); + if (it != image_memory_.end()) { + memory = it->second; + } + } + } + + return memory; +} + +bool BrowserThemePack::HasCustomImage(int idr_id) const { + int prs_id = GetPersistentIDByIDR(idr_id); + if (prs_id == -1) + return false; + + int* img = source_images_; + for (; *img != -1; ++img) { + if (*img == prs_id) + return true; + } + + return false; +} + +// private: + +BrowserThemePack::BrowserThemePack() + : header_(NULL), + tints_(NULL), + colors_(NULL), + display_properties_(NULL), + source_images_(NULL) { +} + +void BrowserThemePack::BuildHeader(Extension* extension) { + header_ = new BrowserThemePackHeader; + header_->version = kThemePackVersion; + + // TODO(erg): Need to make this endian safe on other computers. Prerequisite + // is that base::DataPack removes this same check. +#if defined(__BYTE_ORDER) + // Linux check + COMPILE_ASSERT(__BYTE_ORDER == __LITTLE_ENDIAN, + datapack_assumes_little_endian); +#elif defined(__BIG_ENDIAN__) + // Mac check + #error DataPack assumes little endian +#endif + header_->little_endian = 1; + + const std::string& id = extension->id(); + memcpy(header_->theme_id, id.c_str(), Extension::kIdSize); +} + +void BrowserThemePack::BuildTintsFromJSON(DictionaryValue* tints_value) { + tints_ = new TintEntry[kTintArraySize]; + for (int i = 0; i < kTintArraySize; ++i) { + tints_[i].id = -1; + tints_[i].h = -1; + tints_[i].s = -1; + tints_[i].l = -1; + } + + if (!tints_value) + return; + + // Parse the incoming data from |tints_value| into an intermediary structure. + std::map temp_tints; + for (DictionaryValue::key_iterator iter(tints_value->begin_keys()); + iter != tints_value->end_keys(); ++iter) { + ListValue* tint_list; + if (tints_value->GetList(*iter, &tint_list) && + (tint_list->GetSize() == 3)) { + color_utils::HSL hsl = { -1, -1, -1 }; + + if (ValidRealValue(tint_list, 0, &hsl.h) && + ValidRealValue(tint_list, 1, &hsl.s) && + ValidRealValue(tint_list, 2, &hsl.l)) { + int id = GetIntForString(*iter, kTintTable); + if (id != -1) { + temp_tints[id] = hsl; + } + } + } + } + + // Copy data from the intermediary data structure to the array. + int count = 0; + for (std::map::const_iterator it = + temp_tints.begin(); it != temp_tints.end() && count < kTintArraySize; + ++it, ++count) { + tints_[count].id = it->first; + tints_[count].h = it->second.h; + tints_[count].s = it->second.s; + tints_[count].l = it->second.l; + } +} + +void BrowserThemePack::BuildColorsFromJSON(DictionaryValue* colors_value) { + colors_ = new ColorPair[kColorArraySize]; + for (int i = 0; i < kColorArraySize; ++i) { + colors_[i].id = -1; + colors_[i].color = SkColorSetRGB(0, 0, 0); + } + + std::map temp_colors; + if (colors_value) + ReadColorsFromJSON(colors_value, &temp_colors); + GenerateMissingColors(&temp_colors); + + // Copy data from the intermediary data structure to the array. + int count = 0; + for (std::map::const_iterator it = temp_colors.begin(); + it != temp_colors.end() && count < kColorArraySize; ++it, ++count) { + colors_[count].id = it->first; + colors_[count].color = it->second; + } +} + +void BrowserThemePack::ReadColorsFromJSON( + DictionaryValue* colors_value, + std::map* temp_colors) { + // Parse the incoming data from |colors_value| into an intermediary structure. + for (DictionaryValue::key_iterator iter(colors_value->begin_keys()); + iter != colors_value->end_keys(); ++iter) { + ListValue* color_list; + if (colors_value->GetList(*iter, &color_list) && + ((color_list->GetSize() == 3) || (color_list->GetSize() == 4))) { + SkColor color = SK_ColorWHITE; + int r, g, b; + if (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)) { + color = SkColorSetARGB(static_cast(alpha * 255), r, g, b); + } else if (color_list->GetInteger(3, &alpha_int) && + (alpha_int == 0 || alpha_int == 1)) { + color = SkColorSetARGB(alpha_int ? 255 : 0, r, g, b); + } else { + // Invalid entry for part 4. + continue; + } + } else { + color = SkColorSetRGB(r, g, b); + } + + int id = GetIntForString(*iter, kColorTable); + if (id != -1) { + (*temp_colors)[id] = color; + } + } + } + } +} + +void BrowserThemePack::GenerateMissingColors( + std::map* colors) { + // Generate link colors, if missing. (See GetColor()). + if (!colors->count(BrowserThemeProvider::COLOR_NTP_HEADER) && + colors->count(BrowserThemeProvider::COLOR_NTP_SECTION)) { + (*colors)[BrowserThemeProvider::COLOR_NTP_HEADER] = + (*colors)[BrowserThemeProvider::COLOR_NTP_SECTION]; + } + + if (!colors->count(BrowserThemeProvider::COLOR_NTP_SECTION_LINK_UNDERLINE) && + colors->count(BrowserThemeProvider::COLOR_NTP_SECTION_LINK)) { + SkColor color_section_link = + (*colors)[BrowserThemeProvider::COLOR_NTP_SECTION_LINK]; + (*colors)[BrowserThemeProvider::COLOR_NTP_SECTION_LINK_UNDERLINE] = + SkColorSetA(color_section_link, SkColorGetA(color_section_link) / 3); + } + + if (!colors->count(BrowserThemeProvider::COLOR_NTP_LINK_UNDERLINE) && + colors->count(BrowserThemeProvider::COLOR_NTP_LINK)) { + SkColor color_link = (*colors)[BrowserThemeProvider::COLOR_NTP_LINK]; + (*colors)[BrowserThemeProvider::COLOR_NTP_LINK_UNDERLINE] = + SkColorSetA(color_link, SkColorGetA(color_link) / 3); + } + + // Generate frame colors, if missing. (See GenerateFrameColors()). + SkColor frame; + std::map::const_iterator it = + colors->find(BrowserThemeProvider::COLOR_FRAME); + if (it != colors->end()) { + frame = it->second; + } else { + frame = BrowserThemeProvider::GetDefaultColor( + BrowserThemeProvider::COLOR_FRAME); + } + + if (!colors->count(BrowserThemeProvider::COLOR_FRAME)) { + (*colors)[BrowserThemeProvider::COLOR_FRAME] = + HSLShift(frame, GetTintInternal(BrowserThemeProvider::TINT_FRAME)); + } + if (!colors->count(BrowserThemeProvider::COLOR_FRAME_INACTIVE)) { + (*colors)[BrowserThemeProvider::COLOR_FRAME_INACTIVE] = + HSLShift(frame, GetTintInternal( + BrowserThemeProvider::TINT_FRAME_INACTIVE)); + } + if (!colors->count(BrowserThemeProvider::COLOR_FRAME_INCOGNITO)) { + (*colors)[BrowserThemeProvider::COLOR_FRAME_INCOGNITO] = + HSLShift(frame, GetTintInternal( + BrowserThemeProvider::TINT_FRAME_INCOGNITO)); + } + if (!colors->count(BrowserThemeProvider::COLOR_FRAME_INCOGNITO_INACTIVE)) { + (*colors)[BrowserThemeProvider::COLOR_FRAME_INCOGNITO_INACTIVE] = + HSLShift(frame, GetTintInternal( + BrowserThemeProvider::TINT_FRAME_INCOGNITO_INACTIVE)); + } +} + +void BrowserThemePack::BuildDisplayPropertiesFromJSON( + DictionaryValue* display_properties_value) { + display_properties_ = new DisplayPropertyPair[kDisplayPropertySize]; + for (int i = 0; i < kDisplayPropertySize; ++i) { + display_properties_[i].id = -1; + display_properties_[i].property = 0; + } + + if (!display_properties_value) + return; + + std::map temp_properties; + for (DictionaryValue::key_iterator iter( + display_properties_value->begin_keys()); + iter != display_properties_value->end_keys(); ++iter) { + int property_id = GetIntForString(*iter, kDisplayProperties); + switch (property_id) { + case BrowserThemeProvider::NTP_BACKGROUND_ALIGNMENT: { + std::string val; + if (display_properties_value->GetString(*iter, &val)) { + temp_properties[BrowserThemeProvider::NTP_BACKGROUND_ALIGNMENT] = + BrowserThemeProvider::StringToAlignment(val); + } + break; + } + case BrowserThemeProvider::NTP_BACKGROUND_TILING: { + std::string val; + if (display_properties_value->GetString(*iter, &val)) { + temp_properties[BrowserThemeProvider::NTP_BACKGROUND_TILING] = + GetIntForString(val, kTilingStrings); + } + break; + } + case BrowserThemeProvider::NTP_LOGO_ALTERNATE: { + int val = 0; + if (display_properties_value->GetInteger(*iter, &val)) + temp_properties[BrowserThemeProvider::NTP_LOGO_ALTERNATE] = val; + break; + } + } + } + + // Copy data from the intermediary data structure to the array. + int count = 0; + for (std::map::const_iterator it = temp_properties.begin(); + it != temp_properties.end() && count < kDisplayPropertySize; + ++it, ++count) { + display_properties_[count].id = it->first; + display_properties_[count].property = it->second; + } +} + +void BrowserThemePack::ParseImageNamesFromJSON( + DictionaryValue* images_value, + FilePath images_path, + FilePathMap* file_paths) const { + 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->GetString(*iter, &val)) { + int id = GetPersistentIDByName(*iter); + if (id != -1) + (*file_paths)[id] = images_path.AppendASCII(val); + } + } +} + +void BrowserThemePack::BuildSourceImagesArray(const FilePathMap& file_paths) { + std::vector ids; + for (FilePathMap::const_iterator it = file_paths.begin(); + it != file_paths.end(); ++it) { + ids.push_back(it->first); + } + + source_images_ = new int[ids.size() + 1]; + std::copy(ids.begin(), ids.end(), source_images_); + source_images_[ids.size()] = -1; +} + +bool BrowserThemePack::LoadRawBitmapsTo( + const FilePathMap& file_paths, + ImageCache* raw_bitmaps) { + for (FilePathMap::const_iterator it = file_paths.begin(); + it != file_paths.end(); ++it) { + scoped_refptr raw_data(ReadFileData(it->second)); + if (!raw_data.get()) { + LOG(ERROR) << "Could not load theme image"; + return false; + } + + int id = it->first; + + // Some images need to go directly into |image_memory_|. No modification is + // necessary or desirable. + bool is_copyable = false; + for (size_t i = 0; i < arraysize(kPreloadIDs); ++i) { + if (kPreloadIDs[i] == id) { + is_copyable = true; + break; + } + } + + if (is_copyable) { + image_memory_[id] = raw_data; + } else if (raw_data.get() && raw_data->size()) { + // Decode the PNG. + SkBitmap bitmap; + if (gfx::PNGCodec::Decode(raw_data->front(), raw_data->size(), + &bitmap)) { + (*raw_bitmaps)[it->first] = new SkBitmap(bitmap); + } else { + NOTREACHED() << "Unable to decode theme image resource " << it->first; + } + } + } + + return true; +} + +void BrowserThemePack::GenerateFrameImages(ImageCache* bitmaps) const { + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + + // Create all the output bitmaps in a separate cache and move them back into + // the input bitmaps because there can be name collisions. + ImageCache temp_output; + + for (size_t i = 0; i < arraysize(kFrameTintMap); ++i) { + int prs_id = kFrameTintMap[i].key; + scoped_ptr 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 prs_base_id; + + if (prs_id == PRS_THEME_FRAME_INCOGNITO_INACTIVE) { + prs_base_id = bitmaps->count(PRS_THEME_FRAME_INCOGNITO) ? + PRS_THEME_FRAME_INCOGNITO : PRS_THEME_FRAME; + } else if (prs_id == PRS_THEME_FRAME_OVERLAY_INACTIVE) { + prs_base_id = PRS_THEME_FRAME_OVERLAY; + } else if (prs_id == PRS_THEME_FRAME_INACTIVE) { + prs_base_id = PRS_THEME_FRAME; + } else if (prs_id == PRS_THEME_FRAME_INCOGNITO && + !bitmaps->count(PRS_THEME_FRAME_INCOGNITO)) { + prs_base_id = PRS_THEME_FRAME; + } else { + prs_base_id = prs_id; + } + + if (bitmaps->count(prs_id)) { + frame.reset(new SkBitmap(*(*bitmaps)[prs_id])); + } else if (prs_base_id != prs_id && bitmaps->count(prs_base_id)) { + frame.reset(new SkBitmap(*(*bitmaps)[prs_base_id])); + } else if (prs_base_id == PRS_THEME_FRAME_OVERLAY && + bitmaps->count(PRS_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()) { + temp_output[prs_id] = new SkBitmap( + SkBitmapOperations::CreateHSLShiftedBitmap( + *frame, GetTintInternal(kFrameTintMap[i].value))); + } + } + + MergeImageCaches(temp_output, bitmaps); +} + +void BrowserThemePack::GenerateTintedButtons( + color_utils::HSL button_tint, + ImageCache* processed_bitmaps) const { + if (button_tint.h != -1 || button_tint.s != -1 || button_tint.l != -1) { + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + const std::set& idr_ids = + BrowserThemeProvider::GetTintableToolbarButtons(); + for (std::set::const_iterator it = idr_ids.begin(); + it != idr_ids.end(); ++it) { + int prs_id = GetPersistentIDByIDR(*it); + DCHECK(prs_id > 0); + + // Fetch the image by IDR... + scoped_ptr button(new SkBitmap(*rb.GetBitmapNamed(*it))); + + // but save a version with the persistent ID. + (*processed_bitmaps)[prs_id] = new SkBitmap( + SkBitmapOperations::CreateHSLShiftedBitmap(*button, button_tint)); + } + } +} + +void BrowserThemePack::GenerateTabBackgroundImages(ImageCache* bitmaps) const { + ImageCache temp_output; + for (size_t i = 0; i < arraysize(kTabBackgroundMap); ++i) { + int prs_id = kTabBackgroundMap[i].key; + int prs_base_id = kTabBackgroundMap[i].value; + + // We only need to generate the background tab images if we were provided + // with a PRS_THEME_FRAME. + ImageCache::const_iterator it = bitmaps->find(prs_base_id); + if (it != bitmaps->end()) { + SkBitmap bg_tint = SkBitmapOperations::CreateHSLShiftedBitmap( + *(it->second), GetTintInternal( + BrowserThemeProvider::TINT_BACKGROUND_TAB)); + int vertical_offset = bitmaps->count(prs_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. + ImageCache::const_iterator overlay_it = bitmaps->find(prs_id); + if (overlay_it != bitmaps->end()) { + SkBitmap* overlay = overlay_it->second; + SkCanvas canvas(*bg_tab); + for (int x = 0; x < bg_tab->width(); x += overlay->width()) + canvas.drawBitmap(*overlay, static_cast(x), 0, NULL); + } + + temp_output[prs_id] = bg_tab; + } + } + + MergeImageCaches(temp_output, bitmaps); +} + +void BrowserThemePack::RepackImages(const ImageCache& images, + RawImages* reencoded_images) const { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); + for (ImageCache::const_iterator it = images.begin(); + it != images.end(); ++it) { + std::vector image_data; + if (!gfx::PNGCodec::EncodeBGRASkBitmap(*(it->second), false, &image_data)) { + NOTREACHED() << "Image file for resource " << it->first + << " could not be encoded."; + } else { + (*reencoded_images)[it->first] = RefCountedBytes::TakeVector(&image_data); + } + } +} + +void BrowserThemePack::MergeImageCaches( + const ImageCache& source, ImageCache* destination) const { + + for (ImageCache::const_iterator it = source.begin(); it != source.end(); + ++it) { + ImageCache::const_iterator bitmap_it = destination->find(it->first); + if (bitmap_it != destination->end()) + delete bitmap_it->second; + + (*destination)[it->first] = it->second; + } +} + +void BrowserThemePack::AddRawImagesTo(const RawImages& images, + RawDataForWriting* out) const { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); + for (RawImages::const_iterator it = images.begin(); it != images.end(); + ++it) { + (*out)[it->first] = base::StringPiece( + reinterpret_cast(it->second->front()), it->second->size()); + } +} + +color_utils::HSL BrowserThemePack::GetTintInternal(int id) const { + if (tints_) { + for (int i = 0; i < kTintArraySize; ++i) { + if (tints_[i].id == id) { + color_utils::HSL hsl; + hsl.h = tints_[i].h; + hsl.s = tints_[i].s; + hsl.l = tints_[i].l; + return hsl; + } + } + } + + return BrowserThemeProvider::GetDefaultTint(id); +} diff --git a/chrome/browser/themes/browser_theme_pack.h b/chrome/browser/themes/browser_theme_pack.h new file mode 100644 index 0000000..85d27af --- /dev/null +++ b/chrome/browser/themes/browser_theme_pack.h @@ -0,0 +1,226 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_THEMES_BROWSER_THEME_PACK_H_ +#define CHROME_BROWSER_THEMES_BROWSER_THEME_PACK_H_ +#pragma once + +#include +#include + +#include "base/basictypes.h" +#include "base/scoped_ptr.h" +#include "base/ref_counted.h" +#include "gfx/color_utils.h" +#include "chrome/common/extensions/extension.h" + +namespace base { +class DataPack; +} +class DictionaryValue; +class FilePath; +class RefCountedMemory; + +// An optimized representation of a theme, backed by a mmapped DataPack. +// +// The idea is to pre-process all images (tinting, compositing, etc) at theme +// install time, save all the PNG-ified data into an mmappable file so we don't +// suffer multiple file system access times, therefore solving two of the +// problems with the previous implementation. +// +// A note on const-ness. All public, non-static methods are const. We do this +// because once we've constructed a BrowserThemePack through the +// BuildFromExtension() interface, we WriteToDisk() on a thread other than the +// UI thread that consumes a BrowserThemePack. There is no locking; thread +// safety between the writing thread and the UI thread is ensured by having the +// data be immutable. +class BrowserThemePack : public base::RefCountedThreadSafe { + public: + ~BrowserThemePack(); + + // Builds the theme pack from all data from |extension|. This is often done + // on a separate thread as it takes so long. This can fail and return NULL in + // the case where the theme has invalid data. + static BrowserThemePack* BuildFromExtension(Extension* extension); + + // Builds the theme pack from a previously performed WriteToDisk(). This + // operation should be relatively fast, as it should be an mmap() and some + // pointer swizzling. Returns NULL on any error attempting to read |path|. + static scoped_refptr BuildFromDataPack( + FilePath path, const std::string& expected_id); + + // Builds a data pack on disk at |path| for future quick loading by + // BuildFromDataPack(). Often (but not always) called from the file thread; + // implementation should be threadsafe because neither thread will write to + // |image_memory_| and the worker thread will keep a reference to prevent + // destruction. + bool WriteToDisk(FilePath path) const; + + // If this theme specifies data for the corresponding |id|, return true and + // write the corresponding value to the output parameter. These functions + // don't return the default data. These methods should only be called from + // the UI thread. (But this isn't enforced because of unit tests). + bool GetTint(int id, color_utils::HSL* hsl) const; + bool GetColor(int id, SkColor* color) const; + bool GetDisplayProperty(int id, int* result) const; + + // Returns a bitmap if we have a custom image for |id|, otherwise NULL. Note + // that this is separate from HasCustomImage() which returns whether a custom + // image |id| was included in the unprocessed theme and is used as a proxy + // for making layout decisions in the interface. + SkBitmap* GetBitmapNamed(int id) const; + + // Returns the raw PNG encoded data for IDR_THEME_NTP_*. This method is only + // supposed to work for the NTP attribution and background resources. + RefCountedMemory* GetRawData(int id) const; + + // Whether this theme provides an image for |id|. + bool HasCustomImage(int id) const; + + private: + friend class BrowserThemePackTest; + + // Cached images. We cache all retrieved and generated bitmaps and keep + // track of the pointers. We own these and will delete them when we're done + // using them. + typedef std::map ImageCache; + + // The raw PNG memory associated with a certain id. + typedef std::map > RawImages; + + // The type passed to base::DataPack::WritePack. + typedef std::map RawDataForWriting; + + // An association between an id and the FilePath that has the image data. + typedef std::map FilePathMap; + + // Default. Everything is empty. + BrowserThemePack(); + + // Builds a header ready to write to disk. + void BuildHeader(Extension* extension); + + // Transforms the JSON tint values into their final versions in the |tints_| + // array. + void BuildTintsFromJSON(DictionaryValue* tints_value); + + // Transforms the JSON color values into their final versions in the + // |colors_| array and also fills in unspecified colors based on tint values. + void BuildColorsFromJSON(DictionaryValue* color_value); + + // Implementation details of BuildColorsFromJSON(). + void ReadColorsFromJSON(DictionaryValue* colors_value, + std::map* temp_colors); + void GenerateMissingColors(std::map* temp_colors); + + // Transforms the JSON display properties into |display_properties_|. + void BuildDisplayPropertiesFromJSON(DictionaryValue* display_value); + + // Parses the image names out of an extension. + void ParseImageNamesFromJSON(DictionaryValue* images_value, + FilePath images_path, + FilePathMap* file_paths) const; + + // Creates the data for |source_images_| from |file_paths|. + void BuildSourceImagesArray(const FilePathMap& file_paths); + + // Loads the unmodified bitmaps packed in the extension to SkBitmaps. Returns + // true if all images loaded. + bool LoadRawBitmapsTo(const FilePathMap& file_paths, + ImageCache* raw_bitmaps); + + // Creates tinted and composited frame images. Source and destination is + // |bitmaps|. + void GenerateFrameImages(ImageCache* bitmaps) const; + + // Generates button images tinted with |button_tint| and places them in + // processed_bitmaps. + void GenerateTintedButtons(color_utils::HSL button_tint, + ImageCache* processed_bitmaps) const; + + // Generates the semi-transparent tab background images, putting the results + // in |bitmaps|. Must be called after GenerateFrameImages(). + void GenerateTabBackgroundImages(ImageCache* bitmaps) const; + + // Takes all the SkBitmaps in |images|, encodes them as PNGs and places + // them in |reencoded_images|. + void RepackImages(const ImageCache& images, + RawImages* reencoded_images) const; + + // Takes all images in |source| and puts them in |destination|, freeing any + // image already in |destination| that |source| would overwrite. + void MergeImageCaches(const ImageCache& source, + ImageCache* destination) const; + + // Changes the RefCountedMemory based |images| into StringPiece data in |out|. + void AddRawImagesTo(const RawImages& images, RawDataForWriting* out) const; + + // Retrieves the tint OR the default tint. Unlike the public interface, we + // always need to return a reasonable tint here, instead of partially + // querying if the tint exists. + color_utils::HSL GetTintInternal(int id) const; + + // Data pack, if we have one. + scoped_ptr data_pack_; + + // All structs written to disk need to be packed; no alignment tricks here, + // please. +#pragma pack(push,1) + // Header that is written to disk. + struct BrowserThemePackHeader { + // Numeric version to make sure we're compatible in the future. + int32 version; + + // 1 if little_endian. 0 if big_endian. On mismatch, abort load. + int32 little_endian; + + // theme_id without NULL terminator. + uint8 theme_id[16]; + } *header_; + + // The remaining structs represent individual entries in an array. For the + // following three structs, BrowserThemePack will either allocate an array or + // will point directly to mmapped data. + struct TintEntry { + int32 id; + double h; + double s; + double l; + } *tints_; + + struct ColorPair { + int32 id; + SkColor color; + } *colors_; + + struct DisplayPropertyPair { + int32 id; + int32 property; + } *display_properties_; + + // A list of included source images. A pointer to a -1 terminated array of + // our persistent IDs. + int* source_images_; +#pragma pack(pop) + + // References to raw PNG data. This map isn't touched when |data_pack_| is + // non-NULL; |image_memory_| is only filled during BuildFromExtension(). Any + // image data that needs to be written to the DataPack during WriteToDisk() + // needs to be in |image_memory_|. + RawImages image_memory_; + + // An immutable cache of images generated in BuildFromExtension(). When this + // BrowserThemePack is generated from BuildFromDataPack(), this cache is + // empty. We separate the images from the images loaded from disk so that + // WriteToDisk()'s implementation doesn't need locks. There should be no IDs + // in |image_memory_| that are in |prepared_images_| or vice versa. + ImageCache prepared_images_; + + // Loaded images. These are loaded from |image_memory_| or the |data_pack_|. + mutable ImageCache loaded_images_; + + DISALLOW_COPY_AND_ASSIGN(BrowserThemePack); +}; + +#endif // CHROME_BROWSER_THEMES_BROWSER_THEME_PACK_H_ diff --git a/chrome/browser/themes/browser_theme_pack_unittest.cc b/chrome/browser/themes/browser_theme_pack_unittest.cc new file mode 100644 index 0000000..9fae131 --- /dev/null +++ b/chrome/browser/themes/browser_theme_pack_unittest.cc @@ -0,0 +1,428 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/themes/browser_theme_pack.h" + +#include "base/file_util.h" +#include "base/json/json_reader.h" +#include "base/message_loop.h" +#include "base/path_service.h" +#include "base/scoped_temp_dir.h" +#include "base/values.h" +#include "chrome/browser/chrome_thread.h" +#include "chrome/browser/themes/browser_theme_provider.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/common/json_value_serializer.h" +#include "gfx/color_utils.h" +#include "grit/theme_resources.h" +#include "testing/gtest/include/gtest/gtest.h" + +class BrowserThemePackTest : public ::testing::Test { + public: + BrowserThemePackTest() + : message_loop(), + fake_ui_thread(ChromeThread::UI, &message_loop), + fake_file_thread(ChromeThread::FILE, &message_loop), + theme_pack_(new BrowserThemePack) { + } + + // Transformation for link underline colors. + SkColor BuildThirdOpacity(SkColor color_link) { + return SkColorSetA(color_link, SkColorGetA(color_link) / 3); + } + + void GenerateDefaultFrameColor(std::map* colors, + int color, int tint) { + (*colors)[color] = HSLShift( + BrowserThemeProvider::GetDefaultColor( + BrowserThemeProvider::COLOR_FRAME), + BrowserThemeProvider::GetDefaultTint(tint)); + } + + // Returns a mapping from each COLOR_* constant to the default value for this + // constant. Callers get this map, and then modify expected values and then + // run the resulting thing through VerifyColorMap(). + std::map GetDefaultColorMap() { + std::map colors; + for (int i = BrowserThemeProvider::COLOR_FRAME; + i <= BrowserThemeProvider::COLOR_BUTTON_BACKGROUND; ++i) { + colors[i] = BrowserThemeProvider::GetDefaultColor(i); + } + + GenerateDefaultFrameColor(&colors, BrowserThemeProvider::COLOR_FRAME, + BrowserThemeProvider::TINT_FRAME); + GenerateDefaultFrameColor(&colors, + BrowserThemeProvider::COLOR_FRAME_INACTIVE, + BrowserThemeProvider::TINT_FRAME_INACTIVE); + GenerateDefaultFrameColor(&colors, + BrowserThemeProvider::COLOR_FRAME_INCOGNITO, + BrowserThemeProvider::TINT_FRAME_INCOGNITO); + GenerateDefaultFrameColor( + &colors, + BrowserThemeProvider::COLOR_FRAME_INCOGNITO_INACTIVE, + BrowserThemeProvider::TINT_FRAME_INCOGNITO_INACTIVE); + + return colors; + } + + void VerifyColorMap(const std::map& color_map) { + for (std::map::const_iterator it = color_map.begin(); + it != color_map.end(); ++it) { + SkColor color = BrowserThemeProvider::GetDefaultColor(it->first); + theme_pack_->GetColor(it->first, &color); + EXPECT_EQ(it->second, color) << "Color id = " << it->first; + } + } + + void LoadColorJSON(const std::string& json) { + scoped_ptr value(base::JSONReader::Read(json, false)); + ASSERT_TRUE(value->IsType(Value::TYPE_DICTIONARY)); + LoadColorDictionary(static_cast(value.get())); + } + + void LoadColorDictionary(DictionaryValue* value) { + theme_pack_->BuildColorsFromJSON(value); + } + + void LoadTintJSON(const std::string& json) { + scoped_ptr value(base::JSONReader::Read(json, false)); + ASSERT_TRUE(value->IsType(Value::TYPE_DICTIONARY)); + LoadTintDictionary(static_cast(value.get())); + } + + void LoadTintDictionary(DictionaryValue* value) { + theme_pack_->BuildTintsFromJSON(value); + } + + void LoadDisplayPropertiesJSON(const std::string& json) { + scoped_ptr value(base::JSONReader::Read(json, false)); + ASSERT_TRUE(value->IsType(Value::TYPE_DICTIONARY)); + LoadDisplayPropertiesDictionary(static_cast(value.get())); + } + + void LoadDisplayPropertiesDictionary(DictionaryValue* value) { + theme_pack_->BuildDisplayPropertiesFromJSON(value); + } + + void ParseImageNamesJSON(const std::string& json, + std::map* out_file_paths) { + scoped_ptr value(base::JSONReader::Read(json, false)); + ASSERT_TRUE(value->IsType(Value::TYPE_DICTIONARY)); + ParseImageNamesDictionary(static_cast(value.get()), + out_file_paths); + } + + void ParseImageNamesDictionary(DictionaryValue* value, + std::map* out_file_paths) { + theme_pack_->ParseImageNamesFromJSON(value, FilePath(), out_file_paths); + + // Build the source image list for HasCustomImage(). + theme_pack_->BuildSourceImagesArray(*out_file_paths); + } + + bool LoadRawBitmapsTo(const std::map& out_file_paths) { + return theme_pack_->LoadRawBitmapsTo(out_file_paths, + &theme_pack_->prepared_images_); + } + + FilePath GetStarGazingPath() { + FilePath test_path; + if (!PathService::Get(chrome::DIR_TEST_DATA, &test_path)) { + NOTREACHED(); + return test_path; + } + + test_path = test_path.AppendASCII("profiles"); + test_path = test_path.AppendASCII("complex_theme"); + test_path = test_path.AppendASCII("Default"); + test_path = test_path.AppendASCII("Extensions"); + test_path = test_path.AppendASCII("mblmlcbknbnfebdfjnolmcapmdofhmme"); + test_path = test_path.AppendASCII("1.1"); + return FilePath(test_path); + } + + // Verifies the data in star gazing. We do this multiple times for different + // BrowserThemePack objects to make sure it works in generated and mmapped + // mode correctly. + void VerifyStarGazing(BrowserThemePack* pack) { + // First check that values we know exist, exist. + SkColor color; + EXPECT_TRUE(pack->GetColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT, + &color)); + EXPECT_EQ(SK_ColorBLACK, color); + + EXPECT_TRUE(pack->GetColor(BrowserThemeProvider::COLOR_NTP_BACKGROUND, + &color)); + EXPECT_EQ(SkColorSetRGB(57, 137, 194), color); + + color_utils::HSL expected = { 0.6, 0.553, 0.5 }; + color_utils::HSL actual; + EXPECT_TRUE(pack->GetTint(BrowserThemeProvider::TINT_BUTTONS, &actual)); + EXPECT_DOUBLE_EQ(expected.h, actual.h); + EXPECT_DOUBLE_EQ(expected.s, actual.s); + EXPECT_DOUBLE_EQ(expected.l, actual.l); + + int val; + EXPECT_TRUE(pack->GetDisplayProperty( + BrowserThemeProvider::NTP_BACKGROUND_ALIGNMENT, &val)); + EXPECT_EQ(BrowserThemeProvider::ALIGN_TOP, val); + + // The stargazing theme defines the following images: + EXPECT_TRUE(pack->HasCustomImage(IDR_THEME_BUTTON_BACKGROUND)); + EXPECT_TRUE(pack->HasCustomImage(IDR_THEME_FRAME)); + EXPECT_TRUE(pack->HasCustomImage(IDR_THEME_NTP_BACKGROUND)); + EXPECT_TRUE(pack->HasCustomImage(IDR_THEME_TAB_BACKGROUND)); + EXPECT_TRUE(pack->HasCustomImage(IDR_THEME_TOOLBAR)); + EXPECT_TRUE(pack->HasCustomImage(IDR_THEME_WINDOW_CONTROL_BACKGROUND)); + + // Here are a few images that we shouldn't expect because even though + // they're included in the theme pack, they were autogenerated and + // therefore shouldn't show up when calling HasCustomImage(). + EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_FRAME_INACTIVE)); + EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_FRAME_INCOGNITO)); + EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_FRAME_INCOGNITO_INACTIVE)); + EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_TAB_BACKGROUND_INCOGNITO)); + + // Make sure we don't have phantom data. + EXPECT_FALSE(pack->GetColor(BrowserThemeProvider::COLOR_CONTROL_BACKGROUND, + &color)); + EXPECT_FALSE(pack->GetTint(BrowserThemeProvider::TINT_FRAME, &actual)); + } + + MessageLoop message_loop; + ChromeThread fake_ui_thread; + ChromeThread fake_file_thread; + + scoped_refptr theme_pack_; +}; + + +TEST_F(BrowserThemePackTest, DeriveUnderlineLinkColor) { + // If we specify a link color, but don't specify the underline color, the + // theme provider should create one. + std::string color_json = "{ \"ntp_link\": [128, 128, 128]," + " \"ntp_section_link\": [128, 128, 128] }"; + LoadColorJSON(color_json); + + std::map colors = GetDefaultColorMap(); + SkColor link_color = SkColorSetRGB(128, 128, 128); + colors[BrowserThemeProvider::COLOR_NTP_LINK] = link_color; + colors[BrowserThemeProvider::COLOR_NTP_LINK_UNDERLINE] = + BuildThirdOpacity(link_color); + colors[BrowserThemeProvider::COLOR_NTP_SECTION_LINK] = link_color; + colors[BrowserThemeProvider::COLOR_NTP_SECTION_LINK_UNDERLINE] = + BuildThirdOpacity(link_color); + + VerifyColorMap(colors); +} + +TEST_F(BrowserThemePackTest, ProvideUnderlineLinkColor) { + // If we specify the underline color, it shouldn't try to generate one. + std::string color_json = "{ \"ntp_link\": [128, 128, 128]," + " \"ntp_link_underline\": [255, 255, 255]," + " \"ntp_section_link\": [128, 128, 128]," + " \"ntp_section_link_underline\": [255, 255, 255]" + "}"; + LoadColorJSON(color_json); + + std::map colors = GetDefaultColorMap(); + SkColor link_color = SkColorSetRGB(128, 128, 128); + SkColor underline_color = SkColorSetRGB(255, 255, 255); + colors[BrowserThemeProvider::COLOR_NTP_LINK] = link_color; + colors[BrowserThemeProvider::COLOR_NTP_LINK_UNDERLINE] = underline_color; + colors[BrowserThemeProvider::COLOR_NTP_SECTION_LINK] = link_color; + colors[BrowserThemeProvider::COLOR_NTP_SECTION_LINK_UNDERLINE] = + underline_color; + + VerifyColorMap(colors); +} + +TEST_F(BrowserThemePackTest, UseSectionColorAsNTPHeader) { + std::string color_json = "{ \"ntp_section\": [190, 190, 190] }"; + LoadColorJSON(color_json); + + std::map colors = GetDefaultColorMap(); + SkColor ntp_color = SkColorSetRGB(190, 190, 190); + colors[BrowserThemeProvider::COLOR_NTP_HEADER] = ntp_color; + colors[BrowserThemeProvider::COLOR_NTP_SECTION] = ntp_color; + VerifyColorMap(colors); +} + +TEST_F(BrowserThemePackTest, ProvideNtpHeaderColor) { + std::string color_json = "{ \"ntp_header\": [120, 120, 120], " + " \"ntp_section\": [190, 190, 190] }"; + LoadColorJSON(color_json); + + std::map colors = GetDefaultColorMap(); + SkColor ntp_header = SkColorSetRGB(120, 120, 120); + SkColor ntp_section = SkColorSetRGB(190, 190, 190); + colors[BrowserThemeProvider::COLOR_NTP_HEADER] = ntp_header; + colors[BrowserThemeProvider::COLOR_NTP_SECTION] = ntp_section; + VerifyColorMap(colors); +} + +TEST_F(BrowserThemePackTest, CanReadTints) { + std::string tint_json = "{ \"buttons\": [ 0.5, 0.5, 0.5 ] }"; + LoadTintJSON(tint_json); + + color_utils::HSL expected = { 0.5, 0.5, 0.5 }; + color_utils::HSL actual = { -1, -1, -1 }; + EXPECT_TRUE(theme_pack_->GetTint( + BrowserThemeProvider::TINT_BUTTONS, &actual)); + EXPECT_DOUBLE_EQ(expected.h, actual.h); + EXPECT_DOUBLE_EQ(expected.s, actual.s); + EXPECT_DOUBLE_EQ(expected.l, actual.l); +} + +TEST_F(BrowserThemePackTest, CanReadDisplayProperties) { + std::string json = "{ \"ntp_background_alignment\": \"bottom\", " + " \"ntp_background_repeat\": \"repeat-x\", " + " \"ntp_logo_alternate\": 0 }"; + LoadDisplayPropertiesJSON(json); + + int out_val; + EXPECT_TRUE(theme_pack_->GetDisplayProperty( + BrowserThemeProvider::NTP_BACKGROUND_ALIGNMENT, &out_val)); + EXPECT_EQ(BrowserThemeProvider::ALIGN_BOTTOM, out_val); + + EXPECT_TRUE(theme_pack_->GetDisplayProperty( + BrowserThemeProvider::NTP_BACKGROUND_TILING, &out_val)); + EXPECT_EQ(BrowserThemeProvider::REPEAT_X, out_val); + + EXPECT_TRUE(theme_pack_->GetDisplayProperty( + BrowserThemeProvider::NTP_LOGO_ALTERNATE, &out_val)); + EXPECT_EQ(0, out_val); +} + +TEST_F(BrowserThemePackTest, CanParsePaths) { + std::string path_json = "{ \"theme_button_background\": \"one\", " + " \"theme_toolbar\": \"two\" }"; + std::map out_file_paths; + ParseImageNamesJSON(path_json, &out_file_paths); + + EXPECT_EQ(2u, out_file_paths.size()); + // "12" and "5" are internal constants to BrowserThemePack and are + // PRS_THEME_BUTTON_BACKGROUND and PRS_THEME_TOOLBAR, but they are + // implementation details that shouldn't be exported. + EXPECT_TRUE(FilePath(FILE_PATH_LITERAL("one")) == out_file_paths[12]); + EXPECT_TRUE(FilePath(FILE_PATH_LITERAL("two")) == out_file_paths[5]); +} + +TEST_F(BrowserThemePackTest, InvalidPathNames) { + std::string path_json = "{ \"wrong\": [1], " + " \"theme_button_background\": \"one\", " + " \"not_a_thing\": \"blah\" }"; + std::map out_file_paths; + ParseImageNamesJSON(path_json, &out_file_paths); + + // We should have only parsed one valid path out of that mess above. + EXPECT_EQ(1u, out_file_paths.size()); +} + +TEST_F(BrowserThemePackTest, InvalidColors) { + std::string invalid_color = "{ \"toolbar\": [\"dog\", \"cat\", [12]], " + " \"sound\": \"woof\" }"; + LoadColorJSON(invalid_color); + std::map colors = GetDefaultColorMap(); + VerifyColorMap(colors); +} + +TEST_F(BrowserThemePackTest, InvalidTints) { + std::string invalid_tints = "{ \"buttons\": [ \"dog\", \"cat\", [\"x\"]], " + " \"invalid\": \"entry\" }"; + LoadTintJSON(invalid_tints); + + // We shouldn't have a buttons tint, as it was invalid. + color_utils::HSL actual = { -1, -1, -1 }; + EXPECT_FALSE(theme_pack_->GetTint(BrowserThemeProvider::TINT_BUTTONS, + &actual)); +} + +TEST_F(BrowserThemePackTest, InvalidDisplayProperties) { + std::string invalid_properties = "{ \"ntp_background_alignment\": [15], " + " \"junk\": [15.3] }"; + LoadDisplayPropertiesJSON(invalid_properties); + + int out_val; + EXPECT_FALSE(theme_pack_->GetDisplayProperty( + BrowserThemeProvider::NTP_BACKGROUND_ALIGNMENT, &out_val)); +} + +// These three tests should just not cause a segmentation fault. +TEST_F(BrowserThemePackTest, NullPaths) { + std::map out_file_paths; + ParseImageNamesDictionary(NULL, &out_file_paths); +} + +TEST_F(BrowserThemePackTest, NullTints) { + LoadTintDictionary(NULL); +} + +TEST_F(BrowserThemePackTest, NullColors) { + LoadColorDictionary(NULL); +} + +TEST_F(BrowserThemePackTest, NullDisplayProperties) { + LoadDisplayPropertiesDictionary(NULL); +} + +TEST_F(BrowserThemePackTest, TestHasCustomImage) { + // HasCustomImage should only return true for images that exist in the + // extension and not for autogenerated images. + std::string images = "{ \"theme_frame\": \"one\" }"; + std::map out_file_paths; + ParseImageNamesJSON(images, &out_file_paths); + + EXPECT_TRUE(theme_pack_->HasCustomImage(IDR_THEME_FRAME)); + EXPECT_FALSE(theme_pack_->HasCustomImage(IDR_THEME_FRAME_INCOGNITO)); +} + +TEST_F(BrowserThemePackTest, TestNonExistantImages) { + std::string images = "{ \"theme_frame\": \"does_not_exist\" }"; + std::map out_file_paths; + ParseImageNamesJSON(images, &out_file_paths); + + EXPECT_FALSE(LoadRawBitmapsTo(out_file_paths)); +} + +// TODO(erg): This test should actually test more of the built resources from +// the extension data, but for now, exists so valgrind can test some of the +// tricky memory stuff that BrowserThemePack does. +TEST_F(BrowserThemePackTest, CanBuildAndReadPack) { + ScopedTempDir dir; + ASSERT_TRUE(dir.CreateUniqueTempDir()); + FilePath file = dir.path().Append(FILE_PATH_LITERAL("data.pak")); + + // Part 1: Build the pack from an extension. + { + FilePath star_gazing_path = GetStarGazingPath(); + Extension extension(star_gazing_path); + + FilePath manifest_path = + star_gazing_path.AppendASCII("manifest.json"); + std::string error; + JSONFileValueSerializer serializer(manifest_path); + scoped_ptr valid_value( + static_cast(serializer.Deserialize(NULL, &error))); + EXPECT_EQ("", error); + ASSERT_TRUE(valid_value.get()); + ASSERT_TRUE(extension.InitFromValue(*valid_value, true, &error)); + ASSERT_EQ("", error); + + scoped_refptr pack = + BrowserThemePack::BuildFromExtension(&extension); + ASSERT_TRUE(pack.get()); + ASSERT_TRUE(pack->WriteToDisk(file)); + VerifyStarGazing(pack.get()); + } + + // Part 2: Try to read back the data pack that we just wrote to disk. + { + scoped_refptr pack = + BrowserThemePack::BuildFromDataPack( + file, "mblmlcbknbnfebdfjnolmcapmdofhmme"); + ASSERT_TRUE(pack.get()); + VerifyStarGazing(pack.get()); + } +} diff --git a/chrome/browser/themes/browser_theme_provider.cc b/chrome/browser/themes/browser_theme_provider.cc new file mode 100644 index 0000000..74bddfa --- /dev/null +++ b/chrome/browser/themes/browser_theme_provider.cc @@ -0,0 +1,609 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/themes/browser_theme_provider.h" + +#include "app/resource_bundle.h" +#include "base/string_util.h" +#include "base/utf_string_conversions.h" +#include "chrome/browser/extensions/extensions_service.h" +#include "chrome/browser/metrics/user_metrics.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/themes/browser_theme_pack.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/common/notification_service.h" +#include "chrome/common/notification_type.h" +#include "chrome/common/pref_names.h" +#include "grit/app_resources.h" +#include "grit/theme_resources.h" + +#if defined(OS_WIN) +#include "app/win_util.h" +#endif + +// Strings used in alignment properties. +const char* BrowserThemeProvider::kAlignmentTop = "top"; +const char* BrowserThemeProvider::kAlignmentBottom = "bottom"; +const char* BrowserThemeProvider::kAlignmentLeft = "left"; +const char* BrowserThemeProvider::kAlignmentRight = "right"; + +// Strings used in background tiling repetition properties. +const char* BrowserThemeProvider::kTilingNoRepeat = "no-repeat"; +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 kDefaultColorFrame = SkColorSetRGB(66, 116, 201); +const SkColor kDefaultColorFrameInactive = SkColorSetRGB(161, 182, 228); +const SkColor kDefaultColorFrameIncognito = SkColorSetRGB(83, 106, 139); +const SkColor kDefaultColorFrameIncognitoInactive = + SkColorSetRGB(126, 139, 156); +#if defined(OS_MACOSX) +const SkColor kDefaultColorToolbar = SkColorSetRGB(230, 230, 230); +#else +const SkColor kDefaultColorToolbar = SkColorSetRGB(223, 223, 223); +#endif +const SkColor kDefaultColorTabText = SK_ColorBLACK; +#if defined(OS_MACOSX) +const SkColor kDefaultColorBackgroundTabText = SK_ColorBLACK; +const SkColor kDefaultColorBookmarkText = SK_ColorBLACK; +#else +const SkColor kDefaultColorBackgroundTabText = SkColorSetRGB(64, 64, 64); +const SkColor kDefaultColorBookmarkText = SkColorSetRGB(18, 50, 114); +#endif +#if defined(OS_WIN) +const SkColor kDefaultColorNTPBackground = + color_utils::GetSysSkColor(COLOR_WINDOW); +const SkColor kDefaultColorNTPText = + color_utils::GetSysSkColor(COLOR_WINDOWTEXT); +const SkColor kDefaultColorNTPLink = + color_utils::GetSysSkColor(COLOR_HOTLIGHT); +#else +// TODO(beng): source from theme provider. +const SkColor kDefaultColorNTPBackground = SK_ColorWHITE; +const SkColor kDefaultColorNTPText = SK_ColorBLACK; +const SkColor kDefaultColorNTPLink = SkColorSetRGB(6, 55, 116); +#endif +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); +#if defined(OS_MACOSX) +const SkColor kDefaultColorToolbarButtonStroke = SkColorSetARGB(75, 81, 81, 81); +const SkColor kDefaultColorToolbarButtonStrokeInactive = + SkColorSetARGB(75, 99, 99, 99); +const SkColor kDefaultColorToolbarBezel = SkColorSetRGB(247, 247, 247); +const SkColor kDefaultColorToolbarStroke = SkColorSetRGB(103, 103, 103); +const SkColor kDefaultColorToolbarStrokeInactive = SkColorSetRGB(123, 123, 123); +#endif + +// Default tints. +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 = + BrowserThemeProvider::ALIGN_BOTTOM; +const int kDefaultDisplayPropertyNTPTiling = + BrowserThemeProvider::NO_REPEAT; +const int kDefaultDisplayPropertyNTPInverseLogo = 0; + +// The sum of kFrameBorderThickness and kNonClientRestoredExtraThickness from +// OpaqueBrowserFrameView. +const int kRestoredTabVerticalOffset = 15; + +// The image resources we will allow people to theme. +const int kThemeableImages[] = { + IDR_THEME_FRAME, + IDR_THEME_FRAME_INACTIVE, + IDR_THEME_FRAME_INCOGNITO, + IDR_THEME_FRAME_INCOGNITO_INACTIVE, + IDR_THEME_TOOLBAR, + IDR_THEME_TAB_BACKGROUND, + IDR_THEME_TAB_BACKGROUND_INCOGNITO, + IDR_THEME_TAB_BACKGROUND_V, + IDR_THEME_NTP_BACKGROUND, + IDR_THEME_FRAME_OVERLAY, + IDR_THEME_FRAME_OVERLAY_INACTIVE, + IDR_THEME_BUTTON_BACKGROUND, + IDR_THEME_NTP_ATTRIBUTION, + IDR_THEME_WINDOW_CONTROL_BACKGROUND +}; + +bool HasThemeableImage(int themeable_image_id) { + static std::set themeable_images; + if (themeable_images.empty()) { + themeable_images.insert( + kThemeableImages, kThemeableImages + arraysize(kThemeableImages)); + } + return themeable_images.count(themeable_image_id) > 0; +} + +// The image resources that will be tinted by the 'button' tint value. +// If you change this list, you must increment the version number in +// browser_theme_pack.cc, and you should assign persistent IDs to the +// data table at the start of said file or else tinted versions of +// these resources will not be created. +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_HOME, IDR_HOME_H, IDR_HOME_P, + IDR_RELOAD, IDR_RELOAD_H, IDR_RELOAD_P, + IDR_STOP, IDR_STOP_D, IDR_STOP_H, IDR_STOP_P, + IDR_LOCATIONBG_C, IDR_LOCATIONBG_L, IDR_LOCATIONBG_R, + IDR_BROWSER_ACTIONS_OVERFLOW, IDR_BROWSER_ACTIONS_OVERFLOW_H, + IDR_BROWSER_ACTIONS_OVERFLOW_P, + IDR_TOOLS, IDR_TOOLS_H, IDR_TOOLS_P, + IDR_MENU_DROPARROW, + IDR_THROBBER, IDR_THROBBER_WAITING, IDR_THROBBER_LIGHT, +}; + +// Writes the theme pack to disk on a separate thread. +class WritePackToDiskTask : public Task { + public: + WritePackToDiskTask(BrowserThemePack* pack, const FilePath& path) + : theme_pack_(pack), pack_path_(path) {} + + virtual void Run() { + if (!theme_pack_->WriteToDisk(pack_path_)) { + NOTREACHED() << "Could not write theme pack to disk"; + } + } + + private: + scoped_refptr theme_pack_; + FilePath pack_path_; +}; + +} // namespace + +bool BrowserThemeProvider::IsThemeableImage(int resource_id) { + return HasThemeableImage(resource_id); +} + +BrowserThemeProvider::BrowserThemeProvider() + : rb_(ResourceBundle::GetSharedInstance()), + profile_(NULL), + number_of_infobars_(0) { + // Initialize the themeable image map so we can use it on other threads. + HasThemeableImage(0); +} + +BrowserThemeProvider::~BrowserThemeProvider() { + FreePlatformCaches(); + + RemoveUnusedThemes(); +} + +void BrowserThemeProvider::Init(Profile* profile) { + DCHECK(CalledOnValidThread()); + profile_ = profile; + + LoadThemePrefs(); +} + +SkBitmap* BrowserThemeProvider::GetBitmapNamed(int id) const { + DCHECK(CalledOnValidThread()); + + SkBitmap* bitmap = 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()); + + SkColor color; + if (theme_pack_.get() && theme_pack_->GetColor(id, &color)) + return color; + + return GetDefaultColor(id); +} + +bool BrowserThemeProvider::GetDisplayProperty(int id, int* result) const { + if (theme_pack_.get()) + return theme_pack_->GetDisplayProperty(id, result); + + return GetDefaultDisplayProperty(id, result); +} + +bool BrowserThemeProvider::ShouldUseNativeFrame() const { + if (HasCustomImage(IDR_THEME_FRAME)) + return false; +#if defined(OS_WIN) + return win_util::ShouldUseVistaFrame(); +#else + return false; +#endif +} + +bool BrowserThemeProvider::HasCustomImage(int id) const { + if (!HasThemeableImage(id)) + return false; + + if (theme_pack_) + return theme_pack_->HasCustomImage(id); + + return false; +} + +RefCountedMemory* BrowserThemeProvider::GetRawData(int id) const { + // Check to see whether we should substitute some images. + int ntp_alternate; + GetDisplayProperty(NTP_LOGO_ALTERNATE, &ntp_alternate); + if (id == IDR_PRODUCT_LOGO && ntp_alternate != 0) + id = IDR_PRODUCT_LOGO_WHITE; + + RefCountedMemory* data = NULL; + if (theme_pack_.get()) + data = theme_pack_->GetRawData(id); + if (!data) + data = rb_.LoadDataResourceBytes(id); + + return data; +} + +void BrowserThemeProvider::SetTheme(Extension* extension) { + // Clear our image cache. + FreePlatformCaches(); + + DCHECK(extension); + DCHECK(extension->is_theme()); + + BuildFromExtension(extension); + SaveThemeID(extension->id()); + + NotifyThemeChanged(extension); + UserMetrics::RecordAction(UserMetricsAction("Themes_Installed"), profile_); +} + +void BrowserThemeProvider::RemoveUnusedThemes() { + if (!profile_) + return; + ExtensionsService* service = profile_->GetExtensionsService(); + if (!service) + return; + std::string current_theme = GetThemeID(); + std::vector remove_list; + const ExtensionList* extensions = service->extensions(); + for (ExtensionList::const_iterator it = extensions->begin(); + it != extensions->end(); ++it) { + if ((*it)->is_theme() && (*it)->id() != current_theme) { + remove_list.push_back((*it)->id()); + } + } + for (size_t i = 0; i < remove_list.size(); ++i) + service->UninstallExtension(remove_list[i], false); +} + +void BrowserThemeProvider::UseDefaultTheme() { + ClearAllThemeData(); + NotifyThemeChanged(NULL); + UserMetrics::RecordAction(UserMetricsAction("Themes_Reset"), profile_); +} + +bool BrowserThemeProvider::UsingDefaultTheme() { + return GetThemeID() == BrowserThemeProvider::kDefaultThemeID; +} + +std::string BrowserThemeProvider::GetThemeID() const { + return profile_->GetPrefs()->GetString(prefs::kCurrentThemeID); +} + +// static +std::string BrowserThemeProvider::AlignmentToString(int alignment) { + // Convert from an AlignmentProperty back into a string. + std::string vertical_string; + std::string horizontal_string; + + if (alignment & BrowserThemeProvider::ALIGN_TOP) + vertical_string = kAlignmentTop; + else if (alignment & BrowserThemeProvider::ALIGN_BOTTOM) + vertical_string = kAlignmentBottom; + + if (alignment & BrowserThemeProvider::ALIGN_LEFT) + horizontal_string = kAlignmentLeft; + else if (alignment & BrowserThemeProvider::ALIGN_RIGHT) + horizontal_string = kAlignmentRight; + + if (vertical_string.empty()) + return horizontal_string; + if (horizontal_string.empty()) + return vertical_string; + return vertical_string + " " + horizontal_string; +} + +// static +int BrowserThemeProvider::StringToAlignment(const std::string& alignment) { + std::vector split; + SplitStringAlongWhitespace(UTF8ToWide(alignment), &split); + + int alignment_mask = 0; + for (std::vector::iterator alignments(split.begin()); + alignments != split.end(); ++alignments) { + std::string comp = WideToUTF8(*alignments); + const char* component = comp.c_str(); + + if (base::strcasecmp(component, kAlignmentTop) == 0) + alignment_mask |= BrowserThemeProvider::ALIGN_TOP; + else if (base::strcasecmp(component, kAlignmentBottom) == 0) + alignment_mask |= BrowserThemeProvider::ALIGN_BOTTOM; + + if (base::strcasecmp(component, kAlignmentLeft) == 0) + alignment_mask |= BrowserThemeProvider::ALIGN_LEFT; + else if (base::strcasecmp(component, kAlignmentRight) == 0) + alignment_mask |= BrowserThemeProvider::ALIGN_RIGHT; + } + return alignment_mask; +} + +// static +std::string BrowserThemeProvider::TilingToString(int tiling) { + // Convert from a TilingProperty back into a string. + if (tiling == BrowserThemeProvider::REPEAT_X) + return kTilingRepeatX; + if (tiling == BrowserThemeProvider::REPEAT_Y) + return kTilingRepeatY; + if (tiling == BrowserThemeProvider::REPEAT) + return kTilingRepeat; + return kTilingNoRepeat; +} + +// static +int BrowserThemeProvider::StringToTiling(const std::string& tiling) { + const char* component = tiling.c_str(); + + if (base::strcasecmp(component, kTilingRepeatX) == 0) + return BrowserThemeProvider::REPEAT_X; + if (base::strcasecmp(component, kTilingRepeatY) == 0) + return BrowserThemeProvider::REPEAT_Y; + if (base::strcasecmp(component, kTilingRepeat) == 0) + return BrowserThemeProvider::REPEAT; + // NO_REPEAT is the default choice. + return BrowserThemeProvider::NO_REPEAT; +} + +// static +color_utils::HSL BrowserThemeProvider::GetDefaultTint(int id) { + switch (id) { + case TINT_FRAME: + return kDefaultTintFrame; + case TINT_FRAME_INACTIVE: + return kDefaultTintFrameInactive; + case TINT_FRAME_INCOGNITO: + return kDefaultTintFrameIncognito; + case TINT_FRAME_INCOGNITO_INACTIVE: + return kDefaultTintFrameIncognitoInactive; + case TINT_BUTTONS: + return kDefaultTintButtons; + case TINT_BACKGROUND_TAB: + return kDefaultTintBackgroundTab; + default: + color_utils::HSL result = {-1, -1, -1}; + return result; + } +} + +// static +SkColor BrowserThemeProvider::GetDefaultColor(int id) { + switch (id) { + case COLOR_FRAME: + return kDefaultColorFrame; + case COLOR_FRAME_INACTIVE: + return kDefaultColorFrameInactive; + case COLOR_FRAME_INCOGNITO: + return kDefaultColorFrameIncognito; + case COLOR_FRAME_INCOGNITO_INACTIVE: + return kDefaultColorFrameIncognitoInactive; + case COLOR_TOOLBAR: + return kDefaultColorToolbar; + case COLOR_TAB_TEXT: + return kDefaultColorTabText; + case COLOR_BACKGROUND_TAB_TEXT: + return kDefaultColorBackgroundTabText; + case COLOR_BOOKMARK_TEXT: + return kDefaultColorBookmarkText; + case COLOR_NTP_BACKGROUND: + return kDefaultColorNTPBackground; + case COLOR_NTP_TEXT: + 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: + return kDefaultColorNTPSection; + case COLOR_NTP_SECTION_TEXT: + 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: + return kDefaultColorButtonBackground; +#if defined(OS_MACOSX) + case COLOR_TOOLBAR_BUTTON_STROKE: + return kDefaultColorToolbarButtonStroke; + case COLOR_TOOLBAR_BUTTON_STROKE_INACTIVE: + return kDefaultColorToolbarButtonStrokeInactive; + case COLOR_TOOLBAR_BEZEL: + return kDefaultColorToolbarBezel; + case COLOR_TOOLBAR_STROKE: + return kDefaultColorToolbarStroke; + case COLOR_TOOLBAR_STROKE_INACTIVE: + return kDefaultColorToolbarStrokeInactive; +#endif + default: + // Return a debugging red color. + return 0xffff0000; + } +} + +// 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; +} + +// static +const std::set& BrowserThemeProvider::GetTintableToolbarButtons() { + static std::set button_set; + if (button_set.empty()) { + button_set = std::set( + kToolbarButtonIDs, + kToolbarButtonIDs + arraysize(kToolbarButtonIDs)); + } + + return button_set; +} + +color_utils::HSL BrowserThemeProvider::GetTint(int id) const { + DCHECK(CalledOnValidThread()); + + color_utils::HSL hsl; + if (theme_pack_.get() && theme_pack_->GetTint(id, &hsl)) + return hsl; + + return GetDefaultTint(id); +} + +void BrowserThemeProvider::ClearAllThemeData() { + // Clear our image cache. + FreePlatformCaches(); + theme_pack_ = NULL; + + profile_->GetPrefs()->ClearPref(prefs::kCurrentThemePackFilename); + SaveThemeID(kDefaultThemeID); +} + +void BrowserThemeProvider::LoadThemePrefs() { + PrefService* prefs = profile_->GetPrefs(); + + std::string current_id = GetThemeID(); + if (current_id != kDefaultThemeID) { + bool loaded_pack = false; + + // If we don't have a file pack, we're updating from an old version. + FilePath path = prefs->GetFilePath(prefs::kCurrentThemePackFilename); + if (path != FilePath()) { + theme_pack_ = BrowserThemePack::BuildFromDataPack(path, current_id); + loaded_pack = theme_pack_.get() != NULL; + } + + if (loaded_pack) { + UserMetrics::RecordAction(UserMetricsAction("Themes.Loaded"), profile_); + } else { + // 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(UserMetricsAction("Themes.Migrated"), + profile_); + } else { + DLOG(ERROR) << "Theme is mysteriously gone."; + ClearAllThemeData(); + UserMetrics::RecordAction(UserMetricsAction("Themes.Gone"), profile_); + } + } + } + } +} + +void BrowserThemeProvider::NotifyThemeChanged(Extension* extension) { + LOG(INFO) << "Sending BROWSER_THEME_CHANGED"; + // Redraw! + NotificationService* service = NotificationService::current(); + service->Notify(NotificationType::BROWSER_THEME_CHANGED, + Source(this), + Details(extension)); +#if defined(OS_MACOSX) + NotifyPlatformThemeChanged(); +#endif // OS_MACOSX +} + +#if defined(OS_WIN) +void BrowserThemeProvider::FreePlatformCaches() { + // Views (Skia) has no platform image cache to clear. +} +#endif + +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, id); +} + +void BrowserThemeProvider::BuildFromExtension(Extension* extension) { + scoped_refptr pack = + BrowserThemePack::BuildFromExtension(extension); + if (!pack.get()) { + // TODO(erg): We've failed to install the theme; perhaps we should tell the + // user? http://crbug.com/34780 + LOG(ERROR) << "Could not load theme."; + return; + } + + // Write the packed file to disk. + FilePath pack_path = extension->path().Append(chrome::kThemePackFilename); + ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE, + new WritePackToDiskTask(pack, pack_path)); + + SavePackName(pack_path); + theme_pack_ = pack; +} + +void BrowserThemeProvider::OnInfobarDisplayed() { + number_of_infobars_++; +} + +void BrowserThemeProvider::OnInfobarDestroyed() { + number_of_infobars_--; + + if (number_of_infobars_ == 0) + RemoveUnusedThemes(); +} diff --git a/chrome/browser/themes/browser_theme_provider.h b/chrome/browser/themes/browser_theme_provider.h new file mode 100644 index 0000000..565047e --- /dev/null +++ b/chrome/browser/themes/browser_theme_provider.h @@ -0,0 +1,275 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_THEMES_BROWSER_THEME_PROVIDER_H_ +#define CHROME_BROWSER_THEMES_BROWSER_THEME_PROVIDER_H_ +#pragma once + +#include +#include +#include + +#include "app/theme_provider.h" +#include "base/non_thread_safe.h" +#include "base/ref_counted.h" + +namespace color_utils { + struct HSL; +} + +class BrowserThemePack; +class BrowserThemeProviderTest; +class Extension; +class FilePath; +class Profile; +class ResourceBundle; + +#ifdef __OBJC__ +@class NSString; +// Sent whenever the browser theme changes. Object => NSValue wrapping the +// BrowserThemeProvider that changed. +extern "C" NSString* const kBrowserThemeDidChangeNotification; +#endif // __OBJC__ + +class BrowserThemeProvider : public NonThreadSafe, + public ThemeProvider { + public: + // Public constants used in BrowserThemeProvider and its subclasses: + + // Strings used in alignment properties. + static const char* kAlignmentTop; + static const char* kAlignmentBottom; + static const char* kAlignmentLeft; + static const char* kAlignmentRight; + + // Strings used in tiling properties. + static const char* kTilingNoRepeat; + static const char* kTilingRepeatX; + static const char* kTilingRepeatY; + static const char* kTilingRepeat; + + static const char* kDefaultThemeID; + + // Returns true if the image is themeable. Safe to call on any thread. + static bool IsThemeableImage(int resource_id); + + BrowserThemeProvider(); + virtual ~BrowserThemeProvider(); + + enum { + COLOR_FRAME, + COLOR_FRAME_INACTIVE, + COLOR_FRAME_INCOGNITO, + COLOR_FRAME_INCOGNITO_INACTIVE, + COLOR_TOOLBAR, + COLOR_TAB_TEXT, + COLOR_BACKGROUND_TAB_TEXT, + COLOR_BOOKMARK_TEXT, + COLOR_NTP_BACKGROUND, + COLOR_NTP_TEXT, + COLOR_NTP_LINK, + COLOR_NTP_LINK_UNDERLINE, + COLOR_NTP_HEADER, + COLOR_NTP_SECTION, + COLOR_NTP_SECTION_TEXT, + COLOR_NTP_SECTION_LINK, + COLOR_NTP_SECTION_LINK_UNDERLINE, + COLOR_CONTROL_BACKGROUND, + COLOR_BUTTON_BACKGROUND, + TINT_BUTTONS, + TINT_FRAME, + TINT_FRAME_INACTIVE, + TINT_FRAME_INCOGNITO, + TINT_FRAME_INCOGNITO_INACTIVE, + TINT_BACKGROUND_TAB, + NTP_BACKGROUND_ALIGNMENT, + NTP_BACKGROUND_TILING, + NTP_LOGO_ALTERNATE +#if defined(OS_MACOSX) + , + COLOR_TOOLBAR_BEZEL = 1000, + COLOR_TOOLBAR_STROKE, + COLOR_TOOLBAR_STROKE_INACTIVE, + COLOR_TOOLBAR_BUTTON_STROKE, + COLOR_TOOLBAR_BUTTON_STROKE_INACTIVE, + GRADIENT_FRAME_INCOGNITO, + GRADIENT_FRAME_INCOGNITO_INACTIVE, + GRADIENT_TOOLBAR, + GRADIENT_TOOLBAR_INACTIVE, + GRADIENT_TOOLBAR_BUTTON, + GRADIENT_TOOLBAR_BUTTON_INACTIVE, + GRADIENT_TOOLBAR_BUTTON_PRESSED, + GRADIENT_TOOLBAR_BUTTON_PRESSED_INACTIVE +#endif // OS_MACOSX + }; + + // A bitfield mask for alignments. + typedef enum { + ALIGN_CENTER = 0x0, + ALIGN_LEFT = 0x1, + ALIGN_TOP = 0x2, + ALIGN_RIGHT = 0x4, + ALIGN_BOTTOM = 0x8, + } AlignmentMasks; + + // Background tiling choices. + typedef enum { + NO_REPEAT = 0, + REPEAT_X = 1, + REPEAT_Y = 2, + REPEAT = 3 + } Tiling; + + // ThemeProvider implementation. + virtual void Init(Profile* profile); + virtual SkBitmap* GetBitmapNamed(int id) const; + virtual SkColor GetColor(int id) const; + virtual bool GetDisplayProperty(int id, int* result) const; + virtual bool ShouldUseNativeFrame() const; + virtual bool HasCustomImage(int id) const; + virtual RefCountedMemory* GetRawData(int id) const; +#if defined(TOOLKIT_USES_GTK) + // GdkPixbufs returned by GetPixbufNamed and GetRTLEnabledPixbufNamed are + // shared instances owned by the theme provider and should not be freed. + virtual GdkPixbuf* GetPixbufNamed(int id) const; + virtual GdkPixbuf* GetRTLEnabledPixbufNamed(int id) const; +#elif defined(OS_MACOSX) + virtual NSImage* GetNSImageNamed(int id, bool allow_default) const; + virtual NSColor* GetNSImageColorNamed(int id, bool allow_default) const; + virtual NSColor* GetNSColor(int id, bool allow_default) const; + virtual NSColor* GetNSColorTint(int id, bool allow_default) const; + virtual NSGradient* GetNSGradient(int id) const; +#endif + + // Set the current theme to the theme defined in |extension|. + virtual void SetTheme(Extension* extension); + + // Reset the theme to default. + virtual void UseDefaultTheme(); + + // Set the current theme to the native theme. On some platforms, the native + // theme is the default theme. + virtual void SetNativeTheme() { UseDefaultTheme(); } + + // Whether we're using the chrome default theme. Virtual so linux can check + // if we're using the GTK theme. + virtual bool UsingDefaultTheme(); + + // Gets the id of the last installed theme. (The theme may have been further + // locally customized.) + std::string GetThemeID() const; + + // This class needs to keep track of the number of theme infobars so that we + // clean up unused themes. + void OnInfobarDisplayed(); + + // Decrements the number of theme infobars. If the last infobar has been + // destroyed, uninstalls all themes that aren't the currently selected. + void OnInfobarDestroyed(); + + // Convert a bitfield alignment into a string like "top left". Public so that + // it can be used to generate CSS values. Takes a bitfield of AlignmentMasks. + static std::string AlignmentToString(int alignment); + + // Parse alignments from something like "top left" into a bitfield of + // AlignmentMasks + static int StringToAlignment(const std::string& alignment); + + // Convert a tiling value into a string like "no-repeat". Public + // so that it can be used to generate CSS values. Takes a Tiling. + static std::string TilingToString(int tiling); + + // Parse tiling values from something like "no-repeat" into a Tiling value. + static int StringToTiling(const std::string& tiling); + + // Returns the default tint for the given tint |id| TINT_* enum value. + static color_utils::HSL GetDefaultTint(int id); + + // Returns the default color for the given color |id| COLOR_* enum value. + static SkColor GetDefaultColor(int id); + + // Returns true and sets |result| to the requested default property, if |id| + // is valid. + static bool GetDefaultDisplayProperty(int id, int* result); + + // Returns the set of IDR_* resources that should be tinted. + static const std::set& GetTintableToolbarButtons(); + + // Save the images to be written to disk, mapping file path to id. + typedef std::map ImagesDiskCache; + + protected: + // Get the specified tint - |id| is one of the TINT_* enum values. + color_utils::HSL GetTint(int id) const; + + // Clears all the override fields and saves the dictionary. + virtual void ClearAllThemeData(); + + // Load theme data from preferences. + virtual void LoadThemePrefs(); + + // Let all the browser views know that themes have changed. + // extension is NULL iff the theme is being set to the + // default/system theme. + virtual void NotifyThemeChanged(Extension* extension); + +#if defined(OS_MACOSX) + // Let all the browser views know that themes have changed in a platform way. + virtual void NotifyPlatformThemeChanged(); +#endif // OS_MACOSX + + // Clears the platform-specific caches. Do not call directly; it's called + // from ClearCaches(). + virtual void FreePlatformCaches(); + + Profile* profile() { return profile_; } + + private: + friend class BrowserThemeProviderTest; + + // Saves the filename of the cached theme pack. + void SavePackName(const FilePath& pack_path); + + // Save the id of the last theme installed. + void SaveThemeID(const std::string& id); + + // Implementation of SetTheme() (and the fallback from LoadThemePrefs() in + // case we don't have a theme pack). + void BuildFromExtension(Extension* extension); + + // Remove preference values for themes that are no longer in use. + void RemoveUnusedThemes(); + +#if defined(TOOLKIT_USES_GTK) + // Loads an image and flips it horizontally if |rtl_enabled| is true. + GdkPixbuf* GetPixbufImpl(int id, bool rtl_enabled) const; +#endif + +#if defined(TOOLKIT_USES_GTK) + typedef std::map GdkPixbufMap; + mutable GdkPixbufMap gdk_pixbufs_; +#elif defined(OS_MACOSX) + typedef std::map NSImageMap; + mutable NSImageMap nsimage_cache_; + + // The bool member of the pair is whether the color is a default color. + typedef std::map > NSColorMap; + mutable NSColorMap nscolor_cache_; + + typedef std::map NSGradientMap; + mutable NSGradientMap nsgradient_cache_; +#endif + + ResourceBundle& rb_; + Profile* profile_; + + scoped_refptr theme_pack_; + + // The number of infobars currently displayed. + int number_of_infobars_; + + DISALLOW_COPY_AND_ASSIGN(BrowserThemeProvider); +}; + +#endif // CHROME_BROWSER_THEMES_BROWSER_THEME_PROVIDER_H_ diff --git a/chrome/browser/themes/browser_theme_provider_gtk.cc b/chrome/browser/themes/browser_theme_provider_gtk.cc new file mode 100644 index 0000000..a730f3b --- /dev/null +++ b/chrome/browser/themes/browser_theme_provider_gtk.cc @@ -0,0 +1,73 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/themes/browser_theme_provider.h" + +#include + +#include "base/i18n/rtl.h" +#include "base/logging.h" +#include "gfx/gtk_util.h" +#include "third_party/skia/include/core/SkBitmap.h" + +GdkPixbuf* BrowserThemeProvider::GetPixbufNamed(int id) const { + return GetPixbufImpl(id, false); +} + +GdkPixbuf* BrowserThemeProvider::GetRTLEnabledPixbufNamed(int id) const { + return GetPixbufImpl(id, true); +} + +GdkPixbuf* BrowserThemeProvider::GetPixbufImpl(int id, bool rtl_enabled) const { + DCHECK(CalledOnValidThread()); + // Use the negative |resource_id| for the key for BIDI-aware images. + int key = rtl_enabled ? -id : id; + + // Check to see if we already have the pixbuf in the cache. + GdkPixbufMap::const_iterator pixbufs_iter = gdk_pixbufs_.find(key); + if (pixbufs_iter != gdk_pixbufs_.end()) + return pixbufs_iter->second; + + SkBitmap* bitmap = GetBitmapNamed(id); + GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(bitmap); + + // We loaded successfully. Cache the pixbuf. + if (pixbuf) { + if (base::i18n::IsRTL() && rtl_enabled) { + GdkPixbuf* original_pixbuf = pixbuf; + pixbuf = gdk_pixbuf_flip(pixbuf, TRUE); + g_object_unref(original_pixbuf); + } + + gdk_pixbufs_[key] = pixbuf; + return pixbuf; + } + + // We failed to retrieve the bitmap, show a debugging red square. + LOG(WARNING) << "Unable to load GdkPixbuf with id " << id; + NOTREACHED(); // Want to assert in debug mode. + + static GdkPixbuf* empty_bitmap = NULL; + if (!empty_bitmap) { + // The placeholder bitmap is bright red so people notice the problem. + // This bitmap will be leaked, but this code should never be hit. + scoped_ptr skia_bitmap(new SkBitmap()); + skia_bitmap->setConfig(SkBitmap::kARGB_8888_Config, 32, 32); + skia_bitmap->allocPixels(); + skia_bitmap->eraseARGB(255, 255, 0, 0); + empty_bitmap = gfx::GdkPixbufFromSkBitmap(skia_bitmap.get()); + } + return empty_bitmap; +} + +void BrowserThemeProvider::FreePlatformCaches() { + DCHECK(CalledOnValidThread()); + + // Free GdkPixbufs. + for (GdkPixbufMap::iterator i = gdk_pixbufs_.begin(); + i != gdk_pixbufs_.end(); i++) { + g_object_unref(i->second); + } + gdk_pixbufs_.clear(); +} diff --git a/chrome/browser/themes/browser_theme_provider_mac.mm b/chrome/browser/themes/browser_theme_provider_mac.mm new file mode 100644 index 0000000..0ad2674 --- /dev/null +++ b/chrome/browser/themes/browser_theme_provider_mac.mm @@ -0,0 +1,317 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/themes/browser_theme_provider.h" + +#import + +#include "base/logging.h" +#include "chrome/browser/themes/browser_theme_pack.h" +#include "gfx/color_utils.h" +#include "skia/ext/skia_utils_mac.h" +#import "third_party/GTM/AppKit/GTMNSColor+Luminance.h" + +NSString* const kBrowserThemeDidChangeNotification = + @"BrowserThemeDidChangeNotification"; + +namespace { + +void HSLToHSB(const color_utils::HSL& hsl, CGFloat* h, CGFloat* s, CGFloat* b) { + SkColor color = color_utils::HSLToSkColor(hsl, 255); // alpha doesn't matter + SkScalar hsv[3]; + SkColorToHSV(color, hsv); + + *h = SkScalarToDouble(hsv[0]) / 360.0; + *s = SkScalarToDouble(hsv[1]); + *b = SkScalarToDouble(hsv[2]); +} + +} + +NSImage* BrowserThemeProvider::GetNSImageNamed(int id, + bool allow_default) const { + DCHECK(CalledOnValidThread()); + + if (!allow_default && !HasCustomImage(id)) + return nil; + + // Check to see if we already have the image in the cache. + NSImageMap::const_iterator nsimage_iter = nsimage_cache_.find(id); + if (nsimage_iter != nsimage_cache_.end()) + return nsimage_iter->second; + + // Why don't we load the file directly into the image instead of the whole + // SkBitmap > native conversion? + // - For consistency with other platforms. + // - To get the generated tinted images. + SkBitmap* bitmap = GetBitmapNamed(id); + NSImage* nsimage = gfx::SkBitmapToNSImage(*bitmap); + + // We loaded successfully. Cache the image. + if (nsimage) { + nsimage_cache_[id] = [nsimage retain]; + return nsimage; + } + + // We failed to retrieve the bitmap, show a debugging red square. + LOG(WARNING) << "Unable to load NSImage with id " << id; + NOTREACHED(); // Want to assert in debug mode. + + static NSImage* empty_image = NULL; + if (!empty_image) { + // The placeholder image is bright red so people notice the problem. This + // image will be leaked, but this code should never be hit. + NSRect image_rect = NSMakeRect(0, 0, 32, 32); + empty_image = [[NSImage alloc] initWithSize:image_rect.size]; + [empty_image lockFocus]; + [[NSColor redColor] set]; + NSRectFill(image_rect); + [empty_image unlockFocus]; + } + + return empty_image; +} + +NSColor* BrowserThemeProvider::GetNSImageColorNamed(int id, + bool allow_default) const { + DCHECK(CalledOnValidThread()); + + // Check to see if we already have the color in the cache. + NSColorMap::const_iterator nscolor_iter = nscolor_cache_.find(id); + if (nscolor_iter != nscolor_cache_.end()) { + bool cached_is_default = nscolor_iter->second.second; + if (!cached_is_default || allow_default) + return nscolor_iter->second.first; + } + + NSImage* image = GetNSImageNamed(id, allow_default); + if (!image) + return nil; + NSColor* image_color = [NSColor colorWithPatternImage:image]; + + // We loaded successfully. Cache the color. + if (image_color) { + nscolor_cache_[id] = std::make_pair([image_color retain], + !HasCustomImage(id)); + } + + return image_color; +} + +NSColor* BrowserThemeProvider::GetNSColor(int id, + bool allow_default) const { + DCHECK(CalledOnValidThread()); + + // Check to see if we already have the color in the cache. + NSColorMap::const_iterator nscolor_iter = nscolor_cache_.find(id); + if (nscolor_iter != nscolor_cache_.end()) { + bool cached_is_default = nscolor_iter->second.second; + if (!cached_is_default || allow_default) + return nscolor_iter->second.first; + } + + bool is_default = false; + SkColor sk_color; + if (theme_pack_.get() && theme_pack_->GetColor(id, &sk_color)) { + is_default = false; + } else { + is_default = true; + sk_color = GetDefaultColor(id); + } + + if (is_default && !allow_default) + return nil; + + NSColor* color = [NSColor + colorWithCalibratedRed:SkColorGetR(sk_color)/255.0 + green:SkColorGetG(sk_color)/255.0 + blue:SkColorGetB(sk_color)/255.0 + alpha:SkColorGetA(sk_color)/255.0]; + + // We loaded successfully. Cache the color. + if (color) + nscolor_cache_[id] = std::make_pair([color retain], is_default); + + return color; +} + +NSColor* BrowserThemeProvider::GetNSColorTint(int id, + bool allow_default) const { + DCHECK(CalledOnValidThread()); + + // Check to see if we already have the color in the cache. + NSColorMap::const_iterator nscolor_iter = nscolor_cache_.find(id); + if (nscolor_iter != nscolor_cache_.end()) { + bool cached_is_default = nscolor_iter->second.second; + if (!cached_is_default || allow_default) + return nscolor_iter->second.first; + } + + bool is_default = false; + color_utils::HSL tint; + if (theme_pack_.get() && theme_pack_->GetTint(id, &tint)) { + is_default = false; + } else { + is_default = true; + tint = GetDefaultTint(id); + } + + if (is_default && !allow_default) + return nil; + + NSColor* tint_color = nil; + if (tint.h == -1 && tint.s == -1 && tint.l == -1) { + tint_color = [NSColor blackColor]; + } else { + CGFloat hue, saturation, brightness; + HSLToHSB(tint, &hue, &saturation, &brightness); + + tint_color = [NSColor colorWithCalibratedHue:hue + saturation:saturation + brightness:brightness + alpha:1.0]; + } + + // We loaded successfully. Cache the color. + if (tint_color) + nscolor_cache_[id] = std::make_pair([tint_color retain], is_default); + + return tint_color; +} + +NSGradient* BrowserThemeProvider::GetNSGradient(int id) const { + DCHECK(CalledOnValidThread()); + + // Check to see if we already have the gradient in the cache. + NSGradientMap::const_iterator nsgradient_iter = nsgradient_cache_.find(id); + if (nsgradient_iter != nsgradient_cache_.end()) + return nsgradient_iter->second; + + NSGradient* gradient = nil; + + // Note that we are not leaking when we assign a retained object to + // |gradient|; in all cases we cache it before we return. + switch (id) { + case GRADIENT_FRAME_INCOGNITO: + case GRADIENT_FRAME_INCOGNITO_INACTIVE: { + // TODO(avi): can we simplify this? + BOOL active = id == GRADIENT_FRAME_INCOGNITO; + NSColor* base_color = [NSColor colorWithCalibratedRed:83/255.0 + green:108.0/255.0 + blue:140/255.0 + alpha:1.0]; + + NSColor *start_color = + [base_color gtm_colorAdjustedFor:GTMColorationBaseMidtone + faded:!active]; + NSColor *end_color = + [base_color gtm_colorAdjustedFor:GTMColorationBaseShadow + faded:!active]; + + if (!active) { + start_color = [start_color gtm_colorByAdjustingLuminance:0.1 + saturation:0.5]; + end_color = [end_color gtm_colorByAdjustingLuminance:0.1 + saturation:0.5]; + } + + gradient = [[NSGradient alloc] initWithStartingColor:start_color + endingColor:end_color]; + break; + } + + case GRADIENT_TOOLBAR: + case GRADIENT_TOOLBAR_INACTIVE: { + NSColor* base_color = [NSColor colorWithCalibratedWhite:0.2 alpha:1.0]; + BOOL faded = (id == GRADIENT_TOOLBAR_INACTIVE ) || + (id == GRADIENT_TOOLBAR_BUTTON_INACTIVE); + NSColor* start_color = + [base_color gtm_colorAdjustedFor:GTMColorationLightHighlight + faded:faded]; + NSColor* mid_color = + [base_color gtm_colorAdjustedFor:GTMColorationLightMidtone + faded:faded]; + NSColor* end_color = + [base_color gtm_colorAdjustedFor:GTMColorationLightShadow + faded:faded]; + NSColor* glow_color = + [base_color gtm_colorAdjustedFor:GTMColorationLightPenumbra + faded:faded]; + + gradient = + [[NSGradient alloc] initWithColorsAndLocations:start_color, 0.0, + mid_color, 0.25, + end_color, 0.5, + glow_color, 0.75, + nil]; + break; + } + + case GRADIENT_TOOLBAR_BUTTON: + case GRADIENT_TOOLBAR_BUTTON_INACTIVE: { + NSColor* start_color = [NSColor colorWithCalibratedWhite:1.0 alpha:0.0]; + NSColor* end_color = [NSColor colorWithCalibratedWhite:1.0 alpha:0.3]; + gradient = [[NSGradient alloc] initWithStartingColor:start_color + endingColor:end_color]; + break; + } + case GRADIENT_TOOLBAR_BUTTON_PRESSED: + case GRADIENT_TOOLBAR_BUTTON_PRESSED_INACTIVE: { + NSColor* base_color = [NSColor colorWithCalibratedWhite:0.5 alpha:1.0]; + BOOL faded = id == GRADIENT_TOOLBAR_BUTTON_PRESSED_INACTIVE; + NSColor* start_color = + [base_color gtm_colorAdjustedFor:GTMColorationBaseShadow + faded:faded]; + NSColor* end_color = + [base_color gtm_colorAdjustedFor:GTMColorationBaseMidtone + faded:faded]; + + gradient = [[NSGradient alloc] initWithStartingColor:start_color + endingColor:end_color]; + break; + } + default: + LOG(WARNING) << "Gradient request with unknown id " << id; + NOTREACHED(); // Want to assert in debug mode. + break; + } + + // We loaded successfully. Cache the gradient. + if (gradient) + nsgradient_cache_[id] = gradient; // created retained + + return gradient; +} + +// Let all the browser views know that themes have changed in a platform way. +void BrowserThemeProvider::NotifyPlatformThemeChanged() { + NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter]; + [defaultCenter postNotificationName:kBrowserThemeDidChangeNotification + object:[NSValue valueWithPointer:this]]; +} + +void BrowserThemeProvider::FreePlatformCaches() { + DCHECK(CalledOnValidThread()); + + // Free images. + for (NSImageMap::iterator i = nsimage_cache_.begin(); + i != nsimage_cache_.end(); i++) { + [i->second release]; + } + nsimage_cache_.clear(); + + // Free colors. + for (NSColorMap::iterator i = nscolor_cache_.begin(); + i != nscolor_cache_.end(); i++) { + [i->second.first release]; + } + nscolor_cache_.clear(); + + // Free gradients. + for (NSGradientMap::iterator i = nsgradient_cache_.begin(); + i != nsgradient_cache_.end(); i++) { + [i->second release]; + } + nsgradient_cache_.clear(); +} diff --git a/chrome/browser/themes/browser_theme_provider_unittest.cc b/chrome/browser/themes/browser_theme_provider_unittest.cc new file mode 100644 index 0000000..c99a946 --- /dev/null +++ b/chrome/browser/themes/browser_theme_provider_unittest.cc @@ -0,0 +1,51 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/themes/browser_theme_provider.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "base/json/json_reader.h" + +TEST(BrowserThemeProviderTest, AlignmentConversion) { + // Verify that we get out what we put in. + std::string top_left = "top left"; + int alignment = BrowserThemeProvider::StringToAlignment(top_left); + EXPECT_EQ(BrowserThemeProvider::ALIGN_TOP | BrowserThemeProvider::ALIGN_LEFT, + alignment); + EXPECT_EQ(top_left, BrowserThemeProvider::AlignmentToString(alignment)); + + alignment = BrowserThemeProvider::StringToAlignment("top"); + EXPECT_EQ(BrowserThemeProvider::ALIGN_TOP, alignment); + EXPECT_EQ("top", BrowserThemeProvider::AlignmentToString(alignment)); + + alignment = BrowserThemeProvider::StringToAlignment("left"); + EXPECT_EQ(BrowserThemeProvider::ALIGN_LEFT, alignment); + EXPECT_EQ("left", BrowserThemeProvider::AlignmentToString(alignment)); + + alignment = BrowserThemeProvider::StringToAlignment("right"); + EXPECT_EQ(BrowserThemeProvider::ALIGN_RIGHT, alignment); + EXPECT_EQ("right", BrowserThemeProvider::AlignmentToString(alignment)); + + alignment = BrowserThemeProvider::StringToAlignment("righttopbottom"); + EXPECT_EQ(BrowserThemeProvider::ALIGN_CENTER, alignment); + EXPECT_EQ("", BrowserThemeProvider::AlignmentToString(alignment)); +} + +TEST(BrowserThemeProviderTest, AlignmentConversionInput) { + // Verify that we output in an expected format. + int alignment = BrowserThemeProvider::StringToAlignment("right bottom"); + EXPECT_EQ("bottom right", BrowserThemeProvider::AlignmentToString(alignment)); + + // Verify that bad strings don't cause explosions. + alignment = BrowserThemeProvider::StringToAlignment("new zealand"); + EXPECT_EQ("", BrowserThemeProvider::AlignmentToString(alignment)); + + // Verify that bad strings don't cause explosions. + alignment = BrowserThemeProvider::StringToAlignment("new zealand top"); + EXPECT_EQ("top", BrowserThemeProvider::AlignmentToString(alignment)); + + // Verify that bad strings don't cause explosions. + alignment = BrowserThemeProvider::StringToAlignment("new zealandtop"); + EXPECT_EQ("", BrowserThemeProvider::AlignmentToString(alignment)); +} diff --git a/chrome/browser/views/bookmark_bar_instructions_view.cc b/chrome/browser/views/bookmark_bar_instructions_view.cc index c9e9487..adc708b 100644 --- a/chrome/browser/views/bookmark_bar_instructions_view.cc +++ b/chrome/browser/views/bookmark_bar_instructions_view.cc @@ -5,8 +5,8 @@ #include "chrome/browser/views/bookmark_bar_instructions_view.h" #include "app/l10n_util.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/defaults.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "grit/generated_resources.h" #include "views/controls/label.h" diff --git a/chrome/browser/views/bookmark_bar_view.cc b/chrome/browser/views/bookmark_bar_view.cc index 0c205b0..3e991d1 100644 --- a/chrome/browser/views/bookmark_bar_view.cc +++ b/chrome/browser/views/bookmark_bar_view.cc @@ -18,7 +18,6 @@ #include "chrome/browser/bookmarks/bookmark_model.h" #include "chrome/browser/bookmarks/bookmark_utils.h" #include "chrome/browser/browser.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/chrome_thread.h" #include "chrome/browser/importer/importer_data_types.h" #include "chrome/browser/metrics/user_metrics.h" @@ -29,6 +28,7 @@ #include "chrome/browser/sync/sync_ui_util.h" #include "chrome/browser/tab_contents/page_navigator.h" #include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/browser/view_ids.h" #include "chrome/browser/views/bookmark_context_menu.h" #include "chrome/browser/views/event_utils.h" diff --git a/chrome/browser/views/browser_actions_container.cc b/chrome/browser/views/browser_actions_container.cc index d944696..1db438f 100644 --- a/chrome/browser/views/browser_actions_container.cc +++ b/chrome/browser/views/browser_actions_container.cc @@ -11,16 +11,16 @@ #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "chrome/browser/browser.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/browser_window.h" #include "chrome/browser/extensions/extension_browser_event_router.h" #include "chrome/browser/extensions/extension_host.h" -#include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/extensions/extension_tabs_module.h" -#include "chrome/browser/renderer_host/render_widget_host_view.h" -#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/profile.h" +#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/renderer_host/render_widget_host_view.h" #include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/browser/view_ids.h" #include "chrome/browser/views/detachable_toolbar_view.h" #include "chrome/browser/views/extensions/browser_action_drag_data.h" diff --git a/chrome/browser/views/detachable_toolbar_view.cc b/chrome/browser/views/detachable_toolbar_view.cc index f7664c2..796425f 100644 --- a/chrome/browser/views/detachable_toolbar_view.cc +++ b/chrome/browser/views/detachable_toolbar_view.cc @@ -5,7 +5,7 @@ #include "chrome/browser/views/detachable_toolbar_view.h" #include "app/resource_bundle.h" -#include "chrome/browser/browser_theme_provider.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "gfx/canvas_skia.h" #include "gfx/skia_util.h" #include "grit/theme_resources.h" diff --git a/chrome/browser/views/download_item_view.cc b/chrome/browser/views/download_item_view.cc index 7dc9d5a..7dc8fa1 100644 --- a/chrome/browser/views/download_item_view.cc +++ b/chrome/browser/views/download_item_view.cc @@ -17,9 +17,9 @@ #include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/download/download_item_model.h" #include "chrome/browser/download/download_util.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/browser/views/download_shelf_view.h" #include "gfx/canvas_skia.h" #include "gfx/color_utils.h" diff --git a/chrome/browser/views/download_shelf_view.cc b/chrome/browser/views/download_shelf_view.cc index 5c2b606..ccf51d4 100644 --- a/chrome/browser/views/download_shelf_view.cc +++ b/chrome/browser/views/download_shelf_view.cc @@ -10,11 +10,11 @@ #include "app/resource_bundle.h" #include "base/logging.h" #include "chrome/browser/browser.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/download/download_item.h" #include "chrome/browser/download/download_item_model.h" #include "chrome/browser/download/download_manager.h" #include "chrome/browser/tab_contents/navigation_entry.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/browser/view_ids.h" #include "chrome/browser/views/download_item_view.h" #include "chrome/browser/views/frame/browser_view.h" diff --git a/chrome/browser/views/find_bar_view.cc b/chrome/browser/views/find_bar_view.cc index 62fa29c..0007d9c 100644 --- a/chrome/browser/views/find_bar_view.cc +++ b/chrome/browser/views/find_bar_view.cc @@ -11,14 +11,14 @@ #include "base/string_number_conversions.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/find_bar_controller.h" #include "chrome/browser/find_bar_state.h" #include "chrome/browser/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/themes/browser_theme_provider.h" +#include "chrome/browser/view_ids.h" #include "chrome/browser/views/find_bar_host.h" #include "chrome/browser/views/frame/browser_view.h" -#include "chrome/browser/view_ids.h" #include "gfx/canvas.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" diff --git a/chrome/browser/views/frame/browser_frame_gtk.cc b/chrome/browser/views/frame/browser_frame_gtk.cc index 3a9a1ba..0b529b7 100644 --- a/chrome/browser/views/frame/browser_frame_gtk.cc +++ b/chrome/browser/views/frame/browser_frame_gtk.cc @@ -5,9 +5,9 @@ #include "chrome/browser/views/frame/browser_frame_gtk.h" #include "base/logging.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/profile.h" #include "chrome/browser/status_bubble.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/browser/views/frame/app_panel_browser_frame_view.h" #include "chrome/browser/views/frame/browser_root_view.h" #include "chrome/browser/views/frame/browser_view.h" diff --git a/chrome/browser/views/frame/browser_frame_win.cc b/chrome/browser/views/frame/browser_frame_win.cc index 22fb3cc..5aad9a5 100644 --- a/chrome/browser/views/frame/browser_frame_win.cc +++ b/chrome/browser/views/frame/browser_frame_win.cc @@ -13,7 +13,7 @@ #include "base/win_util.h" #include "chrome/browser/profile.h" #include "chrome/browser/browser_list.h" -#include "chrome/browser/browser_theme_provider.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/browser/views/frame/app_panel_browser_frame_view.h" #include "chrome/browser/views/frame/browser_non_client_frame_view.h" #include "chrome/browser/views/frame/browser_root_view.h" diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc index 4f67d1d..79f4674 100644 --- a/chrome/browser/views/frame/browser_view.cc +++ b/chrome/browser/views/frame/browser_view.cc @@ -23,7 +23,6 @@ #include "chrome/browser/browser.h" #include "chrome/browser/browser_list.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/debugger/devtools_window.h" #include "chrome/browser/dom_ui/bug_report_ui.h" #include "chrome/browser/download/download_manager.h" @@ -37,6 +36,7 @@ #include "chrome/browser/tab_contents/match_preview.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tab_contents/tab_contents_view.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/browser/view_ids.h" #include "chrome/browser/views/accessible_view_helper.h" #include "chrome/browser/views/bookmark_bar_view.h" diff --git a/chrome/browser/views/frame/glass_browser_frame_view.cc b/chrome/browser/views/frame/glass_browser_frame_view.cc index e9f6a41..b532273 100644 --- a/chrome/browser/views/frame/glass_browser_frame_view.cc +++ b/chrome/browser/views/frame/glass_browser_frame_view.cc @@ -7,7 +7,7 @@ #include "app/resource_bundle.h" #include "app/theme_provider.h" #include "chrome/app/chrome_dll_resource.h" -#include "chrome/browser/browser_theme_provider.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/browser/views/frame/browser_view.h" #include "chrome/browser/views/tabs/side_tab_strip.h" #include "chrome/browser/views/tabs/tab.h" diff --git a/chrome/browser/views/frame/opaque_browser_frame_view.cc b/chrome/browser/views/frame/opaque_browser_frame_view.cc index 514a8c7..ffb131c 100644 --- a/chrome/browser/views/frame/opaque_browser_frame_view.cc +++ b/chrome/browser/views/frame/opaque_browser_frame_view.cc @@ -8,8 +8,8 @@ #include "app/resource_bundle.h" #include "app/theme_provider.h" #include "base/compiler_specific.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/browser/views/frame/browser_frame.h" #include "chrome/browser/views/frame/browser_view.h" #include "chrome/browser/views/tabs/tab_strip.h" diff --git a/chrome/browser/views/notifications/balloon_view.cc b/chrome/browser/views/notifications/balloon_view.cc index 22203f8..0f29833 100644 --- a/chrome/browser/views/notifications/balloon_view.cc +++ b/chrome/browser/views/notifications/balloon_view.cc @@ -10,7 +10,6 @@ #include "app/resource_bundle.h" #include "base/message_loop.h" #include "base/utf_string_conversions.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/notifications/balloon.h" #include "chrome/browser/notifications/balloon_collection.h" #include "chrome/browser/notifications/desktop_notification_service.h" @@ -18,6 +17,7 @@ #include "chrome/browser/profile.h" #include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/renderer_host/render_widget_host_view.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/browser/views/bubble_border.h" #include "chrome/browser/views/notifications/balloon_view_host.h" #include "chrome/common/notification_details.h" diff --git a/chrome/browser/views/status_bubble_views.cc b/chrome/browser/views/status_bubble_views.cc index 75f0e8c..9cdf889 100644 --- a/chrome/browser/views/status_bubble_views.cc +++ b/chrome/browser/views/status_bubble_views.cc @@ -13,7 +13,7 @@ #include "base/message_loop.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" -#include "chrome/browser/browser_theme_provider.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "gfx/canvas_skia.h" #include "gfx/point.h" #include "googleurl/src/gurl.h" diff --git a/chrome/browser/views/tabs/tab.cc b/chrome/browser/views/tabs/tab.cc index 7a0ba17..1f58245 100644 --- a/chrome/browser/views/tabs/tab.cc +++ b/chrome/browser/views/tabs/tab.cc @@ -11,8 +11,8 @@ #include "app/slide_animation.h" #include "app/throb_animation.h" #include "base/utf_string_conversions.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/defaults.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "gfx/canvas_skia.h" #include "gfx/favicon_size.h" #include "gfx/font.h" diff --git a/chrome/browser/views/tabs/tab_strip.cc b/chrome/browser/views/tabs/tab_strip.cc index adb1d6a..45b88e6 100644 --- a/chrome/browser/views/tabs/tab_strip.cc +++ b/chrome/browser/views/tabs/tab_strip.cc @@ -11,8 +11,8 @@ #include "base/compiler_specific.h" #include "base/stl_util-inl.h" #include "chrome/browser/browser.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/defaults.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/browser/view_ids.h" #include "chrome/browser/views/tabs/tab.h" #include "chrome/browser/views/tabs/tab_strip_controller.h" diff --git a/chrome/browser/views/theme_background.cc b/chrome/browser/views/theme_background.cc index 06f0f6f..ad8d2ed 100644 --- a/chrome/browser/views/theme_background.cc +++ b/chrome/browser/views/theme_background.cc @@ -5,8 +5,8 @@ #include "chrome/browser/views/theme_background.h" #include "app/resource_bundle.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/profile.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/browser/views/frame/browser_view.h" #include "gfx/canvas.h" #include "grit/app_resources.h" diff --git a/chrome/browser/views/toolbar_view.cc b/chrome/browser/views/toolbar_view.cc index 26f0768..5f919a8 100644 --- a/chrome/browser/views/toolbar_view.cc +++ b/chrome/browser/views/toolbar_view.cc @@ -8,10 +8,10 @@ #include "app/resource_bundle.h" #include "chrome/app/chrome_dll_resource.h" #include "chrome/browser/browser.h" -#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/browser_window.h" #include "chrome/browser/pref_service.h" #include "chrome/browser/profile.h" +#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/browser/upgrade_detector.h" #include "chrome/browser/view_ids.h" #include "chrome/browser/views/browser_actions_container.h" @@ -23,9 +23,9 @@ #include "chrome/common/pref_names.h" #include "gfx/canvas.h" #include "gfx/canvas_skia.h" +#include "gfx/skbitmap_operations.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" -#include "gfx/skbitmap_operations.h" #include "grit/theme_resources.h" #include "views/controls/button/button_dropdown.h" #include "views/focus/view_storage.h" -- cgit v1.1