Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(510)

Side by Side Diff: chrome/browser/background/background_contents_service.cc

Issue 10298002: No longer start BG mode until a BackgroundContents is loaded (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Prospective fix for cros test failures. Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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"
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 // uninstalls the extension. 209 // uninstalls the extension.
210 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED, 210 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
211 content::Source<Profile>(profile)); 211 content::Source<Profile>(profile));
212 } 212 }
213 213
214 void BackgroundContentsService::Observe( 214 void BackgroundContentsService::Observe(
215 int type, 215 int type,
216 const content::NotificationSource& source, 216 const content::NotificationSource& source,
217 const content::NotificationDetails& details) { 217 const content::NotificationDetails& details) {
218 switch (type) { 218 switch (type) {
219 case chrome::NOTIFICATION_EXTENSIONS_READY: 219 case chrome::NOTIFICATION_EXTENSIONS_READY: {
220 LoadBackgroundContentsFromManifests( 220 Profile* profile = content::Source<Profile>(source).ptr();
221 content::Source<Profile>(source).ptr()); 221 LoadBackgroundContentsFromManifests(profile);
222 LoadBackgroundContentsFromPrefs(content::Source<Profile>(source).ptr()); 222 LoadBackgroundContentsFromPrefs(profile);
223 SendChangeNotification(profile);
223 break; 224 break;
225 }
224 case chrome::NOTIFICATION_BACKGROUND_CONTENTS_DELETED: 226 case chrome::NOTIFICATION_BACKGROUND_CONTENTS_DELETED:
225 BackgroundContentsShutdown( 227 BackgroundContentsShutdown(
226 content::Details<BackgroundContents>(details).ptr()); 228 content::Details<BackgroundContents>(details).ptr());
229 SendChangeNotification(content::Source<Profile>(source).ptr());
227 break; 230 break;
228 case chrome::NOTIFICATION_BACKGROUND_CONTENTS_CLOSED: 231 case chrome::NOTIFICATION_BACKGROUND_CONTENTS_CLOSED:
229 DCHECK(IsTracked(content::Details<BackgroundContents>(details).ptr())); 232 DCHECK(IsTracked(content::Details<BackgroundContents>(details).ptr()));
230 UnregisterBackgroundContents( 233 UnregisterBackgroundContents(
231 content::Details<BackgroundContents>(details).ptr()); 234 content::Details<BackgroundContents>(details).ptr());
235 // CLOSED is always followed by a DELETED notification so we'll send our
236 // change notification there.
232 break; 237 break;
233 case chrome::NOTIFICATION_BACKGROUND_CONTENTS_NAVIGATED: { 238 case chrome::NOTIFICATION_BACKGROUND_CONTENTS_NAVIGATED: {
234 DCHECK(IsTracked(content::Details<BackgroundContents>(details).ptr())); 239 DCHECK(IsTracked(content::Details<BackgroundContents>(details).ptr()));
235 240
236 // Do not register in the pref if the extension has a manifest-specified 241 // Do not register in the pref if the extension has a manifest-specified
237 // background page. 242 // background page.
238 BackgroundContents* bgcontents = 243 BackgroundContents* bgcontents =
239 content::Details<BackgroundContents>(details).ptr(); 244 content::Details<BackgroundContents>(details).ptr();
240 Profile* profile = content::Source<Profile>(source).ptr(); 245 Profile* profile = content::Source<Profile>(source).ptr();
241 const string16& appid = GetParentApplicationId(bgcontents); 246 const string16& appid = GetParentApplicationId(bgcontents);
(...skipping 23 matching lines...) Expand all
265 // Now load the manifest-specified background page. If service isn't 270 // Now load the manifest-specified background page. If service isn't
266 // ready, then the background page will be loaded from the 271 // ready, then the background page will be loaded from the
267 // EXTENSIONS_READY callback. 272 // EXTENSIONS_READY callback.
268 LoadBackgroundContents(profile, extension->GetBackgroundURL(), 273 LoadBackgroundContents(profile, extension->GetBackgroundURL(),
269 ASCIIToUTF16("background"), UTF8ToUTF16(extension->id())); 274 ASCIIToUTF16("background"), UTF8ToUTF16(extension->id()));
270 } 275 }
271 } 276 }
272 277
273 // Remove any "This extension has crashed" balloons. 278 // Remove any "This extension has crashed" balloons.
274 ScheduleCloseBalloon(extension->id()); 279 ScheduleCloseBalloon(extension->id());
280 SendChangeNotification(profile);
275 break; 281 break;
276 } 282 }
277 case chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED: 283 case chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED:
278 case chrome::NOTIFICATION_BACKGROUND_CONTENTS_TERMINATED: { 284 case chrome::NOTIFICATION_BACKGROUND_CONTENTS_TERMINATED: {
279 Profile* profile = content::Source<Profile>(source).ptr(); 285 Profile* profile = content::Source<Profile>(source).ptr();
280 const Extension* extension = NULL; 286 const Extension* extension = NULL;
281 if (type == chrome::NOTIFICATION_BACKGROUND_CONTENTS_TERMINATED) { 287 if (type == chrome::NOTIFICATION_BACKGROUND_CONTENTS_TERMINATED) {
282 BackgroundContents* bg = 288 BackgroundContents* bg =
283 content::Details<BackgroundContents>(details).ptr(); 289 content::Details<BackgroundContents>(details).ptr();
284 std::string extension_id = UTF16ToASCII( 290 std::string extension_id = UTF16ToASCII(
(...skipping 19 matching lines...) Expand all
304 break; 310 break;
305 } 311 }
306 case chrome::NOTIFICATION_EXTENSION_UNLOADED: 312 case chrome::NOTIFICATION_EXTENSION_UNLOADED:
307 switch (content::Details<UnloadedExtensionInfo>(details)->reason) { 313 switch (content::Details<UnloadedExtensionInfo>(details)->reason) {
308 case extension_misc::UNLOAD_REASON_DISABLE: // Fall through. 314 case extension_misc::UNLOAD_REASON_DISABLE: // Fall through.
309 case extension_misc::UNLOAD_REASON_TERMINATE: // Fall through. 315 case extension_misc::UNLOAD_REASON_TERMINATE: // Fall through.
310 case extension_misc::UNLOAD_REASON_UNINSTALL: 316 case extension_misc::UNLOAD_REASON_UNINSTALL:
311 ShutdownAssociatedBackgroundContents( 317 ShutdownAssociatedBackgroundContents(
312 ASCIIToUTF16(content::Details<UnloadedExtensionInfo>(details)-> 318 ASCIIToUTF16(content::Details<UnloadedExtensionInfo>(details)->
313 extension->id())); 319 extension->id()));
320 SendChangeNotification(content::Source<Profile>(source).ptr());
314 break; 321 break;
315 case extension_misc::UNLOAD_REASON_UPDATE: { 322 case extension_misc::UNLOAD_REASON_UPDATE: {
316 // If there is a manifest specified background page, then shut it down 323 // If there is a manifest specified background page, then shut it down
317 // here, since if the updated extension still has the background page, 324 // here, since if the updated extension still has the background page,
318 // then it will be loaded from LOADED callback. Otherwise, leave 325 // then it will be loaded from LOADED callback. Otherwise, leave
319 // BackgroundContents in place. 326 // BackgroundContents in place.
327 // We don't call SendChangeNotification here - it will be generated
328 // from the LOADED callback.
320 const Extension* extension = 329 const Extension* extension =
321 content::Details<UnloadedExtensionInfo>(details)->extension; 330 content::Details<UnloadedExtensionInfo>(details)->extension;
322 if (extension->has_background_page()) 331 if (extension->has_background_page())
323 ShutdownAssociatedBackgroundContents(ASCIIToUTF16(extension->id())); 332 ShutdownAssociatedBackgroundContents(ASCIIToUTF16(extension->id()));
324 break; 333 break;
325 } 334 }
326 default: 335 default:
327 NOTREACHED(); 336 NOTREACHED();
328 ShutdownAssociatedBackgroundContents( 337 ShutdownAssociatedBackgroundContents(
329 ASCIIToUTF16(content::Details<UnloadedExtensionInfo>(details)-> 338 ASCIIToUTF16(content::Details<UnloadedExtensionInfo>(details)->
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 NOTREACHED() << "No extension found for BackgroundContents - id = " 378 NOTREACHED() << "No extension found for BackgroundContents - id = "
370 << *it; 379 << *it;
371 // Don't cancel out of our loop, just ignore this BackgroundContents and 380 // Don't cancel out of our loop, just ignore this BackgroundContents and
372 // load the next one. 381 // load the next one.
373 continue; 382 continue;
374 } 383 }
375 LoadBackgroundContentsFromDictionary(profile, *it, contents); 384 LoadBackgroundContentsFromDictionary(profile, *it, contents);
376 } 385 }
377 } 386 }
378 387
388 void BackgroundContentsService::SendChangeNotification(Profile* profile) {
389 content::NotificationService::current()->Notify(
390 chrome::NOTIFICATION_BACKGROUND_CONTENTS_SERVICE_CHANGED,
391 content::Source<Profile>(profile),
392 content::Details<BackgroundContentsService>(this));
393 }
394
379 void BackgroundContentsService::LoadBackgroundContentsForExtension( 395 void BackgroundContentsService::LoadBackgroundContentsForExtension(
380 Profile* profile, 396 Profile* profile,
381 const std::string& extension_id) { 397 const std::string& extension_id) {
382 // First look if the manifest specifies a background page. 398 // First look if the manifest specifies a background page.
383 const Extension* extension = 399 const Extension* extension =
384 profile->GetExtensionService()->GetExtensionById(extension_id, false); 400 profile->GetExtensionService()->GetExtensionById(extension_id, false);
385 DCHECK(!extension || extension->is_hosted_app()); 401 DCHECK(!extension || extension->is_hosted_app());
386 if (extension && extension->has_background_page()) { 402 if (extension && extension->has_background_page()) {
387 LoadBackgroundContents(profile, 403 LoadBackgroundContents(profile,
388 extension->GetBackgroundURL(), 404 extension->GetBackgroundURL(),
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 // Register the BackgroundContents internally, then send out a notification 492 // Register the BackgroundContents internally, then send out a notification
477 // to external listeners. 493 // to external listeners.
478 BackgroundContentsOpenedDetails details = {contents, 494 BackgroundContentsOpenedDetails details = {contents,
479 frame_name, 495 frame_name,
480 application_id}; 496 application_id};
481 BackgroundContentsOpened(&details); 497 BackgroundContentsOpened(&details);
482 content::NotificationService::current()->Notify( 498 content::NotificationService::current()->Notify(
483 chrome::NOTIFICATION_BACKGROUND_CONTENTS_OPENED, 499 chrome::NOTIFICATION_BACKGROUND_CONTENTS_OPENED,
484 content::Source<Profile>(profile), 500 content::Source<Profile>(profile),
485 content::Details<BackgroundContentsOpenedDetails>(&details)); 501 content::Details<BackgroundContentsOpenedDetails>(&details));
502
503 // A new background contents has been created - notify our listeners.
504 SendChangeNotification(profile);
486 return contents; 505 return contents;
487 } 506 }
488 507
489 void BackgroundContentsService::RegisterBackgroundContents( 508 void BackgroundContentsService::RegisterBackgroundContents(
490 BackgroundContents* background_contents) { 509 BackgroundContents* background_contents) {
491 DCHECK(IsTracked(background_contents)); 510 DCHECK(IsTracked(background_contents));
492 if (!prefs_) 511 if (!prefs_)
493 return; 512 return;
494 513
495 // We store the first URL we receive for a given application. If there's 514 // We store the first URL we receive for a given application. If there's
496 // already an entry for this application, no need to do anything. 515 // already an entry for this application, no need to do anything.
497 // TODO(atwilson): Verify that this is the desired behavior based on developer 516 // TODO(atwilson): Verify that this is the desired behavior based on developer
498 // feedback (http://crbug.com/47118). 517 // feedback (http://crbug.com/47118).
499 DictionaryPrefUpdate update(prefs_, prefs::kRegisteredBackgroundContents); 518 DictionaryPrefUpdate update(prefs_, prefs::kRegisteredBackgroundContents);
500 DictionaryValue* pref = update.Get(); 519 DictionaryValue* pref = update.Get();
501 const string16& appid = GetParentApplicationId(background_contents); 520 const string16& appid = GetParentApplicationId(background_contents);
502 DictionaryValue* current; 521 DictionaryValue* current;
503 if (pref->GetDictionaryWithoutPathExpansion(UTF16ToUTF8(appid), &current)) 522 if (pref->GetDictionaryWithoutPathExpansion(UTF16ToUTF8(appid), &current))
504 return; 523 return;
505 524
506 // No entry for this application yet, so add one. 525 // No entry for this application yet, so add one.
507 DictionaryValue* dict = new DictionaryValue(); 526 DictionaryValue* dict = new DictionaryValue();
508 dict->SetString(kUrlKey, background_contents->GetURL().spec()); 527 dict->SetString(kUrlKey, background_contents->GetURL().spec());
509 dict->SetString(kFrameNameKey, contents_map_[appid].frame_name); 528 dict->SetString(kFrameNameKey, contents_map_[appid].frame_name);
510 pref->SetWithoutPathExpansion(UTF16ToUTF8(appid), dict); 529 pref->SetWithoutPathExpansion(UTF16ToUTF8(appid), dict);
511 } 530 }
512 531
532 bool BackgroundContentsService::HasRegisteredBackgroundContents(
533 const string16& app_id) {
534 if (!prefs_)
535 return false;
536 std::string app = UTF16ToUTF8(app_id);
537 const DictionaryValue* contents =
538 prefs_->GetDictionary(prefs::kRegisteredBackgroundContents);
539 return contents->HasKey(app);
540 }
541
513 void BackgroundContentsService::UnregisterBackgroundContents( 542 void BackgroundContentsService::UnregisterBackgroundContents(
514 BackgroundContents* background_contents) { 543 BackgroundContents* background_contents) {
515 if (!prefs_) 544 if (!prefs_)
516 return; 545 return;
517 DCHECK(IsTracked(background_contents)); 546 DCHECK(IsTracked(background_contents));
518 const string16 appid = GetParentApplicationId(background_contents); 547 const string16 appid = GetParentApplicationId(background_contents);
519 DictionaryPrefUpdate update(prefs_, prefs::kRegisteredBackgroundContents); 548 DictionaryPrefUpdate update(prefs_, prefs::kRegisteredBackgroundContents);
520 update.Get()->RemoveWithoutPathExpansion(UTF16ToUTF8(appid), NULL); 549 update.Get()->RemoveWithoutPathExpansion(UTF16ToUTF8(appid), NULL);
521 } 550 }
522 551
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 WebContents* new_contents, 605 WebContents* new_contents,
577 WindowOpenDisposition disposition, 606 WindowOpenDisposition disposition,
578 const gfx::Rect& initial_pos, 607 const gfx::Rect& initial_pos,
579 bool user_gesture) { 608 bool user_gesture) {
580 Browser* browser = BrowserList::GetLastActiveWithProfile( 609 Browser* browser = BrowserList::GetLastActiveWithProfile(
581 Profile::FromBrowserContext(new_contents->GetBrowserContext())); 610 Profile::FromBrowserContext(new_contents->GetBrowserContext()));
582 if (!browser) 611 if (!browser)
583 return; 612 return;
584 browser->AddWebContents(new_contents, disposition, initial_pos, user_gesture); 613 browser->AddWebContents(new_contents, disposition, initial_pos, user_gesture);
585 } 614 }
OLDNEW
« no previous file with comments | « chrome/browser/background/background_contents_service.h ('k') | chrome/browser/background/background_mode_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698