OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "extensions/browser/api/runtime/runtime_api.h" | 5 #include "extensions/browser/api/runtime/runtime_api.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 | 130 |
131 static base::LazyInstance<BrowserContextKeyedAPIFactory<RuntimeAPI> > | 131 static base::LazyInstance<BrowserContextKeyedAPIFactory<RuntimeAPI> > |
132 g_factory = LAZY_INSTANCE_INITIALIZER; | 132 g_factory = LAZY_INSTANCE_INITIALIZER; |
133 | 133 |
134 // static | 134 // static |
135 BrowserContextKeyedAPIFactory<RuntimeAPI>* RuntimeAPI::GetFactoryInstance() { | 135 BrowserContextKeyedAPIFactory<RuntimeAPI>* RuntimeAPI::GetFactoryInstance() { |
136 return g_factory.Pointer(); | 136 return g_factory.Pointer(); |
137 } | 137 } |
138 | 138 |
139 RuntimeAPI::RuntimeAPI(content::BrowserContext* context) | 139 RuntimeAPI::RuntimeAPI(content::BrowserContext* context) |
140 : browser_context_(context), dispatch_chrome_updated_event_(false) { | 140 : browser_context_(context), |
| 141 extension_registry_observer_(this), |
| 142 dispatch_chrome_updated_event_(false) { |
141 registrar_.Add(this, | 143 registrar_.Add(this, |
142 chrome::NOTIFICATION_EXTENSIONS_READY, | 144 chrome::NOTIFICATION_EXTENSIONS_READY, |
143 content::Source<BrowserContext>(context)); | 145 content::Source<BrowserContext>(context)); |
144 registrar_.Add(this, | 146 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); |
145 chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED, | |
146 content::Source<BrowserContext>(context)); | |
147 registrar_.Add(this, | |
148 chrome::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED, | |
149 content::Source<BrowserContext>(context)); | |
150 registrar_.Add(this, | |
151 chrome::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED, | |
152 content::Source<BrowserContext>(context)); | |
153 | 147 |
154 delegate_ = ExtensionsBrowserClient::Get()->CreateRuntimeAPIDelegate( | 148 delegate_ = ExtensionsBrowserClient::Get()->CreateRuntimeAPIDelegate( |
155 browser_context_); | 149 browser_context_); |
156 | 150 |
157 // Check if registered events are up-to-date. We can only do this once | 151 // Check if registered events are up-to-date. We can only do this once |
158 // per browser context, since it updates internal state when called. | 152 // per browser context, since it updates internal state when called. |
159 dispatch_chrome_updated_event_ = | 153 dispatch_chrome_updated_event_ = |
160 ExtensionsBrowserClient::Get()->DidVersionUpdate(browser_context_); | 154 ExtensionsBrowserClient::Get()->DidVersionUpdate(browser_context_); |
161 } | 155 } |
162 | 156 |
163 RuntimeAPI::~RuntimeAPI() { | 157 RuntimeAPI::~RuntimeAPI() { |
164 delegate_->RemoveUpdateObserver(this); | 158 delegate_->RemoveUpdateObserver(this); |
165 } | 159 } |
166 | 160 |
167 void RuntimeAPI::Observe(int type, | 161 void RuntimeAPI::Observe(int type, |
168 const content::NotificationSource& source, | 162 const content::NotificationSource& source, |
169 const content::NotificationDetails& details) { | 163 const content::NotificationDetails& details) { |
170 switch (type) { | 164 DCHECK_EQ(chrome::NOTIFICATION_EXTENSIONS_READY, type); |
171 case chrome::NOTIFICATION_EXTENSIONS_READY: { | 165 OnExtensionsReady(); |
172 OnExtensionsReady(); | |
173 break; | |
174 } | |
175 case chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: { | |
176 const Extension* extension = | |
177 content::Details<const Extension>(details).ptr(); | |
178 OnExtensionLoaded(extension); | |
179 break; | |
180 } | |
181 case chrome::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED: { | |
182 const Extension* extension = | |
183 content::Details<const InstalledExtensionInfo>(details)->extension; | |
184 OnExtensionInstalled(extension); | |
185 break; | |
186 } | |
187 case chrome::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED: { | |
188 const Extension* extension = | |
189 content::Details<const Extension>(details).ptr(); | |
190 OnExtensionUninstalled(extension); | |
191 break; | |
192 } | |
193 default: | |
194 NOTREACHED(); | |
195 break; | |
196 } | |
197 } | 166 } |
198 | 167 |
199 void RuntimeAPI::OnExtensionsReady() { | 168 void RuntimeAPI::OnExtensionsReady() { |
200 // We're done restarting Chrome after an update. | 169 // We're done restarting Chrome after an update. |
201 dispatch_chrome_updated_event_ = false; | 170 dispatch_chrome_updated_event_ = false; |
202 | 171 |
203 delegate_->AddUpdateObserver(this); | 172 delegate_->AddUpdateObserver(this); |
204 | 173 |
205 // RuntimeAPI is redirected in incognito, so |browser_context_| is never | 174 // RuntimeAPI is redirected in incognito, so |browser_context_| is never |
206 // incognito. We don't observe incognito ProcessManagers but that is OK | 175 // incognito. We don't observe incognito ProcessManagers but that is OK |
207 // because we don't send onStartup events to incognito browser contexts. | 176 // because we don't send onStartup events to incognito browser contexts. |
208 DCHECK(!browser_context_->IsOffTheRecord()); | 177 DCHECK(!browser_context_->IsOffTheRecord()); |
209 // Some tests use partially constructed Profiles without a process manager. | 178 // Some tests use partially constructed Profiles without a process manager. |
210 ExtensionSystem* extension_system = ExtensionSystem::Get(browser_context_); | 179 ExtensionSystem* extension_system = ExtensionSystem::Get(browser_context_); |
211 if (extension_system->process_manager()) | 180 if (extension_system->process_manager()) |
212 extension_system->process_manager()->AddObserver(this); | 181 extension_system->process_manager()->AddObserver(this); |
213 } | 182 } |
214 | 183 |
215 void RuntimeAPI::OnExtensionLoaded(const Extension* extension) { | 184 void RuntimeAPI::OnExtensionLoaded(content::BrowserContext* browser_context, |
| 185 const Extension* extension) { |
216 if (!dispatch_chrome_updated_event_) | 186 if (!dispatch_chrome_updated_event_) |
217 return; | 187 return; |
218 | 188 |
219 // Dispatch the onInstalled event with reason "chrome_update". | 189 // Dispatch the onInstalled event with reason "chrome_update". |
220 base::MessageLoop::current()->PostTask( | 190 base::MessageLoop::current()->PostTask( |
221 FROM_HERE, | 191 FROM_HERE, |
222 base::Bind(&RuntimeEventRouter::DispatchOnInstalledEvent, | 192 base::Bind(&RuntimeEventRouter::DispatchOnInstalledEvent, |
223 browser_context_, | 193 browser_context_, |
224 extension->id(), | 194 extension->id(), |
225 Version(), | 195 Version(), |
226 true)); | 196 true)); |
227 } | 197 } |
228 | 198 |
229 void RuntimeAPI::OnExtensionInstalled(const Extension* extension) { | 199 void RuntimeAPI::OnExtensionWillBeInstalled( |
| 200 content::BrowserContext* browser_context, |
| 201 const Extension* extension, |
| 202 bool is_update, |
| 203 bool from_ephemeral, |
| 204 const std::string& old_name) { |
230 // Ephemeral apps are not considered to be installed and do not receive | 205 // Ephemeral apps are not considered to be installed and do not receive |
231 // the onInstalled() event. | 206 // the onInstalled() event. |
232 if (util::IsEphemeralApp(extension->id(), browser_context_)) | 207 if (util::IsEphemeralApp(extension->id(), browser_context_)) |
233 return; | 208 return; |
234 | 209 |
235 Version old_version = delegate_->GetPreviousExtensionVersion(extension); | 210 Version old_version = delegate_->GetPreviousExtensionVersion(extension); |
236 | 211 |
237 // Dispatch the onInstalled event. | 212 // Dispatch the onInstalled event. |
238 base::MessageLoop::current()->PostTask( | 213 base::MessageLoop::current()->PostTask( |
239 FROM_HERE, | 214 FROM_HERE, |
240 base::Bind(&RuntimeEventRouter::DispatchOnInstalledEvent, | 215 base::Bind(&RuntimeEventRouter::DispatchOnInstalledEvent, |
241 browser_context_, | 216 browser_context_, |
242 extension->id(), | 217 extension->id(), |
243 old_version, | 218 old_version, |
244 false)); | 219 false)); |
245 } | 220 } |
246 | 221 |
247 void RuntimeAPI::OnExtensionUninstalled(const Extension* extension) { | 222 void RuntimeAPI::OnExtensionUninstalled( |
| 223 content::BrowserContext* browser_context, |
| 224 const Extension* extension, |
| 225 UninstallReason reason) { |
248 // Ephemeral apps are not considered to be installed, so the uninstall URL | 226 // Ephemeral apps are not considered to be installed, so the uninstall URL |
249 // is not invoked when they are removed. | 227 // is not invoked when they are removed. |
250 if (util::IsEphemeralApp(extension->id(), browser_context_)) | 228 if (util::IsEphemeralApp(extension->id(), browser_context_)) |
251 return; | 229 return; |
252 | 230 |
253 RuntimeEventRouter::OnExtensionUninstalled(browser_context_, extension->id()); | 231 RuntimeEventRouter::OnExtensionUninstalled( |
| 232 browser_context_, extension->id(), reason); |
254 } | 233 } |
255 | 234 |
256 void RuntimeAPI::Shutdown() { | 235 void RuntimeAPI::Shutdown() { |
257 // ExtensionSystem deletes its ProcessManager during the Shutdown() phase, so | 236 // ExtensionSystem deletes its ProcessManager during the Shutdown() phase, so |
258 // the observer must be removed here and not in the RuntimeAPI destructor. | 237 // the observer must be removed here and not in the RuntimeAPI destructor. |
259 ProcessManager* process_manager = | 238 ProcessManager* process_manager = |
260 ExtensionSystem::Get(browser_context_)->process_manager(); | 239 ExtensionSystem::Get(browser_context_)->process_manager(); |
261 // Some tests use partially constructed Profiles without a process manager. | 240 // Some tests use partially constructed Profiles without a process manager. |
262 if (process_manager) | 241 if (process_manager) |
263 process_manager->RemoveObserver(this); | 242 process_manager->RemoveObserver(this); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 new Event(runtime::OnRestartRequired::kEventName, | 384 new Event(runtime::OnRestartRequired::kEventName, |
406 core_api::runtime::OnRestartRequired::Create(reason))); | 385 core_api::runtime::OnRestartRequired::Create(reason))); |
407 | 386 |
408 DCHECK(system->event_router()); | 387 DCHECK(system->event_router()); |
409 system->event_router()->DispatchEventToExtension(app_id, event.Pass()); | 388 system->event_router()->DispatchEventToExtension(app_id, event.Pass()); |
410 } | 389 } |
411 | 390 |
412 // static | 391 // static |
413 void RuntimeEventRouter::OnExtensionUninstalled( | 392 void RuntimeEventRouter::OnExtensionUninstalled( |
414 content::BrowserContext* context, | 393 content::BrowserContext* context, |
415 const std::string& extension_id) { | 394 const std::string& extension_id, |
| 395 UninstallReason reason) { |
| 396 if (!(reason == UNINSTALL_REASON_USER_INITIATED || |
| 397 reason == UNINSTALL_REASON_MANAGEMENT_API)) { |
| 398 return; |
| 399 } |
| 400 |
416 GURL uninstall_url( | 401 GURL uninstall_url( |
417 GetUninstallURL(ExtensionPrefs::Get(context), extension_id)); | 402 GetUninstallURL(ExtensionPrefs::Get(context), extension_id)); |
418 | 403 |
419 if (uninstall_url.is_empty()) | 404 if (uninstall_url.is_empty()) |
420 return; | 405 return; |
421 | 406 |
422 RuntimeAPI::GetFactoryInstance()->Get(context)->OpenURL(uninstall_url); | 407 RuntimeAPI::GetFactoryInstance()->Get(context)->OpenURL(uninstall_url); |
423 } | 408 } |
424 | 409 |
425 ExtensionFunction::ResponseAction RuntimeGetBackgroundPageFunction::Run() { | 410 ExtensionFunction::ResponseAction RuntimeGetBackgroundPageFunction::Run() { |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 content::ChildProcessSecurityPolicy* policy = | 515 content::ChildProcessSecurityPolicy* policy = |
531 content::ChildProcessSecurityPolicy::GetInstance(); | 516 content::ChildProcessSecurityPolicy::GetInstance(); |
532 policy->GrantReadFileSystem(renderer_id, filesystem_id); | 517 policy->GrantReadFileSystem(renderer_id, filesystem_id); |
533 base::DictionaryValue* dict = new base::DictionaryValue(); | 518 base::DictionaryValue* dict = new base::DictionaryValue(); |
534 dict->SetString("fileSystemId", filesystem_id); | 519 dict->SetString("fileSystemId", filesystem_id); |
535 dict->SetString("baseName", relative_path); | 520 dict->SetString("baseName", relative_path); |
536 return RespondNow(OneArgument(dict)); | 521 return RespondNow(OneArgument(dict)); |
537 } | 522 } |
538 | 523 |
539 } // namespace extensions | 524 } // namespace extensions |
OLD | NEW |