Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3396)

Unified Diff: chrome/browser/extensions/external_install_ui.cc

Issue 11150002: New post-sideload UI: (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixed unit tests, disable on chromeos, feature switch Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/external_install_ui.cc
diff --git a/chrome/browser/extensions/external_install_ui.cc b/chrome/browser/extensions/external_install_ui.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b8f66831c73425374d18c7f10c66fdbb5769d58c
--- /dev/null
+++ b/chrome/browser/extensions/external_install_ui.cc
@@ -0,0 +1,299 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/external_install_ui.h"
+
+#include <string>
+
+#include "base/bind.h"
+#include "base/lazy_instance.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop.h"
+#include "base/metrics/histogram.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/extensions/extension_install_prompt.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_uninstall_dialog.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/global_error/global_error.h"
+#include "chrome/browser/ui/global_error/global_error_service.h"
+#include "chrome/browser/ui/global_error/global_error_service_factory.h"
+#include "chrome/common/chrome_notification_types.h"
+#include "chrome/common/extensions/extension.h"
+#include "content/public/browser/notification_details.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
+#include "content/public/browser/notification_source.h"
+#include "grit/chromium_strings.h"
+#include "grit/generated_resources.h"
+#include "grit/theme_resources.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace extensions {
+
+static const int kMenuCommandId = IDC_EXTERNAL_EXTENSION_ALERT;
+
+// ExternalInstallDialogDelegate --------------------------------------------
+
+// TODO(mpcomplete): Get rid of the refcounting on this class, or document
+// why it's necessary. Will do after refactoring to merge back with
+// ExtensionDisabledDialogDelegate.
+class ExternalInstallDialogDelegate
+ : public ExtensionInstallPrompt::Delegate,
+ public base::RefCountedThreadSafe<ExternalInstallDialogDelegate> {
Jeffrey Yasskin 2012/10/17 07:08:56 Ah, ok.
+ public:
+ ExternalInstallDialogDelegate(Browser* browser,
+ ExtensionService* service,
+ const Extension* extension);
+
+ private:
+ friend class base::RefCountedThreadSafe<ExternalInstallDialogDelegate>;
+
+ virtual ~ExternalInstallDialogDelegate();
+
+ // ExtensionInstallPrompt::Delegate:
+ virtual void InstallUIProceed() OVERRIDE;
+ virtual void InstallUIAbort(bool user_initiated) OVERRIDE;
+
+ // The UI for showing the install dialog when enabling.
+ scoped_ptr<ExtensionInstallPrompt> install_ui_;
+
+ ExtensionService* service_;
+ const Extension* extension_;
+};
+
+ExternalInstallDialogDelegate::ExternalInstallDialogDelegate(
+ Browser* browser,
+ ExtensionService* service,
+ const Extension* extension)
+ : service_(service), extension_(extension) {
+ AddRef(); // Balanced in Proceed or Abort.
+
+ install_ui_.reset(chrome::CreateExtensionInstallPromptWithBrowser(browser));
+ install_ui_->ConfirmExternalInstall(this, extension_);
+}
+
+ExternalInstallDialogDelegate::~ExternalInstallDialogDelegate() {
+}
+
+void ExternalInstallDialogDelegate::InstallUIProceed() {
+ service_->GrantPermissionsAndEnableExtension(
+ extension_, install_ui_->record_oauth2_grant());
+ Release();
+}
+
+void ExternalInstallDialogDelegate::InstallUIAbort(bool user_initiated) {
+ service_->UninstallExtension(extension_->id(), false, NULL);
+ Release();
+}
+
+static void ShowExternalInstallDialog(ExtensionService* service,
+ Browser* browser,
+ const Extension* extension) {
+ // This object manages its own lifetime.
+ new ExternalInstallDialogDelegate(browser, service, extension);
+}
+
+// ExternalInstallGlobalError -----------------------------------------------
+
+class ExternalInstallGlobalError : public GlobalError,
+ public content::NotificationObserver {
+ public:
+ ExternalInstallGlobalError(ExtensionService* service,
+ const Extension* extension);
+ virtual ~ExternalInstallGlobalError();
+
+ const Extension* extension() const { return extension_; }
+
+ // GlobalError implementation.
+ virtual bool HasBadge() OVERRIDE;
+ virtual int GetBadgeResourceID() OVERRIDE;
+ virtual bool HasMenuItem() OVERRIDE;
+ virtual int MenuItemCommandID() OVERRIDE;
+ virtual string16 MenuItemLabel() OVERRIDE;
+ virtual int MenuItemIconResourceID() OVERRIDE;
+ virtual void ExecuteMenuItem(Browser* browser) OVERRIDE;
+ virtual bool HasBubbleView() OVERRIDE;
+ virtual string16 GetBubbleViewTitle() OVERRIDE;
+ virtual string16 GetBubbleViewMessage() OVERRIDE;
+ virtual string16 GetBubbleViewAcceptButtonLabel() OVERRIDE;
+ virtual string16 GetBubbleViewCancelButtonLabel() OVERRIDE;
+ virtual void OnBubbleViewDidClose(Browser* browser) OVERRIDE;
+ virtual void BubbleViewAcceptButtonPressed(Browser* browser) OVERRIDE;
+ virtual void BubbleViewCancelButtonPressed(Browser* browser) OVERRIDE;
+
+ // content::NotificationObserver implementation.
+ virtual void Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) OVERRIDE;
+
+ private:
+ ExtensionService* service_;
+ const Extension* extension_;
+
+ // How the user responded to the error; used for metrics.
+ enum UserResponse {
+ IGNORED,
+ REENABLE,
+ UNINSTALL,
+ USER_RESPONSE_BUCKET_BOUNDARY
+ };
+ UserResponse user_response_;
+
+ content::NotificationRegistrar registrar_;
+};
+
+ExternalInstallGlobalError::ExternalInstallGlobalError(
+ ExtensionService* service,
+ const Extension* extension)
+ : service_(service),
+ extension_(extension),
+ user_response_(IGNORED) {
+ registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
+ content::Source<Profile>(service->profile()));
+ registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
+ content::Source<Profile>(service->profile()));
+}
+
+ExternalInstallGlobalError::~ExternalInstallGlobalError() {
+ HISTOGRAM_ENUMERATION("Extensions.ExternalInstallUIUserResponse",
+ user_response_, USER_RESPONSE_BUCKET_BOUNDARY);
+}
+
+bool ExternalInstallGlobalError::HasBadge() {
+ return true;
+}
+
+int ExternalInstallGlobalError::GetBadgeResourceID() {
+ return IDR_UPDATE_BADGE_EXTENSION;
+}
+
+bool ExternalInstallGlobalError::HasMenuItem() {
+ return true;
+}
+
+int ExternalInstallGlobalError::MenuItemCommandID() {
+ return kMenuCommandId;
+}
+
+int ExternalInstallGlobalError::MenuItemIconResourceID() {
+ return IDR_UPDATE_MENU_EXTENSION;
+}
+
+string16 ExternalInstallGlobalError::MenuItemLabel() {
+ return l10n_util::GetStringFUTF16(IDS_EXTENSION_EXTERNAL_INSTALL_ALERT,
+ UTF8ToUTF16(extension_->name()));
+}
+
+void ExternalInstallGlobalError::ExecuteMenuItem(Browser* browser) {
+ ShowExternalInstallDialog(service_, browser, extension_);
+}
+
+bool ExternalInstallGlobalError::HasBubbleView() {
+ return false;
+}
+
+string16 ExternalInstallGlobalError::GetBubbleViewTitle() {
+ return string16();
+}
+
+string16 ExternalInstallGlobalError::GetBubbleViewMessage() {
+ return string16();
+}
+
+string16 ExternalInstallGlobalError::GetBubbleViewAcceptButtonLabel() {
+ return string16();
+}
+
+string16 ExternalInstallGlobalError::GetBubbleViewCancelButtonLabel() {
+ return string16();
+}
+
+void ExternalInstallGlobalError::OnBubbleViewDidClose(Browser* browser) {
+ NOTREACHED();
+}
+
+void ExternalInstallGlobalError::BubbleViewAcceptButtonPressed(
+ Browser* browser) {
+ NOTREACHED();
+}
+
+void ExternalInstallGlobalError::BubbleViewCancelButtonPressed(
+ Browser* browser) {
+ NOTREACHED();
+}
+
+void ExternalInstallGlobalError::Observe(
+ int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ const Extension* extension = NULL;
+ // The error is invalidated if the extension has been reloaded
+ // or unloaded.
+ if (type == chrome::NOTIFICATION_EXTENSION_LOADED) {
+ extension = content::Details<const Extension>(details).ptr();
+ } else {
+ DCHECK_EQ(chrome::NOTIFICATION_EXTENSION_UNLOADED, type);
+ extensions::UnloadedExtensionInfo* info =
+ content::Details<extensions::UnloadedExtensionInfo>(details).ptr();
+ extension = info->extension;
+ }
+ if (extension == extension_) {
+ // We only check for new external installs on startup, so these
+ // notifications are guaranteed to be user-initiated.
+ if (type == chrome::NOTIFICATION_EXTENSION_LOADED)
+ user_response_ = REENABLE;
+ else if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED)
+ user_response_ = UNINSTALL;
+
+ // This call deletes us (via Add/RemoveExternalInstallError).
+ service_->AcknowledgeExternalExtension(extension_->id());
+ }
+}
+
+// Public interface ---------------------------------------------------------
+
+bool AddExternalInstallError(ExtensionService* service,
+ const Extension* extension) {
+ GlobalErrorService* error_service =
+ GlobalErrorServiceFactory::GetForProfile(service->profile());
+ GlobalError* error = error_service->GetGlobalErrorByMenuItemCommandID(
+ kMenuCommandId);
+ if (error) {
+ if (static_cast<ExternalInstallGlobalError*>(error)->extension() ==
+ extension) {
+ return false; // already showing
+ }
+ error_service->RemoveGlobalError(error);
+ delete error;
+ }
+
+ error_service->AddGlobalError(
+ new ExternalInstallGlobalError(service, extension));
+ return true;
+}
+
+void RemoveExternalInstallError(ExtensionService* service) {
+ GlobalErrorService* error_service =
+ GlobalErrorServiceFactory::GetForProfile(service->profile());
+ GlobalError* error = error_service->GetGlobalErrorByMenuItemCommandID(
+ kMenuCommandId);
+ if (error) {
+ error_service->RemoveGlobalError(error);
+ delete error;
+ }
+}
+
+bool HasExternalInstallError(ExtensionService* service) {
+ GlobalErrorService* error_service =
+ GlobalErrorServiceFactory::GetForProfile(service->profile());
+ GlobalError* error = error_service->GetGlobalErrorByMenuItemCommandID(
+ kMenuCommandId);
+ return !!error;
+}
+
+} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698