Move external install warning logic from ExtService to ExternalInstallManager
Move the logic to create warnings about externally-installed extensions from
ExtensionService into ExternalInstallManager.
Next step: Move tests from extension_service_unittest.
BUG=378042
BUG=351891
Review URL: https://codereview.chromium.org/308473002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@281071 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index 47076d0..42cad4f 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -109,21 +109,6 @@
namespace {
-// Histogram values for logging events related to externally installed
-// extensions.
-enum ExternalExtensionEvent {
- EXTERNAL_EXTENSION_INSTALLED = 0,
- EXTERNAL_EXTENSION_IGNORED,
- EXTERNAL_EXTENSION_REENABLED,
- EXTERNAL_EXTENSION_UNINSTALLED,
- EXTERNAL_EXTENSION_BUCKET_BOUNDARY,
-};
-
-#if defined(ENABLE_EXTENSIONS)
-// Prompt the user this many times before considering an extension acknowledged.
-const int kMaxExtensionAcknowledgePromptCount = 3;
-#endif
-
// Wait this many seconds after an extensions becomes idle before updating it.
const int kUpdateIdleDelay = 5;
@@ -297,8 +282,6 @@
browser_terminating_(false),
installs_delayed_for_gc_(false),
is_first_run_(false),
- external_install_manager_(
- new extensions::ExternalInstallManager(profile_)),
shared_module_service_(new extensions::SharedModuleService(profile_)) {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -364,6 +347,8 @@
error_controller_.reset(
new extensions::ExtensionErrorController(profile_, is_first_run_));
+ external_install_manager_.reset(
+ new extensions::ExternalInstallManager(profile_, is_first_run_));
#if defined(ENABLE_EXTENSIONS)
extension_action_storage_manager_.reset(
@@ -562,7 +547,7 @@
installer->set_grant_permissions(false);
creation_flags = pending_extension_info->creation_flags();
if (pending_extension_info->mark_acknowledged())
- AcknowledgeExternalExtension(id);
+ external_install_manager_->AcknowledgeExternalExtension(id);
} else if (extension) {
installer->set_install_source(extension->location());
}
@@ -746,20 +731,6 @@
system_->install_verifier()->Remove(extension->id());
- if (IsUnacknowledgedExternalExtension(extension.get())) {
- UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEvent",
- EXTERNAL_EXTENSION_UNINSTALLED,
- EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
- if (extensions::ManifestURL::UpdatesFromGallery(extension.get())) {
- UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEventWebstore",
- EXTERNAL_EXTENSION_UNINSTALLED,
- EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
- } else {
- UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEventNonWebstore",
- EXTERNAL_EXTENSION_UNINSTALLED,
- EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
- }
- }
UMA_HISTOGRAM_ENUMERATION("Extensions.UninstallType",
extension->GetType(), 100);
RecordPermissionMessagesHistogram(extension.get(),
@@ -860,22 +831,6 @@
if (!extension)
return;
- if (IsUnacknowledgedExternalExtension(extension)) {
- UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEvent",
- EXTERNAL_EXTENSION_REENABLED,
- EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
- if (extensions::ManifestURL::UpdatesFromGallery(extension)) {
- UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEventWebstore",
- EXTERNAL_EXTENSION_REENABLED,
- EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
- } else {
- UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEventNonWebstore",
- EXTERNAL_EXTENSION_REENABLED,
- EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
- }
- AcknowledgeExternalExtension(extension->id());
- }
-
// Move it over to the enabled list.
registry_->AddEnabled(make_scoped_refptr(extension));
registry_->RemoveDisabled(extension->id());
@@ -1288,78 +1243,10 @@
error_controller_->ShowErrorIfNeeded();
- UpdateExternalExtensionAlert();
+ external_install_manager_->UpdateExternalExtensionAlert();
#endif
}
-void ExtensionService::AcknowledgeExternalExtension(const std::string& id) {
- extension_prefs_->AcknowledgeExternalExtension(id);
- UpdateExternalExtensionAlert();
-}
-
-bool ExtensionService::IsUnacknowledgedExternalExtension(
- const Extension* extension) {
- if (!FeatureSwitch::prompt_for_external_extensions()->IsEnabled())
- return false;
-
- return (Manifest::IsExternalLocation(extension->location()) &&
- !extension_prefs_->IsExternalExtensionAcknowledged(extension->id()) &&
- !(extension_prefs_->GetDisableReasons(extension->id()) &
- Extension::DISABLE_SIDELOAD_WIPEOUT));
-}
-
-void ExtensionService::UpdateExternalExtensionAlert() {
-#if defined(ENABLE_EXTENSIONS)
- if (!FeatureSwitch::prompt_for_external_extensions()->IsEnabled())
- return;
-
- const Extension* extension = NULL;
- const ExtensionSet& disabled_extensions = registry_->disabled_extensions();
- for (ExtensionSet::const_iterator iter = disabled_extensions.begin();
- iter != disabled_extensions.end(); ++iter) {
- const Extension* e = iter->get();
- if (IsUnacknowledgedExternalExtension(e)) {
- extension = e;
- break;
- }
- }
-
- if (extension) {
- if (!external_install_manager_->HasExternalInstallError()) {
- if (extension_prefs_->IncrementAcknowledgePromptCount(extension->id()) >
- kMaxExtensionAcknowledgePromptCount) {
- // Stop prompting for this extension, and check if there's another
- // one that needs prompting.
- extension_prefs_->AcknowledgeExternalExtension(extension->id());
- UpdateExternalExtensionAlert();
- UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEvent",
- EXTERNAL_EXTENSION_IGNORED,
- EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
- if (extensions::ManifestURL::UpdatesFromGallery(extension)) {
- UMA_HISTOGRAM_ENUMERATION(
- "Extensions.ExternalExtensionEventWebstore",
- EXTERNAL_EXTENSION_IGNORED,
- EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
- } else {
- UMA_HISTOGRAM_ENUMERATION(
- "Extensions.ExternalExtensionEventNonWebstore",
- EXTERNAL_EXTENSION_IGNORED,
- EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
- }
- return;
- }
- if (is_first_run_)
- extension_prefs_->SetExternalInstallFirstRun(extension->id());
- // first_run is true if the extension was installed during a first run
- // (even if it's post-first run now).
- bool first_run = extension_prefs_->IsExternalInstallFirstRun(
- extension->id());
- external_install_manager_->AddExternalInstallError(extension, first_run);
- }
- }
-#endif // defined(ENABLE_EXTENSIONS)
-}
-
void ExtensionService::UnloadExtension(
const std::string& extension_id,
UnloadedExtensionInfo::Reason reason) {
@@ -1775,11 +1662,6 @@
extension->location(), Manifest::NUM_LOCATIONS);
}
- // Certain extension locations are specific enough that we can
- // auto-acknowledge any extension that came from one of them.
- if (Manifest::IsPolicyLocation(extension->location()) ||
- extension->location() == Manifest::EXTERNAL_COMPONENT)
- AcknowledgeExternalExtension(extension->id());
const Extension::State initial_state =
initial_enable ? Extension::ENABLED : Extension::DISABLED;
if (ShouldDelayExtensionUpdate(
@@ -1920,8 +1802,6 @@
registry_->TriggerOnWillBeInstalled(
extension, is_update, from_ephemeral, old_name);
- bool unacknowledged_external = IsUnacknowledgedExternalExtension(extension);
-
// Unpacked extensions default to allowing file access, but if that has been
// overridden, don't reset the value.
if (Manifest::ShouldAlwaysAllowFileAccess(extension->location()) &&
@@ -1934,30 +1814,10 @@
// Notify observers that need to know when an installation is complete.
registry_->TriggerOnInstalled(extension);
- // If this is a new external extension that was disabled, alert the user
- // so he can reenable it. We do this last so that it has already been
- // added to our list of extensions.
- if (unacknowledged_external && !is_update) {
- UpdateExternalExtensionAlert();
- UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEvent",
- EXTERNAL_EXTENSION_INSTALLED,
- EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
- if (extensions::ManifestURL::UpdatesFromGallery(extension)) {
- UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEventWebstore",
- EXTERNAL_EXTENSION_INSTALLED,
- EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
- } else {
- UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEventNonWebstore",
- EXTERNAL_EXTENSION_INSTALLED,
- EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
- }
- }
-
// Check extensions that may have been delayed only because this shared module
// was not available.
- if (SharedModuleInfo::IsSharedModule(extension)) {
+ if (SharedModuleInfo::IsSharedModule(extension))
MaybeFinishDelayedInstallations();
- }
}
void ExtensionService::PromoteEphemeralApp(
@@ -2120,7 +1980,7 @@
// notification on installation. For such extensions, mark them acknowledged
// now to suppress the notification.
if (mark_acknowledged)
- AcknowledgeExternalExtension(id);
+ external_install_manager_->AcknowledgeExternalExtension(id);
return true;
#else
diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h
index 943e3e3..db8611c 100644
--- a/chrome/browser/extensions/extension_service.h
+++ b/chrome/browser/extensions/extension_service.h
@@ -313,13 +313,6 @@
// Changes sequenced task runner for crx installation tasks to |task_runner|.
void SetFileTaskRunnerForTesting(base::SequencedTaskRunner* task_runner);
- // Checks if there are any new external extensions to notify the user about.
- void UpdateExternalExtensionAlert();
-
- // Given a (presumably just-installed) extension id, mark that extension as
- // acknowledged.
- void AcknowledgeExternalExtension(const std::string& id);
-
// Postpone installations so that we don't have to worry about race
// conditions.
void OnGarbageCollectIsolatedStorageStart();
@@ -471,11 +464,6 @@
// external extensions.
void OnAllExternalProvidersReady();
- // Returns true if this extension is an external one that has yet to be
- // marked as acknowledged.
- bool IsUnacknowledgedExternalExtension(
- const extensions::Extension* extension);
-
// Return true if the sync type of |extension| matches |type|.
void OnExtensionInstallPrefChanged();
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc
index 25907ff6..8bec09dd 100644
--- a/chrome/browser/extensions/extension_service_unittest.cc
+++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -6607,7 +6607,7 @@
new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
AddMockExternalProvider(provider);
- service()->UpdateExternalExtensionAlert();
+ service()->external_install_manager()->UpdateExternalExtensionAlert();
// Should return false, meaning there aren't any extensions that the user
// needs to know about.
EXPECT_FALSE(
@@ -6719,19 +6719,22 @@
service()->EnableExtension(page_action);
EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
- EXPECT_FALSE(
- service()->external_install_manager()->HasExternalInstallBubble());
+ EXPECT_FALSE(service()
+ ->external_install_manager()
+ ->HasExternalInstallBubbleForTesting());
service()->EnableExtension(theme_crx);
EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
- EXPECT_FALSE(
- service()->external_install_manager()->HasExternalInstallBubble());
+ EXPECT_FALSE(service()
+ ->external_install_manager()
+ ->HasExternalInstallBubbleForTesting());
service()->EnableExtension(good_crx);
EXPECT_FALSE(
service()->external_install_manager()->HasExternalInstallError());
- EXPECT_FALSE(
- service()->external_install_manager()->HasExternalInstallBubble());
+ EXPECT_FALSE(service()
+ ->external_install_manager()
+ ->HasExternalInstallBubbleForTesting());
}
// Test that there is a bubble for external extensions that update
@@ -6762,8 +6765,9 @@
service()->CheckForExternalUpdates();
observer.Wait();
EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
- EXPECT_TRUE(
- service()->external_install_manager()->HasExternalInstallBubble());
+ EXPECT_TRUE(service()
+ ->external_install_manager()
+ ->HasExternalInstallBubbleForTesting());
EXPECT_FALSE(service()->IsExtensionEnabled(updates_from_webstore));
}
@@ -6790,8 +6794,9 @@
service()->CheckForExternalUpdates();
observer.Wait();
EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
- EXPECT_FALSE(
- service()->external_install_manager()->HasExternalInstallBubble());
+ EXPECT_FALSE(service()
+ ->external_install_manager()
+ ->HasExternalInstallBubbleForTesting());
EXPECT_FALSE(service()->IsExtensionEnabled(updates_from_webstore));
}
diff --git a/chrome/browser/extensions/external_install_error.cc b/chrome/browser/extensions/external_install_error.cc
index 6b35e54..a08a40c 100644
--- a/chrome/browser/extensions/external_install_error.cc
+++ b/chrome/browser/extensions/external_install_error.cc
@@ -295,15 +295,6 @@
}
}
-void ExternalInstallError::AcknowledgeExtension() {
- const Extension* extension = GetExtension();
- if (extension) {
- ExtensionSystem::Get(browser_context_)
- ->extension_service()
- ->AcknowledgeExternalExtension(extension->id());
- }
-}
-
void ExternalInstallError::ShowDialog(Browser* browser) {
DCHECK(install_ui_.get());
DCHECK(prompt_.get());
diff --git a/chrome/browser/extensions/external_install_error.h b/chrome/browser/extensions/external_install_error.h
index 5704a8f..ff65e498 100644
--- a/chrome/browser/extensions/external_install_error.h
+++ b/chrome/browser/extensions/external_install_error.h
@@ -54,9 +54,6 @@
virtual void InstallUIProceed() OVERRIDE;
virtual void InstallUIAbort(bool user_initiated) OVERRIDE;
- // Acknowledge the associated external extension.
- void AcknowledgeExtension();
-
// Show the associated dialog. This should only be called once the dialog is
// ready.
void ShowDialog(Browser* browser);
diff --git a/chrome/browser/extensions/external_install_manager.cc b/chrome/browser/extensions/external_install_manager.cc
index dcdf764f..daf3e72 100644
--- a/chrome/browser/extensions/external_install_manager.cc
+++ b/chrome/browser/extensions/external_install_manager.cc
@@ -7,22 +7,63 @@
#include <string>
#include "base/logging.h"
+#include "base/metrics/histogram.h"
#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/external_install_error.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/manifest_url_handler.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
+#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
-#include "extensions/browser/extension_system.h"
#include "extensions/common/extension.h"
+#include "extensions/common/feature_switch.h"
+#include "extensions/common/manifest.h"
namespace extensions {
+namespace {
+
+// Histogram values for logging events related to externally installed
+// extensions.
+enum ExternalExtensionEvent {
+ EXTERNAL_EXTENSION_INSTALLED = 0,
+ EXTERNAL_EXTENSION_IGNORED,
+ EXTERNAL_EXTENSION_REENABLED,
+ EXTERNAL_EXTENSION_UNINSTALLED,
+ EXTERNAL_EXTENSION_BUCKET_BOUNDARY,
+};
+
+#if defined(ENABLE_EXTENSIONS)
+// Prompt the user this many times before considering an extension acknowledged.
+const int kMaxExtensionAcknowledgePromptCount = 3;
+#endif
+
+void LogExternalExtensionEvent(const Extension* extension,
+ ExternalExtensionEvent event) {
+ UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEvent",
+ event,
+ EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
+ if (ManifestURL::UpdatesFromGallery(extension)) {
+ UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEventWebstore",
+ event,
+ EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
+ } else {
+ UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEventNonWebstore",
+ event,
+ EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
+ }
+}
+
+} // namespace
+
ExternalInstallManager::ExternalInstallManager(
- content::BrowserContext* browser_context)
- : browser_context_(browser_context), extension_registry_observer_(this) {
+ content::BrowserContext* browser_context,
+ bool is_first_run)
+ : browser_context_(browser_context),
+ is_first_run_(is_first_run),
+ extension_prefs_(ExtensionPrefs::Get(browser_context_)),
+ extension_registry_observer_(this) {
DCHECK(browser_context_);
extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_));
registrar_.Add(
@@ -39,33 +80,79 @@
if (HasExternalInstallError())
return; // Only have one external install error at a time.
- if (ManifestURL::UpdatesFromGallery(extension) && !is_new_profile) {
- error_.reset(new ExternalInstallError(browser_context_,
- extension->id(),
- ExternalInstallError::BUBBLE_ALERT,
- this));
- } else {
- error_.reset(new ExternalInstallError(browser_context_,
- extension->id(),
- ExternalInstallError::MENU_ALERT,
- this));
- }
+ ExternalInstallError::AlertType alert_type =
+ (ManifestURL::UpdatesFromGallery(extension) && !is_new_profile)
+ ? ExternalInstallError::BUBBLE_ALERT
+ : ExternalInstallError::MENU_ALERT;
+
+ error_.reset(new ExternalInstallError(
+ browser_context_, extension->id(), alert_type, this));
}
void ExternalInstallManager::RemoveExternalInstallError() {
- if (error_.get()) {
- error_.reset();
- ExtensionSystem::Get(browser_context_)
- ->extension_service()
- ->UpdateExternalExtensionAlert();
- }
+ error_.reset();
+ UpdateExternalExtensionAlert();
}
bool ExternalInstallManager::HasExternalInstallError() const {
return error_.get() != NULL;
}
-bool ExternalInstallManager::HasExternalInstallBubble() const {
+void ExternalInstallManager::UpdateExternalExtensionAlert() {
+#if defined(ENABLE_EXTENSIONS)
+ // If the feature is not enabled, or there is already an error displayed, do
+ // nothing.
+ if (!FeatureSwitch::prompt_for_external_extensions()->IsEnabled() ||
+ HasExternalInstallError()) {
+ return;
+ }
+
+ // Look for any extensions that were disabled because of being unacknowledged
+ // external extensions.
+ const Extension* extension = NULL;
+ const ExtensionSet& disabled_extensions =
+ ExtensionRegistry::Get(browser_context_)->disabled_extensions();
+ for (ExtensionSet::const_iterator iter = disabled_extensions.begin();
+ iter != disabled_extensions.end();
+ ++iter) {
+ if (IsUnacknowledgedExternalExtension(iter->get())) {
+ extension = iter->get();
+ break;
+ }
+ }
+
+ if (!extension)
+ return; // No unacknowledged external extensions.
+
+ // Otherwise, warn the user about the suspicious extension.
+ if (extension_prefs_->IncrementAcknowledgePromptCount(extension->id()) >
+ kMaxExtensionAcknowledgePromptCount) {
+ // Stop prompting for this extension and record metrics.
+ extension_prefs_->AcknowledgeExternalExtension(extension->id());
+ LogExternalExtensionEvent(extension, EXTERNAL_EXTENSION_IGNORED);
+
+ // Check if there's another extension that needs prompting.
+ UpdateExternalExtensionAlert();
+ return;
+ }
+
+ if (is_first_run_)
+ extension_prefs_->SetExternalInstallFirstRun(extension->id());
+
+ // |first_run| is true if the extension was installed during a first run
+ // (even if it's post-first run now).
+ AddExternalInstallError(
+ extension, extension_prefs_->IsExternalInstallFirstRun(extension->id()));
+#endif // defined(ENABLE_EXTENSIONS)
+}
+
+void ExternalInstallManager::AcknowledgeExternalExtension(
+ const std::string& id) {
+ extension_prefs_->AcknowledgeExternalExtension(id);
+ UpdateExternalExtensionAlert();
+}
+
+bool ExternalInstallManager::HasExternalInstallBubbleForTesting() const {
return error_.get() &&
error_->alert_type() == ExternalInstallError::BUBBLE_ALERT;
}
@@ -73,13 +160,54 @@
void ExternalInstallManager::OnExtensionLoaded(
content::BrowserContext* browser_context,
const Extension* extension) {
- // The error is invalidated if the extension has been loaded or removed.
- if (error_.get() && extension->id() == error_->extension_id()) {
- // We treat loading as acknowledgement (since the user consciously chose to
- // re-enable the extension).
- error_->AcknowledgeExtension();
+ if (!IsUnacknowledgedExternalExtension(extension))
+ return;
+
+ // We treat loading as acknowledgement (since the user consciously chose to
+ // re-enable the extension).
+ AcknowledgeExternalExtension(extension->id());
+ LogExternalExtensionEvent(extension, EXTERNAL_EXTENSION_REENABLED);
+
+ // If we had an error for this extension, remove it.
+ if (error_.get() && extension->id() == error_->extension_id())
RemoveExternalInstallError();
+}
+
+void ExternalInstallManager::OnExtensionInstalled(
+ content::BrowserContext* browser_context,
+ const Extension* extension) {
+ // Certain extension locations are specific enough that we can
+ // auto-acknowledge any extension that came from one of them.
+ if (Manifest::IsPolicyLocation(extension->location()) ||
+ extension->location() == Manifest::EXTERNAL_COMPONENT) {
+ AcknowledgeExternalExtension(extension->id());
+ return;
}
+
+ if (!IsUnacknowledgedExternalExtension(extension))
+ return;
+
+ LogExternalExtensionEvent(extension, EXTERNAL_EXTENSION_INSTALLED);
+
+ UpdateExternalExtensionAlert();
+}
+
+void ExternalInstallManager::OnExtensionUninstalled(
+ content::BrowserContext* browser_context,
+ const Extension* extension) {
+ if (IsUnacknowledgedExternalExtension(extension))
+ LogExternalExtensionEvent(extension, EXTERNAL_EXTENSION_UNINSTALLED);
+}
+
+bool ExternalInstallManager::IsUnacknowledgedExternalExtension(
+ const Extension* extension) const {
+ if (!FeatureSwitch::prompt_for_external_extensions()->IsEnabled())
+ return false;
+
+ return (Manifest::IsExternalLocation(extension->location()) &&
+ !extension_prefs_->IsExternalExtensionAcknowledged(extension->id()) &&
+ !(extension_prefs_->GetDisableReasons(extension->id()) &
+ Extension::DISABLE_SIDELOAD_WIPEOUT));
}
void ExternalInstallManager::Observe(
diff --git a/chrome/browser/extensions/external_install_manager.h b/chrome/browser/extensions/external_install_manager.h
index 59e30370..72e32f7 100644
--- a/chrome/browser/extensions/external_install_manager.h
+++ b/chrome/browser/extensions/external_install_manager.h
@@ -12,8 +12,6 @@
#include "content/public/browser/notification_registrar.h"
#include "extensions/browser/extension_registry_observer.h"
-class GlobalErrorService;
-
namespace content {
class BrowserContext;
class NotificationDetails;
@@ -23,28 +21,32 @@
namespace extensions {
class Extension;
class ExtensionRegistry;
+class ExtensionPrefs;
class ExternalInstallError;
class ExternalInstallManager : public ExtensionRegistryObserver,
public content::NotificationObserver {
public:
- explicit ExternalInstallManager(content::BrowserContext* browser_context);
+ ExternalInstallManager(content::BrowserContext* browser_context,
+ bool is_first_run);
virtual ~ExternalInstallManager();
- // Adds a global error informing the user that an external extension was
- // installed. If |is_new_profile| is true, then this error is from the first
- // time our profile checked for new extensions.
- void AddExternalInstallError(const Extension* extension, bool is_new_profile);
-
// Removes the global error, if one existed.
void RemoveExternalInstallError();
// Returns true if there is a global error for an external install.
bool HasExternalInstallError() const;
+ // Checks if there are any new external extensions to notify the user about.
+ void UpdateExternalExtensionAlert();
+
+ // Given a (presumably just-installed) extension id, mark that extension as
+ // acknowledged.
+ void AcknowledgeExternalExtension(const std::string& extension_id);
+
// Returns true if there is a global error with a bubble view for an external
// install. Used for testing.
- bool HasExternalInstallBubble() const;
+ bool HasExternalInstallBubbleForTesting() const;
// Returns the current install error, if one exists.
const ExternalInstallError* error() { return error_.get(); }
@@ -56,15 +58,34 @@
// ExtensionRegistryObserver implementation.
virtual void OnExtensionLoaded(content::BrowserContext* browser_context,
const Extension* extension) OVERRIDE;
+ virtual void OnExtensionInstalled(content::BrowserContext* browser_context,
+ const Extension* extension) OVERRIDE;
+ virtual void OnExtensionUninstalled(content::BrowserContext* browser_context,
+ const Extension* extension) OVERRIDE;
// content::NotificationObserver implementation.
virtual void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
+ // Adds a global error informing the user that an external extension was
+ // installed. If |is_new_profile| is true, then this error is from the first
+ // time our profile checked for new extensions.
+ void AddExternalInstallError(const Extension* extension, bool is_new_profile);
+
+ // Returns true if this extension is an external one that has yet to be
+ // marked as acknowledged.
+ bool IsUnacknowledgedExternalExtension(const Extension* extension) const;
+
// The associated BrowserContext.
content::BrowserContext* browser_context_;
+ // Whether or not this is the first run for the profile.
+ bool is_first_run_;
+
+ // The associated ExtensionPrefs.
+ ExtensionPrefs* extension_prefs_;
+
// The current ExternalInstallError, if one exists.
scoped_ptr<ExternalInstallError> error_;