Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/themes/theme_service.h" | 5 #include "chrome/browser/themes/theme_service.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/memory/ref_counted_memory.h" | 8 #include "base/memory/ref_counted_memory.h" |
| 9 #include "base/message_loop/message_loop.h" | |
| 9 #include "base/prefs/pref_service.h" | 10 #include "base/prefs/pref_service.h" |
| 10 #include "base/sequenced_task_runner.h" | 11 #include "base/sequenced_task_runner.h" |
| 11 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" |
| 12 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
| 13 #include "chrome/browser/chrome_notification_types.h" | 14 #include "chrome/browser/chrome_notification_types.h" |
| 14 #include "chrome/browser/extensions/extension_service.h" | 15 #include "chrome/browser/extensions/extension_service.h" |
| 15 #include "chrome/browser/extensions/extension_system.h" | 16 #include "chrome/browser/extensions/extension_system.h" |
| 16 #include "chrome/browser/profiles/profile.h" | 17 #include "chrome/browser/profiles/profile.h" |
| 17 #include "chrome/browser/themes/browser_theme_pack.h" | 18 #include "chrome/browser/themes/browser_theme_pack.h" |
| 18 #include "chrome/browser/themes/custom_theme_supplier.h" | 19 #include "chrome/browser/themes/custom_theme_supplier.h" |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 49 const char* ThemeService::kDefaultThemeID = ""; | 50 const char* ThemeService::kDefaultThemeID = ""; |
| 50 | 51 |
| 51 namespace { | 52 namespace { |
| 52 | 53 |
| 53 // The default theme if we've gone to the theme gallery and installed the | 54 // The default theme if we've gone to the theme gallery and installed the |
| 54 // "Default" theme. We have to detect this case specifically. (By the time we | 55 // "Default" theme. We have to detect this case specifically. (By the time we |
| 55 // realize we've installed the default theme, we already have an extension | 56 // realize we've installed the default theme, we already have an extension |
| 56 // unpacked on the filesystem.) | 57 // unpacked on the filesystem.) |
| 57 const char* kDefaultThemeGalleryID = "hkacjpbfdknhflllbcmjibkdeoafencn"; | 58 const char* kDefaultThemeGalleryID = "hkacjpbfdknhflllbcmjibkdeoafencn"; |
| 58 | 59 |
| 60 // Wait this many seconds after startup to garbage collect unused themes. | |
| 61 // Removing unused themes is done after a delay because there is no | |
| 62 // reason to do it at startup. | |
| 63 // ExtensionService::GarbageCollectExtensions() does something similar. | |
| 64 const int kRemoveUnusedThemesStartupDelay = 30; | |
| 65 | |
| 59 SkColor TintForUnderline(SkColor input) { | 66 SkColor TintForUnderline(SkColor input) { |
| 60 return SkColorSetA(input, SkColorGetA(input) / 3); | 67 return SkColorSetA(input, SkColorGetA(input) / 3); |
| 61 } | 68 } |
| 62 | 69 |
| 63 SkColor IncreaseLightness(SkColor color, double percent) { | 70 SkColor IncreaseLightness(SkColor color, double percent) { |
| 64 color_utils::HSL result; | 71 color_utils::HSL result; |
| 65 color_utils::SkColorToHSL(color, &result); | 72 color_utils::SkColorToHSL(color, &result); |
| 66 result.l += (1 - result.l) * percent; | 73 result.l += (1 - result.l) * percent; |
| 67 return color_utils::HSLToSkColor(result, SkColorGetA(color)); | 74 return color_utils::HSLToSkColor(result, SkColorGetA(color)); |
| 68 } | 75 } |
| 69 | 76 |
| 70 // Writes the theme pack to disk on a separate thread. | 77 // Writes the theme pack to disk on a separate thread. |
| 71 void WritePackToDiskCallback(BrowserThemePack* pack, | 78 void WritePackToDiskCallback(BrowserThemePack* pack, |
| 72 const base::FilePath& path) { | 79 const base::FilePath& path) { |
| 73 if (!pack->WriteToDisk(path)) | 80 if (!pack->WriteToDisk(path)) |
| 74 NOTREACHED() << "Could not write theme pack to disk"; | 81 NOTREACHED() << "Could not write theme pack to disk"; |
| 75 } | 82 } |
| 76 | 83 |
| 77 } // namespace | 84 } // namespace |
| 78 | 85 |
| 79 ThemeService::ThemeService() | 86 ThemeService::ThemeService() |
| 80 : rb_(ResourceBundle::GetSharedInstance()), | 87 : rb_(ResourceBundle::GetSharedInstance()), |
| 81 profile_(NULL), | 88 profile_(NULL), |
| 82 ready_(false), | 89 ready_(false), |
| 83 number_of_infobars_(0) { | 90 installed_pending_load_id_(kDefaultThemeID), |
| 91 number_of_infobars_(0), | |
| 92 weak_ptr_factory_(this) { | |
| 84 } | 93 } |
| 85 | 94 |
| 86 ThemeService::~ThemeService() { | 95 ThemeService::~ThemeService() { |
| 87 FreePlatformCaches(); | 96 FreePlatformCaches(); |
| 88 } | 97 } |
| 89 | 98 |
| 90 void ThemeService::Init(Profile* profile) { | 99 void ThemeService::Init(Profile* profile) { |
| 91 DCHECK(CalledOnValidThread()); | 100 DCHECK(CalledOnValidThread()); |
| 92 profile_ = profile; | 101 profile_ = profile; |
| 93 | 102 |
| 94 LoadThemePrefs(); | 103 LoadThemePrefs(); |
| 95 | 104 |
| 96 if (!ready_) { | 105 registrar_.Add(this, |
| 97 registrar_.Add(this, | 106 chrome::NOTIFICATION_EXTENSIONS_READY, |
| 98 chrome::NOTIFICATION_EXTENSIONS_READY, | 107 content::Source<Profile>(profile_)); |
| 99 content::Source<Profile>(profile_)); | |
| 100 } | |
| 101 | 108 |
| 102 theme_syncable_service_.reset(new ThemeSyncableService(profile_, this)); | 109 theme_syncable_service_.reset(new ThemeSyncableService(profile_, this)); |
| 103 } | 110 } |
| 104 | 111 |
| 105 gfx::Image ThemeService::GetImageNamed(int id) const { | 112 gfx::Image ThemeService::GetImageNamed(int id) const { |
| 106 DCHECK(CalledOnValidThread()); | 113 DCHECK(CalledOnValidThread()); |
| 107 | 114 |
| 108 gfx::Image image; | 115 gfx::Image image; |
| 109 if (theme_supplier_.get()) | 116 if (theme_supplier_.get()) |
| 110 image = theme_supplier_->GetImageNamed(id); | 117 image = theme_supplier_->GetImageNamed(id); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 196 data = theme_supplier_->GetRawData(id, scale_factor); | 203 data = theme_supplier_->GetRawData(id, scale_factor); |
| 197 if (!data) | 204 if (!data) |
| 198 data = rb_.LoadDataResourceBytesForScale(id, ui::SCALE_FACTOR_100P); | 205 data = rb_.LoadDataResourceBytesForScale(id, ui::SCALE_FACTOR_100P); |
| 199 | 206 |
| 200 return data; | 207 return data; |
| 201 } | 208 } |
| 202 | 209 |
| 203 void ThemeService::Observe(int type, | 210 void ThemeService::Observe(int type, |
| 204 const content::NotificationSource& source, | 211 const content::NotificationSource& source, |
| 205 const content::NotificationDetails& details) { | 212 const content::NotificationDetails& details) { |
| 206 DCHECK(type == chrome::NOTIFICATION_EXTENSIONS_READY); | 213 using content::Details; |
| 207 registrar_.Remove(this, chrome::NOTIFICATION_EXTENSIONS_READY, | 214 switch (type) { |
| 208 content::Source<Profile>(profile_)); | 215 case chrome::NOTIFICATION_EXTENSIONS_READY: |
| 209 | 216 registrar_.Remove(this, chrome::NOTIFICATION_EXTENSIONS_READY, |
| 210 MigrateTheme(); | 217 content::Source<Profile>(profile_)); |
| 211 set_ready(); | 218 OnExtensionServiceReady(); |
| 212 | 219 break; |
| 213 // Send notification in case anyone requested data and cached it when the | 220 case chrome::NOTIFICATION_EXTENSION_INSTALLED: |
| 214 // theme service was not ready yet. | 221 { |
| 215 NotifyThemeChanged(); | 222 // The theme may be initially disabled. Wait till it is loaded (if ever). |
| 223 Details<const extensions::InstalledExtensionInfo> installed_details( | |
| 224 details); | |
| 225 if (installed_details->extension->is_theme()) | |
| 226 installed_pending_load_id_ = installed_details->extension->id(); | |
| 227 break; | |
| 228 } | |
| 229 case chrome::NOTIFICATION_EXTENSION_LOADED: | |
| 230 { | |
| 231 const Extension* extension = Details<const Extension>(details).ptr(); | |
| 232 if (extension->is_theme() && | |
| 233 installed_pending_load_id_ != kDefaultThemeID && | |
| 234 installed_pending_load_id_ == extension->id()) { | |
| 235 SetTheme(extension); | |
| 236 } | |
| 237 installed_pending_load_id_ = kDefaultThemeID; | |
| 238 break; | |
| 239 } | |
| 240 case chrome::NOTIFICATION_EXTENSION_ENABLED: | |
| 241 { | |
| 242 const Extension* extension = Details<const Extension>(details).ptr(); | |
| 243 if (extension->is_theme()) | |
| 244 SetTheme(extension); | |
| 245 break; | |
| 246 } | |
| 247 case chrome::NOTIFICATION_EXTENSION_UNLOADED: | |
| 248 { | |
| 249 Details<const extensions::UnloadedExtensionInfo> unloaded_details( | |
| 250 details); | |
| 251 if (unloaded_details->reason != extension_misc::UNLOAD_REASON_UPDATE && | |
| 252 unloaded_details->extension->is_theme() && | |
| 253 unloaded_details->extension->id() == GetThemeID()) { | |
| 254 UseDefaultTheme(); | |
| 255 } | |
| 256 break; | |
| 257 } | |
| 258 } | |
| 216 } | 259 } |
| 217 | 260 |
| 218 void ThemeService::SetTheme(const Extension* extension) { | 261 void ThemeService::SetTheme(const Extension* extension) { |
| 262 DCHECK(extension->is_theme()); | |
| 263 ExtensionService* service = | |
| 264 extensions::ExtensionSystem::Get(profile_)->extension_service(); | |
| 265 if (!service->IsExtensionEnabled(extension->id())) { | |
| 266 // |extension| is disabled when reverting to the previous theme via an | |
| 267 // infobar. | |
| 268 service->EnableExtension(extension->id()); | |
| 269 // Enabling the extension will call back to SetTheme(). | |
| 270 return; | |
| 271 } | |
| 272 | |
| 273 std::string previous_theme_id = GetThemeID(); | |
| 274 | |
| 219 // Clear our image cache. | 275 // Clear our image cache. |
| 220 FreePlatformCaches(); | 276 FreePlatformCaches(); |
| 221 | 277 |
| 222 DCHECK(extension); | |
| 223 DCHECK(extension->is_theme()); | |
| 224 if (DCHECK_IS_ON()) { | |
| 225 ExtensionService* service = | |
| 226 extensions::ExtensionSystem::Get(profile_)->extension_service(); | |
| 227 DCHECK(service); | |
| 228 DCHECK(service->GetExtensionById(extension->id(), false)); | |
| 229 } | |
| 230 | |
| 231 BuildFromExtension(extension); | 278 BuildFromExtension(extension); |
| 232 SaveThemeID(extension->id()); | 279 SaveThemeID(extension->id()); |
| 233 | 280 |
| 234 NotifyThemeChanged(); | 281 NotifyThemeChanged(); |
| 235 content::RecordAction(UserMetricsAction("Themes_Installed")); | 282 content::RecordAction(UserMetricsAction("Themes_Installed")); |
| 283 | |
| 284 if (previous_theme_id != kDefaultThemeID && | |
| 285 previous_theme_id != extension->id()) { | |
| 286 // Disable the old theme. | |
| 287 service->DisableExtension(previous_theme_id, | |
| 288 extensions::Extension::DISABLE_USER_ACTION); | |
| 289 } | |
| 236 } | 290 } |
| 237 | 291 |
| 238 void ThemeService::SetCustomDefaultTheme( | 292 void ThemeService::SetCustomDefaultTheme( |
| 239 scoped_refptr<CustomThemeSupplier> theme_supplier) { | 293 scoped_refptr<CustomThemeSupplier> theme_supplier) { |
| 240 ClearAllThemeData(); | 294 ClearAllThemeData(); |
| 241 SwapThemeSupplier(theme_supplier); | 295 SwapThemeSupplier(theme_supplier); |
| 242 NotifyThemeChanged(); | 296 NotifyThemeChanged(); |
| 243 } | 297 } |
| 244 | 298 |
| 245 bool ThemeService::ShouldInitWithNativeTheme() const { | 299 bool ThemeService::ShouldInitWithNativeTheme() const { |
| 246 return false; | 300 return false; |
| 247 } | 301 } |
| 248 | 302 |
| 249 void ThemeService::RemoveUnusedThemes() { | 303 void ThemeService::RemoveUnusedThemes(bool ignore_infobars) { |
| 250 // We do not want to garbage collect themes on startup (|ready_| is false). | 304 // We do not want to garbage collect themes on startup (|ready_| is false). |
| 251 // Themes will get garbage collected once | 305 // Themes will get garbage collected after |kRemoveUnusedThemesStartupDelay|. |
| 252 // ExtensionService::GarbageCollectExtensions() runs. | |
| 253 if (!profile_ || !ready_) | 306 if (!profile_ || !ready_) |
| 254 return; | 307 return; |
| 308 if (!ignore_infobars && number_of_infobars_ != 0) | |
| 309 return; | |
| 255 | 310 |
| 256 ExtensionService* service = profile_->GetExtensionService(); | 311 ExtensionService* service = profile_->GetExtensionService(); |
| 257 if (!service) | 312 if (!service) |
| 258 return; | 313 return; |
| 259 std::string current_theme = GetThemeID(); | 314 std::string current_theme = GetThemeID(); |
| 260 std::vector<std::string> remove_list; | 315 std::vector<std::string> remove_list; |
| 261 const ExtensionSet* extensions = service->extensions(); | 316 scoped_ptr<const ExtensionSet> extensions( |
| 317 service->GenerateInstalledExtensionsSet()); | |
| 318 extensions::ExtensionPrefs* prefs = service->extension_prefs(); | |
| 262 for (ExtensionSet::const_iterator it = extensions->begin(); | 319 for (ExtensionSet::const_iterator it = extensions->begin(); |
| 263 it != extensions->end(); ++it) { | 320 it != extensions->end(); ++it) { |
| 264 if ((*it)->is_theme() && (*it)->id() != current_theme) { | 321 const extensions::Extension* extension = *it; |
| 265 remove_list.push_back((*it)->id()); | 322 if (extension->is_theme() && |
| 323 extension->id() != current_theme) { | |
| 324 // Only uninstall themes which are not disabled or are disabled with | |
| 325 // reason DISABLE_USER_ACTION. We cannot blanket uninstall all disabled | |
| 326 // themes because externally installed themes are initially disabled. | |
| 327 int disable_reason = prefs->GetDisableReasons(extension->id()); | |
| 328 if (!prefs->IsExtensionDisabled(extension->id()) || | |
| 329 disable_reason == Extension::DISABLE_USER_ACTION) { | |
| 330 remove_list.push_back((*it)->id()); | |
| 331 } | |
| 266 } | 332 } |
| 267 } | 333 } |
| 334 // TODO: Garbage collect all unused themes. This method misses themes which | |
| 335 // are installed but not loaded because they are blacklisted by a management | |
| 336 // policy provider. | |
| 337 | |
| 268 for (size_t i = 0; i < remove_list.size(); ++i) | 338 for (size_t i = 0; i < remove_list.size(); ++i) |
| 269 service->UninstallExtension(remove_list[i], false, NULL); | 339 service->UninstallExtension(remove_list[i], false, NULL); |
| 270 } | 340 } |
| 271 | 341 |
| 272 void ThemeService::UseDefaultTheme() { | 342 void ThemeService::UseDefaultTheme() { |
| 273 if (ready_) | 343 if (ready_) |
| 274 content::RecordAction(UserMetricsAction("Themes_Reset")); | 344 content::RecordAction(UserMetricsAction("Themes_Reset")); |
| 275 if (IsManagedUser()) { | 345 if (IsManagedUser()) { |
| 276 SetManagedUserTheme(); | 346 SetManagedUserTheme(); |
| 277 return; | 347 return; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 312 | 382 |
| 313 void ThemeService::ClearAllThemeData() { | 383 void ThemeService::ClearAllThemeData() { |
| 314 SwapThemeSupplier(NULL); | 384 SwapThemeSupplier(NULL); |
| 315 | 385 |
| 316 // Clear our image cache. | 386 // Clear our image cache. |
| 317 FreePlatformCaches(); | 387 FreePlatformCaches(); |
| 318 | 388 |
| 319 profile_->GetPrefs()->ClearPref(prefs::kCurrentThemePackFilename); | 389 profile_->GetPrefs()->ClearPref(prefs::kCurrentThemePackFilename); |
| 320 SaveThemeID(kDefaultThemeID); | 390 SaveThemeID(kDefaultThemeID); |
| 321 | 391 |
| 322 RemoveUnusedThemes(); | 392 // There should be no more infobars. This may not be the case because of |
| 393 // http://crbug.com/62154 | |
| 394 // RemoveUnusedThemes is called on a task because ClearAllThemeData() may | |
| 395 // be called as a result of NOTIFICATION_EXTENSION_UNLOADED. | |
| 396 base::MessageLoop::current()->PostTask(FROM_HERE, | |
|
Jeffrey Yasskin
2013/08/06 21:46:01
In local test runs, I'm getting stack traces like:
| |
| 397 base::Bind(&ThemeService::RemoveUnusedThemes, | |
| 398 weak_ptr_factory_.GetWeakPtr(), | |
| 399 true)); | |
| 323 } | 400 } |
| 324 | 401 |
| 325 void ThemeService::LoadThemePrefs() { | 402 void ThemeService::LoadThemePrefs() { |
| 326 PrefService* prefs = profile_->GetPrefs(); | 403 PrefService* prefs = profile_->GetPrefs(); |
| 327 | 404 |
| 328 std::string current_id = GetThemeID(); | 405 std::string current_id = GetThemeID(); |
| 329 if (current_id == kDefaultThemeID) { | 406 if (current_id == kDefaultThemeID) { |
| 330 // Managed users have a different default theme. | 407 // Managed users have a different default theme. |
| 331 if (IsManagedUser()) | 408 if (IsManagedUser()) |
| 332 SetManagedUserTheme(); | 409 SetManagedUserTheme(); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 343 // If we don't have a file pack, we're updating from an old version. | 420 // If we don't have a file pack, we're updating from an old version. |
| 344 base::FilePath path = prefs->GetFilePath(prefs::kCurrentThemePackFilename); | 421 base::FilePath path = prefs->GetFilePath(prefs::kCurrentThemePackFilename); |
| 345 if (path != base::FilePath()) { | 422 if (path != base::FilePath()) { |
| 346 SwapThemeSupplier(BrowserThemePack::BuildFromDataPack(path, current_id)); | 423 SwapThemeSupplier(BrowserThemePack::BuildFromDataPack(path, current_id)); |
| 347 loaded_pack = theme_supplier_.get() != NULL; | 424 loaded_pack = theme_supplier_.get() != NULL; |
| 348 } | 425 } |
| 349 | 426 |
| 350 if (loaded_pack) { | 427 if (loaded_pack) { |
| 351 content::RecordAction(UserMetricsAction("Themes.Loaded")); | 428 content::RecordAction(UserMetricsAction("Themes.Loaded")); |
| 352 set_ready(); | 429 set_ready(); |
| 353 } else { | |
| 354 // TODO(erg): We need to pop up a dialog informing the user that their | |
| 355 // theme is being migrated. | |
| 356 ExtensionService* service = | |
| 357 extensions::ExtensionSystem::Get(profile_)->extension_service(); | |
| 358 if (service && service->is_ready()) { | |
| 359 MigrateTheme(); | |
| 360 set_ready(); | |
| 361 } | |
| 362 } | 430 } |
| 431 // Else: wait for the extension service to be ready so that the theme pack | |
| 432 // can be recreated from the extension. | |
| 363 } | 433 } |
| 364 | 434 |
| 365 void ThemeService::NotifyThemeChanged() { | 435 void ThemeService::NotifyThemeChanged() { |
| 366 if (!ready_) | 436 if (!ready_) |
| 367 return; | 437 return; |
| 368 | 438 |
| 369 DVLOG(1) << "Sending BROWSER_THEME_CHANGED"; | 439 DVLOG(1) << "Sending BROWSER_THEME_CHANGED"; |
| 370 // Redraw! | 440 // Redraw! |
| 371 content::NotificationService* service = | 441 content::NotificationService* service = |
| 372 content::NotificationService::current(); | 442 content::NotificationService::current(); |
| 373 service->Notify(chrome::NOTIFICATION_BROWSER_THEME_CHANGED, | 443 service->Notify(chrome::NOTIFICATION_BROWSER_THEME_CHANGED, |
| 374 content::Source<ThemeService>(this), | 444 content::Source<ThemeService>(this), |
| 375 content::NotificationService::NoDetails()); | 445 content::NotificationService::NoDetails()); |
| 376 #if defined(OS_MACOSX) | 446 #if defined(OS_MACOSX) |
| 377 NotifyPlatformThemeChanged(); | 447 NotifyPlatformThemeChanged(); |
| 378 #endif // OS_MACOSX | 448 #endif // OS_MACOSX |
| 379 | 449 |
| 380 // Notify sync that theme has changed. | 450 // Notify sync that theme has changed. |
| 381 if (theme_syncable_service_.get()) { | 451 if (theme_syncable_service_.get()) { |
| 382 theme_syncable_service_->OnThemeChange(); | 452 theme_syncable_service_->OnThemeChange(); |
| 383 } | 453 } |
| 384 } | 454 } |
| 385 | 455 |
| 386 #if defined(OS_WIN) || defined(USE_AURA) | 456 #if defined(OS_WIN) || defined(USE_AURA) |
| 387 void ThemeService::FreePlatformCaches() { | 457 void ThemeService::FreePlatformCaches() { |
| 388 // Views (Skia) has no platform image cache to clear. | 458 // Views (Skia) has no platform image cache to clear. |
| 389 } | 459 } |
| 390 #endif | 460 #endif |
| 391 | 461 |
| 392 void ThemeService::SwapThemeSupplier( | 462 void ThemeService::OnExtensionServiceReady() { |
| 393 scoped_refptr<CustomThemeSupplier> theme_supplier) { | 463 if (!ready_) { |
| 394 if (theme_supplier_.get()) | 464 // If the ThemeService is not ready yet, the custom theme data pack needs to |
| 395 theme_supplier_->StopUsingTheme(); | 465 // be recreated from the extension. |
| 396 theme_supplier_ = theme_supplier; | 466 MigrateTheme(); |
| 397 if (theme_supplier_.get()) | 467 set_ready(); |
| 398 theme_supplier_->StartUsingTheme(); | 468 |
| 469 // Send notification in case anyone requested data and cached it when the | |
| 470 // theme service was not ready yet. | |
| 471 NotifyThemeChanged(); | |
| 472 } | |
| 473 | |
| 474 registrar_.Add(this, | |
| 475 chrome::NOTIFICATION_EXTENSION_INSTALLED, | |
| 476 content::Source<Profile>(profile_)); | |
| 477 registrar_.Add(this, | |
| 478 chrome::NOTIFICATION_EXTENSION_LOADED, | |
| 479 content::Source<Profile>(profile_)); | |
| 480 registrar_.Add(this, | |
| 481 chrome::NOTIFICATION_EXTENSION_ENABLED, | |
| 482 content::Source<Profile>(profile_)); | |
| 483 registrar_.Add(this, | |
| 484 chrome::NOTIFICATION_EXTENSION_UNLOADED, | |
| 485 content::Source<Profile>(profile_)); | |
| 486 | |
| 487 base::MessageLoop::current()->PostDelayedTask(FROM_HERE, | |
| 488 base::Bind(&ThemeService::RemoveUnusedThemes, | |
| 489 weak_ptr_factory_.GetWeakPtr(), | |
| 490 false), | |
| 491 base::TimeDelta::FromSeconds(kRemoveUnusedThemesStartupDelay)); | |
| 399 } | 492 } |
| 400 | 493 |
| 401 void ThemeService::MigrateTheme() { | 494 void ThemeService::MigrateTheme() { |
| 495 // TODO(erg): We need to pop up a dialog informing the user that their | |
| 496 // theme is being migrated. | |
| 402 ExtensionService* service = | 497 ExtensionService* service = |
| 403 extensions::ExtensionSystem::Get(profile_)->extension_service(); | 498 extensions::ExtensionSystem::Get(profile_)->extension_service(); |
| 404 const Extension* extension = service ? | 499 const Extension* extension = service ? |
| 405 service->GetExtensionById(GetThemeID(), false) : NULL; | 500 service->GetExtensionById(GetThemeID(), false) : NULL; |
| 406 if (extension) { | 501 if (extension) { |
| 407 DLOG(ERROR) << "Migrating theme"; | 502 DLOG(ERROR) << "Migrating theme"; |
| 408 BuildFromExtension(extension); | 503 BuildFromExtension(extension); |
| 409 content::RecordAction(UserMetricsAction("Themes.Migrated")); | 504 content::RecordAction(UserMetricsAction("Themes.Migrated")); |
| 410 } else { | 505 } else { |
| 411 DLOG(ERROR) << "Theme is mysteriously gone."; | 506 DLOG(ERROR) << "Theme is mysteriously gone."; |
| 412 ClearAllThemeData(); | 507 ClearAllThemeData(); |
| 413 content::RecordAction(UserMetricsAction("Themes.Gone")); | 508 content::RecordAction(UserMetricsAction("Themes.Gone")); |
| 414 } | 509 } |
| 415 } | 510 } |
| 416 | 511 |
| 512 void ThemeService::SwapThemeSupplier( | |
| 513 scoped_refptr<CustomThemeSupplier> theme_supplier) { | |
| 514 if (theme_supplier_.get()) | |
| 515 theme_supplier_->StopUsingTheme(); | |
| 516 theme_supplier_ = theme_supplier; | |
| 517 if (theme_supplier_.get()) | |
| 518 theme_supplier_->StartUsingTheme(); | |
| 519 } | |
| 520 | |
| 417 void ThemeService::SavePackName(const base::FilePath& pack_path) { | 521 void ThemeService::SavePackName(const base::FilePath& pack_path) { |
| 418 profile_->GetPrefs()->SetFilePath( | 522 profile_->GetPrefs()->SetFilePath( |
| 419 prefs::kCurrentThemePackFilename, pack_path); | 523 prefs::kCurrentThemePackFilename, pack_path); |
| 420 } | 524 } |
| 421 | 525 |
| 422 void ThemeService::SaveThemeID(const std::string& id) { | 526 void ThemeService::SaveThemeID(const std::string& id) { |
| 423 profile_->GetPrefs()->SetString(prefs::kCurrentThemeID, id); | 527 profile_->GetPrefs()->SetString(prefs::kCurrentThemeID, id); |
| 424 } | 528 } |
| 425 | 529 |
| 426 void ThemeService::BuildFromExtension(const Extension* extension) { | 530 void ThemeService::BuildFromExtension(const Extension* extension) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 462 } | 566 } |
| 463 | 567 |
| 464 void ThemeService::OnInfobarDisplayed() { | 568 void ThemeService::OnInfobarDisplayed() { |
| 465 number_of_infobars_++; | 569 number_of_infobars_++; |
| 466 } | 570 } |
| 467 | 571 |
| 468 void ThemeService::OnInfobarDestroyed() { | 572 void ThemeService::OnInfobarDestroyed() { |
| 469 number_of_infobars_--; | 573 number_of_infobars_--; |
| 470 | 574 |
| 471 if (number_of_infobars_ == 0) | 575 if (number_of_infobars_ == 0) |
| 472 RemoveUnusedThemes(); | 576 RemoveUnusedThemes(false); |
| 473 } | 577 } |
| 474 | 578 |
| 475 ThemeSyncableService* ThemeService::GetThemeSyncableService() const { | 579 ThemeSyncableService* ThemeService::GetThemeSyncableService() const { |
| 476 return theme_syncable_service_.get(); | 580 return theme_syncable_service_.get(); |
| 477 } | 581 } |
| OLD | NEW |