lazy_event_dispatch_util.cc 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "extensions/browser/events/lazy_event_dispatch_util.h"
  5. #include "base/observer_list.h"
  6. #include "base/version.h"
  7. #include "content/public/browser/browser_context.h"
  8. #include "extensions/browser/event_router.h"
  9. #include "extensions/browser/extension_prefs.h"
  10. namespace extensions {
  11. namespace {
  12. // Previously installed version number.
  13. const char kPrefPreviousVersion[] = "previous_version";
  14. // A preference key storing the information about an extension that was
  15. // installed but not loaded. We keep the pending info here so that we can send
  16. // chrome.runtime.onInstalled event during the extension load.
  17. const char kPrefPendingOnInstalledEventDispatchInfo[] =
  18. "pending_on_installed_event_dispatch_info";
  19. } // namespace
  20. LazyEventDispatchUtil::LazyEventDispatchUtil(
  21. content::BrowserContext* browser_context)
  22. : browser_context_(browser_context) {
  23. extension_registry_observation_.Observe(
  24. ExtensionRegistry::Get(browser_context_));
  25. }
  26. LazyEventDispatchUtil::~LazyEventDispatchUtil() {}
  27. void LazyEventDispatchUtil::AddObserver(Observer* observer) {
  28. observers_.AddObserver(observer);
  29. }
  30. void LazyEventDispatchUtil::RemoveObserver(Observer* observer) {
  31. observers_.RemoveObserver(observer);
  32. }
  33. void LazyEventDispatchUtil::OnExtensionLoaded(
  34. content::BrowserContext* browser_context,
  35. const Extension* extension) {
  36. base::Version previous_version;
  37. if (ReadPendingOnInstallInfoFromPref(extension->id(), &previous_version)) {
  38. for (auto& observer : observers_) {
  39. observer.OnExtensionInstalledAndLoaded(browser_context_, extension,
  40. previous_version);
  41. }
  42. RemovePendingOnInstallInfoFromPref(extension->id());
  43. }
  44. }
  45. void LazyEventDispatchUtil::OnExtensionUninstalled(
  46. content::BrowserContext* browser_context,
  47. const Extension* extension,
  48. UninstallReason reason) {
  49. RemovePendingOnInstallInfoFromPref(extension->id());
  50. }
  51. void LazyEventDispatchUtil::OnExtensionWillBeInstalled(
  52. content::BrowserContext* browser_context,
  53. const Extension* extension,
  54. bool is_update,
  55. const std::string& old_name) {
  56. StorePendingOnInstallInfoToPref(extension);
  57. }
  58. bool LazyEventDispatchUtil::ReadPendingOnInstallInfoFromPref(
  59. const ExtensionId& extension_id,
  60. base::Version* previous_version) {
  61. ExtensionPrefs* prefs = ExtensionPrefs::Get(browser_context_);
  62. DCHECK(prefs);
  63. const base::DictionaryValue* info = nullptr;
  64. if (!prefs->ReadPrefAsDictionary(
  65. extension_id, kPrefPendingOnInstalledEventDispatchInfo, &info)) {
  66. return false;
  67. }
  68. const std::string* previous_version_string =
  69. info->FindStringKey(kPrefPreviousVersion);
  70. // |previous_version_string| can be empty.
  71. *previous_version = base::Version(
  72. previous_version_string ? *previous_version_string : std::string());
  73. return true;
  74. }
  75. void LazyEventDispatchUtil::RemovePendingOnInstallInfoFromPref(
  76. const ExtensionId& extension_id) {
  77. ExtensionPrefs* prefs = ExtensionPrefs::Get(browser_context_);
  78. DCHECK(prefs);
  79. prefs->UpdateExtensionPref(extension_id,
  80. kPrefPendingOnInstalledEventDispatchInfo, nullptr);
  81. }
  82. void LazyEventDispatchUtil::StorePendingOnInstallInfoToPref(
  83. const Extension* extension) {
  84. ExtensionPrefs* prefs = ExtensionPrefs::Get(browser_context_);
  85. DCHECK(prefs);
  86. // |pending_on_install_info| currently only contains a version string. Instead
  87. // of making the pref hold a plain string, we store it as a dictionary value
  88. // so that we can add more stuff to it in the future if necessary.
  89. auto pending_on_install_info = std::make_unique<base::DictionaryValue>();
  90. base::Version previous_version = ExtensionRegistry::Get(browser_context_)
  91. ->GetStoredVersion(extension->id());
  92. pending_on_install_info->SetStringKey(kPrefPreviousVersion,
  93. previous_version.IsValid()
  94. ? previous_version.GetString()
  95. : std::string());
  96. prefs->UpdateExtensionPref(extension->id(),
  97. kPrefPendingOnInstalledEventDispatchInfo,
  98. std::move(pending_on_install_info));
  99. }
  100. } // namespace extensions