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