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

Side by Side Diff: chrome/browser/extensions/lazy_background_task_queue.cc

Issue 10082019: Have LazyBackgroundTaskQueue notify consumers when the transient page fails to (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: yoyo Created 8 years, 8 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/extensions/lazy_background_task_queue.h" 5 #include "chrome/browser/extensions/lazy_background_task_queue.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "chrome/browser/extensions/extension_host.h" 8 #include "chrome/browser/extensions/extension_host.h"
9 #include "chrome/browser/extensions/extension_process_manager.h" 9 #include "chrome/browser/extensions/extension_process_manager.h"
10 #include "chrome/browser/extensions/extension_service.h" 10 #include "chrome/browser/extensions/extension_service.h"
11 #include "chrome/browser/extensions/extension_system.h"
11 #include "chrome/browser/extensions/extension_tab_util.h" 12 #include "chrome/browser/extensions/extension_tab_util.h"
12 #include "chrome/browser/extensions/process_map.h" 13 #include "chrome/browser/extensions/process_map.h"
13 #include "chrome/browser/profiles/profile.h" 14 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/tab_contents/tab_util.h" 15 #include "chrome/browser/tab_contents/tab_util.h"
15 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 16 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
16 #include "chrome/common/chrome_notification_types.h" 17 #include "chrome/common/chrome_notification_types.h"
17 #include "chrome/common/chrome_view_type.h" 18 #include "chrome/common/chrome_view_type.h"
18 #include "chrome/common/extensions/extension.h" 19 #include "chrome/common/extensions/extension.h"
19 #include "chrome/common/extensions/extension_messages.h" 20 #include "chrome/common/extensions/extension_messages.h"
20 #include "content/public/browser/notification_service.h" 21 #include "content/public/browser/notification_service.h"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 const PendingTask& task) { 59 const PendingTask& task) {
59 PendingTasksList* tasks_list = NULL; 60 PendingTasksList* tasks_list = NULL;
60 PendingTasksKey key(profile, extension_id); 61 PendingTasksKey key(profile, extension_id);
61 PendingTasksMap::iterator it = pending_tasks_.find(key); 62 PendingTasksMap::iterator it = pending_tasks_.find(key);
62 if (it == pending_tasks_.end()) { 63 if (it == pending_tasks_.end()) {
63 tasks_list = new PendingTasksList(); 64 tasks_list = new PendingTasksList();
64 pending_tasks_[key] = linked_ptr<PendingTasksList>(tasks_list); 65 pending_tasks_[key] = linked_ptr<PendingTasksList>(tasks_list);
65 66
66 // If this is the first enqueued task, ensure the background page 67 // If this is the first enqueued task, ensure the background page
67 // is loaded. 68 // is loaded.
68 const Extension* extension = profile->GetExtensionService()-> 69 const Extension* extension =
69 extensions()->GetByID(extension_id); 70 ExtensionSystem::Get(profile)->extension_service()->
71 extensions()->GetByID(extension_id);
70 DCHECK(extension->has_lazy_background_page()); 72 DCHECK(extension->has_lazy_background_page());
71 ExtensionProcessManager* pm = profile->GetExtensionProcessManager(); 73 ExtensionProcessManager* pm =
74 ExtensionSystem::Get(profile)->process_manager();
72 pm->IncrementLazyKeepaliveCount(extension); 75 pm->IncrementLazyKeepaliveCount(extension);
73 pm->CreateBackgroundHost(extension, extension->GetBackgroundURL()); 76 pm->CreateBackgroundHost(extension, extension->GetBackgroundURL());
74 } else { 77 } else {
75 tasks_list = it->second.get(); 78 tasks_list = it->second.get();
76 } 79 }
77 80
78 tasks_list->push_back(task); 81 tasks_list->push_back(task);
79 } 82 }
80 83
81 void LazyBackgroundTaskQueue::ProcessPendingTasks(ExtensionHost* host) { 84 void LazyBackgroundTaskQueue::ProcessPendingTasks(
82 PendingTasksKey key(host->profile(), host->extension()->id()); 85 ExtensionHost* host,
86 Profile* profile,
87 const Extension* extension) {
88 if (!profile->IsSameProfile(profile_) ||
89 !extension->has_lazy_background_page())
90 return;
91
92 PendingTasksKey key(profile, extension->id());
83 PendingTasksMap::iterator map_it = pending_tasks_.find(key); 93 PendingTasksMap::iterator map_it = pending_tasks_.find(key);
84 if (map_it == pending_tasks_.end()) { 94 if (map_it == pending_tasks_.end()) {
85 NOTREACHED(); // lazy page should not load without any pending tasks 95 CHECK(!host); // lazy page should not load without any pending tasks
86 return; 96 return;
87 } 97 }
88 98
89 PendingTasksList* tasks = map_it->second.get(); 99 PendingTasksList* tasks = map_it->second.get();
90 for (PendingTasksList::const_iterator it = tasks->begin(); 100 for (PendingTasksList::const_iterator it = tasks->begin();
91 it != tasks->end(); ++it) { 101 it != tasks->end(); ++it) {
92 it->Run(host); 102 it->Run(host);
93 } 103 }
94 104
95 tasks->clear(); 105 tasks->clear();
96 pending_tasks_.erase(map_it); 106 pending_tasks_.erase(map_it);
97 107
98 // Balance the keepalive in AddPendingTask. 108 // Balance the keepalive in AddPendingTask. Note we don't do this on a
99 host->profile()->GetExtensionProcessManager()-> 109 // failure to load, because the keepalive count is reset in that case.
100 DecrementLazyKeepaliveCount(host->extension()); 110 if (host) {
111 ExtensionSystem::Get(profile)->process_manager()->
112 DecrementLazyKeepaliveCount(extension);
113 }
101 } 114 }
102 115
103 void LazyBackgroundTaskQueue::Observe( 116 void LazyBackgroundTaskQueue::Observe(
104 int type, 117 int type,
105 const content::NotificationSource& source, 118 const content::NotificationSource& source,
106 const content::NotificationDetails& details) { 119 const content::NotificationDetails& details) {
107 switch (type) { 120 switch (type) {
108 case chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING: { 121 case chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING: {
109 // If an on-demand background page finished loading, dispatch queued up 122 // If an on-demand background page finished loading, dispatch queued up
110 // events for it. 123 // events for it.
111 ExtensionHost* host = content::Details<ExtensionHost>(details).ptr(); 124 ExtensionHost* host = content::Details<ExtensionHost>(details).ptr();
112 if (host->profile()->IsSameProfile(profile_) && 125 if (host->extension_host_type() ==
113 host->extension_host_type() == 126 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) {
114 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE &&
115 host->extension()->has_lazy_background_page()) {
116 CHECK(host->did_stop_loading()); 127 CHECK(host->did_stop_loading());
117 ProcessPendingTasks(host); 128 ProcessPendingTasks(host, host->profile(), host->extension());
118 } 129 }
119 break; 130 break;
120 } 131 }
121 case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: { 132 case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: {
122 // Clear pending tasks when the background host dies. This can happen 133 // Notify consumers about the load failure when the background host dies.
123 // if the extension crashes. This is not strictly necessary, since we 134 // This can happen if the extension crashes. This is not strictly
124 // also unload the extension in that case (which clears the tasks below), 135 // necessary, since we also unload the extension in that case (which
125 // but is a good extra precaution. 136 // dispatches the tasks below), but is a good extra precaution.
126 Profile* profile = content::Source<Profile>(source).ptr(); 137 Profile* profile = content::Source<Profile>(source).ptr();
127 ExtensionHost* host = content::Details<ExtensionHost>(details).ptr(); 138 ExtensionHost* host = content::Details<ExtensionHost>(details).ptr();
128 if (host->extension_host_type() == 139 if (host->extension_host_type() ==
129 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { 140 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) {
130 pending_tasks_.erase(PendingTasksKey(profile, host->extension()->id())); 141 ProcessPendingTasks(NULL, profile, host->extension());
131 } 142 }
132 break; 143 break;
133 } 144 }
134 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { 145 case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
135 // Clear pending tasks for this extension. 146 // Notify consumers that the page failed to load.
136 Profile* profile = content::Source<Profile>(source).ptr(); 147 Profile* profile = content::Source<Profile>(source).ptr();
137 UnloadedExtensionInfo* unloaded = 148 UnloadedExtensionInfo* unloaded =
138 content::Details<UnloadedExtensionInfo>(details).ptr(); 149 content::Details<UnloadedExtensionInfo>(details).ptr();
139 pending_tasks_.erase(PendingTasksKey( 150 ProcessPendingTasks(NULL, profile, unloaded->extension);
140 profile, unloaded->extension->id())); 151 if (profile->HasOffTheRecordProfile()) {
141 if (profile->HasOffTheRecordProfile()) 152 ProcessPendingTasks(NULL, profile->GetOffTheRecordProfile(),
142 pending_tasks_.erase(PendingTasksKey( 153 unloaded->extension);
143 profile->GetOffTheRecordProfile(), unloaded->extension->id())); 154 }
144 break; 155 break;
145 } 156 }
146 default: 157 default:
147 NOTREACHED(); 158 NOTREACHED();
148 break; 159 break;
149 } 160 }
150 } 161 }
151 162
152 } // namespace extensions 163 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698