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