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

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

Issue 10828218: Add chrome.runtime.onStartup, which is fired on browser start. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix unnecessary start Created 8 years, 4 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"
(...skipping 24 matching lines...) Expand all
35 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, 35 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
36 content::Source<Profile>(profile)); 36 content::Source<Profile>(profile));
37 } 37 }
38 38
39 LazyBackgroundTaskQueue::~LazyBackgroundTaskQueue() { 39 LazyBackgroundTaskQueue::~LazyBackgroundTaskQueue() {
40 } 40 }
41 41
42 bool LazyBackgroundTaskQueue::ShouldEnqueueTask( 42 bool LazyBackgroundTaskQueue::ShouldEnqueueTask(
43 Profile* profile, const Extension* extension) { 43 Profile* profile, const Extension* extension) {
44 DCHECK(extension); 44 DCHECK(extension);
45 if (extension->has_lazy_background_page()) { 45 if (extension->has_background_page()) {
46 ExtensionProcessManager* pm = profile->GetExtensionProcessManager(); 46 ExtensionProcessManager* pm = profile->GetExtensionProcessManager();
47 ExtensionHost* background_host = 47 ExtensionHost* background_host =
48 pm->GetBackgroundHostForExtension(extension->id()); 48 pm->GetBackgroundHostForExtension(extension->id());
49 if (!background_host || !background_host->did_stop_loading()) 49 if (!background_host || !background_host->did_stop_loading())
50 return true; 50 return true;
51 if (pm->IsBackgroundHostClosing(extension->id())) 51 if (pm->IsBackgroundHostClosing(extension->id()))
52 pm->CancelSuspend(extension); 52 pm->CancelSuspend(extension);
53 } 53 }
54 54
55 return false; 55 return false;
56 } 56 }
57 57
58 void LazyBackgroundTaskQueue::AddPendingTask( 58 void LazyBackgroundTaskQueue::AddPendingTask(
59 Profile* profile, 59 Profile* profile,
60 const std::string& extension_id, 60 const std::string& extension_id,
61 const PendingTask& task) { 61 const PendingTask& task) {
62 LOG(ERROR) << "AddPendingTask: " << extension_id;
62 PendingTasksList* tasks_list = NULL; 63 PendingTasksList* tasks_list = NULL;
63 PendingTasksKey key(profile, extension_id); 64 PendingTasksKey key(profile, extension_id);
64 PendingTasksMap::iterator it = pending_tasks_.find(key); 65 PendingTasksMap::iterator it = pending_tasks_.find(key);
65 if (it == pending_tasks_.end()) { 66 if (it == pending_tasks_.end()) {
66 tasks_list = new PendingTasksList(); 67 tasks_list = new PendingTasksList();
67 pending_tasks_[key] = linked_ptr<PendingTasksList>(tasks_list); 68 pending_tasks_[key] = linked_ptr<PendingTasksList>(tasks_list);
68 69
69 // If this is the first enqueued task, ensure the background page
70 // is loaded.
71 const Extension* extension = 70 const Extension* extension =
72 ExtensionSystem::Get(profile)->extension_service()-> 71 ExtensionSystem::Get(profile)->extension_service()->
73 extensions()->GetByID(extension_id); 72 extensions()->GetByID(extension_id);
74 DCHECK(extension->has_lazy_background_page()); 73 if (extension && extension->has_lazy_background_page()) {
75 ExtensionProcessManager* pm = 74 // If this is the first enqueued task, and we're not waiting for the
76 ExtensionSystem::Get(profile)->process_manager(); 75 // background page to unload, ensure the background page is loaded.
77 pm->IncrementLazyKeepaliveCount(extension); 76 LOG(ERROR) << "AddPendingTask NEWHOST: " << extension_id;
78 pm->CreateBackgroundHost(extension, extension->GetBackgroundURL()); 77 ExtensionProcessManager* pm =
78 ExtensionSystem::Get(profile)->process_manager();
79 pm->IncrementLazyKeepaliveCount(extension);
80 pm->CreateBackgroundHost(extension, extension->GetBackgroundURL());
81 }
79 } else { 82 } else {
80 tasks_list = it->second.get(); 83 tasks_list = it->second.get();
81 } 84 }
82 85
83 tasks_list->push_back(task); 86 tasks_list->push_back(task);
84 } 87 }
85 88
86 void LazyBackgroundTaskQueue::ProcessPendingTasks( 89 void LazyBackgroundTaskQueue::ProcessPendingTasks(
87 ExtensionHost* host, 90 ExtensionHost* host,
88 Profile* profile, 91 Profile* profile,
89 const Extension* extension) { 92 const Extension* extension) {
90 if (!profile->IsSameProfile(profile_) || 93 if (!profile->IsSameProfile(profile_))
91 !extension->has_lazy_background_page())
92 return; 94 return;
93 95
94 PendingTasksKey key(profile, extension->id()); 96 PendingTasksKey key(profile, extension->id());
95 PendingTasksMap::iterator map_it = pending_tasks_.find(key); 97 PendingTasksMap::iterator map_it = pending_tasks_.find(key);
96 if (map_it == pending_tasks_.end()) { 98 if (map_it == pending_tasks_.end()) {
97 CHECK(!host); // lazy page should not load without any pending tasks 99 if (extension->has_lazy_background_page())
100 CHECK(!host); // lazy page should not load without any pending tasks
98 return; 101 return;
99 } 102 }
100 103
104 LOG(ERROR) << "ProcessPendingTasks: " << extension->id() << " " << host;
101 // Swap the pending tasks to a temporary, to avoid problems if the task 105 // Swap the pending tasks to a temporary, to avoid problems if the task
102 // list is modified during processing. 106 // list is modified during processing.
103 PendingTasksList tasks; 107 PendingTasksList tasks;
104 tasks.swap(*map_it->second); 108 tasks.swap(*map_it->second);
105 for (PendingTasksList::const_iterator it = tasks.begin(); 109 for (PendingTasksList::const_iterator it = tasks.begin();
106 it != tasks.end(); ++it) { 110 it != tasks.end(); ++it) {
107 it->Run(host); 111 it->Run(host);
108 } 112 }
109 113
110 pending_tasks_.erase(key); 114 pending_tasks_.erase(key);
111 115
112 // Balance the keepalive in AddPendingTask. Note we don't do this on a 116 // Balance the keepalive in AddPendingTask. Note we don't do this on a
113 // failure to load, because the keepalive count is reset in that case. 117 // failure to load, because the keepalive count is reset in that case.
114 if (host) { 118 if (host && extension->has_lazy_background_page()) {
115 ExtensionSystem::Get(profile)->process_manager()-> 119 ExtensionSystem::Get(profile)->process_manager()->
116 DecrementLazyKeepaliveCount(extension); 120 DecrementLazyKeepaliveCount(extension);
117 } 121 }
118 } 122 }
119 123
120 void LazyBackgroundTaskQueue::Observe( 124 void LazyBackgroundTaskQueue::Observe(
121 int type, 125 int type,
122 const content::NotificationSource& source, 126 const content::NotificationSource& source,
123 const content::NotificationDetails& details) { 127 const content::NotificationDetails& details) {
124 switch (type) { 128 switch (type) {
125 case chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING: { 129 case chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING: {
126 // If an on-demand background page finished loading, dispatch queued up 130 // If an on-demand background page finished loading, dispatch queued up
127 // events for it. 131 // events for it.
128 ExtensionHost* host = 132 ExtensionHost* host =
129 content::Details<ExtensionHost>(details).ptr(); 133 content::Details<ExtensionHost>(details).ptr();
134 LOG(ERROR) << "Host done loading: " << host->extension()->id();
130 if (host->extension_host_type() == 135 if (host->extension_host_type() ==
131 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { 136 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) {
132 CHECK(host->did_stop_loading()); 137 CHECK(host->did_stop_loading());
133 ProcessPendingTasks(host, host->profile(), host->extension()); 138 ProcessPendingTasks(host, host->profile(), host->extension());
134 } 139 }
135 break; 140 break;
136 } 141 }
137 case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: { 142 case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: {
138 // Notify consumers about the load failure when the background host dies. 143 // Notify consumers about the load failure when the background host dies.
139 // This can happen if the extension crashes. This is not strictly 144 // This can happen if the extension crashes. This is not strictly
140 // necessary, since we also unload the extension in that case (which 145 // necessary, since we also unload the extension in that case (which
141 // dispatches the tasks below), but is a good extra precaution. 146 // dispatches the tasks below), but is a good extra precaution.
142 Profile* profile = content::Source<Profile>(source).ptr(); 147 Profile* profile = content::Source<Profile>(source).ptr();
143 ExtensionHost* host = 148 ExtensionHost* host =
144 content::Details<ExtensionHost>(details).ptr(); 149 content::Details<ExtensionHost>(details).ptr();
150 LOG(ERROR) << "Host destroyed: " << host->extension()->id();
145 if (host->extension_host_type() == 151 if (host->extension_host_type() ==
146 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { 152 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) {
147 ProcessPendingTasks(NULL, profile, host->extension()); 153 ProcessPendingTasks(NULL, profile, host->extension());
148 } 154 }
149 break; 155 break;
150 } 156 }
151 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { 157 case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
152 // Notify consumers that the page failed to load. 158 // Notify consumers that the page failed to load.
153 Profile* profile = content::Source<Profile>(source).ptr(); 159 Profile* profile = content::Source<Profile>(source).ptr();
154 UnloadedExtensionInfo* unloaded = 160 UnloadedExtensionInfo* unloaded =
155 content::Details<UnloadedExtensionInfo>(details).ptr(); 161 content::Details<UnloadedExtensionInfo>(details).ptr();
156 ProcessPendingTasks(NULL, profile, unloaded->extension); 162 ProcessPendingTasks(NULL, profile, unloaded->extension);
157 if (profile->HasOffTheRecordProfile()) { 163 if (profile->HasOffTheRecordProfile()) {
158 ProcessPendingTasks(NULL, profile->GetOffTheRecordProfile(), 164 ProcessPendingTasks(NULL, profile->GetOffTheRecordProfile(),
159 unloaded->extension); 165 unloaded->extension);
160 } 166 }
161 break; 167 break;
162 } 168 }
163 default: 169 default:
164 NOTREACHED(); 170 NOTREACHED();
165 break; 171 break;
166 } 172 }
167 } 173 }
168 174
169 } // namespace extensions 175 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698