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/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 11 matching lines...) Expand all Loading... |
22 #include "content/public/browser/render_view_host.h" | 22 #include "content/public/browser/render_view_host.h" |
23 #include "content/public/browser/site_instance.h" | 23 #include "content/public/browser/site_instance.h" |
24 #include "content/public/browser/web_contents.h" | 24 #include "content/public/browser/web_contents.h" |
25 | 25 |
26 namespace extensions { | 26 namespace extensions { |
27 | 27 |
28 LazyBackgroundTaskQueue::LazyBackgroundTaskQueue(Profile* profile) | 28 LazyBackgroundTaskQueue::LazyBackgroundTaskQueue(Profile* profile) |
29 : profile_(profile) { | 29 : profile_(profile) { |
30 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING, | 30 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING, |
31 content::NotificationService::AllBrowserContextsAndSources()); | 31 content::NotificationService::AllBrowserContextsAndSources()); |
| 32 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, |
| 33 content::NotificationService::AllBrowserContextsAndSources()); |
32 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, | 34 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, |
33 content::Source<Profile>(profile)); | 35 content::Source<Profile>(profile)); |
34 } | 36 } |
35 | 37 |
36 LazyBackgroundTaskQueue::~LazyBackgroundTaskQueue() { | 38 LazyBackgroundTaskQueue::~LazyBackgroundTaskQueue() { |
37 } | 39 } |
38 | 40 |
39 bool LazyBackgroundTaskQueue::ShouldEnqueueTask( | 41 bool LazyBackgroundTaskQueue::ShouldEnqueueTask( |
40 Profile* profile, const Extension* extension) { | 42 Profile* profile, const Extension* extension) { |
41 DCHECK(extension); | 43 DCHECK(extension); |
(...skipping 17 matching lines...) Expand all Loading... |
59 PendingTasksMap::iterator it = pending_tasks_.find(key); | 61 PendingTasksMap::iterator it = pending_tasks_.find(key); |
60 if (it == pending_tasks_.end()) { | 62 if (it == pending_tasks_.end()) { |
61 tasks_list = new PendingTasksList(); | 63 tasks_list = new PendingTasksList(); |
62 pending_tasks_[key] = linked_ptr<PendingTasksList>(tasks_list); | 64 pending_tasks_[key] = linked_ptr<PendingTasksList>(tasks_list); |
63 | 65 |
64 // If this is the first enqueued task, ensure the background page | 66 // If this is the first enqueued task, ensure the background page |
65 // is loaded. | 67 // is loaded. |
66 const Extension* extension = profile->GetExtensionService()-> | 68 const Extension* extension = profile->GetExtensionService()-> |
67 extensions()->GetByID(extension_id); | 69 extensions()->GetByID(extension_id); |
68 DCHECK(extension->has_lazy_background_page()); | 70 DCHECK(extension->has_lazy_background_page()); |
69 ExtensionProcessManager* pm = profile->GetExtensionProcessManager(); | 71 ExtensionProcessManager* pm = profile->GetExtensionProcessManager(); |
70 pm->IncrementLazyKeepaliveCount(extension); | 72 pm->IncrementLazyKeepaliveCount(extension); |
71 pm->CreateBackgroundHost(extension, extension->GetBackgroundURL()); | 73 pm->CreateBackgroundHost(extension, extension->GetBackgroundURL()); |
72 } else { | 74 } else { |
73 tasks_list = it->second.get(); | 75 tasks_list = it->second.get(); |
74 } | 76 } |
75 | 77 |
76 tasks_list->push_back(task); | 78 tasks_list->push_back(task); |
77 } | 79 } |
78 | 80 |
79 void LazyBackgroundTaskQueue::ProcessPendingTasks(ExtensionHost* host) { | 81 void LazyBackgroundTaskQueue::ProcessPendingTasks(ExtensionHost* host) { |
(...skipping 29 matching lines...) Expand all Loading... |
109 ExtensionHost* host = content::Details<ExtensionHost>(details).ptr(); | 111 ExtensionHost* host = content::Details<ExtensionHost>(details).ptr(); |
110 if (host->profile()->IsSameProfile(profile_) && | 112 if (host->profile()->IsSameProfile(profile_) && |
111 host->extension_host_type() == | 113 host->extension_host_type() == |
112 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE && | 114 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE && |
113 host->extension()->has_lazy_background_page()) { | 115 host->extension()->has_lazy_background_page()) { |
114 CHECK(host->did_stop_loading()); | 116 CHECK(host->did_stop_loading()); |
115 ProcessPendingTasks(host); | 117 ProcessPendingTasks(host); |
116 } | 118 } |
117 break; | 119 break; |
118 } | 120 } |
| 121 case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: { |
| 122 // Clear pending tasks when the background host dies. This can happen |
| 123 // if the extension crashes. This is not strictly necessary, since we |
| 124 // also unload the extension in that case (which clears the tasks below), |
| 125 // but is a good extra precaution. |
| 126 Profile* profile = content::Source<Profile>(source).ptr(); |
| 127 ExtensionHost* host = content::Details<ExtensionHost>(details).ptr(); |
| 128 if (host->extension_host_type() == |
| 129 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { |
| 130 pending_tasks_.erase(PendingTasksKey(profile, host->extension()->id())); |
| 131 } |
| 132 break; |
| 133 } |
119 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { | 134 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { |
120 // Clear pending tasks for this extension. | 135 // Clear pending tasks for this extension. |
121 Profile* profile = content::Source<Profile>(source).ptr(); | 136 Profile* profile = content::Source<Profile>(source).ptr(); |
122 UnloadedExtensionInfo* unloaded = | 137 UnloadedExtensionInfo* unloaded = |
123 content::Details<UnloadedExtensionInfo>(details).ptr(); | 138 content::Details<UnloadedExtensionInfo>(details).ptr(); |
124 pending_tasks_.erase(PendingTasksKey( | 139 pending_tasks_.erase(PendingTasksKey( |
125 profile, unloaded->extension->id())); | 140 profile, unloaded->extension->id())); |
126 if (profile->HasOffTheRecordProfile()) | 141 if (profile->HasOffTheRecordProfile()) |
127 pending_tasks_.erase(PendingTasksKey( | 142 pending_tasks_.erase(PendingTasksKey( |
128 profile->GetOffTheRecordProfile(), unloaded->extension->id())); | 143 profile->GetOffTheRecordProfile(), unloaded->extension->id())); |
129 break; | 144 break; |
130 } | 145 } |
131 default: | 146 default: |
132 NOTREACHED(); | 147 NOTREACHED(); |
133 break; | 148 break; |
134 } | 149 } |
135 } | 150 } |
136 | 151 |
137 } // namespace extensions | 152 } // namespace extensions |
OLD | NEW |