15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/themes/theme_service.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted_memory.h" 93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/message_loop/message_loop.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/sequenced_task_runner.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_system.h" 172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/managed_mode/managed_user_theme.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/themes/browser_theme_pack.h" 20558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "chrome/browser/themes/custom_theme_supplier.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/themes/theme_properties.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/themes/theme_syncable_service.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/user_metrics.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ui_resources.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/layout.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/win/shell.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::UserMetricsAction; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::Extension; 401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)using extensions::UnloadedExtensionInfo; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ui::ResourceBundle; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef ThemeProperties Properties; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The default theme if we haven't installed a theme yet or if we've clicked 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the "Use Classic" button. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* ThemeService::kDefaultThemeID = ""; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The default theme if we've gone to the theme gallery and installed the 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "Default" theme. We have to detect this case specifically. (By the time we 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// realize we've installed the default theme, we already have an extension 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// unpacked on the filesystem.) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* kDefaultThemeGalleryID = "hkacjpbfdknhflllbcmjibkdeoafencn"; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Wait this many seconds after startup to garbage collect unused themes. 583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Removing unused themes is done after a delay because there is no 593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// reason to do it at startup. 603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// ExtensionService::GarbageCollectExtensions() does something similar. 613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const int kRemoveUnusedThemesStartupDelay = 30; 623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkColor IncreaseLightness(SkColor color, double percent) { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) color_utils::HSL result; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) color_utils::SkColorToHSL(color, &result); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.l += (1 - result.l) * percent; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return color_utils::HSLToSkColor(result, SkColorGetA(color)); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Writes the theme pack to disk on a separate thread. 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WritePackToDiskCallback(BrowserThemePack* pack, 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& path) { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pack->WriteToDisk(path)) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Could not write theme pack to disk"; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ThemeService::ThemeService() 80bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch : ready_(false), 81bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch rb_(ResourceBundle::GetSharedInstance()), 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_(NULL), 833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) installed_pending_load_id_(kDefaultThemeID), 84ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch number_of_infobars_(0), 85ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch weak_ptr_factory_(this) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ThemeService::~ThemeService() { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FreePlatformCaches(); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThemeService::Init(Profile* profile) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_ = profile; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadThemePrefs(); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) registrar_.Add(this, 993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) chrome::NOTIFICATION_EXTENSIONS_READY, 1003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) content::Source<Profile>(profile_)); 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) theme_syncable_service_.reset(new ThemeSyncableService(profile_, this)); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Image ThemeService::GetImageNamed(int id) const { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Image image; 109558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (theme_supplier_.get()) 110558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch image = theme_supplier_->GetImageNamed(id); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (image.IsEmpty()) 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) image = rb_.GetNativeImageNamed(id); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return image; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::ImageSkia* ThemeService::GetImageSkiaNamed(int id) const { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Image image = GetImageNamed(id); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (image.IsEmpty()) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(pkotwicz): Remove this const cast. The gfx::Image interface returns 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // its images const. GetImageSkiaNamed() also should but has many callsites. 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return const_cast<gfx::ImageSkia*>(image.ToImageSkia()); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkColor ThemeService::GetColor(int id) const { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkColor color; 130558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (theme_supplier_.get() && theme_supplier_->GetColor(id, &color)) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return color; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For backward compat with older themes, some newer colors are generated from 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // older ones if they are missing. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (id) { 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case Properties::COLOR_NTP_SECTION_HEADER_TEXT: 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return IncreaseLightness(GetColor(Properties::COLOR_NTP_TEXT), 0.30); 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case Properties::COLOR_NTP_SECTION_HEADER_TEXT_HOVER: 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GetColor(Properties::COLOR_NTP_TEXT); 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case Properties::COLOR_NTP_SECTION_HEADER_RULE: 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return IncreaseLightness(GetColor(Properties::COLOR_NTP_TEXT), 0.70); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case Properties::COLOR_NTP_SECTION_HEADER_RULE_LIGHT: 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return IncreaseLightness(GetColor(Properties::COLOR_NTP_TEXT), 0.86); 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case Properties::COLOR_NTP_TEXT_LIGHT: 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return IncreaseLightness(GetColor(Properties::COLOR_NTP_TEXT), 0.40); 1467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case Properties::COLOR_MANAGED_USER_LABEL: 147558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return color_utils::GetReadableColor( 148558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch SK_ColorWHITE, 149558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch GetColor(Properties::COLOR_MANAGED_USER_LABEL_BACKGROUND)); 1507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case Properties::COLOR_MANAGED_USER_LABEL_BACKGROUND: 151558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return color_utils::BlendTowardOppositeLuminance( 152558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch GetColor(Properties::COLOR_FRAME), 0x80); 153ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case Properties::COLOR_MANAGED_USER_LABEL_BORDER: 154ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return color_utils::AlphaBlend( 155ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GetColor(Properties::COLOR_MANAGED_USER_LABEL_BACKGROUND), 156ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch SK_ColorBLACK, 157ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 230); 158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case Properties::COLOR_STATUS_BAR_TEXT: { 159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // A long time ago, we blended the toolbar and the tab text together to 160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // get the status bar text because, at the time, our text rendering in 161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // views couldn't do alpha blending. Even though this is no longer the 162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // case, this blending decision is built into the majority of themes that 163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // exist, and we must keep doing it. 164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SkColor toolbar_color = GetColor(Properties::COLOR_TOOLBAR); 165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SkColor text_color = GetColor(Properties::COLOR_TAB_TEXT); 166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return SkColorSetARGB( 167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SkColorGetA(text_color), 168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (SkColorGetR(text_color) + SkColorGetR(toolbar_color)) / 2, 169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (SkColorGetG(text_color) + SkColorGetR(toolbar_color)) / 2, 170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (SkColorGetB(text_color) + SkColorGetR(toolbar_color)) / 2); 171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Properties::GetDefaultColor(id); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 177424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)int ThemeService::GetDisplayProperty(int id) const { 178424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int result = 0; 179424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (theme_supplier_.get() && 180424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) theme_supplier_->GetDisplayProperty(id, &result)) { 181424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return result; 182424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 183424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 184424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (id == Properties::NTP_LOGO_ALTERNATE && 185424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) !UsingDefaultTheme() && 186424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) !UsingNativeTheme()) { 187424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Use the alternate logo for themes from the web store except for 188424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // |kDefaultThemeGalleryID|. 189424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return 1; 190424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 192424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return Properties::GetDefaultDisplayProperty(id); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ThemeService::ShouldUseNativeFrame() const { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasCustomImage(IDR_THEME_FRAME)) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ui::win::IsAeroGlassEnabled(); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ThemeService::HasCustomImage(int id) const { 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!Properties::IsThemeableImage(id)) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 209558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (theme_supplier_.get()) 210558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return theme_supplier_->HasCustomImage(id); 2117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::RefCountedMemory* ThemeService::GetRawData( 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int id, 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::ScaleFactor scale_factor) const { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check to see whether we should substitute some images. 219424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int ntp_alternate = GetDisplayProperty(Properties::NTP_LOGO_ALTERNATE); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (id == IDR_PRODUCT_LOGO && ntp_alternate != 0) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id = IDR_PRODUCT_LOGO_WHITE; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::RefCountedMemory* data = NULL; 224558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (theme_supplier_.get()) 225558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch data = theme_supplier_->GetRawData(id, scale_factor); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = rb_.LoadDataResourceBytesForScale(id, ui::SCALE_FACTOR_100P); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return data; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThemeService::Observe(int type, 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const content::NotificationSource& source, 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const content::NotificationDetails& details) { 2353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) using content::Details; 2363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (type) { 2373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case chrome::NOTIFICATION_EXTENSIONS_READY: 2383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) registrar_.Remove(this, chrome::NOTIFICATION_EXTENSIONS_READY, 2393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) content::Source<Profile>(profile_)); 2403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) OnExtensionServiceReady(); 2413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 2423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_INSTALLED: 2433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { 2443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // The theme may be initially disabled. Wait till it is loaded (if ever). 2453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Details<const extensions::InstalledExtensionInfo> installed_details( 2463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) details); 2473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (installed_details->extension->is_theme()) 2483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) installed_pending_load_id_ = installed_details->extension->id(); 2493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 2503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_LOADED: 2523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { 2533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const Extension* extension = Details<const Extension>(details).ptr(); 2543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (extension->is_theme() && 2553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) installed_pending_load_id_ != kDefaultThemeID && 2563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) installed_pending_load_id_ == extension->id()) { 2573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetTheme(extension); 2583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) installed_pending_load_id_ = kDefaultThemeID; 2603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 2613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_ENABLED: 2633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { 2643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const Extension* extension = Details<const Extension>(details).ptr(); 2653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (extension->is_theme()) 2663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetTheme(extension); 2673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 2683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_UNLOADED: 2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { 2711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Details<const UnloadedExtensionInfo> unloaded_details(details); 2721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (unloaded_details->reason != UnloadedExtensionInfo::REASON_UPDATE && 2733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) unloaded_details->extension->is_theme() && 2743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) unloaded_details->extension->id() == GetThemeID()) { 2753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UseDefaultTheme(); 2763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 2783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 280bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 281a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 282bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochvoid ThemeService::SetTheme(const Extension* extension) { 283bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch DCHECK(extension->is_theme()); 2843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ExtensionService* service = 2853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) extensions::ExtensionSystem::Get(profile_)->extension_service(); 2863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!service->IsExtensionEnabled(extension->id())) { 2873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // |extension| is disabled when reverting to the previous theme via an 2883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // infobar. 2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) service->EnableExtension(extension->id()); 2903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Enabling the extension will call back to SetTheme(). 2913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 292bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 293bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 2943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string previous_theme_id = GetThemeID(); 2953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Clear our image cache. 2973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FreePlatformCaches(); 2983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BuildFromExtension(extension); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SaveThemeID(extension->id()); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyThemeChanged(); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RecordAction(UserMetricsAction("Themes_Installed")); 3043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (previous_theme_id != kDefaultThemeID && 3063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) previous_theme_id != extension->id()) { 3073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Disable the old theme. 3083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) service->DisableExtension(previous_theme_id, 3093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) extensions::Extension::DISABLE_USER_ACTION); 3103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 313558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid ThemeService::SetCustomDefaultTheme( 314558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scoped_refptr<CustomThemeSupplier> theme_supplier) { 315558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ClearAllThemeData(); 316558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch SwapThemeSupplier(theme_supplier); 317558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch NotifyThemeChanged(); 318558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 319558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 320558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochbool ThemeService::ShouldInitWithNativeTheme() const { 321558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return false; 322558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 323558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 3243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ThemeService::RemoveUnusedThemes(bool ignore_infobars) { 325558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // We do not want to garbage collect themes on startup (|ready_| is false). 3263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Themes will get garbage collected after |kRemoveUnusedThemesStartupDelay|. 327558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (!profile_ || !ready_) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!ignore_infobars && number_of_infobars_ != 0) 3303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 331558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionService* service = profile_->GetExtensionService(); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!service) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string current_theme = GetThemeID(); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> remove_list; 3373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<const ExtensionSet> extensions( 3383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) service->GenerateInstalledExtensionsSet()); 3393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) extensions::ExtensionPrefs* prefs = service->extension_prefs(); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ExtensionSet::const_iterator it = extensions->begin(); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != extensions->end(); ++it) { 3423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const extensions::Extension* extension = *it; 3433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (extension->is_theme() && 3443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) extension->id() != current_theme) { 3453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Only uninstall themes which are not disabled or are disabled with 3463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // reason DISABLE_USER_ACTION. We cannot blanket uninstall all disabled 3473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // themes because externally installed themes are initially disabled. 3483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int disable_reason = prefs->GetDisableReasons(extension->id()); 3493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!prefs->IsExtensionDisabled(extension->id()) || 3503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) disable_reason == Extension::DISABLE_USER_ACTION) { 3513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) remove_list.push_back((*it)->id()); 3523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // TODO: Garbage collect all unused themes. This method misses themes which 3563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // are installed but not loaded because they are blacklisted by a management 3573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // policy provider. 3583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < remove_list.size(); ++i) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service->UninstallExtension(remove_list[i], false, NULL); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThemeService::UseDefaultTheme() { 364558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (ready_) 365558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch content::RecordAction(UserMetricsAction("Themes_Reset")); 366558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (IsManagedUser()) { 367558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch SetManagedUserTheme(); 368558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return; 369558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 370bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch ClearAllThemeData(); 371bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch NotifyThemeChanged(); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThemeService::SetNativeTheme() { 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UseDefaultTheme(); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ThemeService::UsingDefaultTheme() const { 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string id = GetThemeID(); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return id == ThemeService::kDefaultThemeID || 381424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) id == kDefaultThemeGalleryID; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ThemeService::UsingNativeTheme() const { 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return UsingDefaultTheme(); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ThemeService::GetThemeID() const { 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return profile_->GetPrefs()->GetString(prefs::kCurrentThemeID); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)color_utils::HSL ThemeService::GetTint(int id) const { 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) color_utils::HSL hsl; 396558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (theme_supplier_.get() && theme_supplier_->GetTint(id, &hsl)) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hsl; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ThemeProperties::GetDefaultTint(id); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThemeService::ClearAllThemeData() { 403bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (!ready_) 404bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return; 405bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 406558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch SwapThemeSupplier(NULL); 407558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear our image cache. 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FreePlatformCaches(); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_->GetPrefs()->ClearPref(prefs::kCurrentThemePackFilename); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SaveThemeID(kDefaultThemeID); 413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // There should be no more infobars. This may not be the case because of 4153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // http://crbug.com/62154 4163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // RemoveUnusedThemes is called on a task because ClearAllThemeData() may 4173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // be called as a result of NOTIFICATION_EXTENSION_UNLOADED. 4183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::MessageLoop::current()->PostTask(FROM_HERE, 4193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&ThemeService::RemoveUnusedThemes, 4203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 4213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) true)); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThemeService::LoadThemePrefs() { 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefService* prefs = profile_->GetPrefs(); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string current_id = GetThemeID(); 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (current_id == kDefaultThemeID) { 429558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Managed users have a different default theme. 430558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (IsManagedUser()) 431558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch SetManagedUserTheme(); 432558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch else if (ShouldInitWithNativeTheme()) 433558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch SetNativeTheme(); 434558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch else 435558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch UseDefaultTheme(); 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) set_ready(); 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool loaded_pack = false; 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we don't have a file pack, we're updating from an old version. 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath path = prefs->GetFilePath(prefs::kCurrentThemePackFilename); 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (path != base::FilePath()) { 445558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch SwapThemeSupplier(BrowserThemePack::BuildFromDataPack(path, current_id)); 446558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch loaded_pack = theme_supplier_.get() != NULL; 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (loaded_pack) { 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::RecordAction(UserMetricsAction("Themes.Loaded")); 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) set_ready(); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Else: wait for the extension service to be ready so that the theme pack 4543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // can be recreated from the extension. 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThemeService::NotifyThemeChanged() { 458558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (!ready_) 459558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return; 460558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Sending BROWSER_THEME_CHANGED"; 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Redraw! 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService* service = 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::current(); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service->Notify(chrome::NOTIFICATION_BROWSER_THEME_CHANGED, 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<ThemeService>(this), 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::NoDetails()); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyPlatformThemeChanged(); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // OS_MACOSX 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Notify sync that theme has changed. 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (theme_syncable_service_.get()) { 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) theme_syncable_service_->OnThemeChange(); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) || defined(USE_AURA) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThemeService::FreePlatformCaches() { 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Views (Skia) has no platform image cache to clear. 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ThemeService::OnExtensionServiceReady() { 4853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!ready_) { 4863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // If the ThemeService is not ready yet, the custom theme data pack needs to 4873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // be recreated from the extension. 4883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MigrateTheme(); 4893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) set_ready(); 4903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Send notification in case anyone requested data and cached it when the 4923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // theme service was not ready yet. 4933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NotifyThemeChanged(); 4943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 4953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) registrar_.Add(this, 4973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) chrome::NOTIFICATION_EXTENSION_INSTALLED, 4983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) content::Source<Profile>(profile_)); 4993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) registrar_.Add(this, 5003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) chrome::NOTIFICATION_EXTENSION_LOADED, 5013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) content::Source<Profile>(profile_)); 5023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) registrar_.Add(this, 5033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) chrome::NOTIFICATION_EXTENSION_ENABLED, 5043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) content::Source<Profile>(profile_)); 5053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) registrar_.Add(this, 5063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) chrome::NOTIFICATION_EXTENSION_UNLOADED, 5073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) content::Source<Profile>(profile_)); 5083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::MessageLoop::current()->PostDelayedTask(FROM_HERE, 5103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&ThemeService::RemoveUnusedThemes, 5113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 5123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) false), 5133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::TimeDelta::FromSeconds(kRemoveUnusedThemesStartupDelay)); 514558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 515558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThemeService::MigrateTheme() { 5173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // TODO(erg): We need to pop up a dialog informing the user that their 5183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // theme is being migrated. 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionService* service = 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::ExtensionSystem::Get(profile_)->extension_service(); 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* extension = service ? 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) service->GetExtensionById(GetThemeID(), false) : NULL; 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (extension) { 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DLOG(ERROR) << "Migrating theme"; 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BuildFromExtension(extension); 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::RecordAction(UserMetricsAction("Themes.Migrated")); 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DLOG(ERROR) << "Theme is mysteriously gone."; 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearAllThemeData(); 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::RecordAction(UserMetricsAction("Themes.Gone")); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ThemeService::SwapThemeSupplier( 5353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<CustomThemeSupplier> theme_supplier) { 5363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (theme_supplier_.get()) 5373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) theme_supplier_->StopUsingTheme(); 5383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) theme_supplier_ = theme_supplier; 5393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (theme_supplier_.get()) 5403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) theme_supplier_->StartUsingTheme(); 5413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ThemeService::SavePackName(const base::FilePath& pack_path) { 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_->GetPrefs()->SetFilePath( 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefs::kCurrentThemePackFilename, pack_path); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThemeService::SaveThemeID(const std::string& id) { 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_->GetPrefs()->SetString(prefs::kCurrentThemeID, id); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThemeService::BuildFromExtension(const Extension* extension) { 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<BrowserThemePack> pack( 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThemePack::BuildFromExtension(extension)); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pack.get()) { 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(erg): We've failed to install the theme; perhaps we should tell the 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // user? http://crbug.com/34780 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Could not load theme."; 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionService* service = 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::ExtensionSystem::Get(profile_)->extension_service(); 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!service) 5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Write the packed file to disk. 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath pack_path = 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension->path().Append(chrome::kThemePackFilename); 5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) service->GetFileTaskRunner()->PostTask( 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&WritePackToDiskCallback, pack, pack_path)); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SavePackName(pack_path); 575558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch SwapThemeSupplier(pack); 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 578eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool ThemeService::IsManagedUser() const { 579a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return profile_->IsManaged(); 580eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 581eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 582558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid ThemeService::SetManagedUserTheme() { 583558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch SetCustomDefaultTheme(new ManagedUserTheme); 584558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 585558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThemeService::OnInfobarDisplayed() { 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) number_of_infobars_++; 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThemeService::OnInfobarDestroyed() { 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) number_of_infobars_--; 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (number_of_infobars_ == 0) 5943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) RemoveUnusedThemes(false); 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ThemeSyncableService* ThemeService::GetThemeSyncableService() const { 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return theme_syncable_service_.get(); 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 600