172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Use of this source code is governed by a BSD-style license that can be
3bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// found in the LICENSE file.
4bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/themes/theme_service.h"
6bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
74a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "base/string_split.h"
8bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/string_util.h"
9bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/utf_string_conversions.h"
1021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/extensions/extension_service.h"
11bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/metrics/user_metrics.h"
1221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
13bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/themes/browser_theme_pack.h"
14bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/common/chrome_constants.h"
15bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/common/pref_names.h"
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h"
17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_type.h"
18bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "grit/app_resources.h"
19bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "grit/theme_resources.h"
2072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/resource/resource_bundle.h"
21bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
22bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#if defined(OS_WIN)
2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "views/widget/widget_win.h"
24bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#endif
25bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
26bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Strings used in alignment properties.
27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char* ThemeService::kAlignmentTop = "top";
28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char* ThemeService::kAlignmentBottom = "bottom";
29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char* ThemeService::kAlignmentLeft = "left";
30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char* ThemeService::kAlignmentRight = "right";
31bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
32bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Strings used in background tiling repetition properties.
33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char* ThemeService::kTilingNoRepeat = "no-repeat";
34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char* ThemeService::kTilingRepeatX = "repeat-x";
35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char* ThemeService::kTilingRepeatY = "repeat-y";
36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char* ThemeService::kTilingRepeat = "repeat";
37bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
38dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// The default theme if we haven't installed a theme yet or if we've clicked
39dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// the "Use Classic" button.
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char* ThemeService::kDefaultThemeID = "";
41bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
42bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsennamespace {
43bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
44dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// The default theme if we've gone to the theme gallery and installed the
45dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// "Default" theme. We have to detect this case specifically. (By the time we
46dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// realize we've installed the default theme, we already have an extension
47dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// unpacked on the filesystem.)
48dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenconst char* kDefaultThemeGalleryID = "hkacjpbfdknhflllbcmjibkdeoafencn";
49dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
50bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenSkColor TintForUnderline(SkColor input) {
51bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return SkColorSetA(input, SkColorGetA(input) / 3);
52bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
53bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
54bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenSkColor IncreaseLightness(SkColor color, double percent) {
55bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  color_utils::HSL result;
56bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  color_utils::SkColorToHSL(color, &result);
57bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  result.l += (1 - result.l) * percent;
58bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return color_utils::HSLToSkColor(result, SkColorGetA(color));
59bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
60bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
61bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Default colors.
62bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorFrame = SkColorSetRGB(66, 116, 201);
63bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorFrameInactive = SkColorSetRGB(161, 182, 228);
64bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorFrameIncognito = SkColorSetRGB(83, 106, 139);
65bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorFrameIncognitoInactive =
66bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    SkColorSetRGB(126, 139, 156);
67bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#if defined(OS_MACOSX)
68bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorToolbar = SkColorSetRGB(230, 230, 230);
69bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#else
70bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorToolbar = SkColorSetRGB(223, 223, 223);
71bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#endif
72bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorTabText = SK_ColorBLACK;
73bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#if defined(OS_MACOSX)
74bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorBackgroundTabText = SK_ColorBLACK;
75bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorBookmarkText = SK_ColorBLACK;
76bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#else
77bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorBackgroundTabText = SkColorSetRGB(64, 64, 64);
78bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorBookmarkText = SkColorSetRGB(18, 50, 114);
79bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#endif
80bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#if defined(OS_WIN)
81bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorNTPBackground =
82bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    color_utils::GetSysSkColor(COLOR_WINDOW);
83bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorNTPText =
84bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    color_utils::GetSysSkColor(COLOR_WINDOWTEXT);
85bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorNTPLink =
86bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    color_utils::GetSysSkColor(COLOR_HOTLIGHT);
87bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#else
88bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// TODO(beng): source from theme provider.
89bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorNTPBackground = SK_ColorWHITE;
90bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorNTPText = SK_ColorBLACK;
91bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorNTPLink = SkColorSetRGB(6, 55, 116);
92bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#endif
93bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorNTPHeader = SkColorSetRGB(150, 150, 150);
94bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorNTPSection = SkColorSetRGB(229, 229, 229);
95bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorNTPSectionText = SK_ColorBLACK;
96bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorNTPSectionLink = SkColorSetRGB(6, 55, 116);
97bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorControlBackground = SkColorSetARGB(0, 0, 0, 0);
98bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorButtonBackground = SkColorSetARGB(0, 0, 0, 0);
99bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#if defined(OS_MACOSX)
100bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorToolbarButtonStroke = SkColorSetARGB(75, 81, 81, 81);
101bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorToolbarButtonStrokeInactive =
102bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    SkColorSetARGB(75, 99, 99, 99);
103bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorToolbarBezel = SkColorSetRGB(247, 247, 247);
104bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorToolbarStroke = SkColorSetRGB(103, 103, 103);
105bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst SkColor kDefaultColorToolbarStrokeInactive = SkColorSetRGB(123, 123, 123);
106bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#endif
107bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
108bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Default tints.
109bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst color_utils::HSL kDefaultTintButtons = { -1, -1, -1 };
110bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst color_utils::HSL kDefaultTintFrame = { -1, -1, -1 };
111bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst color_utils::HSL kDefaultTintFrameInactive = { -1, -1, 0.75f };
112bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst color_utils::HSL kDefaultTintFrameIncognito = { -1, 0.2f, 0.35f };
113bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst color_utils::HSL kDefaultTintFrameIncognitoInactive = { -1, 0.3f, 0.6f };
114bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst color_utils::HSL kDefaultTintBackgroundTab = { -1, 0.5, 0.75 };
115bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
116bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Default display properties.
117bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst int kDefaultDisplayPropertyNTPAlignment =
118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ThemeService::ALIGN_BOTTOM;
119bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst int kDefaultDisplayPropertyNTPTiling =
120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ThemeService::NO_REPEAT;
121bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst int kDefaultDisplayPropertyNTPInverseLogo = 0;
122bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
123bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// The sum of kFrameBorderThickness and kNonClientRestoredExtraThickness from
124bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// OpaqueBrowserFrameView.
125bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst int kRestoredTabVerticalOffset = 15;
126bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
127bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// The image resources we will allow people to theme.
128bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst int kThemeableImages[] = {
129bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  IDR_THEME_FRAME,
130bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  IDR_THEME_FRAME_INACTIVE,
131bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  IDR_THEME_FRAME_INCOGNITO,
132bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  IDR_THEME_FRAME_INCOGNITO_INACTIVE,
133bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  IDR_THEME_TOOLBAR,
134bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  IDR_THEME_TAB_BACKGROUND,
135bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  IDR_THEME_TAB_BACKGROUND_INCOGNITO,
136bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  IDR_THEME_TAB_BACKGROUND_V,
137bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  IDR_THEME_NTP_BACKGROUND,
138bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  IDR_THEME_FRAME_OVERLAY,
139bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  IDR_THEME_FRAME_OVERLAY_INACTIVE,
140bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  IDR_THEME_BUTTON_BACKGROUND,
141bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  IDR_THEME_NTP_ATTRIBUTION,
142bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  IDR_THEME_WINDOW_CONTROL_BACKGROUND
143bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen};
144bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
145bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenbool HasThemeableImage(int themeable_image_id) {
146bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  static std::set<int> themeable_images;
147bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (themeable_images.empty()) {
148bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    themeable_images.insert(
149bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        kThemeableImages, kThemeableImages + arraysize(kThemeableImages));
150bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
151bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return themeable_images.count(themeable_image_id) > 0;
152bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
153bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
154bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// The image resources that will be tinted by the 'button' tint value.
155bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// If you change this list, you must increment the version number in
156bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// browser_theme_pack.cc, and you should assign persistent IDs to the
157bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// data table at the start of said file or else tinted versions of
158bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// these resources will not be created.
159bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst int kToolbarButtonIDs[] = {
160bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  IDR_BACK, IDR_BACK_D, IDR_BACK_H, IDR_BACK_P,
161bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  IDR_FORWARD, IDR_FORWARD_D, IDR_FORWARD_H, IDR_FORWARD_P,
162bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  IDR_HOME, IDR_HOME_H, IDR_HOME_P,
163bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  IDR_RELOAD, IDR_RELOAD_H, IDR_RELOAD_P,
164bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  IDR_STOP, IDR_STOP_D, IDR_STOP_H, IDR_STOP_P,
165bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  IDR_LOCATIONBG_C, IDR_LOCATIONBG_L, IDR_LOCATIONBG_R,
166bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  IDR_BROWSER_ACTIONS_OVERFLOW, IDR_BROWSER_ACTIONS_OVERFLOW_H,
167bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  IDR_BROWSER_ACTIONS_OVERFLOW_P,
168bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  IDR_TOOLS, IDR_TOOLS_H, IDR_TOOLS_P,
169bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  IDR_MENU_DROPARROW,
170bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  IDR_THROBBER, IDR_THROBBER_WAITING, IDR_THROBBER_LIGHT,
171bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen};
172bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
173bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Writes the theme pack to disk on a separate thread.
174bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenclass WritePackToDiskTask : public Task {
175bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen public:
176bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  WritePackToDiskTask(BrowserThemePack* pack, const FilePath& path)
177bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      : theme_pack_(pack), pack_path_(path) {}
178bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
179bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  virtual void Run() {
180bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    if (!theme_pack_->WriteToDisk(pack_path_)) {
181bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      NOTREACHED() << "Could not write theme pack to disk";
182bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    }
183bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
184bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
185bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen private:
186bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  scoped_refptr<BrowserThemePack> theme_pack_;
187bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  FilePath pack_path_;
188bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen};
189bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
190bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}  // namespace
191bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ThemeService::IsThemeableImage(int resource_id) {
193bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return HasThemeableImage(resource_id);
194bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
195bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenThemeService::ThemeService()
197bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    : rb_(ResourceBundle::GetSharedInstance()),
198bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      profile_(NULL),
199bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      number_of_infobars_(0) {
200bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Initialize the themeable image map so we can use it on other threads.
201bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  HasThemeableImage(0);
202bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
203bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenThemeService::~ThemeService() {
205bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  FreePlatformCaches();
206bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
207bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ThemeService::Init(Profile* profile) {
209bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DCHECK(CalledOnValidThread());
210bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  profile_ = profile;
211bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Listen to EXTENSION_LOADED instead of EXTENSION_INSTALLED because
213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // the extension cannot yet be found via GetExtensionById() if it is
214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // installed but not loaded (which may confuse listeners to
215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // BROWSER_THEME_CHANGED).
216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  registrar_.Add(this,
217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                 NotificationType::EXTENSION_LOADED,
218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                 Source<Profile>(profile_));
219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
220bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  LoadThemePrefs();
221bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
222bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSkBitmap* ThemeService::GetBitmapNamed(int id) const {
224bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DCHECK(CalledOnValidThread());
225bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
226bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  SkBitmap* bitmap = NULL;
227bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
228bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (theme_pack_.get())
229bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    bitmap = theme_pack_->GetBitmapNamed(id);
230bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
231bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (!bitmap)
232bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    bitmap = rb_.GetBitmapNamed(id);
233bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
234bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return bitmap;
235bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
236bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSkColor ThemeService::GetColor(int id) const {
238bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DCHECK(CalledOnValidThread());
239bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
240bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  SkColor color;
241bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (theme_pack_.get() && theme_pack_->GetColor(id, &color))
242bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return color;
243bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
244bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // For backward compat with older themes, some newer colors are generated from
245bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // older ones if they are missing.
246bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  switch (id) {
247bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_NTP_SECTION_HEADER_TEXT:
248bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return IncreaseLightness(GetColor(COLOR_NTP_TEXT), 0.30);
249bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_NTP_SECTION_HEADER_TEXT_HOVER:
250bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return GetColor(COLOR_NTP_TEXT);
251bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_NTP_SECTION_HEADER_RULE:
252bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return IncreaseLightness(GetColor(COLOR_NTP_TEXT), 0.70);
253bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_NTP_SECTION_HEADER_RULE_LIGHT:
254bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return IncreaseLightness(GetColor(COLOR_NTP_TEXT), 0.86);
255731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    case COLOR_NTP_TEXT_LIGHT:
256731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      return IncreaseLightness(GetColor(COLOR_NTP_TEXT), 0.40);
257bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
258bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
259bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return GetDefaultColor(id);
260bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
261bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ThemeService::GetDisplayProperty(int id, int* result) const {
263bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (theme_pack_.get())
264bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return theme_pack_->GetDisplayProperty(id, result);
265bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
266bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return GetDefaultDisplayProperty(id, result);
267bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
268bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ThemeService::ShouldUseNativeFrame() const {
270bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (HasCustomImage(IDR_THEME_FRAME))
271bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return false;
272bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#if defined(OS_WIN)
27372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return views::WidgetWin::IsAeroGlassEnabled();
274bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#else
275bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return false;
276bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#endif
277bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
278bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ThemeService::HasCustomImage(int id) const {
280bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (!HasThemeableImage(id))
281bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return false;
282bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
283bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (theme_pack_)
284bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return theme_pack_->HasCustomImage(id);
285bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
286bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return false;
287bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
288bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenRefCountedMemory* ThemeService::GetRawData(int id) const {
290bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Check to see whether we should substitute some images.
291bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  int ntp_alternate;
292bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  GetDisplayProperty(NTP_LOGO_ALTERNATE, &ntp_alternate);
293bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (id == IDR_PRODUCT_LOGO && ntp_alternate != 0)
294bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    id = IDR_PRODUCT_LOGO_WHITE;
295bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
296bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  RefCountedMemory* data = NULL;
297bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (theme_pack_.get())
298bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    data = theme_pack_->GetRawData(id);
299bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (!data)
300bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    data = rb_.LoadDataResourceBytes(id);
301bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
302bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return data;
303bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
304bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ThemeService::SetTheme(const Extension* extension) {
306bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Clear our image cache.
307bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  FreePlatformCaches();
308bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
309bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DCHECK(extension);
310bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DCHECK(extension->is_theme());
311bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
312bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  BuildFromExtension(extension);
313bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  SaveThemeID(extension->id());
314bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  NotifyThemeChanged();
316bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  UserMetrics::RecordAction(UserMetricsAction("Themes_Installed"), profile_);
317bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
318bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ThemeService::RemoveUnusedThemes() {
320bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (!profile_)
321bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return;
32221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* service = profile_->GetExtensionService();
323bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (!service)
324bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return;
325bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  std::string current_theme = GetThemeID();
326bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  std::vector<std::string> remove_list;
327bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  const ExtensionList* extensions = service->extensions();
328bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  for (ExtensionList::const_iterator it = extensions->begin();
329bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen       it != extensions->end(); ++it) {
330bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    if ((*it)->is_theme() && (*it)->id() != current_theme) {
331bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      remove_list.push_back((*it)->id());
332bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    }
333bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
334bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  for (size_t i = 0; i < remove_list.size(); ++i)
335ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    service->UninstallExtension(remove_list[i], false, NULL);
336bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
337bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ThemeService::UseDefaultTheme() {
339bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  ClearAllThemeData();
340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  NotifyThemeChanged();
341bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  UserMetrics::RecordAction(UserMetricsAction("Themes_Reset"), profile_);
342bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
343bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ThemeService::SetNativeTheme() {
34521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  UseDefaultTheme();
34621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
34721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
348ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ThemeService::UsingDefaultTheme() {
349dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::string id = GetThemeID();
350ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return id == ThemeService::kDefaultThemeID ||
351dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      id == kDefaultThemeGalleryID;
352bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
353bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
354ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstd::string ThemeService::GetThemeID() const {
355bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return profile_->GetPrefs()->GetString(prefs::kCurrentThemeID);
356bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
357bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
358bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// static
359ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstd::string ThemeService::AlignmentToString(int alignment) {
360bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Convert from an AlignmentProperty back into a string.
361bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  std::string vertical_string;
362bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  std::string horizontal_string;
363bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
364ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (alignment & ThemeService::ALIGN_TOP)
365bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    vertical_string = kAlignmentTop;
366ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  else if (alignment & ThemeService::ALIGN_BOTTOM)
367bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    vertical_string = kAlignmentBottom;
368bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (alignment & ThemeService::ALIGN_LEFT)
370bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    horizontal_string = kAlignmentLeft;
371ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  else if (alignment & ThemeService::ALIGN_RIGHT)
372bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    horizontal_string = kAlignmentRight;
373bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
374bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (vertical_string.empty())
375bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return horizontal_string;
376bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (horizontal_string.empty())
377bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return vertical_string;
378bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return vertical_string + " " + horizontal_string;
379bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
380bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
381bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// static
382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenint ThemeService::StringToAlignment(const std::string& alignment) {
383bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  std::vector<std::wstring> split;
3844a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  base::SplitStringAlongWhitespace(UTF8ToWide(alignment), &split);
385bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
386bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  int alignment_mask = 0;
387bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  for (std::vector<std::wstring>::iterator alignments(split.begin());
388bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen       alignments != split.end(); ++alignments) {
389bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    std::string comp = WideToUTF8(*alignments);
390bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    const char* component = comp.c_str();
391bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
392bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    if (base::strcasecmp(component, kAlignmentTop) == 0)
393ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      alignment_mask |= ThemeService::ALIGN_TOP;
394bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    else if (base::strcasecmp(component, kAlignmentBottom) == 0)
395ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      alignment_mask |= ThemeService::ALIGN_BOTTOM;
396bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
397bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    if (base::strcasecmp(component, kAlignmentLeft) == 0)
398ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      alignment_mask |= ThemeService::ALIGN_LEFT;
399bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    else if (base::strcasecmp(component, kAlignmentRight) == 0)
400ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      alignment_mask |= ThemeService::ALIGN_RIGHT;
401bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
402bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return alignment_mask;
403bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
404bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
405bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// static
406ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstd::string ThemeService::TilingToString(int tiling) {
407bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Convert from a TilingProperty back into a string.
408ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (tiling == ThemeService::REPEAT_X)
409bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return kTilingRepeatX;
410ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (tiling == ThemeService::REPEAT_Y)
411bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return kTilingRepeatY;
412ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (tiling == ThemeService::REPEAT)
413bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return kTilingRepeat;
414bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return kTilingNoRepeat;
415bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
416bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
417bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// static
418ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenint ThemeService::StringToTiling(const std::string& tiling) {
419bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  const char* component = tiling.c_str();
420bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
421bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (base::strcasecmp(component, kTilingRepeatX) == 0)
422ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return ThemeService::REPEAT_X;
423bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (base::strcasecmp(component, kTilingRepeatY) == 0)
424ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return ThemeService::REPEAT_Y;
425bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (base::strcasecmp(component, kTilingRepeat) == 0)
426ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return ThemeService::REPEAT;
427bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // NO_REPEAT is the default choice.
428ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return ThemeService::NO_REPEAT;
429bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
430bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
431bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// static
432ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsencolor_utils::HSL ThemeService::GetDefaultTint(int id) {
433bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  switch (id) {
434bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case TINT_FRAME:
435bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultTintFrame;
436bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case TINT_FRAME_INACTIVE:
437bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultTintFrameInactive;
438bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case TINT_FRAME_INCOGNITO:
439bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultTintFrameIncognito;
440bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case TINT_FRAME_INCOGNITO_INACTIVE:
441bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultTintFrameIncognitoInactive;
442bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case TINT_BUTTONS:
443bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultTintButtons;
444bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case TINT_BACKGROUND_TAB:
445bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultTintBackgroundTab;
446bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    default:
447bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      color_utils::HSL result = {-1, -1, -1};
448bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return result;
449bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
450bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
451bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
452bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// static
453ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSkColor ThemeService::GetDefaultColor(int id) {
454bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  switch (id) {
455bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_FRAME:
456bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultColorFrame;
457bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_FRAME_INACTIVE:
458bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultColorFrameInactive;
459bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_FRAME_INCOGNITO:
460bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultColorFrameIncognito;
461bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_FRAME_INCOGNITO_INACTIVE:
462bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultColorFrameIncognitoInactive;
463bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_TOOLBAR:
464bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultColorToolbar;
465bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_TAB_TEXT:
466bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultColorTabText;
467bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_BACKGROUND_TAB_TEXT:
468bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultColorBackgroundTabText;
469bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_BOOKMARK_TEXT:
470bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultColorBookmarkText;
471bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_NTP_BACKGROUND:
472bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultColorNTPBackground;
473bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_NTP_TEXT:
474bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultColorNTPText;
475bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_NTP_LINK:
476bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultColorNTPLink;
477bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_NTP_LINK_UNDERLINE:
478bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return TintForUnderline(kDefaultColorNTPLink);
479bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_NTP_HEADER:
480bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultColorNTPHeader;
481bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_NTP_SECTION:
482bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultColorNTPSection;
483bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_NTP_SECTION_TEXT:
484bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultColorNTPSectionText;
485bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_NTP_SECTION_LINK:
486bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultColorNTPSectionLink;
487bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_NTP_SECTION_LINK_UNDERLINE:
488bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return TintForUnderline(kDefaultColorNTPSectionLink);
489bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_CONTROL_BACKGROUND:
490bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultColorControlBackground;
491bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_BUTTON_BACKGROUND:
492bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultColorButtonBackground;
493bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#if defined(OS_MACOSX)
494bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_TOOLBAR_BUTTON_STROKE:
495bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultColorToolbarButtonStroke;
496bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_TOOLBAR_BUTTON_STROKE_INACTIVE:
497bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultColorToolbarButtonStrokeInactive;
498bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_TOOLBAR_BEZEL:
499bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultColorToolbarBezel;
500bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_TOOLBAR_STROKE:
501bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultColorToolbarStroke;
502bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case COLOR_TOOLBAR_STROKE_INACTIVE:
503bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return kDefaultColorToolbarStrokeInactive;
504bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#endif
505bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    default:
506bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // Return a debugging red color.
507bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return 0xffff0000;
508bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
509bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
510bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
511bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// static
512ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ThemeService::GetDefaultDisplayProperty(int id, int* result) {
513bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  switch (id) {
514bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case NTP_BACKGROUND_ALIGNMENT:
515bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      *result = kDefaultDisplayPropertyNTPAlignment;
516bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return true;
517bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case NTP_BACKGROUND_TILING:
518bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      *result = kDefaultDisplayPropertyNTPTiling;
519bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return true;
520bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    case NTP_LOGO_ALTERNATE:
521bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      *result = kDefaultDisplayPropertyNTPInverseLogo;
522bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return true;
523bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
524bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
525bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return false;
526bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
527bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
528bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// static
529ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst std::set<int>& ThemeService::GetTintableToolbarButtons() {
530bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  static std::set<int> button_set;
531bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (button_set.empty()) {
532bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    button_set = std::set<int>(
533bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        kToolbarButtonIDs,
534bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        kToolbarButtonIDs + arraysize(kToolbarButtonIDs));
535bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
536bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
537bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return button_set;
538bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
539bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
540ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsencolor_utils::HSL ThemeService::GetTint(int id) const {
541bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DCHECK(CalledOnValidThread());
542bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
543bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  color_utils::HSL hsl;
544bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (theme_pack_.get() && theme_pack_->GetTint(id, &hsl))
545bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return hsl;
546bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
547bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return GetDefaultTint(id);
548bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
549bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
550ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ThemeService::ClearAllThemeData() {
551bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Clear our image cache.
552bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  FreePlatformCaches();
553bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  theme_pack_ = NULL;
554bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
555bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  profile_->GetPrefs()->ClearPref(prefs::kCurrentThemePackFilename);
556bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  SaveThemeID(kDefaultThemeID);
557bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
558bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
559ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ThemeService::LoadThemePrefs() {
560bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  PrefService* prefs = profile_->GetPrefs();
561bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
562bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  std::string current_id = GetThemeID();
563bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (current_id != kDefaultThemeID) {
564bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    bool loaded_pack = false;
565bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
566bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    // If we don't have a file pack, we're updating from an old version.
567bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    FilePath path = prefs->GetFilePath(prefs::kCurrentThemePackFilename);
568bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    if (path != FilePath()) {
569bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      theme_pack_ = BrowserThemePack::BuildFromDataPack(path, current_id);
570bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      loaded_pack = theme_pack_.get() != NULL;
571bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    }
572bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
573bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    if (loaded_pack) {
574bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      UserMetrics::RecordAction(UserMetricsAction("Themes.Loaded"), profile_);
575bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    } else {
576bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // TODO(erg): We need to pop up a dialog informing the user that their
577bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // theme is being migrated.
57821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      ExtensionService* service = profile_->GetExtensionService();
579bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      if (service) {
580513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        const Extension* extension =
581513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch            service->GetExtensionById(current_id, false);
582bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        if (extension) {
583bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          DLOG(ERROR) << "Migrating theme";
584bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          BuildFromExtension(extension);
585bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          UserMetrics::RecordAction(UserMetricsAction("Themes.Migrated"),
586bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                    profile_);
587bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        } else {
588bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          DLOG(ERROR) << "Theme is mysteriously gone.";
589bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          ClearAllThemeData();
590bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          UserMetrics::RecordAction(UserMetricsAction("Themes.Gone"), profile_);
591bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        }
592bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
593bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    }
594bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
595bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
596bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
597ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ThemeService::NotifyThemeChanged() {
598731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  VLOG(1) << "Sending BROWSER_THEME_CHANGED";
599bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Redraw!
600bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  NotificationService* service = NotificationService::current();
601bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  service->Notify(NotificationType::BROWSER_THEME_CHANGED,
602ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  Source<ThemeService>(this),
603ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  NotificationService::NoDetails());
604bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#if defined(OS_MACOSX)
605bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  NotifyPlatformThemeChanged();
606bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#endif  // OS_MACOSX
607bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
608bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
609bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#if defined(OS_WIN)
610ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ThemeService::FreePlatformCaches() {
611bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Views (Skia) has no platform image cache to clear.
612bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
613bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#endif
614bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
615ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ThemeService::Observe(NotificationType type,
616ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                           const NotificationSource& source,
617ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                           const NotificationDetails& details) {
618ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(type == NotificationType::EXTENSION_LOADED);
619ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const Extension* extension = Details<const Extension>(details).ptr();
620ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!extension->is_theme()) {
621ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
622ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
623ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  SetTheme(extension);
624ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
625ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
626ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ThemeService::SavePackName(const FilePath& pack_path) {
627bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  profile_->GetPrefs()->SetFilePath(
628bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      prefs::kCurrentThemePackFilename, pack_path);
629bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
630bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
631ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ThemeService::SaveThemeID(const std::string& id) {
632bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  profile_->GetPrefs()->SetString(prefs::kCurrentThemeID, id);
633bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
634bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
635ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ThemeService::BuildFromExtension(const Extension* extension) {
636513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<BrowserThemePack> pack(
637513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      BrowserThemePack::BuildFromExtension(extension));
638bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (!pack.get()) {
639bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    // TODO(erg): We've failed to install the theme; perhaps we should tell the
640bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    // user? http://crbug.com/34780
641bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    LOG(ERROR) << "Could not load theme.";
642bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return;
643bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
644bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
645bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Write the packed file to disk.
646bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  FilePath pack_path = extension->path().Append(chrome::kThemePackFilename);
647731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
648731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                          new WritePackToDiskTask(pack, pack_path));
649bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
650bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  SavePackName(pack_path);
651bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  theme_pack_ = pack;
652bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
653bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
654ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ThemeService::OnInfobarDisplayed() {
655bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  number_of_infobars_++;
656bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
657bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
658ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ThemeService::OnInfobarDestroyed() {
659bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  number_of_infobars_--;
660bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
661bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (number_of_infobars_ == 0)
662bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    RemoveUnusedThemes();
663bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
664