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

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: Fixed tests. 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);
242 ExtensionService* extension_service = profile->GetExtensionService(); 247 ExtensionService* extension_service = profile->GetExtensionService();
243 // extension_service can be NULL when running tests. 248 // extension_service can be NULL when running tests.
244 if (extension_service) { 249 if (extension_service) {
245 const Extension* extension = 250 const Extension* extension =
246 extension_service->GetExtensionById(UTF16ToUTF8(appid), false); 251 extension_service->GetExtensionById(UTF16ToUTF8(appid), false);
247 if (extension && extension->has_background_page()) 252 if (extension && extension->has_background_page())
248 break; 253 break;
249 } 254 }
250 RegisterBackgroundContents(bgcontents); 255 RegisterBackgroundContents(bgcontents);
256 SendChangeNotification(profile);
Mihai Parparita -not on Chrome 2012/05/03 00:54:11 Why would a navigation cause the list of backgroun
Andrew T Wilson (Slow) 2012/05/03 07:42:56 It doesn't change the list of background content *
251 break; 257 break;
252 } 258 }
253 case chrome::NOTIFICATION_EXTENSION_LOADED: { 259 case chrome::NOTIFICATION_EXTENSION_LOADED: {
254 const Extension* extension = 260 const Extension* extension =
255 content::Details<const Extension>(details).ptr(); 261 content::Details<const Extension>(details).ptr();
256 Profile* profile = content::Source<Profile>(source).ptr(); 262 Profile* profile = content::Source<Profile>(source).ptr();
257 if (extension->is_hosted_app() && 263 if (extension->is_hosted_app() &&
258 extension->has_background_page()) { 264 extension->has_background_page()) {
259 // If there is a background page specified in the manifest for a hosted 265 // If there is a background page specified in the manifest for a hosted
260 // app, then blow away registered urls in the pref. 266 // app, then blow away registered urls in the pref.
261 ShutdownAssociatedBackgroundContents(ASCIIToUTF16(extension->id())); 267 ShutdownAssociatedBackgroundContents(ASCIIToUTF16(extension->id()));
262 268
263 ExtensionService* service = profile->GetExtensionService(); 269 ExtensionService* service = profile->GetExtensionService();
264 if (service && service->is_ready()) { 270 if (service && service->is_ready()) {
265 // Now load the manifest-specified background page. If service isn't 271 // Now load the manifest-specified background page. If service isn't
266 // ready, then the background page will be loaded from the 272 // ready, then the background page will be loaded from the
267 // EXTENSIONS_READY callback. 273 // EXTENSIONS_READY callback.
268 LoadBackgroundContents(profile, extension->GetBackgroundURL(), 274 LoadBackgroundContents(profile, extension->GetBackgroundURL(),
269 ASCIIToUTF16("background"), UTF8ToUTF16(extension->id())); 275 ASCIIToUTF16("background"), UTF8ToUTF16(extension->id()));
270 } 276 }
271 } 277 }
272 278
273 // Remove any "This extension has crashed" balloons. 279 // Remove any "This extension has crashed" balloons.
274 ScheduleCloseBalloon(extension->id()); 280 ScheduleCloseBalloon(extension->id());
281 SendChangeNotification(profile);
275 break; 282 break;
276 } 283 }
277 case chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED: 284 case chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED:
278 case chrome::NOTIFICATION_BACKGROUND_CONTENTS_TERMINATED: { 285 case chrome::NOTIFICATION_BACKGROUND_CONTENTS_TERMINATED: {
279 Profile* profile = content::Source<Profile>(source).ptr(); 286 Profile* profile = content::Source<Profile>(source).ptr();
280 const Extension* extension = NULL; 287 const Extension* extension = NULL;
281 if (type == chrome::NOTIFICATION_BACKGROUND_CONTENTS_TERMINATED) { 288 if (type == chrome::NOTIFICATION_BACKGROUND_CONTENTS_TERMINATED) {
282 BackgroundContents* bg = 289 BackgroundContents* bg =
283 content::Details<BackgroundContents>(details).ptr(); 290 content::Details<BackgroundContents>(details).ptr();
284 std::string extension_id = UTF16ToASCII( 291 std::string extension_id = UTF16ToASCII(
(...skipping 19 matching lines...) Expand all
304 break; 311 break;
305 } 312 }
306 case chrome::NOTIFICATION_EXTENSION_UNLOADED: 313 case chrome::NOTIFICATION_EXTENSION_UNLOADED:
307 switch (content::Details<UnloadedExtensionInfo>(details)->reason) { 314 switch (content::Details<UnloadedExtensionInfo>(details)->reason) {
308 case extension_misc::UNLOAD_REASON_DISABLE: // Fall through. 315 case extension_misc::UNLOAD_REASON_DISABLE: // Fall through.
309 case extension_misc::UNLOAD_REASON_TERMINATE: // Fall through. 316 case extension_misc::UNLOAD_REASON_TERMINATE: // Fall through.
310 case extension_misc::UNLOAD_REASON_UNINSTALL: 317 case extension_misc::UNLOAD_REASON_UNINSTALL:
311 ShutdownAssociatedBackgroundContents( 318 ShutdownAssociatedBackgroundContents(
312 ASCIIToUTF16(content::Details<UnloadedExtensionInfo>(details)-> 319 ASCIIToUTF16(content::Details<UnloadedExtensionInfo>(details)->
313 extension->id())); 320 extension->id()));
321 SendChangeNotification(content::Source<Profile>(source).ptr());
314 break; 322 break;
315 case extension_misc::UNLOAD_REASON_UPDATE: { 323 case extension_misc::UNLOAD_REASON_UPDATE: {
316 // If there is a manifest specified background page, then shut it down 324 // If there is a manifest specified background page, then shut it down
317 // here, since if the updated extension still has the background page, 325 // here, since if the updated extension still has the background page,
318 // then it will be loaded from LOADED callback. Otherwise, leave 326 // then it will be loaded from LOADED callback. Otherwise, leave
319 // BackgroundContents in place. 327 // BackgroundContents in place.
328 // We don't call SendChangeNotification here - it will be generated
329 // from the LOADED callback.
320 const Extension* extension = 330 const Extension* extension =
321 content::Details<UnloadedExtensionInfo>(details)->extension; 331 content::Details<UnloadedExtensionInfo>(details)->extension;
322 if (extension->has_background_page()) 332 if (extension->has_background_page())
323 ShutdownAssociatedBackgroundContents(ASCIIToUTF16(extension->id())); 333 ShutdownAssociatedBackgroundContents(ASCIIToUTF16(extension->id()));
324 break; 334 break;
325 } 335 }
326 default: 336 default:
327 NOTREACHED(); 337 NOTREACHED();
328 ShutdownAssociatedBackgroundContents( 338 ShutdownAssociatedBackgroundContents(
329 ASCIIToUTF16(content::Details<UnloadedExtensionInfo>(details)-> 339 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 = " 379 NOTREACHED() << "No extension found for BackgroundContents - id = "
370 << *it; 380 << *it;
371 // Don't cancel out of our loop, just ignore this BackgroundContents and 381 // Don't cancel out of our loop, just ignore this BackgroundContents and
372 // load the next one. 382 // load the next one.
373 continue; 383 continue;
374 } 384 }
375 LoadBackgroundContentsFromDictionary(profile, *it, contents); 385 LoadBackgroundContentsFromDictionary(profile, *it, contents);
376 } 386 }
377 } 387 }
378 388
389 void BackgroundContentsService::SendChangeNotification(Profile* profile) {
390 content::NotificationService::current()->Notify(
391 chrome::NOTIFICATION_BACKGROUND_CONTENTS_SERVICE_CHANGED,
392 content::Source<Profile>(profile),
393 content::Details<BackgroundContentsService>(this));
394 }
395
379 void BackgroundContentsService::LoadBackgroundContentsForExtension( 396 void BackgroundContentsService::LoadBackgroundContentsForExtension(
380 Profile* profile, 397 Profile* profile,
381 const std::string& extension_id) { 398 const std::string& extension_id) {
382 // First look if the manifest specifies a background page. 399 // First look if the manifest specifies a background page.
383 const Extension* extension = 400 const Extension* extension =
384 profile->GetExtensionService()->GetExtensionById(extension_id, false); 401 profile->GetExtensionService()->GetExtensionById(extension_id, false);
385 DCHECK(!extension || extension->is_hosted_app()); 402 DCHECK(!extension || extension->is_hosted_app());
386 if (extension && extension->has_background_page()) { 403 if (extension && extension->has_background_page()) {
387 LoadBackgroundContents(profile, 404 LoadBackgroundContents(profile,
388 extension->GetBackgroundURL(), 405 extension->GetBackgroundURL(),
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 if (pref->GetDictionaryWithoutPathExpansion(UTF16ToUTF8(appid), &current)) 520 if (pref->GetDictionaryWithoutPathExpansion(UTF16ToUTF8(appid), &current))
504 return; 521 return;
505 522
506 // No entry for this application yet, so add one. 523 // No entry for this application yet, so add one.
507 DictionaryValue* dict = new DictionaryValue(); 524 DictionaryValue* dict = new DictionaryValue();
508 dict->SetString(kUrlKey, background_contents->GetURL().spec()); 525 dict->SetString(kUrlKey, background_contents->GetURL().spec());
509 dict->SetString(kFrameNameKey, contents_map_[appid].frame_name); 526 dict->SetString(kFrameNameKey, contents_map_[appid].frame_name);
510 pref->SetWithoutPathExpansion(UTF16ToUTF8(appid), dict); 527 pref->SetWithoutPathExpansion(UTF16ToUTF8(appid), dict);
511 } 528 }
512 529
530 bool BackgroundContentsService::HasRegisteredBackgroundContents(
531 const string16& app_id) {
532 if (!prefs_)
533 return false;
534 std::string app = UTF16ToUTF8(app_id);
535 const DictionaryValue* contents =
536 prefs_->GetDictionary(prefs::kRegisteredBackgroundContents);
537 // Walk our dictionary looking for any entries with this key.
Mihai Parparita -not on Chrome 2012/05/03 00:54:11 Why not use contents->HasKey(app)?
Andrew T Wilson (Slow) 2012/05/03 07:42:56 Ah, good idea. I should've checked DictionaryValue
538 for (DictionaryValue::key_iterator it = contents->begin_keys();
539 it != contents->end_keys(); ++it) {
540 if (*it == app)
541 return true;
542 }
543 return false;
544 }
545
513 void BackgroundContentsService::UnregisterBackgroundContents( 546 void BackgroundContentsService::UnregisterBackgroundContents(
514 BackgroundContents* background_contents) { 547 BackgroundContents* background_contents) {
515 if (!prefs_) 548 if (!prefs_)
516 return; 549 return;
517 DCHECK(IsTracked(background_contents)); 550 DCHECK(IsTracked(background_contents));
518 const string16 appid = GetParentApplicationId(background_contents); 551 const string16 appid = GetParentApplicationId(background_contents);
519 DictionaryPrefUpdate update(prefs_, prefs::kRegisteredBackgroundContents); 552 DictionaryPrefUpdate update(prefs_, prefs::kRegisteredBackgroundContents);
520 update.Get()->RemoveWithoutPathExpansion(UTF16ToUTF8(appid), NULL); 553 update.Get()->RemoveWithoutPathExpansion(UTF16ToUTF8(appid), NULL);
521 } 554 }
522 555
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 WebContents* new_contents, 609 WebContents* new_contents,
577 WindowOpenDisposition disposition, 610 WindowOpenDisposition disposition,
578 const gfx::Rect& initial_pos, 611 const gfx::Rect& initial_pos,
579 bool user_gesture) { 612 bool user_gesture) {
580 Browser* browser = BrowserList::GetLastActiveWithProfile( 613 Browser* browser = BrowserList::GetLastActiveWithProfile(
581 Profile::FromBrowserContext(new_contents->GetBrowserContext())); 614 Profile::FromBrowserContext(new_contents->GetBrowserContext()));
582 if (!browser) 615 if (!browser)
583 return; 616 return;
584 browser->AddWebContents(new_contents, disposition, initial_pos, user_gesture); 617 browser->AddWebContents(new_contents, disposition, initial_pos, user_gesture);
585 } 618 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698