| 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" |
| 11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
| 12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 13 #include "base/values.h" | 13 #include "base/values.h" |
| 14 #include "base/version.h" | 14 #include "base/version.h" |
| 15 #include "content/public/browser/browser_context.h" | 15 #include "content/public/browser/browser_context.h" |
| 16 #include "content/public/browser/child_process_security_policy.h" | 16 #include "content/public/browser/child_process_security_policy.h" |
| 17 #include "content/public/browser/notification_service.h" | 17 #include "content/public/browser/notification_service.h" |
| 18 #include "content/public/browser/render_process_host.h" | 18 #include "content/public/browser/render_process_host.h" |
| 19 #include "content/public/browser/render_view_host.h" | 19 #include "content/public/browser/render_view_host.h" |
| 20 #include "extensions/browser/api/runtime/runtime_api_delegate.h" | 20 #include "extensions/browser/api/runtime/runtime_api_delegate.h" |
| 21 #include "extensions/browser/event_router.h" | 21 #include "extensions/browser/event_router.h" |
| 22 #include "extensions/browser/extension_host.h" | 22 #include "extensions/browser/extension_host.h" |
| 23 #include "extensions/browser/extension_prefs.h" | 23 #include "extensions/browser/extension_prefs.h" |
| 24 #include "extensions/browser/extension_registry.h" | 24 #include "extensions/browser/extension_registry.h" |
| 25 #include "extensions/browser/extension_system.h" | 25 #include "extensions/browser/extension_system.h" |
| 26 #include "extensions/browser/extension_util.h" | 26 #include "extensions/browser/extension_util.h" |
| 27 #include "extensions/browser/extensions_browser_client.h" | 27 #include "extensions/browser/extensions_browser_client.h" |
| 28 #include "extensions/browser/lazy_background_task_queue.h" | 28 #include "extensions/browser/lazy_background_task_queue.h" |
| 29 #include "extensions/browser/notification_types.h" | 29 #include "extensions/browser/notification_types.h" |
| 30 #include "extensions/browser/process_manager.h" | 30 #include "extensions/browser/process_manager_factory.h" |
| 31 #include "extensions/common/api/runtime.h" | 31 #include "extensions/common/api/runtime.h" |
| 32 #include "extensions/common/error_utils.h" | 32 #include "extensions/common/error_utils.h" |
| 33 #include "extensions/common/extension.h" | 33 #include "extensions/common/extension.h" |
| 34 #include "extensions/common/manifest_handlers/background_info.h" | 34 #include "extensions/common/manifest_handlers/background_info.h" |
| 35 #include "extensions/common/manifest_handlers/shared_module_info.h" | 35 #include "extensions/common/manifest_handlers/shared_module_info.h" |
| 36 #include "storage/browser/fileapi/isolated_context.h" | 36 #include "storage/browser/fileapi/isolated_context.h" |
| 37 #include "url/gurl.h" | 37 #include "url/gurl.h" |
| 38 | 38 |
| 39 using content::BrowserContext; | 39 using content::BrowserContext; |
| 40 | 40 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 /////////////////////////////////////////////////////////////////////////////// | 129 /////////////////////////////////////////////////////////////////////////////// |
| 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 template <> |
| 140 void BrowserContextKeyedAPIFactory<RuntimeAPI>::DeclareFactoryDependencies() { |
| 141 DependsOn(ProcessManagerFactory::GetInstance()); |
| 142 } |
| 143 |
| 139 RuntimeAPI::RuntimeAPI(content::BrowserContext* context) | 144 RuntimeAPI::RuntimeAPI(content::BrowserContext* context) |
| 140 : browser_context_(context), | 145 : browser_context_(context), |
| 141 dispatch_chrome_updated_event_(false), | 146 dispatch_chrome_updated_event_(false), |
| 142 extension_registry_observer_(this) { | 147 extension_registry_observer_(this), |
| 148 process_manager_observer_(this) { |
| 149 // RuntimeAPI is redirected in incognito, so |browser_context_| is never |
| 150 // incognito. |
| 151 DCHECK(!browser_context_->IsOffTheRecord()); |
| 152 |
| 143 registrar_.Add(this, | 153 registrar_.Add(this, |
| 144 extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, | 154 extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, |
| 145 content::Source<BrowserContext>(context)); | 155 content::Source<BrowserContext>(context)); |
| 146 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); | 156 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); |
| 157 process_manager_observer_.Add(ProcessManager::Get(browser_context_)); |
| 147 | 158 |
| 148 delegate_ = ExtensionsBrowserClient::Get()->CreateRuntimeAPIDelegate( | 159 delegate_ = ExtensionsBrowserClient::Get()->CreateRuntimeAPIDelegate( |
| 149 browser_context_); | 160 browser_context_); |
| 150 | 161 |
| 151 // Check if registered events are up-to-date. We can only do this once | 162 // Check if registered events are up-to-date. We can only do this once |
| 152 // per browser context, since it updates internal state when called. | 163 // per browser context, since it updates internal state when called. |
| 153 dispatch_chrome_updated_event_ = | 164 dispatch_chrome_updated_event_ = |
| 154 ExtensionsBrowserClient::Get()->DidVersionUpdate(browser_context_); | 165 ExtensionsBrowserClient::Get()->DidVersionUpdate(browser_context_); |
| 155 } | 166 } |
| 156 | 167 |
| 157 RuntimeAPI::~RuntimeAPI() { | 168 RuntimeAPI::~RuntimeAPI() { |
| 158 delegate_->RemoveUpdateObserver(this); | |
| 159 } | 169 } |
| 160 | 170 |
| 161 void RuntimeAPI::Observe(int type, | 171 void RuntimeAPI::Observe(int type, |
| 162 const content::NotificationSource& source, | 172 const content::NotificationSource& source, |
| 163 const content::NotificationDetails& details) { | 173 const content::NotificationDetails& details) { |
| 164 DCHECK_EQ(extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, type); | 174 DCHECK_EQ(extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, type); |
| 165 // We're done restarting Chrome after an update. | 175 // We're done restarting Chrome after an update. |
| 166 dispatch_chrome_updated_event_ = false; | 176 dispatch_chrome_updated_event_ = false; |
| 167 | 177 |
| 168 delegate_->AddUpdateObserver(this); | 178 delegate_->AddUpdateObserver(this); |
| 169 | |
| 170 // RuntimeAPI is redirected in incognito, so |browser_context_| is never | |
| 171 // incognito. We don't observe incognito ProcessManagers but that is OK | |
| 172 // because we don't send onStartup events to incognito browser contexts. | |
| 173 DCHECK(!browser_context_->IsOffTheRecord()); | |
| 174 // Some tests use partially constructed Profiles without a process manager. | |
| 175 ExtensionSystem* extension_system = ExtensionSystem::Get(browser_context_); | |
| 176 if (extension_system->process_manager()) | |
| 177 extension_system->process_manager()->AddObserver(this); | |
| 178 } | 179 } |
| 179 | 180 |
| 180 void RuntimeAPI::OnExtensionLoaded(content::BrowserContext* browser_context, | 181 void RuntimeAPI::OnExtensionLoaded(content::BrowserContext* browser_context, |
| 181 const Extension* extension) { | 182 const Extension* extension) { |
| 182 if (!dispatch_chrome_updated_event_) | 183 if (!dispatch_chrome_updated_event_) |
| 183 return; | 184 return; |
| 184 | 185 |
| 185 // Dispatch the onInstalled event with reason "chrome_update". | 186 // Dispatch the onInstalled event with reason "chrome_update". |
| 186 base::MessageLoop::current()->PostTask( | 187 base::MessageLoop::current()->PostTask( |
| 187 FROM_HERE, | 188 FROM_HERE, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 // Ephemeral apps are not considered to be installed, so the uninstall URL | 223 // Ephemeral apps are not considered to be installed, so the uninstall URL |
| 223 // is not invoked when they are removed. | 224 // is not invoked when they are removed. |
| 224 if (util::IsEphemeralApp(extension->id(), browser_context_)) | 225 if (util::IsEphemeralApp(extension->id(), browser_context_)) |
| 225 return; | 226 return; |
| 226 | 227 |
| 227 RuntimeEventRouter::OnExtensionUninstalled( | 228 RuntimeEventRouter::OnExtensionUninstalled( |
| 228 browser_context_, extension->id(), reason); | 229 browser_context_, extension->id(), reason); |
| 229 } | 230 } |
| 230 | 231 |
| 231 void RuntimeAPI::Shutdown() { | 232 void RuntimeAPI::Shutdown() { |
| 232 // ExtensionSystem deletes its ProcessManager during the Shutdown() phase, so | 233 delegate_->RemoveUpdateObserver(this); |
| 233 // the observer must be removed here and not in the RuntimeAPI destructor. | |
| 234 ProcessManager* process_manager = | |
| 235 ExtensionSystem::Get(browser_context_)->process_manager(); | |
| 236 // Some tests use partially constructed Profiles without a process manager. | |
| 237 if (process_manager) | |
| 238 process_manager->RemoveObserver(this); | |
| 239 } | 234 } |
| 240 | 235 |
| 241 void RuntimeAPI::OnAppUpdateAvailable(const Extension* extension) { | 236 void RuntimeAPI::OnAppUpdateAvailable(const Extension* extension) { |
| 242 RuntimeEventRouter::DispatchOnUpdateAvailableEvent( | 237 RuntimeEventRouter::DispatchOnUpdateAvailableEvent( |
| 243 browser_context_, extension->id(), extension->manifest()->value()); | 238 browser_context_, extension->id(), extension->manifest()->value()); |
| 244 } | 239 } |
| 245 | 240 |
| 246 void RuntimeAPI::OnChromeUpdateAvailable() { | 241 void RuntimeAPI::OnChromeUpdateAvailable() { |
| 247 RuntimeEventRouter::DispatchOnBrowserUpdateAvailableEvent(browser_context_); | 242 RuntimeEventRouter::DispatchOnBrowserUpdateAvailableEvent(browser_context_); |
| 248 } | 243 } |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 GetUninstallURL(ExtensionPrefs::Get(context), extension_id)); | 393 GetUninstallURL(ExtensionPrefs::Get(context), extension_id)); |
| 399 | 394 |
| 400 if (uninstall_url.is_empty()) | 395 if (uninstall_url.is_empty()) |
| 401 return; | 396 return; |
| 402 | 397 |
| 403 RuntimeAPI::GetFactoryInstance()->Get(context)->OpenURL(uninstall_url); | 398 RuntimeAPI::GetFactoryInstance()->Get(context)->OpenURL(uninstall_url); |
| 404 } | 399 } |
| 405 | 400 |
| 406 ExtensionFunction::ResponseAction RuntimeGetBackgroundPageFunction::Run() { | 401 ExtensionFunction::ResponseAction RuntimeGetBackgroundPageFunction::Run() { |
| 407 ExtensionSystem* system = ExtensionSystem::Get(browser_context()); | 402 ExtensionSystem* system = ExtensionSystem::Get(browser_context()); |
| 408 ExtensionHost* host = | 403 ExtensionHost* host = ProcessManager::Get(browser_context()) |
| 409 system->process_manager()->GetBackgroundHostForExtension(extension_id()); | 404 ->GetBackgroundHostForExtension(extension_id()); |
| 410 if (system->lazy_background_task_queue()->ShouldEnqueueTask(browser_context(), | 405 if (system->lazy_background_task_queue()->ShouldEnqueueTask(browser_context(), |
| 411 extension())) { | 406 extension())) { |
| 412 system->lazy_background_task_queue()->AddPendingTask( | 407 system->lazy_background_task_queue()->AddPendingTask( |
| 413 browser_context(), | 408 browser_context(), |
| 414 extension_id(), | 409 extension_id(), |
| 415 base::Bind(&RuntimeGetBackgroundPageFunction::OnPageLoaded, this)); | 410 base::Bind(&RuntimeGetBackgroundPageFunction::OnPageLoaded, this)); |
| 416 } else if (host) { | 411 } else if (host) { |
| 417 OnPageLoaded(host); | 412 OnPageLoaded(host); |
| 418 } else { | 413 } else { |
| 419 return RespondNow(Error(kNoBackgroundPageError)); | 414 return RespondNow(Error(kNoBackgroundPageError)); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 511 content::ChildProcessSecurityPolicy* policy = | 506 content::ChildProcessSecurityPolicy* policy = |
| 512 content::ChildProcessSecurityPolicy::GetInstance(); | 507 content::ChildProcessSecurityPolicy::GetInstance(); |
| 513 policy->GrantReadFileSystem(renderer_id, filesystem_id); | 508 policy->GrantReadFileSystem(renderer_id, filesystem_id); |
| 514 base::DictionaryValue* dict = new base::DictionaryValue(); | 509 base::DictionaryValue* dict = new base::DictionaryValue(); |
| 515 dict->SetString("fileSystemId", filesystem_id); | 510 dict->SetString("fileSystemId", filesystem_id); |
| 516 dict->SetString("baseName", relative_path); | 511 dict->SetString("baseName", relative_path); |
| 517 return RespondNow(OneArgument(dict)); | 512 return RespondNow(OneArgument(dict)); |
| 518 } | 513 } |
| 519 | 514 |
| 520 } // namespace extensions | 515 } // namespace extensions |
| OLD | NEW |