| 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/background/background_contents_service.h" | 5 #include "chrome/browser/background/background_contents_service.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| 11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
| 12 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
| 13 #include "base/values.h" | 13 #include "base/values.h" |
| 14 #include "chrome/browser/background/background_contents_service_factory.h" | 14 #include "chrome/browser/background/background_contents_service_factory.h" |
| 15 #include "chrome/browser/browser_process.h" | 15 #include "chrome/browser/browser_process.h" |
| 16 #include "chrome/browser/extensions/extension_host.h" | 16 #include "chrome/browser/extensions/extension_host.h" |
| 17 #include "chrome/browser/extensions/extension_service.h" | 17 #include "chrome/browser/extensions/extension_service.h" |
| 18 #include "chrome/browser/extensions/extension_system.h" |
| 18 #include "chrome/browser/notifications/desktop_notification_service.h" | 19 #include "chrome/browser/notifications/desktop_notification_service.h" |
| 19 #include "chrome/browser/notifications/notification.h" | 20 #include "chrome/browser/notifications/notification.h" |
| 20 #include "chrome/browser/notifications/notification_ui_manager.h" | 21 #include "chrome/browser/notifications/notification_ui_manager.h" |
| 21 #include "chrome/browser/prefs/pref_service.h" | 22 #include "chrome/browser/prefs/pref_service.h" |
| 22 #include "chrome/browser/prefs/scoped_user_pref_update.h" | 23 #include "chrome/browser/prefs/scoped_user_pref_update.h" |
| 23 #include "chrome/browser/profiles/profile.h" | 24 #include "chrome/browser/profiles/profile.h" |
| 24 #include "chrome/browser/ui/browser.h" | 25 #include "chrome/browser/ui/browser.h" |
| 25 #include "chrome/browser/ui/browser_finder.h" | 26 #include "chrome/browser/ui/browser_finder.h" |
| 26 #include "chrome/browser/ui/browser_tabstrip.h" | 27 #include "chrome/browser/ui/browser_tabstrip.h" |
| 27 #include "chrome/browser/ui/host_desktop.h" | 28 #include "chrome/browser/ui/host_desktop.h" |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 virtual void Click() OVERRIDE { | 77 virtual void Click() OVERRIDE { |
| 77 if (is_hosted_app_) { | 78 if (is_hosted_app_) { |
| 78 // There can be a race here: user clicks the balloon, and simultaneously | 79 // There can be a race here: user clicks the balloon, and simultaneously |
| 79 // reloads the sad tab for the app. So we check here to be safe before | 80 // reloads the sad tab for the app. So we check here to be safe before |
| 80 // loading the background page. | 81 // loading the background page. |
| 81 BackgroundContentsService* service = | 82 BackgroundContentsService* service = |
| 82 BackgroundContentsServiceFactory::GetForProfile(profile_); | 83 BackgroundContentsServiceFactory::GetForProfile(profile_); |
| 83 if (!service->GetAppBackgroundContents(ASCIIToUTF16(extension_id_))) | 84 if (!service->GetAppBackgroundContents(ASCIIToUTF16(extension_id_))) |
| 84 service->LoadBackgroundContentsForExtension(profile_, extension_id_); | 85 service->LoadBackgroundContentsForExtension(profile_, extension_id_); |
| 85 } else { | 86 } else { |
| 86 profile_->GetExtensionService()->ReloadExtension(extension_id_); | 87 extensions::ExtensionSystem::Get(profile_)->extension_service()-> |
| 88 ReloadExtension(extension_id_); |
| 87 } | 89 } |
| 88 | 90 |
| 89 // Closing the balloon here should be OK, but it causes a crash on Mac | 91 // Closing the balloon here should be OK, but it causes a crash on Mac |
| 90 // http://crbug.com/78167 | 92 // http://crbug.com/78167 |
| 91 ScheduleCloseBalloon(extension_id_); | 93 ScheduleCloseBalloon(extension_id_); |
| 92 } | 94 } |
| 93 | 95 |
| 94 virtual std::string id() const OVERRIDE { | 96 virtual std::string id() const OVERRIDE { |
| 95 return kNotificationPrefix + extension_id_; | 97 return kNotificationPrefix + extension_id_; |
| 96 } | 98 } |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 break; | 246 break; |
| 245 case chrome::NOTIFICATION_BACKGROUND_CONTENTS_NAVIGATED: { | 247 case chrome::NOTIFICATION_BACKGROUND_CONTENTS_NAVIGATED: { |
| 246 DCHECK(IsTracked(content::Details<BackgroundContents>(details).ptr())); | 248 DCHECK(IsTracked(content::Details<BackgroundContents>(details).ptr())); |
| 247 | 249 |
| 248 // Do not register in the pref if the extension has a manifest-specified | 250 // Do not register in the pref if the extension has a manifest-specified |
| 249 // background page. | 251 // background page. |
| 250 BackgroundContents* bgcontents = | 252 BackgroundContents* bgcontents = |
| 251 content::Details<BackgroundContents>(details).ptr(); | 253 content::Details<BackgroundContents>(details).ptr(); |
| 252 Profile* profile = content::Source<Profile>(source).ptr(); | 254 Profile* profile = content::Source<Profile>(source).ptr(); |
| 253 const string16& appid = GetParentApplicationId(bgcontents); | 255 const string16& appid = GetParentApplicationId(bgcontents); |
| 254 ExtensionService* extension_service = profile->GetExtensionService(); | 256 ExtensionService* extension_service = |
| 257 extensions::ExtensionSystem::Get(profile)->extension_service(); |
| 255 // extension_service can be NULL when running tests. | 258 // extension_service can be NULL when running tests. |
| 256 if (extension_service) { | 259 if (extension_service) { |
| 257 const Extension* extension = | 260 const Extension* extension = |
| 258 extension_service->GetExtensionById(UTF16ToUTF8(appid), false); | 261 extension_service->GetExtensionById(UTF16ToUTF8(appid), false); |
| 259 if (extension && extension->has_background_page()) | 262 if (extension && extension->has_background_page()) |
| 260 break; | 263 break; |
| 261 } | 264 } |
| 262 RegisterBackgroundContents(bgcontents); | 265 RegisterBackgroundContents(bgcontents); |
| 263 break; | 266 break; |
| 264 } | 267 } |
| 265 case chrome::NOTIFICATION_EXTENSION_LOADED: { | 268 case chrome::NOTIFICATION_EXTENSION_LOADED: { |
| 266 const Extension* extension = | 269 const Extension* extension = |
| 267 content::Details<const Extension>(details).ptr(); | 270 content::Details<const Extension>(details).ptr(); |
| 268 Profile* profile = content::Source<Profile>(source).ptr(); | 271 Profile* profile = content::Source<Profile>(source).ptr(); |
| 269 if (extension->is_hosted_app() && | 272 if (extension->is_hosted_app() && |
| 270 extension->has_background_page()) { | 273 extension->has_background_page()) { |
| 271 // If there is a background page specified in the manifest for a hosted | 274 // If there is a background page specified in the manifest for a hosted |
| 272 // app, then blow away registered urls in the pref. | 275 // app, then blow away registered urls in the pref. |
| 273 ShutdownAssociatedBackgroundContents(ASCIIToUTF16(extension->id())); | 276 ShutdownAssociatedBackgroundContents(ASCIIToUTF16(extension->id())); |
| 274 | 277 |
| 275 ExtensionService* service = profile->GetExtensionService(); | 278 ExtensionService* service = |
| 279 extensions::ExtensionSystem::Get(profile)->extension_service(); |
| 276 if (service && service->is_ready()) { | 280 if (service && service->is_ready()) { |
| 277 // Now load the manifest-specified background page. If service isn't | 281 // Now load the manifest-specified background page. If service isn't |
| 278 // ready, then the background page will be loaded from the | 282 // ready, then the background page will be loaded from the |
| 279 // EXTENSIONS_READY callback. | 283 // EXTENSIONS_READY callback. |
| 280 LoadBackgroundContents(profile, extension->GetBackgroundURL(), | 284 LoadBackgroundContents(profile, extension->GetBackgroundURL(), |
| 281 ASCIIToUTF16("background"), UTF8ToUTF16(extension->id())); | 285 ASCIIToUTF16("background"), UTF8ToUTF16(extension->id())); |
| 282 } | 286 } |
| 283 } | 287 } |
| 284 | 288 |
| 285 // Remove any "This extension has crashed" balloons. | 289 // Remove any "This extension has crashed" balloons. |
| 286 ScheduleCloseBalloon(extension->id()); | 290 ScheduleCloseBalloon(extension->id()); |
| 287 SendChangeNotification(profile); | 291 SendChangeNotification(profile); |
| 288 break; | 292 break; |
| 289 } | 293 } |
| 290 case chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED: | 294 case chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED: |
| 291 case chrome::NOTIFICATION_BACKGROUND_CONTENTS_TERMINATED: { | 295 case chrome::NOTIFICATION_BACKGROUND_CONTENTS_TERMINATED: { |
| 292 Profile* profile = content::Source<Profile>(source).ptr(); | 296 Profile* profile = content::Source<Profile>(source).ptr(); |
| 293 const Extension* extension = NULL; | 297 const Extension* extension = NULL; |
| 294 if (type == chrome::NOTIFICATION_BACKGROUND_CONTENTS_TERMINATED) { | 298 if (type == chrome::NOTIFICATION_BACKGROUND_CONTENTS_TERMINATED) { |
| 295 BackgroundContents* bg = | 299 BackgroundContents* bg = |
| 296 content::Details<BackgroundContents>(details).ptr(); | 300 content::Details<BackgroundContents>(details).ptr(); |
| 297 std::string extension_id = UTF16ToASCII( | 301 std::string extension_id = UTF16ToASCII( |
| 298 BackgroundContentsServiceFactory::GetForProfile(profile)-> | 302 BackgroundContentsServiceFactory::GetForProfile(profile)-> |
| 299 GetParentApplicationId(bg)); | 303 GetParentApplicationId(bg)); |
| 300 extension = | 304 extension = |
| 301 profile->GetExtensionService()->GetExtensionById(extension_id, false); | 305 extensions::ExtensionSystem::Get(profile)->extension_service()-> |
| 306 GetExtensionById(extension_id, false); |
| 302 } else { | 307 } else { |
| 303 extensions::ExtensionHost* extension_host = | 308 extensions::ExtensionHost* extension_host = |
| 304 content::Details<extensions::ExtensionHost>(details).ptr(); | 309 content::Details<extensions::ExtensionHost>(details).ptr(); |
| 305 extension = extension_host->extension(); | 310 extension = extension_host->extension(); |
| 306 } | 311 } |
| 307 if (!extension) | 312 if (!extension) |
| 308 break; | 313 break; |
| 309 | 314 |
| 310 // When an extension crashes, EXTENSION_PROCESS_TERMINATED is followed by | 315 // When an extension crashes, EXTENSION_PROCESS_TERMINATED is followed by |
| 311 // an EXTENSION_UNLOADED notification. This UNLOADED signal causes all the | 316 // an EXTENSION_UNLOADED notification. This UNLOADED signal causes all the |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 | 368 |
| 364 // Loads all background contents whose urls have been stored in prefs. | 369 // Loads all background contents whose urls have been stored in prefs. |
| 365 void BackgroundContentsService::LoadBackgroundContentsFromPrefs( | 370 void BackgroundContentsService::LoadBackgroundContentsFromPrefs( |
| 366 Profile* profile) { | 371 Profile* profile) { |
| 367 if (!prefs_) | 372 if (!prefs_) |
| 368 return; | 373 return; |
| 369 const DictionaryValue* contents = | 374 const DictionaryValue* contents = |
| 370 prefs_->GetDictionary(prefs::kRegisteredBackgroundContents); | 375 prefs_->GetDictionary(prefs::kRegisteredBackgroundContents); |
| 371 if (!contents) | 376 if (!contents) |
| 372 return; | 377 return; |
| 373 ExtensionService* extensions_service = profile->GetExtensionService(); | 378 ExtensionService* extensions_service = |
| 379 extensions::ExtensionSystem::Get(profile)->extension_service(); |
| 374 DCHECK(extensions_service); | 380 DCHECK(extensions_service); |
| 375 for (DictionaryValue::key_iterator it = contents->begin_keys(); | 381 for (DictionaryValue::key_iterator it = contents->begin_keys(); |
| 376 it != contents->end_keys(); ++it) { | 382 it != contents->end_keys(); ++it) { |
| 377 // Check to make sure that the parent extension is still enabled. | 383 // Check to make sure that the parent extension is still enabled. |
| 378 const Extension* extension = extensions_service-> | 384 const Extension* extension = extensions_service-> |
| 379 GetExtensionById(*it, false); | 385 GetExtensionById(*it, false); |
| 380 if (!extension) { | 386 if (!extension) { |
| 381 // We should never reach here - it should not be possible for an app | 387 // We should never reach here - it should not be possible for an app |
| 382 // to become uninstalled without the associated BackgroundContents being | 388 // to become uninstalled without the associated BackgroundContents being |
| 383 // unregistered via the EXTENSIONS_UNLOADED notification, unless there's a | 389 // unregistered via the EXTENSIONS_UNLOADED notification, unless there's a |
| (...skipping 14 matching lines...) Expand all Loading... |
| 398 chrome::NOTIFICATION_BACKGROUND_CONTENTS_SERVICE_CHANGED, | 404 chrome::NOTIFICATION_BACKGROUND_CONTENTS_SERVICE_CHANGED, |
| 399 content::Source<Profile>(profile), | 405 content::Source<Profile>(profile), |
| 400 content::Details<BackgroundContentsService>(this)); | 406 content::Details<BackgroundContentsService>(this)); |
| 401 } | 407 } |
| 402 | 408 |
| 403 void BackgroundContentsService::LoadBackgroundContentsForExtension( | 409 void BackgroundContentsService::LoadBackgroundContentsForExtension( |
| 404 Profile* profile, | 410 Profile* profile, |
| 405 const std::string& extension_id) { | 411 const std::string& extension_id) { |
| 406 // First look if the manifest specifies a background page. | 412 // First look if the manifest specifies a background page. |
| 407 const Extension* extension = | 413 const Extension* extension = |
| 408 profile->GetExtensionService()->GetExtensionById(extension_id, false); | 414 extensions::ExtensionSystem::Get(profile)->extension_service()-> |
| 415 GetExtensionById(extension_id, false); |
| 409 DCHECK(!extension || extension->is_hosted_app()); | 416 DCHECK(!extension || extension->is_hosted_app()); |
| 410 if (extension && extension->has_background_page()) { | 417 if (extension && extension->has_background_page()) { |
| 411 LoadBackgroundContents(profile, | 418 LoadBackgroundContents(profile, |
| 412 extension->GetBackgroundURL(), | 419 extension->GetBackgroundURL(), |
| 413 ASCIIToUTF16("background"), | 420 ASCIIToUTF16("background"), |
| 414 UTF8ToUTF16(extension->id())); | 421 UTF8ToUTF16(extension->id())); |
| 415 return; | 422 return; |
| 416 } | 423 } |
| 417 | 424 |
| 418 // Now look in the prefs. | 425 // Now look in the prefs. |
| 419 if (!prefs_) | 426 if (!prefs_) |
| 420 return; | 427 return; |
| 421 const DictionaryValue* contents = | 428 const DictionaryValue* contents = |
| 422 prefs_->GetDictionary(prefs::kRegisteredBackgroundContents); | 429 prefs_->GetDictionary(prefs::kRegisteredBackgroundContents); |
| 423 if (!contents) | 430 if (!contents) |
| 424 return; | 431 return; |
| 425 LoadBackgroundContentsFromDictionary(profile, extension_id, contents); | 432 LoadBackgroundContentsFromDictionary(profile, extension_id, contents); |
| 426 } | 433 } |
| 427 | 434 |
| 428 void BackgroundContentsService::LoadBackgroundContentsFromDictionary( | 435 void BackgroundContentsService::LoadBackgroundContentsFromDictionary( |
| 429 Profile* profile, | 436 Profile* profile, |
| 430 const std::string& extension_id, | 437 const std::string& extension_id, |
| 431 const DictionaryValue* contents) { | 438 const DictionaryValue* contents) { |
| 432 ExtensionService* extensions_service = profile->GetExtensionService(); | 439 ExtensionService* extensions_service = |
| 440 extensions::ExtensionSystem::Get(profile)->extension_service(); |
| 433 DCHECK(extensions_service); | 441 DCHECK(extensions_service); |
| 434 | 442 |
| 435 const DictionaryValue* dict; | 443 const DictionaryValue* dict; |
| 436 if (!contents->GetDictionaryWithoutPathExpansion(extension_id, &dict) || | 444 if (!contents->GetDictionaryWithoutPathExpansion(extension_id, &dict) || |
| 437 dict == NULL) | 445 dict == NULL) |
| 438 return; | 446 return; |
| 439 | 447 |
| 440 string16 frame_name; | 448 string16 frame_name; |
| 441 std::string url; | 449 std::string url; |
| 442 dict->GetString(kUrlKey, &url); | 450 dict->GetString(kUrlKey, &url); |
| 443 dict->GetString(kFrameNameKey, &frame_name); | 451 dict->GetString(kFrameNameKey, &frame_name); |
| 444 LoadBackgroundContents(profile, | 452 LoadBackgroundContents(profile, |
| 445 GURL(url), | 453 GURL(url), |
| 446 frame_name, | 454 frame_name, |
| 447 UTF8ToUTF16(extension_id)); | 455 UTF8ToUTF16(extension_id)); |
| 448 } | 456 } |
| 449 | 457 |
| 450 void BackgroundContentsService::LoadBackgroundContentsFromManifests( | 458 void BackgroundContentsService::LoadBackgroundContentsFromManifests( |
| 451 Profile* profile) { | 459 Profile* profile) { |
| 452 const ExtensionSet* extensions = | 460 const ExtensionSet* extensions = extensions::ExtensionSystem::Get(profile)-> |
| 453 profile->GetExtensionService()->extensions(); | 461 extension_service()->extensions(); |
| 454 ExtensionSet::const_iterator iter = extensions->begin(); | 462 ExtensionSet::const_iterator iter = extensions->begin(); |
| 455 for (; iter != extensions->end(); ++iter) { | 463 for (; iter != extensions->end(); ++iter) { |
| 456 const Extension* extension = *iter; | 464 const Extension* extension = *iter; |
| 457 if (extension->is_hosted_app() && extension->has_background_page()) { | 465 if (extension->is_hosted_app() && extension->has_background_page()) { |
| 458 LoadBackgroundContents(profile, | 466 LoadBackgroundContents(profile, |
| 459 extension->GetBackgroundURL(), | 467 extension->GetBackgroundURL(), |
| 460 ASCIIToUTF16("background"), | 468 ASCIIToUTF16("background"), |
| 461 UTF8ToUTF16(extension->id())); | 469 UTF8ToUTF16(extension->id())); |
| 462 } | 470 } |
| 463 } | 471 } |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 616 bool user_gesture, | 624 bool user_gesture, |
| 617 bool* was_blocked) { | 625 bool* was_blocked) { |
| 618 Browser* browser = chrome::FindLastActiveWithProfile( | 626 Browser* browser = chrome::FindLastActiveWithProfile( |
| 619 Profile::FromBrowserContext(new_contents->GetBrowserContext()), | 627 Profile::FromBrowserContext(new_contents->GetBrowserContext()), |
| 620 chrome::GetActiveDesktop()); | 628 chrome::GetActiveDesktop()); |
| 621 if (browser) { | 629 if (browser) { |
| 622 chrome::AddWebContents(browser, NULL, new_contents, disposition, | 630 chrome::AddWebContents(browser, NULL, new_contents, disposition, |
| 623 initial_pos, user_gesture, was_blocked); | 631 initial_pos, user_gesture, was_blocked); |
| 624 } | 632 } |
| 625 } | 633 } |
| OLD | NEW |