summaryrefslogtreecommitdiffstats
path: root/chrome/browser/themes
diff options
context:
space:
mode:
authorerg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-23 17:36:42 +0000
committererg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-23 17:36:42 +0000
commita0ea76cbf036408912e337653500aaefd51586b9 (patch)
treeed1bf3f0a50025df8c2d4b7e083593ded4d2e01a /chrome/browser/themes
parent58492209d54a3af3e40fa0a876c9d6381d943188 (diff)
downloadchromium_src-a0ea76cbf036408912e337653500aaefd51586b9.zip
chromium_src-a0ea76cbf036408912e337653500aaefd51586b9.tar.gz
chromium_src-a0ea76cbf036408912e337653500aaefd51586b9.tar.bz2
Theme system cleanup
- Removes useless dependencies on themeing from content/ - Renames BrowserThemeProvider to ThemeService, along with name variants such as GtkThemeService. BrowserThemeProvider has grown by a lot to be more than an implementation of the ui::ThemeProvider interface. This change touches everything. - Rename theme_service.{h,cc} (which defined ThemeServiceFactory) to theme_service_factory.{h,cc}. BUG=77155 TEST=compiles. Review URL: http://codereview.chromium.org/6727005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79145 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/themes')
-rw-r--r--chrome/browser/themes/browser_theme_pack.cc156
-rw-r--r--chrome/browser/themes/browser_theme_pack_unittest.cc88
-rw-r--r--chrome/browser/themes/browser_theme_provider.cc644
-rw-r--r--chrome/browser/themes/browser_theme_provider.h288
-rw-r--r--chrome/browser/themes/browser_theme_provider_unittest.cc51
-rw-r--r--chrome/browser/themes/theme_service.cc677
-rw-r--r--chrome/browser/themes/theme_service.h295
-rw-r--r--chrome/browser/themes/theme_service_factory.cc109
-rw-r--r--chrome/browser/themes/theme_service_factory.h59
-rw-r--r--chrome/browser/themes/theme_service_gtk.cc (renamed from chrome/browser/themes/browser_theme_provider_gtk.cc)12
-rw-r--r--chrome/browser/themes/theme_service_mac.mm (renamed from chrome/browser/themes/browser_theme_provider_mac.mm)24
-rw-r--r--chrome/browser/themes/theme_service_unittest.cc51
12 files changed, 1225 insertions, 1229 deletions
diff --git a/chrome/browser/themes/browser_theme_pack.cc b/chrome/browser/themes/browser_theme_pack.cc
index 71c6116..93633a9 100644
--- a/chrome/browser/themes/browser_theme_pack.cc
+++ b/chrome/browser/themes/browser_theme_pack.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -9,7 +9,7 @@
#include "base/threading/thread_restrictions.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
-#include "chrome/browser/themes/browser_theme_provider.h"
+#include "chrome/browser/themes/theme_service.h"
#include "content/browser/browser_thread.h"
#include "grit/app_resources.h"
#include "grit/theme_resources.h"
@@ -174,57 +174,57 @@ struct StringToIntTable {
// 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 },
+ { "buttons", ThemeService::TINT_BUTTONS },
+ { "frame", ThemeService::TINT_FRAME },
+ { "frame_inactive", ThemeService::TINT_FRAME_INACTIVE },
+ { "frame_incognito", ThemeService::TINT_FRAME_INCOGNITO },
{ "frame_incognito_inactive",
- BrowserThemeProvider::TINT_FRAME_INCOGNITO_INACTIVE },
- { "background_tab", BrowserThemeProvider::TINT_BACKGROUND_TAB },
+ ThemeService::TINT_FRAME_INCOGNITO_INACTIVE },
+ { "background_tab", ThemeService::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", ThemeService::COLOR_FRAME },
+ { "frame_inactive", ThemeService::COLOR_FRAME_INACTIVE },
+ { "frame_incognito", ThemeService::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 },
+ ThemeService::COLOR_FRAME_INCOGNITO_INACTIVE },
+ { "toolbar", ThemeService::COLOR_TOOLBAR },
+ { "tab_text", ThemeService::COLOR_TAB_TEXT },
+ { "tab_background_text", ThemeService::COLOR_BACKGROUND_TAB_TEXT },
+ { "bookmark_text", ThemeService::COLOR_BOOKMARK_TEXT },
+ { "ntp_background", ThemeService::COLOR_NTP_BACKGROUND },
+ { "ntp_text", ThemeService::COLOR_NTP_TEXT },
+ { "ntp_link", ThemeService::COLOR_NTP_LINK },
+ { "ntp_link_underline", ThemeService::COLOR_NTP_LINK_UNDERLINE },
+ { "ntp_header", ThemeService::COLOR_NTP_HEADER },
+ { "ntp_section", ThemeService::COLOR_NTP_SECTION },
+ { "ntp_section_text", ThemeService::COLOR_NTP_SECTION_TEXT },
+ { "ntp_section_link", ThemeService::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 },
+ ThemeService::COLOR_NTP_SECTION_LINK_UNDERLINE },
+ { "control_background", ThemeService::COLOR_CONTROL_BACKGROUND },
+ { "button_background", ThemeService::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 },
+ ThemeService::NTP_BACKGROUND_ALIGNMENT },
+ { "ntp_background_repeat", ThemeService::NTP_BACKGROUND_TILING },
+ { "ntp_logo_alternate", ThemeService::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 },
+ { "no-repeat", ThemeService::NO_REPEAT },
+ { "repeat-x", ThemeService::REPEAT_X },
+ { "repeat-y", ThemeService::REPEAT_Y },
+ { "repeat", ThemeService::REPEAT },
{ NULL, 0 }
};
@@ -246,14 +246,14 @@ struct IntToIntTable {
// 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, ThemeService::TINT_FRAME },
+ { PRS_THEME_FRAME_INACTIVE, ThemeService::TINT_FRAME_INACTIVE },
+ { PRS_THEME_FRAME_OVERLAY, ThemeService::TINT_FRAME },
{ PRS_THEME_FRAME_OVERLAY_INACTIVE,
- BrowserThemeProvider::TINT_FRAME_INACTIVE },
- { PRS_THEME_FRAME_INCOGNITO, BrowserThemeProvider::TINT_FRAME_INCOGNITO },
+ ThemeService::TINT_FRAME_INACTIVE },
+ { PRS_THEME_FRAME_INCOGNITO, ThemeService::TINT_FRAME_INCOGNITO },
{ PRS_THEME_FRAME_INCOGNITO_INACTIVE,
- BrowserThemeProvider::TINT_FRAME_INCOGNITO_INACTIVE }
+ ThemeService::TINT_FRAME_INCOGNITO_INACTIVE }
};
// Mapping used in GenerateTabBackgroundImages() to associate what frame image
@@ -355,7 +355,7 @@ BrowserThemePack* BrowserThemePack::BuildFromExtension(
// 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->GetTintInternal(ThemeService::TINT_BUTTONS),
&pack->prepared_images_);
#endif
@@ -705,56 +705,56 @@ void BrowserThemePack::ReadColorsFromJSON(
void BrowserThemePack::GenerateMissingColors(
std::map<int, SkColor>* 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(ThemeService::COLOR_NTP_HEADER) &&
+ colors->count(ThemeService::COLOR_NTP_SECTION)) {
+ (*colors)[ThemeService::COLOR_NTP_HEADER] =
+ (*colors)[ThemeService::COLOR_NTP_SECTION];
}
- if (!colors->count(BrowserThemeProvider::COLOR_NTP_SECTION_LINK_UNDERLINE) &&
- colors->count(BrowserThemeProvider::COLOR_NTP_SECTION_LINK)) {
+ if (!colors->count(ThemeService::COLOR_NTP_SECTION_LINK_UNDERLINE) &&
+ colors->count(ThemeService::COLOR_NTP_SECTION_LINK)) {
SkColor color_section_link =
- (*colors)[BrowserThemeProvider::COLOR_NTP_SECTION_LINK];
- (*colors)[BrowserThemeProvider::COLOR_NTP_SECTION_LINK_UNDERLINE] =
+ (*colors)[ThemeService::COLOR_NTP_SECTION_LINK];
+ (*colors)[ThemeService::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] =
+ if (!colors->count(ThemeService::COLOR_NTP_LINK_UNDERLINE) &&
+ colors->count(ThemeService::COLOR_NTP_LINK)) {
+ SkColor color_link = (*colors)[ThemeService::COLOR_NTP_LINK];
+ (*colors)[ThemeService::COLOR_NTP_LINK_UNDERLINE] =
SkColorSetA(color_link, SkColorGetA(color_link) / 3);
}
// Generate frame colors, if missing. (See GenerateFrameColors()).
SkColor frame;
std::map<int, SkColor>::const_iterator it =
- colors->find(BrowserThemeProvider::COLOR_FRAME);
+ colors->find(ThemeService::COLOR_FRAME);
if (it != colors->end()) {
frame = it->second;
} else {
- frame = BrowserThemeProvider::GetDefaultColor(
- BrowserThemeProvider::COLOR_FRAME);
+ frame = ThemeService::GetDefaultColor(
+ ThemeService::COLOR_FRAME);
}
- if (!colors->count(BrowserThemeProvider::COLOR_FRAME)) {
- (*colors)[BrowserThemeProvider::COLOR_FRAME] =
- HSLShift(frame, GetTintInternal(BrowserThemeProvider::TINT_FRAME));
+ if (!colors->count(ThemeService::COLOR_FRAME)) {
+ (*colors)[ThemeService::COLOR_FRAME] =
+ HSLShift(frame, GetTintInternal(ThemeService::TINT_FRAME));
}
- if (!colors->count(BrowserThemeProvider::COLOR_FRAME_INACTIVE)) {
- (*colors)[BrowserThemeProvider::COLOR_FRAME_INACTIVE] =
+ if (!colors->count(ThemeService::COLOR_FRAME_INACTIVE)) {
+ (*colors)[ThemeService::COLOR_FRAME_INACTIVE] =
HSLShift(frame, GetTintInternal(
- BrowserThemeProvider::TINT_FRAME_INACTIVE));
+ ThemeService::TINT_FRAME_INACTIVE));
}
- if (!colors->count(BrowserThemeProvider::COLOR_FRAME_INCOGNITO)) {
- (*colors)[BrowserThemeProvider::COLOR_FRAME_INCOGNITO] =
+ if (!colors->count(ThemeService::COLOR_FRAME_INCOGNITO)) {
+ (*colors)[ThemeService::COLOR_FRAME_INCOGNITO] =
HSLShift(frame, GetTintInternal(
- BrowserThemeProvider::TINT_FRAME_INCOGNITO));
+ ThemeService::TINT_FRAME_INCOGNITO));
}
- if (!colors->count(BrowserThemeProvider::COLOR_FRAME_INCOGNITO_INACTIVE)) {
- (*colors)[BrowserThemeProvider::COLOR_FRAME_INCOGNITO_INACTIVE] =
+ if (!colors->count(ThemeService::COLOR_FRAME_INCOGNITO_INACTIVE)) {
+ (*colors)[ThemeService::COLOR_FRAME_INCOGNITO_INACTIVE] =
HSLShift(frame, GetTintInternal(
- BrowserThemeProvider::TINT_FRAME_INCOGNITO_INACTIVE));
+ ThemeService::TINT_FRAME_INCOGNITO_INACTIVE));
}
}
@@ -775,26 +775,26 @@ void BrowserThemePack::BuildDisplayPropertiesFromJSON(
iter != display_properties_value->end_keys(); ++iter) {
int property_id = GetIntForString(*iter, kDisplayProperties);
switch (property_id) {
- case BrowserThemeProvider::NTP_BACKGROUND_ALIGNMENT: {
+ case ThemeService::NTP_BACKGROUND_ALIGNMENT: {
std::string val;
if (display_properties_value->GetString(*iter, &val)) {
- temp_properties[BrowserThemeProvider::NTP_BACKGROUND_ALIGNMENT] =
- BrowserThemeProvider::StringToAlignment(val);
+ temp_properties[ThemeService::NTP_BACKGROUND_ALIGNMENT] =
+ ThemeService::StringToAlignment(val);
}
break;
}
- case BrowserThemeProvider::NTP_BACKGROUND_TILING: {
+ case ThemeService::NTP_BACKGROUND_TILING: {
std::string val;
if (display_properties_value->GetString(*iter, &val)) {
- temp_properties[BrowserThemeProvider::NTP_BACKGROUND_TILING] =
+ temp_properties[ThemeService::NTP_BACKGROUND_TILING] =
GetIntForString(val, kTilingStrings);
}
break;
}
- case BrowserThemeProvider::NTP_LOGO_ALTERNATE: {
+ case ThemeService::NTP_LOGO_ALTERNATE: {
int val = 0;
if (display_properties_value->GetInteger(*iter, &val))
- temp_properties[BrowserThemeProvider::NTP_LOGO_ALTERNATE] = val;
+ temp_properties[ThemeService::NTP_LOGO_ALTERNATE] = val;
break;
}
}
@@ -945,7 +945,7 @@ void BrowserThemePack::GenerateTintedButtons(
if (button_tint.h != -1 || button_tint.s != -1 || button_tint.l != -1) {
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
const std::set<int>& idr_ids =
- BrowserThemeProvider::GetTintableToolbarButtons();
+ ThemeService::GetTintableToolbarButtons();
for (std::set<int>::const_iterator it = idr_ids.begin();
it != idr_ids.end(); ++it) {
int prs_id = GetPersistentIDByIDR(*it);
@@ -973,7 +973,7 @@ void BrowserThemePack::GenerateTabBackgroundImages(ImageCache* bitmaps) const {
if (it != bitmaps->end()) {
SkBitmap bg_tint = SkBitmapOperations::CreateHSLShiftedBitmap(
*(it->second), GetTintInternal(
- BrowserThemeProvider::TINT_BACKGROUND_TAB));
+ ThemeService::TINT_BACKGROUND_TAB));
int vertical_offset = bitmaps->count(prs_id)
? kRestoredTabVerticalOffset : 0;
SkBitmap* bg_tab = new SkBitmap(SkBitmapOperations::CreateTiledBitmap(
@@ -1046,5 +1046,5 @@ color_utils::HSL BrowserThemePack::GetTintInternal(int id) const {
}
}
- return BrowserThemeProvider::GetDefaultTint(id);
+ return ThemeService::GetDefaultTint(id);
}
diff --git a/chrome/browser/themes/browser_theme_pack_unittest.cc b/chrome/browser/themes/browser_theme_pack_unittest.cc
index 72219f0..7eb8b5f 100644
--- a/chrome/browser/themes/browser_theme_pack_unittest.cc
+++ b/chrome/browser/themes/browser_theme_pack_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -10,7 +10,7 @@
#include "base/path_service.h"
#include "base/scoped_temp_dir.h"
#include "base/values.h"
-#include "chrome/browser/themes/browser_theme_provider.h"
+#include "chrome/browser/themes/theme_service.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/json_value_serializer.h"
#include "content/browser/browser_thread.h"
@@ -35,9 +35,9 @@ class BrowserThemePackTest : public ::testing::Test {
void GenerateDefaultFrameColor(std::map<int, SkColor>* colors,
int color, int tint) {
(*colors)[color] = HSLShift(
- BrowserThemeProvider::GetDefaultColor(
- BrowserThemeProvider::COLOR_FRAME),
- BrowserThemeProvider::GetDefaultTint(tint));
+ ThemeService::GetDefaultColor(
+ ThemeService::COLOR_FRAME),
+ ThemeService::GetDefaultTint(tint));
}
// Returns a mapping from each COLOR_* constant to the default value for this
@@ -45,23 +45,23 @@ class BrowserThemePackTest : public ::testing::Test {
// run the resulting thing through VerifyColorMap().
std::map<int, SkColor> GetDefaultColorMap() {
std::map<int, SkColor> colors;
- for (int i = BrowserThemeProvider::COLOR_FRAME;
- i <= BrowserThemeProvider::COLOR_BUTTON_BACKGROUND; ++i) {
- colors[i] = BrowserThemeProvider::GetDefaultColor(i);
+ for (int i = ThemeService::COLOR_FRAME;
+ i <= ThemeService::COLOR_BUTTON_BACKGROUND; ++i) {
+ colors[i] = ThemeService::GetDefaultColor(i);
}
- GenerateDefaultFrameColor(&colors, BrowserThemeProvider::COLOR_FRAME,
- BrowserThemeProvider::TINT_FRAME);
+ GenerateDefaultFrameColor(&colors, ThemeService::COLOR_FRAME,
+ ThemeService::TINT_FRAME);
GenerateDefaultFrameColor(&colors,
- BrowserThemeProvider::COLOR_FRAME_INACTIVE,
- BrowserThemeProvider::TINT_FRAME_INACTIVE);
+ ThemeService::COLOR_FRAME_INACTIVE,
+ ThemeService::TINT_FRAME_INACTIVE);
GenerateDefaultFrameColor(&colors,
- BrowserThemeProvider::COLOR_FRAME_INCOGNITO,
- BrowserThemeProvider::TINT_FRAME_INCOGNITO);
+ ThemeService::COLOR_FRAME_INCOGNITO,
+ ThemeService::TINT_FRAME_INCOGNITO);
GenerateDefaultFrameColor(
&colors,
- BrowserThemeProvider::COLOR_FRAME_INCOGNITO_INACTIVE,
- BrowserThemeProvider::TINT_FRAME_INCOGNITO_INACTIVE);
+ ThemeService::COLOR_FRAME_INCOGNITO_INACTIVE,
+ ThemeService::TINT_FRAME_INCOGNITO_INACTIVE);
return colors;
}
@@ -69,7 +69,7 @@ class BrowserThemePackTest : public ::testing::Test {
void VerifyColorMap(const std::map<int, SkColor>& color_map) {
for (std::map<int, SkColor>::const_iterator it = color_map.begin();
it != color_map.end(); ++it) {
- SkColor color = BrowserThemeProvider::GetDefaultColor(it->first);
+ SkColor color = ThemeService::GetDefaultColor(it->first);
theme_pack_->GetColor(it->first, &color);
EXPECT_EQ(it->second, color) << "Color id = " << it->first;
}
@@ -148,25 +148,25 @@ class BrowserThemePackTest : public ::testing::Test {
void VerifyStarGazing(BrowserThemePack* pack) {
// First check that values we know exist, exist.
SkColor color;
- EXPECT_TRUE(pack->GetColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT,
+ EXPECT_TRUE(pack->GetColor(ThemeService::COLOR_BOOKMARK_TEXT,
&color));
EXPECT_EQ(SK_ColorBLACK, color);
- EXPECT_TRUE(pack->GetColor(BrowserThemeProvider::COLOR_NTP_BACKGROUND,
+ EXPECT_TRUE(pack->GetColor(ThemeService::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_TRUE(pack->GetTint(ThemeService::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);
+ ThemeService::NTP_BACKGROUND_ALIGNMENT, &val));
+ EXPECT_EQ(ThemeService::ALIGN_TOP, val);
// The stargazing theme defines the following images:
EXPECT_TRUE(pack->HasCustomImage(IDR_THEME_BUTTON_BACKGROUND));
@@ -185,9 +185,9 @@ class BrowserThemePackTest : public ::testing::Test {
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,
+ EXPECT_FALSE(pack->GetColor(ThemeService::COLOR_CONTROL_BACKGROUND,
&color));
- EXPECT_FALSE(pack->GetTint(BrowserThemeProvider::TINT_FRAME, &actual));
+ EXPECT_FALSE(pack->GetTint(ThemeService::TINT_FRAME, &actual));
}
MessageLoop message_loop;
@@ -207,11 +207,11 @@ TEST_F(BrowserThemePackTest, DeriveUnderlineLinkColor) {
std::map<int, SkColor> colors = GetDefaultColorMap();
SkColor link_color = SkColorSetRGB(128, 128, 128);
- colors[BrowserThemeProvider::COLOR_NTP_LINK] = link_color;
- colors[BrowserThemeProvider::COLOR_NTP_LINK_UNDERLINE] =
+ colors[ThemeService::COLOR_NTP_LINK] = link_color;
+ colors[ThemeService::COLOR_NTP_LINK_UNDERLINE] =
BuildThirdOpacity(link_color);
- colors[BrowserThemeProvider::COLOR_NTP_SECTION_LINK] = link_color;
- colors[BrowserThemeProvider::COLOR_NTP_SECTION_LINK_UNDERLINE] =
+ colors[ThemeService::COLOR_NTP_SECTION_LINK] = link_color;
+ colors[ThemeService::COLOR_NTP_SECTION_LINK_UNDERLINE] =
BuildThirdOpacity(link_color);
VerifyColorMap(colors);
@@ -229,10 +229,10 @@ TEST_F(BrowserThemePackTest, ProvideUnderlineLinkColor) {
std::map<int, SkColor> 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] =
+ colors[ThemeService::COLOR_NTP_LINK] = link_color;
+ colors[ThemeService::COLOR_NTP_LINK_UNDERLINE] = underline_color;
+ colors[ThemeService::COLOR_NTP_SECTION_LINK] = link_color;
+ colors[ThemeService::COLOR_NTP_SECTION_LINK_UNDERLINE] =
underline_color;
VerifyColorMap(colors);
@@ -244,8 +244,8 @@ TEST_F(BrowserThemePackTest, UseSectionColorAsNTPHeader) {
std::map<int, SkColor> colors = GetDefaultColorMap();
SkColor ntp_color = SkColorSetRGB(190, 190, 190);
- colors[BrowserThemeProvider::COLOR_NTP_HEADER] = ntp_color;
- colors[BrowserThemeProvider::COLOR_NTP_SECTION] = ntp_color;
+ colors[ThemeService::COLOR_NTP_HEADER] = ntp_color;
+ colors[ThemeService::COLOR_NTP_SECTION] = ntp_color;
VerifyColorMap(colors);
}
@@ -257,8 +257,8 @@ TEST_F(BrowserThemePackTest, ProvideNtpHeaderColor) {
std::map<int, SkColor> 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;
+ colors[ThemeService::COLOR_NTP_HEADER] = ntp_header;
+ colors[ThemeService::COLOR_NTP_SECTION] = ntp_section;
VerifyColorMap(colors);
}
@@ -269,7 +269,7 @@ TEST_F(BrowserThemePackTest, CanReadTints) {
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));
+ ThemeService::TINT_BUTTONS, &actual));
EXPECT_DOUBLE_EQ(expected.h, actual.h);
EXPECT_DOUBLE_EQ(expected.s, actual.s);
EXPECT_DOUBLE_EQ(expected.l, actual.l);
@@ -283,15 +283,15 @@ TEST_F(BrowserThemePackTest, CanReadDisplayProperties) {
int out_val;
EXPECT_TRUE(theme_pack_->GetDisplayProperty(
- BrowserThemeProvider::NTP_BACKGROUND_ALIGNMENT, &out_val));
- EXPECT_EQ(BrowserThemeProvider::ALIGN_BOTTOM, out_val);
+ ThemeService::NTP_BACKGROUND_ALIGNMENT, &out_val));
+ EXPECT_EQ(ThemeService::ALIGN_BOTTOM, out_val);
EXPECT_TRUE(theme_pack_->GetDisplayProperty(
- BrowserThemeProvider::NTP_BACKGROUND_TILING, &out_val));
- EXPECT_EQ(BrowserThemeProvider::REPEAT_X, out_val);
+ ThemeService::NTP_BACKGROUND_TILING, &out_val));
+ EXPECT_EQ(ThemeService::REPEAT_X, out_val);
EXPECT_TRUE(theme_pack_->GetDisplayProperty(
- BrowserThemeProvider::NTP_LOGO_ALTERNATE, &out_val));
+ ThemeService::NTP_LOGO_ALTERNATE, &out_val));
EXPECT_EQ(0, out_val);
}
@@ -335,7 +335,7 @@ TEST_F(BrowserThemePackTest, InvalidTints) {
// 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,
+ EXPECT_FALSE(theme_pack_->GetTint(ThemeService::TINT_BUTTONS,
&actual));
}
@@ -346,7 +346,7 @@ TEST_F(BrowserThemePackTest, InvalidDisplayProperties) {
int out_val;
EXPECT_FALSE(theme_pack_->GetDisplayProperty(
- BrowserThemeProvider::NTP_BACKGROUND_ALIGNMENT, &out_val));
+ ThemeService::NTP_BACKGROUND_ALIGNMENT, &out_val));
}
// These three tests should just not cause a segmentation fault.
diff --git a/chrome/browser/themes/browser_theme_provider.cc b/chrome/browser/themes/browser_theme_provider.cc
deleted file mode 100644
index 3c8ee4a..0000000
--- a/chrome/browser/themes/browser_theme_provider.cc
+++ /dev/null
@@ -1,644 +0,0 @@
-// Copyright (c) 2011 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 "base/string_split.h"
-#include "base/string_util.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/metrics/user_metrics.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/themes/browser_theme_pack.h"
-#include "chrome/common/chrome_constants.h"
-#include "chrome/common/pref_names.h"
-#include "content/common/notification_service.h"
-#include "content/common/notification_type.h"
-#include "grit/app_resources.h"
-#include "grit/theme_resources.h"
-#include "ui/base/resource/resource_bundle.h"
-
-#if defined(OS_WIN)
-#include "views/widget/widget_win.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";
-
-// The default theme if we haven't installed a theme yet or if we've clicked
-// the "Use Classic" button.
-const char* BrowserThemeProvider::kDefaultThemeID = "";
-
-namespace {
-
-// The default theme if we've gone to the theme gallery and installed the
-// "Default" theme. We have to detect this case specifically. (By the time we
-// realize we've installed the default theme, we already have an extension
-// unpacked on the filesystem.)
-const char* kDefaultThemeGalleryID = "hkacjpbfdknhflllbcmjibkdeoafencn";
-
-SkColor TintForUnderline(SkColor input) {
- return SkColorSetA(input, SkColorGetA(input) / 3);
-}
-
-SkColor IncreaseLightness(SkColor color, double percent) {
- color_utils::HSL result;
- color_utils::SkColorToHSL(color, &result);
- result.l += (1 - result.l) * percent;
- return color_utils::HSLToSkColor(result, SkColorGetA(color));
-}
-
-// 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(150, 150, 150);
-const SkColor kDefaultColorNTPSection = SkColorSetRGB(229, 229, 229);
-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<int> 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<BrowserThemePack> 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();
-}
-
-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;
-
- // For backward compat with older themes, some newer colors are generated from
- // older ones if they are missing.
- switch (id) {
- case COLOR_NTP_SECTION_HEADER_TEXT:
- return IncreaseLightness(GetColor(COLOR_NTP_TEXT), 0.30);
- case COLOR_NTP_SECTION_HEADER_TEXT_HOVER:
- return GetColor(COLOR_NTP_TEXT);
- case COLOR_NTP_SECTION_HEADER_RULE:
- return IncreaseLightness(GetColor(COLOR_NTP_TEXT), 0.70);
- case COLOR_NTP_SECTION_HEADER_RULE_LIGHT:
- return IncreaseLightness(GetColor(COLOR_NTP_TEXT), 0.86);
- case COLOR_NTP_TEXT_LIGHT:
- return IncreaseLightness(GetColor(COLOR_NTP_TEXT), 0.40);
- }
-
- 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 views::WidgetWin::IsAeroGlassEnabled();
-#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(const 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;
- ExtensionService* service = profile_->GetExtensionService();
- if (!service)
- return;
- std::string current_theme = GetThemeID();
- std::vector<std::string> 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_);
-}
-
-void BrowserThemeProvider::SetNativeTheme() {
- UseDefaultTheme();
-}
-
-bool BrowserThemeProvider::UsingDefaultTheme() {
- std::string id = GetThemeID();
- return id == BrowserThemeProvider::kDefaultThemeID ||
- id == kDefaultThemeGalleryID;
-}
-
-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<std::wstring> split;
- base::SplitStringAlongWhitespace(UTF8ToWide(alignment), &split);
-
- int alignment_mask = 0;
- for (std::vector<std::wstring>::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<int>& BrowserThemeProvider::GetTintableToolbarButtons() {
- static std::set<int> button_set;
- if (button_set.empty()) {
- button_set = std::set<int>(
- 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.
- ExtensionService* service = profile_->GetExtensionService();
- if (service) {
- const 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(const Extension* extension) {
- VLOG(1) << "Sending BROWSER_THEME_CHANGED";
- // Redraw!
- NotificationService* service = NotificationService::current();
- service->Notify(NotificationType::BROWSER_THEME_CHANGED,
- Source<BrowserThemeProvider>(this),
- Details<const Extension>(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(const Extension* extension) {
- scoped_refptr<BrowserThemePack> 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);
- BrowserThread::PostTask(BrowserThread::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
deleted file mode 100644
index 92a5c57..0000000
--- a/chrome/browser/themes/browser_theme_provider.h
+++ /dev/null
@@ -1,288 +0,0 @@
-// Copyright (c) 2011 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 <map>
-#include <set>
-#include <string>
-
-#include "base/ref_counted.h"
-#include "base/threading/non_thread_safe.h"
-#include "ui/base/theme_provider.h"
-
-class BrowserThemePack;
-class BrowserThemeProviderTest;
-class Extension;
-class FilePath;
-class Profile;
-
-namespace color_utils {
-struct HSL;
-}
-
-namespace ui {
-class ResourceBundle;
-}
-using ui::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 base::NonThreadSafe,
- public ui::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,
-
- // These colors don't have constant default values. They are derived from
- // the runtime value of other colors.
- COLOR_NTP_SECTION_HEADER_TEXT,
- COLOR_NTP_SECTION_HEADER_TEXT_HOVER,
- COLOR_NTP_SECTION_HEADER_RULE,
- COLOR_NTP_SECTION_HEADER_RULE_LIGHT,
- COLOR_NTP_TEXT_LIGHT,
-
- 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;
-
- // ui::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(const 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();
-
- // 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.)
- virtual 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<int>& GetTintableToolbarButtons();
-
- // Remove preference values for themes that are no longer in use.
- void RemoveUnusedThemes();
-
- // Save the images to be written to disk, mapping file path to id.
- typedef std::map<FilePath, int> 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(const 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(const Extension* extension);
-
-#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<int, GdkPixbuf*> GdkPixbufMap;
- mutable GdkPixbufMap gdk_pixbufs_;
-#elif defined(OS_MACOSX)
- typedef std::map<int, NSImage*> NSImageMap;
- mutable NSImageMap nsimage_cache_;
-
- // The bool member of the pair is whether the color is a default color.
- typedef std::map<int, std::pair<NSColor*, bool> > NSColorMap;
- mutable NSColorMap nscolor_cache_;
-
- typedef std::map<int, NSGradient*> NSGradientMap;
- mutable NSGradientMap nsgradient_cache_;
-#endif
-
- ResourceBundle& rb_;
- Profile* profile_;
-
- scoped_refptr<BrowserThemePack> 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_unittest.cc b/chrome/browser/themes/browser_theme_provider_unittest.cc
deleted file mode 100644
index c99a946..0000000
--- a/chrome/browser/themes/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/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/themes/theme_service.cc b/chrome/browser/themes/theme_service.cc
index eae2b76..1731b47 100644
--- a/chrome/browser/themes/theme_service.cc
+++ b/chrome/browser/themes/theme_service.cc
@@ -4,106 +4,641 @@
#include "chrome/browser/themes/theme_service.h"
-#include "base/logging.h"
+#include "base/string_split.h"
+#include "base/string_util.h"
+#include "base/utf_string_conversions.h"
#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/metrics/user_metrics.h"
#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/themes/browser_theme_provider.h"
+#include "chrome/browser/themes/browser_theme_pack.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/pref_names.h"
#include "content/common/notification_service.h"
+#include "content/common/notification_type.h"
+#include "grit/app_resources.h"
+#include "grit/theme_resources.h"
+#include "ui/base/resource/resource_bundle.h"
-#if defined(TOOLKIT_USES_GTK)
-#include "chrome/browser/ui/gtk/gtk_theme_provider.h"
+#if defined(OS_WIN)
+#include "views/widget/widget_win.h"
#endif
-// static
-BrowserThemeProvider* ThemeServiceFactory::GetForProfile(Profile* top_profile) {
- // We may be asked for the Theme of an incognito profile. Make sure we're
- // operating on the real profile.
- Profile* profile = top_profile->GetOriginalProfile();
+// Strings used in alignment properties.
+const char* ThemeService::kAlignmentTop = "top";
+const char* ThemeService::kAlignmentBottom = "bottom";
+const char* ThemeService::kAlignmentLeft = "left";
+const char* ThemeService::kAlignmentRight = "right";
+
+// Strings used in background tiling repetition properties.
+const char* ThemeService::kTilingNoRepeat = "no-repeat";
+const char* ThemeService::kTilingRepeatX = "repeat-x";
+const char* ThemeService::kTilingRepeatY = "repeat-y";
+const char* ThemeService::kTilingRepeat = "repeat";
+
+// The default theme if we haven't installed a theme yet or if we've clicked
+// the "Use Classic" button.
+const char* ThemeService::kDefaultThemeID = "";
+
+namespace {
- ThemeServiceFactory* service = GetInstance();
+// The default theme if we've gone to the theme gallery and installed the
+// "Default" theme. We have to detect this case specifically. (By the time we
+// realize we've installed the default theme, we already have an extension
+// unpacked on the filesystem.)
+const char* kDefaultThemeGalleryID = "hkacjpbfdknhflllbcmjibkdeoafencn";
- std::map<Profile*, BrowserThemeProvider*>::const_iterator it =
- service->mapping_.find(profile);
- if (it != service->mapping_.end())
- return it->second;
+SkColor TintForUnderline(SkColor input) {
+ return SkColorSetA(input, SkColorGetA(input) / 3);
+}
+
+SkColor IncreaseLightness(SkColor color, double percent) {
+ color_utils::HSL result;
+ color_utils::SkColorToHSL(color, &result);
+ result.l += (1 - result.l) * percent;
+ return color_utils::HSLToSkColor(result, SkColorGetA(color));
+}
- BrowserThemeProvider* provider = NULL;
-#if defined(TOOLKIT_USES_GTK)
- provider = new GtkThemeProvider;
+// 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
- provider = new BrowserThemeProvider;
+// 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(150, 150, 150);
+const SkColor kDefaultColorNTPSection = SkColorSetRGB(229, 229, 229);
+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
- provider->Init(profile);
- service->Associate(profile, provider);
- return provider;
+// 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 =
+ ThemeService::ALIGN_BOTTOM;
+const int kDefaultDisplayPropertyNTPTiling =
+ ThemeService::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<int> 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<BrowserThemePack> theme_pack_;
+ FilePath pack_path_;
+};
+
+} // namespace
+
+bool ThemeService::IsThemeableImage(int resource_id) {
+ return HasThemeableImage(resource_id);
+}
+
+ThemeService::ThemeService()
+ : rb_(ResourceBundle::GetSharedInstance()),
+ profile_(NULL),
+ number_of_infobars_(0) {
+ // Initialize the themeable image map so we can use it on other threads.
+ HasThemeableImage(0);
+}
+
+ThemeService::~ThemeService() {
+ FreePlatformCaches();
+}
+
+void ThemeService::Init(Profile* profile) {
+ DCHECK(CalledOnValidThread());
+ profile_ = profile;
+
+ LoadThemePrefs();
}
-const Extension* ThemeServiceFactory::GetThemeForProfile(Profile* profile) {
- std::string id = GetForProfile(profile)->GetThemeID();
- if (id == BrowserThemeProvider::kDefaultThemeID)
- return NULL;
+SkBitmap* ThemeService::GetBitmapNamed(int id) const {
+ DCHECK(CalledOnValidThread());
- return profile->GetExtensionService()->GetExtensionById(id, false);
+ SkBitmap* bitmap = NULL;
+
+ if (theme_pack_.get())
+ bitmap = theme_pack_->GetBitmapNamed(id);
+
+ if (!bitmap)
+ bitmap = rb_.GetBitmapNamed(id);
+
+ return bitmap;
+}
+
+SkColor ThemeService::GetColor(int id) const {
+ DCHECK(CalledOnValidThread());
+
+ SkColor color;
+ if (theme_pack_.get() && theme_pack_->GetColor(id, &color))
+ return color;
+
+ // For backward compat with older themes, some newer colors are generated from
+ // older ones if they are missing.
+ switch (id) {
+ case COLOR_NTP_SECTION_HEADER_TEXT:
+ return IncreaseLightness(GetColor(COLOR_NTP_TEXT), 0.30);
+ case COLOR_NTP_SECTION_HEADER_TEXT_HOVER:
+ return GetColor(COLOR_NTP_TEXT);
+ case COLOR_NTP_SECTION_HEADER_RULE:
+ return IncreaseLightness(GetColor(COLOR_NTP_TEXT), 0.70);
+ case COLOR_NTP_SECTION_HEADER_RULE_LIGHT:
+ return IncreaseLightness(GetColor(COLOR_NTP_TEXT), 0.86);
+ case COLOR_NTP_TEXT_LIGHT:
+ return IncreaseLightness(GetColor(COLOR_NTP_TEXT), 0.40);
+ }
+
+ return GetDefaultColor(id);
}
-void ThemeServiceFactory::ForceAssociationBetween(Profile* top_profile,
- BrowserThemeProvider* provider) {
- ThemeServiceFactory* service = GetInstance();
- Profile* profile = top_profile->GetOriginalProfile();
+bool ThemeService::GetDisplayProperty(int id, int* result) const {
+ if (theme_pack_.get())
+ return theme_pack_->GetDisplayProperty(id, result);
- service->Associate(profile, provider);
+ return GetDefaultDisplayProperty(id, result);
}
-ThemeServiceFactory* ThemeServiceFactory::GetInstance() {
- return Singleton<ThemeServiceFactory>::get();
+bool ThemeService::ShouldUseNativeFrame() const {
+ if (HasCustomImage(IDR_THEME_FRAME))
+ return false;
+#if defined(OS_WIN)
+ return views::WidgetWin::IsAeroGlassEnabled();
+#else
+ return false;
+#endif
}
-ThemeServiceFactory::ThemeServiceFactory() {}
+bool ThemeService::HasCustomImage(int id) const {
+ if (!HasThemeableImage(id))
+ return false;
+
+ if (theme_pack_)
+ return theme_pack_->HasCustomImage(id);
-ThemeServiceFactory::~ThemeServiceFactory() {
- DCHECK(mapping_.empty());
+ return false;
}
-void ThemeServiceFactory::Associate(Profile* profile,
- BrowserThemeProvider* provider) {
- DCHECK(mapping_.find(profile) == mapping_.end());
- mapping_.insert(std::make_pair(profile, provider));
+RefCountedMemory* ThemeService::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;
- registrar_.Add(this,
- NotificationType::PROFILE_DESTROYED,
- Source<Profile>(profile));
- registrar_.Add(this,
- NotificationType::THEME_INSTALLED,
- Source<Profile>(profile));
+ RefCountedMemory* data = NULL;
+ if (theme_pack_.get())
+ data = theme_pack_->GetRawData(id);
+ if (!data)
+ data = rb_.LoadDataResourceBytes(id);
+
+ return data;
}
-void ThemeServiceFactory::Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- std::map<Profile*, BrowserThemeProvider*>::iterator it =
- mapping_.find(Source<Profile>(source).ptr());
- DCHECK(it != mapping_.end());
+void ThemeService::SetTheme(const Extension* extension) {
+ // Clear our image cache.
+ FreePlatformCaches();
+
+ DCHECK(extension);
+ DCHECK(extension->is_theme());
- if (NotificationType::PROFILE_DESTROYED == type) {
- delete it->second;
- mapping_.erase(it);
+ BuildFromExtension(extension);
+ SaveThemeID(extension->id());
+
+ NotifyThemeChanged(extension);
+ UserMetrics::RecordAction(UserMetricsAction("Themes_Installed"), profile_);
+}
- // Remove ourselves from listening to all notifications because the source
- // profile has been deleted. We have to do this because several unit tests
- // are set up so a Profile is on the same place on the stack multiple
- // times, so while they are different instances, they have the same
- // addresses.
- registrar_.Remove(this,
- NotificationType::PROFILE_DESTROYED,
- source);
- registrar_.Remove(this,
- NotificationType::THEME_INSTALLED,
- source);
- } else if (NotificationType::THEME_INSTALLED == type) {
- const Extension* extension = Details<const Extension>(details).ptr();
- it->second->SetTheme(extension);
- } else {
- NOTREACHED();
+void ThemeService::RemoveUnusedThemes() {
+ if (!profile_)
+ return;
+ ExtensionService* service = profile_->GetExtensionService();
+ if (!service)
+ return;
+ std::string current_theme = GetThemeID();
+ std::vector<std::string> 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 ThemeService::UseDefaultTheme() {
+ ClearAllThemeData();
+ NotifyThemeChanged(NULL);
+ UserMetrics::RecordAction(UserMetricsAction("Themes_Reset"), profile_);
+}
+
+void ThemeService::SetNativeTheme() {
+ UseDefaultTheme();
+}
+
+bool ThemeService::UsingDefaultTheme() {
+ std::string id = GetThemeID();
+ return id == ThemeService::kDefaultThemeID ||
+ id == kDefaultThemeGalleryID;
+}
+
+std::string ThemeService::GetThemeID() const {
+ return profile_->GetPrefs()->GetString(prefs::kCurrentThemeID);
+}
+
+// static
+std::string ThemeService::AlignmentToString(int alignment) {
+ // Convert from an AlignmentProperty back into a string.
+ std::string vertical_string;
+ std::string horizontal_string;
+
+ if (alignment & ThemeService::ALIGN_TOP)
+ vertical_string = kAlignmentTop;
+ else if (alignment & ThemeService::ALIGN_BOTTOM)
+ vertical_string = kAlignmentBottom;
+
+ if (alignment & ThemeService::ALIGN_LEFT)
+ horizontal_string = kAlignmentLeft;
+ else if (alignment & ThemeService::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 ThemeService::StringToAlignment(const std::string& alignment) {
+ std::vector<std::wstring> split;
+ base::SplitStringAlongWhitespace(UTF8ToWide(alignment), &split);
+
+ int alignment_mask = 0;
+ for (std::vector<std::wstring>::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 |= ThemeService::ALIGN_TOP;
+ else if (base::strcasecmp(component, kAlignmentBottom) == 0)
+ alignment_mask |= ThemeService::ALIGN_BOTTOM;
+
+ if (base::strcasecmp(component, kAlignmentLeft) == 0)
+ alignment_mask |= ThemeService::ALIGN_LEFT;
+ else if (base::strcasecmp(component, kAlignmentRight) == 0)
+ alignment_mask |= ThemeService::ALIGN_RIGHT;
+ }
+ return alignment_mask;
+}
+
+// static
+std::string ThemeService::TilingToString(int tiling) {
+ // Convert from a TilingProperty back into a string.
+ if (tiling == ThemeService::REPEAT_X)
+ return kTilingRepeatX;
+ if (tiling == ThemeService::REPEAT_Y)
+ return kTilingRepeatY;
+ if (tiling == ThemeService::REPEAT)
+ return kTilingRepeat;
+ return kTilingNoRepeat;
+}
+
+// static
+int ThemeService::StringToTiling(const std::string& tiling) {
+ const char* component = tiling.c_str();
+
+ if (base::strcasecmp(component, kTilingRepeatX) == 0)
+ return ThemeService::REPEAT_X;
+ if (base::strcasecmp(component, kTilingRepeatY) == 0)
+ return ThemeService::REPEAT_Y;
+ if (base::strcasecmp(component, kTilingRepeat) == 0)
+ return ThemeService::REPEAT;
+ // NO_REPEAT is the default choice.
+ return ThemeService::NO_REPEAT;
+}
+
+// static
+color_utils::HSL ThemeService::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 ThemeService::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 ThemeService::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<int>& ThemeService::GetTintableToolbarButtons() {
+ static std::set<int> button_set;
+ if (button_set.empty()) {
+ button_set = std::set<int>(
+ kToolbarButtonIDs,
+ kToolbarButtonIDs + arraysize(kToolbarButtonIDs));
+ }
+
+ return button_set;
+}
+
+color_utils::HSL ThemeService::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 ThemeService::ClearAllThemeData() {
+ // Clear our image cache.
+ FreePlatformCaches();
+ theme_pack_ = NULL;
+
+ profile_->GetPrefs()->ClearPref(prefs::kCurrentThemePackFilename);
+ SaveThemeID(kDefaultThemeID);
+}
+
+void ThemeService::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.
+ ExtensionService* service = profile_->GetExtensionService();
+ if (service) {
+ const 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 ThemeService::NotifyThemeChanged(const Extension* extension) {
+ VLOG(1) << "Sending BROWSER_THEME_CHANGED";
+ // Redraw!
+ NotificationService* service = NotificationService::current();
+ service->Notify(NotificationType::BROWSER_THEME_CHANGED,
+ Source<ThemeService>(this),
+ Details<const Extension>(extension));
+#if defined(OS_MACOSX)
+ NotifyPlatformThemeChanged();
+#endif // OS_MACOSX
+}
+
+#if defined(OS_WIN)
+void ThemeService::FreePlatformCaches() {
+ // Views (Skia) has no platform image cache to clear.
+}
+#endif
+
+void ThemeService::SavePackName(const FilePath& pack_path) {
+ profile_->GetPrefs()->SetFilePath(
+ prefs::kCurrentThemePackFilename, pack_path);
+}
+
+void ThemeService::SaveThemeID(const std::string& id) {
+ profile_->GetPrefs()->SetString(prefs::kCurrentThemeID, id);
+}
+
+void ThemeService::BuildFromExtension(const Extension* extension) {
+ scoped_refptr<BrowserThemePack> 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);
+ BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+ new WritePackToDiskTask(pack, pack_path));
+
+ SavePackName(pack_path);
+ theme_pack_ = pack;
+}
+
+void ThemeService::OnInfobarDisplayed() {
+ number_of_infobars_++;
+}
+
+void ThemeService::OnInfobarDestroyed() {
+ number_of_infobars_--;
+
+ if (number_of_infobars_ == 0)
+ RemoveUnusedThemes();
}
diff --git a/chrome/browser/themes/theme_service.h b/chrome/browser/themes/theme_service.h
index 44abcc2..672bbf0 100644
--- a/chrome/browser/themes/theme_service.h
+++ b/chrome/browser/themes/theme_service.h
@@ -4,56 +4,285 @@
#ifndef CHROME_BROWSER_THEMES_THEME_SERVICE_H_
#define CHROME_BROWSER_THEMES_THEME_SERVICE_H_
+#pragma once
#include <map>
+#include <set>
+#include <string>
-#include "base/singleton.h"
-#include "content/common/notification_observer.h"
-#include "content/common/notification_registrar.h"
+#include "base/ref_counted.h"
+#include "base/threading/non_thread_safe.h"
+#include "ui/base/theme_provider.h"
-class BrowserThemeProvider;
+class BrowserThemePack;
+class ThemeServiceTest;
class Extension;
+class FilePath;
class Profile;
-// Singleton that owns all BrowserThemeProviders and associates them with
-// Profiles. Listens for the Profile's destruction notification and cleans up
-// the associated BrowserThemeProvider.
-class ThemeServiceFactory : public NotificationObserver {
+namespace color_utils {
+struct HSL;
+}
+
+namespace ui {
+class ResourceBundle;
+}
+using ui::ResourceBundle;
+
+#ifdef __OBJC__
+@class NSString;
+// Sent whenever the browser theme changes. Object => NSValue wrapping the
+// ThemeService that changed.
+extern "C" NSString* const kBrowserThemeDidChangeNotification;
+#endif // __OBJC__
+
+class ThemeService : public base::NonThreadSafe,
+ public ui::ThemeProvider {
public:
- // Returns the BrowserThemeProvider that provides theming resources for
- // |profile|. Note that even if a Profile doesn't have a theme installed, it
- // still needs a BrowserThemeProvider to hand back the default theme images.
- static BrowserThemeProvider* GetForProfile(Profile* profile);
+ // Public constants used in ThemeService 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);
+
+ ThemeService();
+ virtual ~ThemeService();
+
+ 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,
+
+ // These colors don't have constant default values. They are derived from
+ // the runtime value of other colors.
+ COLOR_NTP_SECTION_HEADER_TEXT,
+ COLOR_NTP_SECTION_HEADER_TEXT_HOVER,
+ COLOR_NTP_SECTION_HEADER_RULE,
+ COLOR_NTP_SECTION_HEADER_RULE_LIGHT,
+ COLOR_NTP_TEXT_LIGHT,
+
+ 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;
+
+ // ui::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(const 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();
+
+ // 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.)
+ virtual 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();
- // Returns the Extension that implements the theme associated with
- // |profile|. Returns NULL if the theme is no longer installed, if there is
- // no installed theme, or the theme was cleared.
- static const Extension* GetThemeForProfile(Profile* profile);
+ // 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);
- // Forces an association between |profile| and |provider|. Used in unit tests
- // where we need to mock BrowserThemeProvider.
- static void ForceAssociationBetween(Profile* profile,
- BrowserThemeProvider* provider);
+ // Parse alignments from something like "top left" into a bitfield of
+ // AlignmentMasks
+ static int StringToAlignment(const std::string& alignment);
- static ThemeServiceFactory* GetInstance();
+ // 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<int>& GetTintableToolbarButtons();
+
+ // Remove preference values for themes that are no longer in use.
+ void RemoveUnusedThemes();
+
+ // Save the images to be written to disk, mapping file path to id.
+ typedef std::map<FilePath, int> 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(const 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 struct DefaultSingletonTraits<ThemeServiceFactory>;
+ friend class ThemeServiceTest;
+
+ // 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(const Extension* extension);
+
+#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<int, GdkPixbuf*> GdkPixbufMap;
+ mutable GdkPixbufMap gdk_pixbufs_;
+#elif defined(OS_MACOSX)
+ typedef std::map<int, NSImage*> NSImageMap;
+ mutable NSImageMap nsimage_cache_;
+
+ // The bool member of the pair is whether the color is a default color.
+ typedef std::map<int, std::pair<NSColor*, bool> > NSColorMap;
+ mutable NSColorMap nscolor_cache_;
+
+ typedef std::map<int, NSGradient*> NSGradientMap;
+ mutable NSGradientMap nsgradient_cache_;
+#endif
- ThemeServiceFactory();
- ~ThemeServiceFactory();
+ ResourceBundle& rb_;
+ Profile* profile_;
- // Maps |profile| to |provider| and listens for notifications relating to
- // either.
- void Associate(Profile* profile, BrowserThemeProvider* provider);
+ scoped_refptr<BrowserThemePack> theme_pack_;
- // NotificationObserver:
- virtual void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details);
+ // The number of infobars currently displayed.
+ int number_of_infobars_;
- NotificationRegistrar registrar_;
- std::map<Profile*, BrowserThemeProvider*> mapping_;
+ DISALLOW_COPY_AND_ASSIGN(ThemeService);
};
#endif // CHROME_BROWSER_THEMES_THEME_SERVICE_H_
diff --git a/chrome/browser/themes/theme_service_factory.cc b/chrome/browser/themes/theme_service_factory.cc
new file mode 100644
index 0000000..f93b838
--- /dev/null
+++ b/chrome/browser/themes/theme_service_factory.cc
@@ -0,0 +1,109 @@
+// Copyright (c) 2011 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/theme_service_factory.h"
+
+#include "base/logging.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/themes/theme_service.h"
+#include "content/common/notification_service.h"
+
+#if defined(TOOLKIT_USES_GTK)
+#include "chrome/browser/ui/gtk/gtk_theme_service.h"
+#endif
+
+// static
+ThemeService* ThemeServiceFactory::GetForProfile(Profile* top_profile) {
+ // We may be asked for the Theme of an incognito profile. Make sure we're
+ // operating on the real profile.
+ Profile* profile = top_profile->GetOriginalProfile();
+
+ ThemeServiceFactory* service = GetInstance();
+
+ std::map<Profile*, ThemeService*>::const_iterator it =
+ service->mapping_.find(profile);
+ if (it != service->mapping_.end())
+ return it->second;
+
+ ThemeService* provider = NULL;
+#if defined(TOOLKIT_USES_GTK)
+ provider = new GtkThemeService;
+#else
+ provider = new ThemeService;
+#endif
+ provider->Init(profile);
+
+ service->Associate(profile, provider);
+ return provider;
+}
+
+const Extension* ThemeServiceFactory::GetThemeForProfile(Profile* profile) {
+ std::string id = GetForProfile(profile)->GetThemeID();
+ if (id == ThemeService::kDefaultThemeID)
+ return NULL;
+
+ return profile->GetExtensionService()->GetExtensionById(id, false);
+}
+
+void ThemeServiceFactory::ForceAssociationBetween(Profile* top_profile,
+ ThemeService* provider) {
+ ThemeServiceFactory* service = GetInstance();
+ Profile* profile = top_profile->GetOriginalProfile();
+
+ service->Associate(profile, provider);
+}
+
+ThemeServiceFactory* ThemeServiceFactory::GetInstance() {
+ return Singleton<ThemeServiceFactory>::get();
+}
+
+ThemeServiceFactory::ThemeServiceFactory() {}
+
+ThemeServiceFactory::~ThemeServiceFactory() {
+ DCHECK(mapping_.empty());
+}
+
+void ThemeServiceFactory::Associate(Profile* profile,
+ ThemeService* provider) {
+ DCHECK(mapping_.find(profile) == mapping_.end());
+ mapping_.insert(std::make_pair(profile, provider));
+
+ registrar_.Add(this,
+ NotificationType::PROFILE_DESTROYED,
+ Source<Profile>(profile));
+ registrar_.Add(this,
+ NotificationType::THEME_INSTALLED,
+ Source<Profile>(profile));
+}
+
+void ThemeServiceFactory::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ std::map<Profile*, ThemeService*>::iterator it =
+ mapping_.find(Source<Profile>(source).ptr());
+ DCHECK(it != mapping_.end());
+
+ if (NotificationType::PROFILE_DESTROYED == type) {
+ delete it->second;
+ mapping_.erase(it);
+
+ // Remove ourselves from listening to all notifications because the source
+ // profile has been deleted. We have to do this because several unit tests
+ // are set up so a Profile is on the same place on the stack multiple
+ // times, so while they are different instances, they have the same
+ // addresses.
+ registrar_.Remove(this,
+ NotificationType::PROFILE_DESTROYED,
+ source);
+ registrar_.Remove(this,
+ NotificationType::THEME_INSTALLED,
+ source);
+ } else if (NotificationType::THEME_INSTALLED == type) {
+ const Extension* extension = Details<const Extension>(details).ptr();
+ it->second->SetTheme(extension);
+ } else {
+ NOTREACHED();
+ }
+}
diff --git a/chrome/browser/themes/theme_service_factory.h b/chrome/browser/themes/theme_service_factory.h
new file mode 100644
index 0000000..8211130
--- /dev/null
+++ b/chrome/browser/themes/theme_service_factory.h
@@ -0,0 +1,59 @@
+// Copyright (c) 2011 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_THEME_SERVICE_FACTORY_H_
+#define CHROME_BROWSER_THEMES_THEME_SERVICE_FACTORY_H_
+
+#include <map>
+
+#include "base/singleton.h"
+#include "content/common/notification_observer.h"
+#include "content/common/notification_registrar.h"
+
+class ThemeService;
+class Extension;
+class Profile;
+
+// Singleton that owns all ThemeServices and associates them with
+// Profiles. Listens for the Profile's destruction notification and cleans up
+// the associated ThemeService.
+class ThemeServiceFactory : public NotificationObserver {
+ public:
+ // Returns the ThemeService that provides theming resources for
+ // |profile|. Note that even if a Profile doesn't have a theme installed, it
+ // still needs a ThemeService to hand back the default theme images.
+ static ThemeService* GetForProfile(Profile* profile);
+
+ // Returns the Extension that implements the theme associated with
+ // |profile|. Returns NULL if the theme is no longer installed, if there is
+ // no installed theme, or the theme was cleared.
+ static const Extension* GetThemeForProfile(Profile* profile);
+
+ // Forces an association between |profile| and |provider|. Used in unit tests
+ // where we need to mock ThemeService.
+ static void ForceAssociationBetween(Profile* profile,
+ ThemeService* provider);
+
+ static ThemeServiceFactory* GetInstance();
+
+ private:
+ friend struct DefaultSingletonTraits<ThemeServiceFactory>;
+
+ ThemeServiceFactory();
+ ~ThemeServiceFactory();
+
+ // Maps |profile| to |provider| and listens for notifications relating to
+ // either.
+ void Associate(Profile* profile, ThemeService* provider);
+
+ // NotificationObserver:
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ NotificationRegistrar registrar_;
+ std::map<Profile*, ThemeService*> mapping_;
+};
+
+#endif // CHROME_BROWSER_THEMES_THEME_SERVICE_FACTORY_H_
diff --git a/chrome/browser/themes/browser_theme_provider_gtk.cc b/chrome/browser/themes/theme_service_gtk.cc
index 52be010..e9d33bc 100644
--- a/chrome/browser/themes/browser_theme_provider_gtk.cc
+++ b/chrome/browser/themes/theme_service_gtk.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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 "chrome/browser/themes/theme_service.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
@@ -11,15 +11,15 @@
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/gtk_util.h"
-GdkPixbuf* BrowserThemeProvider::GetPixbufNamed(int id) const {
+GdkPixbuf* ThemeService::GetPixbufNamed(int id) const {
return GetPixbufImpl(id, false);
}
-GdkPixbuf* BrowserThemeProvider::GetRTLEnabledPixbufNamed(int id) const {
+GdkPixbuf* ThemeService::GetRTLEnabledPixbufNamed(int id) const {
return GetPixbufImpl(id, true);
}
-GdkPixbuf* BrowserThemeProvider::GetPixbufImpl(int id, bool rtl_enabled) const {
+GdkPixbuf* ThemeService::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;
@@ -61,7 +61,7 @@ GdkPixbuf* BrowserThemeProvider::GetPixbufImpl(int id, bool rtl_enabled) const {
return empty_bitmap;
}
-void BrowserThemeProvider::FreePlatformCaches() {
+void ThemeService::FreePlatformCaches() {
DCHECK(CalledOnValidThread());
// Free GdkPixbufs.
diff --git a/chrome/browser/themes/browser_theme_provider_mac.mm b/chrome/browser/themes/theme_service_mac.mm
index 887f625..30d359e 100644
--- a/chrome/browser/themes/browser_theme_provider_mac.mm
+++ b/chrome/browser/themes/theme_service_mac.mm
@@ -1,8 +1,8 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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 "chrome/browser/themes/theme_service.h"
#import <Cocoa/Cocoa.h>
@@ -27,10 +27,9 @@ void HSLToHSB(const color_utils::HSL& hsl, CGFloat* h, CGFloat* s, CGFloat* b) {
*b = SkScalarToDouble(hsv[2]);
}
-}
+} // namespace
-NSImage* BrowserThemeProvider::GetNSImageNamed(int id,
- bool allow_default) const {
+NSImage* ThemeService::GetNSImageNamed(int id, bool allow_default) const {
DCHECK(CalledOnValidThread());
if (!allow_default && !HasCustomImage(id))
@@ -73,8 +72,7 @@ NSImage* BrowserThemeProvider::GetNSImageNamed(int id,
return empty_image;
}
-NSColor* BrowserThemeProvider::GetNSImageColorNamed(int id,
- bool allow_default) const {
+NSColor* ThemeService::GetNSImageColorNamed(int id, bool allow_default) const {
DCHECK(CalledOnValidThread());
// Check to see if we already have the color in the cache.
@@ -99,8 +97,7 @@ NSColor* BrowserThemeProvider::GetNSImageColorNamed(int id,
return image_color;
}
-NSColor* BrowserThemeProvider::GetNSColor(int id,
- bool allow_default) const {
+NSColor* ThemeService::GetNSColor(int id, bool allow_default) const {
DCHECK(CalledOnValidThread());
// Check to see if we already have the color in the cache.
@@ -136,8 +133,7 @@ NSColor* BrowserThemeProvider::GetNSColor(int id,
return color;
}
-NSColor* BrowserThemeProvider::GetNSColorTint(int id,
- bool allow_default) const {
+NSColor* ThemeService::GetNSColorTint(int id, bool allow_default) const {
DCHECK(CalledOnValidThread());
// Check to see if we already have the color in the cache.
@@ -180,7 +176,7 @@ NSColor* BrowserThemeProvider::GetNSColorTint(int id,
return tint_color;
}
-NSGradient* BrowserThemeProvider::GetNSGradient(int id) const {
+NSGradient* ThemeService::GetNSGradient(int id) const {
DCHECK(CalledOnValidThread());
// Check to see if we already have the gradient in the cache.
@@ -285,13 +281,13 @@ NSGradient* BrowserThemeProvider::GetNSGradient(int id) const {
}
// Let all the browser views know that themes have changed in a platform way.
-void BrowserThemeProvider::NotifyPlatformThemeChanged() {
+void ThemeService::NotifyPlatformThemeChanged() {
NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter];
[defaultCenter postNotificationName:kBrowserThemeDidChangeNotification
object:[NSValue valueWithPointer:this]];
}
-void BrowserThemeProvider::FreePlatformCaches() {
+void ThemeService::FreePlatformCaches() {
DCHECK(CalledOnValidThread());
// Free images.
diff --git a/chrome/browser/themes/theme_service_unittest.cc b/chrome/browser/themes/theme_service_unittest.cc
new file mode 100644
index 0000000..7b39c2e
--- /dev/null
+++ b/chrome/browser/themes/theme_service_unittest.cc
@@ -0,0 +1,51 @@
+// Copyright (c) 2011 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/theme_service.h"
+
+#include "base/json/json_reader.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+TEST(ThemeServiceTest, AlignmentConversion) {
+ // Verify that we get out what we put in.
+ std::string top_left = "top left";
+ int alignment = ThemeService::StringToAlignment(top_left);
+ EXPECT_EQ(ThemeService::ALIGN_TOP | ThemeService::ALIGN_LEFT,
+ alignment);
+ EXPECT_EQ(top_left, ThemeService::AlignmentToString(alignment));
+
+ alignment = ThemeService::StringToAlignment("top");
+ EXPECT_EQ(ThemeService::ALIGN_TOP, alignment);
+ EXPECT_EQ("top", ThemeService::AlignmentToString(alignment));
+
+ alignment = ThemeService::StringToAlignment("left");
+ EXPECT_EQ(ThemeService::ALIGN_LEFT, alignment);
+ EXPECT_EQ("left", ThemeService::AlignmentToString(alignment));
+
+ alignment = ThemeService::StringToAlignment("right");
+ EXPECT_EQ(ThemeService::ALIGN_RIGHT, alignment);
+ EXPECT_EQ("right", ThemeService::AlignmentToString(alignment));
+
+ alignment = ThemeService::StringToAlignment("righttopbottom");
+ EXPECT_EQ(ThemeService::ALIGN_CENTER, alignment);
+ EXPECT_EQ("", ThemeService::AlignmentToString(alignment));
+}
+
+TEST(ThemeServiceTest, AlignmentConversionInput) {
+ // Verify that we output in an expected format.
+ int alignment = ThemeService::StringToAlignment("right bottom");
+ EXPECT_EQ("bottom right", ThemeService::AlignmentToString(alignment));
+
+ // Verify that bad strings don't cause explosions.
+ alignment = ThemeService::StringToAlignment("new zealand");
+ EXPECT_EQ("", ThemeService::AlignmentToString(alignment));
+
+ // Verify that bad strings don't cause explosions.
+ alignment = ThemeService::StringToAlignment("new zealand top");
+ EXPECT_EQ("top", ThemeService::AlignmentToString(alignment));
+
+ // Verify that bad strings don't cause explosions.
+ alignment = ThemeService::StringToAlignment("new zealandtop");
+ EXPECT_EQ("", ThemeService::AlignmentToString(alignment));
+}