Chromium Code Reviews| 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 <memory> | 7 #include <memory> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 61 const char kInstallReasonSharedModuleUpdate[] = "shared_module_update"; | 61 const char kInstallReasonSharedModuleUpdate[] = "shared_module_update"; |
| 62 const char kInstallPreviousVersion[] = "previousVersion"; | 62 const char kInstallPreviousVersion[] = "previousVersion"; |
| 63 const char kInvalidUrlError[] = "Invalid URL: \"*\"."; | 63 const char kInvalidUrlError[] = "Invalid URL: \"*\"."; |
| 64 const char kPlatformInfoUnavailable[] = "Platform information unavailable."; | 64 const char kPlatformInfoUnavailable[] = "Platform information unavailable."; |
| 65 | 65 |
| 66 const char kUpdatesDisabledError[] = "Autoupdate is not enabled."; | 66 const char kUpdatesDisabledError[] = "Autoupdate is not enabled."; |
| 67 | 67 |
| 68 // A preference key storing the url loaded when an extension is uninstalled. | 68 // A preference key storing the url loaded when an extension is uninstalled. |
| 69 const char kUninstallUrl[] = "uninstall_url"; | 69 const char kUninstallUrl[] = "uninstall_url"; |
| 70 | 70 |
| 71 // A preference key storing the information about an extension that was | |
| 72 // installed but not loaded. We keep the pending info here so that we can send | |
| 73 // chrome.runtime.onInstalled event during the extension load. | |
| 74 const char kPrefPendingOnInstalledEventDispatchInfo[] = | |
| 75 "pending_on_installed_event_dispatch_info"; | |
| 76 | |
| 77 // Previously installed version number. | |
| 78 const char kPrefPreviousVersion[] = "previous_version"; | |
| 79 | |
| 80 // The name of the directory to be returned by getPackageDirectoryEntry. This | 71 // The name of the directory to be returned by getPackageDirectoryEntry. This |
| 81 // particular value does not matter to user code, but is chosen for consistency | 72 // particular value does not matter to user code, but is chosen for consistency |
| 82 // with the equivalent Pepper API. | 73 // with the equivalent Pepper API. |
| 83 const char kPackageDirectoryPath[] = "crxfs"; | 74 const char kPackageDirectoryPath[] = "crxfs"; |
| 84 | 75 |
| 85 // Preference key for storing the last successful restart due to a call to | 76 // Preference key for storing the last successful restart due to a call to |
| 86 // chrome.runtime.restartAfterDelay(). | 77 // chrome.runtime.restartAfterDelay(). |
| 87 constexpr char kPrefLastRestartAfterDelayTime[] = | 78 constexpr char kPrefLastRestartAfterDelayTime[] = |
| 88 "last_restart_after_delay_time"; | 79 "last_restart_after_delay_time"; |
| 89 // Preference key for storing whether the most recent restart was due to a | 80 // Preference key for storing whether the most recent restart was due to a |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 211 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); | 202 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); |
| 212 process_manager_observer_.Add(ProcessManager::Get(browser_context_)); | 203 process_manager_observer_.Add(ProcessManager::Get(browser_context_)); |
| 213 | 204 |
| 214 delegate_ = ExtensionsBrowserClient::Get()->CreateRuntimeAPIDelegate( | 205 delegate_ = ExtensionsBrowserClient::Get()->CreateRuntimeAPIDelegate( |
| 215 browser_context_); | 206 browser_context_); |
| 216 | 207 |
| 217 // Check if registered events are up to date. We can only do this once | 208 // Check if registered events are up to date. We can only do this once |
| 218 // per browser context, since it updates internal state when called. | 209 // per browser context, since it updates internal state when called. |
| 219 dispatch_chrome_updated_event_ = | 210 dispatch_chrome_updated_event_ = |
| 220 ExtensionsBrowserClient::Get()->DidVersionUpdate(browser_context_); | 211 ExtensionsBrowserClient::Get()->DidVersionUpdate(browser_context_); |
| 212 | |
| 213 EventRouter::Get(browser_context_) | |
|
Devlin
2017/05/25 21:08:44
Add this as a dependency, and remove the observer
lazyboy
2017/05/30 23:38:35
Done.
The observer is removed in ::Shutdown as we
| |
| 214 ->lazy_event_dispatch_util() | |
| 215 ->AddObserver(this); | |
| 221 } | 216 } |
| 222 | 217 |
| 223 RuntimeAPI::~RuntimeAPI() { | 218 RuntimeAPI::~RuntimeAPI() { |
| 224 } | 219 } |
| 225 | 220 |
| 226 void RuntimeAPI::OnExtensionLoaded(content::BrowserContext* browser_context, | 221 void RuntimeAPI::OnExtensionLoaded(content::BrowserContext* browser_context, |
| 227 const Extension* extension) { | 222 const Extension* extension) { |
| 228 base::Version previous_version; | |
| 229 if (ReadPendingOnInstallInfoFromPref(extension->id(), &previous_version)) { | |
| 230 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 231 FROM_HERE, | |
| 232 base::Bind(&RuntimeEventRouter::DispatchOnInstalledEvent, | |
| 233 browser_context_, extension->id(), previous_version, false)); | |
| 234 RemovePendingOnInstallInfoFromPref(extension->id()); | |
| 235 } | |
| 236 | |
| 237 if (!dispatch_chrome_updated_event_) | 223 if (!dispatch_chrome_updated_event_) |
| 238 return; | 224 return; |
| 239 | 225 |
| 240 // Dispatch the onInstalled event with reason "chrome_update". | 226 // Dispatch the onInstalled event with reason "chrome_update". |
| 241 base::ThreadTaskRunnerHandle::Get()->PostTask( | 227 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 242 FROM_HERE, | 228 FROM_HERE, |
| 243 base::Bind(&RuntimeEventRouter::DispatchOnInstalledEvent, | 229 base::Bind(&RuntimeEventRouter::DispatchOnInstalledEvent, |
| 244 browser_context_, extension->id(), base::Version(), true)); | 230 browser_context_, extension->id(), base::Version(), true)); |
| 245 } | 231 } |
| 246 | 232 |
| 247 void RuntimeAPI::OnExtensionWillBeInstalled( | |
| 248 content::BrowserContext* browser_context, | |
| 249 const Extension* extension, | |
| 250 bool is_update, | |
| 251 const std::string& old_name) { | |
| 252 // This extension might be disabled before it has a chance to load, e.g. if | |
| 253 // the extension increased its permissions. So instead of trying to send the | |
| 254 // onInstalled event here, we remember the fact in prefs and fire the event | |
| 255 // when the extension is actually loaded. | |
| 256 StorePendingOnInstallInfoToPref(extension); | |
| 257 } | |
| 258 | |
| 259 void RuntimeAPI::OnExtensionUninstalled( | 233 void RuntimeAPI::OnExtensionUninstalled( |
| 260 content::BrowserContext* browser_context, | 234 content::BrowserContext* browser_context, |
| 261 const Extension* extension, | 235 const Extension* extension, |
| 262 UninstallReason reason) { | 236 UninstallReason reason) { |
| 263 RemovePendingOnInstallInfoFromPref(extension->id()); | |
| 264 | |
| 265 RuntimeEventRouter::OnExtensionUninstalled( | 237 RuntimeEventRouter::OnExtensionUninstalled( |
| 266 browser_context_, extension->id(), reason); | 238 browser_context_, extension->id(), reason); |
| 267 } | 239 } |
| 268 | 240 |
| 269 void RuntimeAPI::Shutdown() { | 241 void RuntimeAPI::Shutdown() { |
| 270 delegate_->RemoveUpdateObserver(this); | 242 delegate_->RemoveUpdateObserver(this); |
| 243 EventRouter::Get(browser_context_) | |
| 244 ->lazy_event_dispatch_util() | |
| 245 ->RemoveObserver(this); | |
| 271 } | 246 } |
| 272 | 247 |
| 273 void RuntimeAPI::OnAppUpdateAvailable(const Extension* extension) { | 248 void RuntimeAPI::OnAppUpdateAvailable(const Extension* extension) { |
| 274 RuntimeEventRouter::DispatchOnUpdateAvailableEvent( | 249 RuntimeEventRouter::DispatchOnUpdateAvailableEvent( |
| 275 browser_context_, extension->id(), extension->manifest()->value()); | 250 browser_context_, extension->id(), extension->manifest()->value()); |
| 276 } | 251 } |
| 277 | 252 |
| 278 void RuntimeAPI::OnChromeUpdateAvailable() { | 253 void RuntimeAPI::OnChromeUpdateAvailable() { |
| 279 RuntimeEventRouter::DispatchOnBrowserUpdateAvailableEvent(browser_context_); | 254 RuntimeEventRouter::DispatchOnBrowserUpdateAvailableEvent(browser_context_); |
| 280 } | 255 } |
| 281 | 256 |
| 282 void RuntimeAPI::OnBackgroundHostStartup(const Extension* extension) { | 257 void RuntimeAPI::OnBackgroundHostStartup(const Extension* extension) { |
| 283 RuntimeEventRouter::DispatchOnStartupEvent(browser_context_, extension->id()); | 258 RuntimeEventRouter::DispatchOnStartupEvent(browser_context_, extension->id()); |
| 284 } | 259 } |
| 285 | 260 |
| 286 bool RuntimeAPI::ReadPendingOnInstallInfoFromPref( | |
| 287 const ExtensionId& extension_id, | |
| 288 base::Version* previous_version) { | |
| 289 ExtensionPrefs* prefs = ExtensionPrefs::Get(browser_context_); | |
| 290 DCHECK(prefs); | |
| 291 | |
| 292 const base::DictionaryValue* info = nullptr; | |
| 293 if (!prefs->ReadPrefAsDictionary( | |
| 294 extension_id, kPrefPendingOnInstalledEventDispatchInfo, &info)) { | |
| 295 return false; | |
| 296 } | |
| 297 | |
| 298 std::string previous_version_string; | |
| 299 info->GetString(kPrefPreviousVersion, &previous_version_string); | |
| 300 // |previous_version_string| can be empty. | |
| 301 *previous_version = base::Version(previous_version_string); | |
| 302 return true; | |
| 303 } | |
| 304 | |
| 305 void RuntimeAPI::RemovePendingOnInstallInfoFromPref( | |
| 306 const ExtensionId& extension_id) { | |
| 307 ExtensionPrefs* prefs = ExtensionPrefs::Get(browser_context_); | |
| 308 DCHECK(prefs); | |
| 309 | |
| 310 prefs->UpdateExtensionPref(extension_id, | |
| 311 kPrefPendingOnInstalledEventDispatchInfo, nullptr); | |
| 312 } | |
| 313 | |
| 314 void RuntimeAPI::StorePendingOnInstallInfoToPref(const Extension* extension) { | |
| 315 ExtensionPrefs* prefs = ExtensionPrefs::Get(browser_context_); | |
| 316 DCHECK(prefs); | |
| 317 | |
| 318 // |pending_on_install_info| currently only contains a version string. Instead | |
| 319 // of making the pref hold a plain string, we store it as a dictionary value | |
| 320 // so that we can add more stuff to it in the future if necessary. | |
| 321 std::unique_ptr<base::DictionaryValue> pending_on_install_info( | |
| 322 new base::DictionaryValue()); | |
| 323 base::Version previous_version = ExtensionRegistry::Get(browser_context_) | |
| 324 ->GetStoredVersion(extension->id()); | |
| 325 pending_on_install_info->SetString( | |
| 326 kPrefPreviousVersion, | |
| 327 previous_version.IsValid() ? previous_version.GetString() : ""); | |
| 328 prefs->UpdateExtensionPref(extension->id(), | |
| 329 kPrefPendingOnInstalledEventDispatchInfo, | |
| 330 std::move(pending_on_install_info)); | |
| 331 } | |
| 332 | |
| 333 void RuntimeAPI::ReloadExtension(const std::string& extension_id) { | 261 void RuntimeAPI::ReloadExtension(const std::string& extension_id) { |
| 334 delegate_->ReloadExtension(extension_id); | 262 delegate_->ReloadExtension(extension_id); |
| 335 } | 263 } |
| 336 | 264 |
| 337 bool RuntimeAPI::CheckForUpdates( | 265 bool RuntimeAPI::CheckForUpdates( |
| 338 const std::string& extension_id, | 266 const std::string& extension_id, |
| 339 const RuntimeAPIDelegate::UpdateCheckCallback& callback) { | 267 const RuntimeAPIDelegate::UpdateCheckCallback& callback) { |
| 340 return delegate_->CheckForUpdates(extension_id, callback); | 268 return delegate_->CheckForUpdates(extension_id, callback); |
| 341 } | 269 } |
| 342 | 270 |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 627 | 555 |
| 628 if (!uninstall_url.SchemeIsHTTPOrHTTPS()) { | 556 if (!uninstall_url.SchemeIsHTTPOrHTTPS()) { |
| 629 // Previous versions of Chrome allowed non-http(s) URLs to be stored in the | 557 // Previous versions of Chrome allowed non-http(s) URLs to be stored in the |
| 630 // prefs. Now they're disallowed, but the old data may still exist. | 558 // prefs. Now they're disallowed, but the old data may still exist. |
| 631 return; | 559 return; |
| 632 } | 560 } |
| 633 | 561 |
| 634 RuntimeAPI::GetFactoryInstance()->Get(context)->OpenURL(uninstall_url); | 562 RuntimeAPI::GetFactoryInstance()->Get(context)->OpenURL(uninstall_url); |
| 635 } | 563 } |
| 636 | 564 |
| 565 void RuntimeAPI::OnExtensionInstalledAndLoaded( | |
| 566 content::BrowserContext* browser_context, | |
| 567 const Extension* extension, | |
| 568 const base::Version& previous_version) { | |
| 569 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 570 FROM_HERE, | |
| 571 base::Bind(&RuntimeEventRouter::DispatchOnInstalledEvent, | |
| 572 browser_context_, extension->id(), previous_version, false)); | |
| 573 } | |
| 574 | |
| 637 ExtensionFunction::ResponseAction RuntimeGetBackgroundPageFunction::Run() { | 575 ExtensionFunction::ResponseAction RuntimeGetBackgroundPageFunction::Run() { |
| 638 ExtensionHost* host = ProcessManager::Get(browser_context()) | 576 ExtensionHost* host = ProcessManager::Get(browser_context()) |
| 639 ->GetBackgroundHostForExtension(extension_id()); | 577 ->GetBackgroundHostForExtension(extension_id()); |
| 640 if (LazyBackgroundTaskQueue::Get(browser_context()) | 578 if (LazyBackgroundTaskQueue::Get(browser_context()) |
| 641 ->ShouldEnqueueTask(browser_context(), extension())) { | 579 ->ShouldEnqueueTask(browser_context(), extension())) { |
| 642 LazyBackgroundTaskQueue::Get(browser_context()) | 580 LazyBackgroundTaskQueue::Get(browser_context()) |
| 643 ->AddPendingTask( | 581 ->AddPendingTask( |
| 644 browser_context(), extension_id(), | 582 browser_context(), extension_id(), |
| 645 base::Bind(&RuntimeGetBackgroundPageFunction::OnPageLoaded, this)); | 583 base::Bind(&RuntimeGetBackgroundPageFunction::OnPageLoaded, this)); |
| 646 } else if (host) { | 584 } else if (host) { |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 782 content::ChildProcessSecurityPolicy* policy = | 720 content::ChildProcessSecurityPolicy* policy = |
| 783 content::ChildProcessSecurityPolicy::GetInstance(); | 721 content::ChildProcessSecurityPolicy::GetInstance(); |
| 784 policy->GrantReadFileSystem(renderer_id, filesystem_id); | 722 policy->GrantReadFileSystem(renderer_id, filesystem_id); |
| 785 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 723 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
| 786 dict->SetString("fileSystemId", filesystem_id); | 724 dict->SetString("fileSystemId", filesystem_id); |
| 787 dict->SetString("baseName", relative_path); | 725 dict->SetString("baseName", relative_path); |
| 788 return RespondNow(OneArgument(std::move(dict))); | 726 return RespondNow(OneArgument(std::move(dict))); |
| 789 } | 727 } |
| 790 | 728 |
| 791 } // namespace extensions | 729 } // namespace extensions |
| OLD | NEW |