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 |