Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / extension_install_prompt.cc
index 6e94baa..82678d9 100644 (file)
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/extensions/bundle_installer.h"
 #include "chrome/browser/extensions/extension_install_ui.h"
-#include "chrome/browser/extensions/image_loader.h"
+#include "chrome/browser/extensions/extension_util.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/signin/profile_oauth2_token_service.h"
-#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/common/chrome_switches.h"
-#include "chrome/common/extensions/api/identity/oauth2_manifest_handler.h"
-#include "chrome/common/extensions/extension_constants.h"
-#include "chrome/common/extensions/extension_icon_set.h"
-#include "chrome/common/extensions/manifest_handlers/icons_handler.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
+#include "extensions/browser/extension_prefs.h"
+#include "extensions/browser/extension_util.h"
+#include "extensions/browser/image_loader.h"
+#include "extensions/common/constants.h"
 #include "extensions/common/extension.h"
+#include "extensions/common/extension_icon_set.h"
 #include "extensions/common/extension_resource.h"
 #include "extensions/common/feature_switch.h"
 #include "extensions/common/manifest.h"
 #include "extensions/common/manifest_constants.h"
+#include "extensions/common/manifest_handlers/icons_handler.h"
 #include "extensions/common/permissions/permission_message_provider.h"
 #include "extensions/common/permissions/permission_set.h"
 #include "extensions/common/permissions/permissions_data.h"
@@ -53,92 +52,79 @@ using extensions::PermissionSet;
 namespace {
 
 static const int kTitleIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
-  0,  // The regular install prompt depends on what's being installed.
-  IDS_EXTENSION_INLINE_INSTALL_PROMPT_TITLE,
-  IDS_EXTENSION_INSTALL_PROMPT_TITLE,
-  IDS_EXTENSION_RE_ENABLE_PROMPT_TITLE,
-  IDS_EXTENSION_PERMISSIONS_PROMPT_TITLE,
-  IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_TITLE,
-  IDS_EXTENSION_POST_INSTALL_PERMISSIONS_PROMPT_TITLE,
-  IDS_EXTENSION_LAUNCH_APP_PROMPT_TITLE,
+    0,  // The regular install prompt depends on what's being installed.
+    IDS_EXTENSION_INLINE_INSTALL_PROMPT_TITLE,
+    IDS_EXTENSION_INSTALL_PROMPT_TITLE,
+    IDS_EXTENSION_RE_ENABLE_PROMPT_TITLE,
+    IDS_EXTENSION_PERMISSIONS_PROMPT_TITLE,
+    IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_TITLE,
+    IDS_EXTENSION_POST_INSTALL_PERMISSIONS_PROMPT_TITLE,
+    IDS_EXTENSION_LAUNCH_APP_PROMPT_TITLE,
+    0,  // The remote install prompt depends on what's being installed.
 };
 static const int kHeadingIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
-  IDS_EXTENSION_INSTALL_PROMPT_HEADING,
-  0,  // Inline installs use the extension name.
-  0,  // Heading for bundle installs depends on the bundle contents.
-  IDS_EXTENSION_RE_ENABLE_PROMPT_HEADING,
-  IDS_EXTENSION_PERMISSIONS_PROMPT_HEADING,
-  0,  // External installs use different strings for extensions/apps.
-  IDS_EXTENSION_POST_INSTALL_PERMISSIONS_PROMPT_HEADING,
-  IDS_EXTENSION_LAUNCH_APP_PROMPT_HEADING,
+    IDS_EXTENSION_INSTALL_PROMPT_HEADING,
+    0,  // Inline installs use the extension name.
+    0,  // Heading for bundle installs depends on the bundle contents.
+    IDS_EXTENSION_RE_ENABLE_PROMPT_HEADING,
+    IDS_EXTENSION_PERMISSIONS_PROMPT_HEADING,
+    0,  // External installs use different strings for extensions/apps.
+    IDS_EXTENSION_POST_INSTALL_PERMISSIONS_PROMPT_HEADING,
+    IDS_EXTENSION_LAUNCH_APP_PROMPT_HEADING,
+    IDS_EXTENSION_REMOTE_INSTALL_PROMPT_HEADING,
 };
 static const int kButtons[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
-  ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
-  ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
-  ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
-  ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
-  ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
-  ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
-  ui::DIALOG_BUTTON_CANCEL,
-  ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
+    ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
+    ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
+    ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
+    ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
+    ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
+    ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
+    ui::DIALOG_BUTTON_CANCEL,
+    ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
+    ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
 };
 static const int kAcceptButtonIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
-  IDS_EXTENSION_PROMPT_INSTALL_BUTTON,
-  IDS_EXTENSION_PROMPT_INSTALL_BUTTON,
-  IDS_EXTENSION_PROMPT_INSTALL_BUTTON,
-  IDS_EXTENSION_PROMPT_RE_ENABLE_BUTTON,
-  IDS_EXTENSION_PROMPT_PERMISSIONS_BUTTON,
-  0,  // External installs use different strings for extensions/apps.
-  IDS_EXTENSION_PROMPT_PERMISSIONS_CLEAR_RETAINED_FILES_BUTTON,
-  IDS_EXTENSION_PROMPT_LAUNCH_BUTTON,
+    IDS_EXTENSION_PROMPT_INSTALL_BUTTON,
+    IDS_EXTENSION_PROMPT_INSTALL_BUTTON,
+    IDS_EXTENSION_PROMPT_INSTALL_BUTTON,
+    IDS_EXTENSION_PROMPT_RE_ENABLE_BUTTON,
+    IDS_EXTENSION_PROMPT_PERMISSIONS_BUTTON,
+    0,  // External installs use different strings for extensions/apps.
+    IDS_EXTENSION_PROMPT_PERMISSIONS_CLEAR_RETAINED_FILES_BUTTON,
+    IDS_EXTENSION_PROMPT_LAUNCH_BUTTON,
+    IDS_EXTENSION_PROMPT_REMOTE_INSTALL_BUTTON,
 };
 static const int kAbortButtonIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
-  0,  // These all use the platform's default cancel label.
-  0,
-  0,
-  0,
-  IDS_EXTENSION_PROMPT_PERMISSIONS_ABORT_BUTTON,
-  IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_ABORT_BUTTON,
-  IDS_CLOSE,
-  0,  // Platform dependent cancel button.
+    0,  // These all use the platform's default cancel label.
+    0,
+    0,
+    0,
+    IDS_EXTENSION_PROMPT_PERMISSIONS_ABORT_BUTTON,
+    IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_ABORT_BUTTON,
+    IDS_CLOSE,
+    0,  // Platform dependent cancel button.
+    0,
 };
-static const int kPermissionsHeaderIds[
-    ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
-  IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
-  IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
-  IDS_EXTENSION_PROMPT_THESE_WILL_HAVE_ACCESS_TO,
-  IDS_EXTENSION_PROMPT_WILL_NOW_HAVE_ACCESS_TO,
-  IDS_EXTENSION_PROMPT_WANTS_ACCESS_TO,
-  IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
-  IDS_EXTENSION_PROMPT_CAN_ACCESS,
-  IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
+static const int
+    kPermissionsHeaderIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
+        IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
+        IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
+        IDS_EXTENSION_PROMPT_THESE_WILL_HAVE_ACCESS_TO,
+        IDS_EXTENSION_PROMPT_WILL_NOW_HAVE_ACCESS_TO,
+        IDS_EXTENSION_PROMPT_WANTS_ACCESS_TO,
+        IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
+        IDS_EXTENSION_PROMPT_CAN_ACCESS,
+        IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
+        IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
 };
-static const int kOAuthHeaderIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
-  IDS_EXTENSION_PROMPT_OAUTH_HEADER,
-  0,  // Inline installs don't show OAuth permissions.
-  0,  // Bundle installs don't show OAuth permissions.
-  IDS_EXTENSION_PROMPT_OAUTH_REENABLE_HEADER,
-  IDS_EXTENSION_PROMPT_OAUTH_PERMISSIONS_HEADER,
-  0,
-  0,
-  IDS_EXTENSION_PROMPT_OAUTH_HEADER,
-};
-
-// Size of extension icon in top left of dialog.
-const int kIconSize = 69;
-
-// Returns pixel size under maximal scale factor for the icon whose device
-// independent size is |size_in_dip|
-int GetSizeForMaxScaleFactor(int size_in_dip) {
-  return static_cast<int>(size_in_dip * gfx::ImageSkia::GetMaxSupportedScale());
-}
 
 // Returns bitmap for the default icon with size equal to the default icon's
 // pixel size under maximal supported scale factor.
 SkBitmap GetDefaultIconBitmapForMaxScaleFactor(bool is_app) {
   const gfx::ImageSkia& image = is_app ?
-      extensions::IconsInfo::GetDefaultAppIcon() :
-      extensions::IconsInfo::GetDefaultExtensionIcon();
+      extensions::util::GetDefaultAppIcon() :
+      extensions::util::GetDefaultExtensionIcon();
   return image.GetRepresentation(
       gfx::ImageSkia::GetMaxSupportedScale()).sk_bitmap();
 }
@@ -146,30 +132,25 @@ SkBitmap GetDefaultIconBitmapForMaxScaleFactor(bool is_app) {
 // If auto confirm is enabled then posts a task to proceed with or cancel the
 // install and returns true. Otherwise returns false.
 bool AutoConfirmPrompt(ExtensionInstallPrompt::Delegate* delegate) {
-  const CommandLine* cmdline = CommandLine::ForCurrentProcess();
-  if (!cmdline->HasSwitch(switches::kAppsGalleryInstallAutoConfirmForTests))
-    return false;
-  std::string value = cmdline->GetSwitchValueASCII(
-      switches::kAppsGalleryInstallAutoConfirmForTests);
-
-  // We use PostTask instead of calling the delegate directly here, because in
-  // the real implementations it's highly likely the message loop will be
-  // pumping a few times before the user clicks accept or cancel.
-  if (value == "accept") {
-    base::MessageLoop::current()->PostTask(
-        FROM_HERE,
-        base::Bind(&ExtensionInstallPrompt::Delegate::InstallUIProceed,
-                   base::Unretained(delegate)));
-    return true;
-  }
-
-  if (value == "cancel") {
-    base::MessageLoop::current()->PostTask(
-        FROM_HERE,
-        base::Bind(&ExtensionInstallPrompt::Delegate::InstallUIAbort,
-                   base::Unretained(delegate),
-                   true));
-    return true;
+  switch (ExtensionInstallPrompt::g_auto_confirm_for_tests) {
+    case ExtensionInstallPrompt::NONE:
+      return false;
+    // We use PostTask instead of calling the delegate directly here, because in
+    // the real implementations it's highly likely the message loop will be
+    // pumping a few times before the user clicks accept or cancel.
+    case ExtensionInstallPrompt::ACCEPT:
+      base::MessageLoop::current()->PostTask(
+          FROM_HERE,
+          base::Bind(&ExtensionInstallPrompt::Delegate::InstallUIProceed,
+                     base::Unretained(delegate)));
+      return true;
+    case ExtensionInstallPrompt::CANCEL:
+      base::MessageLoop::current()->PostTask(
+          FROM_HERE,
+          base::Bind(&ExtensionInstallPrompt::Delegate::InstallUIAbort,
+                     base::Unretained(delegate),
+                     true));
+      return true;
   }
 
   NOTREACHED();
@@ -186,11 +167,43 @@ gfx::NativeWindow NativeWindowForWebContents(content::WebContents* contents) {
   if (!contents)
     return NULL;
 
-  return contents->GetView()->GetTopLevelNativeWindow();
+  return contents->GetTopLevelNativeWindow();
 }
 
 }  // namespace
 
+// static
+ExtensionInstallPrompt::AutoConfirmForTests
+ExtensionInstallPrompt::g_auto_confirm_for_tests = ExtensionInstallPrompt::NONE;
+
+// This should match the PromptType enum.
+std::string ExtensionInstallPrompt::PromptTypeToString(PromptType type) {
+  switch (type) {
+    case ExtensionInstallPrompt::INSTALL_PROMPT:
+      return "INSTALL_PROMPT";
+    case ExtensionInstallPrompt::INLINE_INSTALL_PROMPT:
+      return "INLINE_INSTALL_PROMPT";
+    case ExtensionInstallPrompt::BUNDLE_INSTALL_PROMPT:
+      return "BUNDLE_INSTALL_PROMPT";
+    case ExtensionInstallPrompt::RE_ENABLE_PROMPT:
+      return "RE_ENABLE_PROMPT";
+    case ExtensionInstallPrompt::PERMISSIONS_PROMPT:
+      return "PERMISSIONS_PROMPT";
+    case ExtensionInstallPrompt::EXTERNAL_INSTALL_PROMPT:
+      return "EXTERNAL_INSTALL_PROMPT";
+    case ExtensionInstallPrompt::POST_INSTALL_PERMISSIONS_PROMPT:
+      return "POST_INSTALL_PERMISSIONS_PROMPT";
+    case ExtensionInstallPrompt::LAUNCH_PROMPT:
+      return "LAUNCH_PROMPT";
+    case ExtensionInstallPrompt::REMOTE_INSTALL_PROMPT:
+      return "REMOTE_INSTALL_PROMPT";
+    case ExtensionInstallPrompt::UNSET_PROMPT_TYPE:
+    case ExtensionInstallPrompt::NUM_PROMPT_TYPES:
+      break;
+  }
+  return "OTHER";
+}
+
 ExtensionInstallPrompt::Prompt::Prompt(PromptType type)
     : type_(type),
       is_showing_details_for_retained_files_(false),
@@ -198,7 +211,8 @@ ExtensionInstallPrompt::Prompt::Prompt(PromptType type)
       bundle_(NULL),
       average_rating_(0.0),
       rating_count_(0),
-      show_user_count_(false) {
+      show_user_count_(false),
+      has_webstore_data_(false) {
 }
 
 ExtensionInstallPrompt::Prompt::~Prompt() {
@@ -225,44 +239,23 @@ void ExtensionInstallPrompt::Prompt::SetIsShowingDetails(
     case PERMISSIONS_DETAILS:
       is_showing_details_for_permissions_[index] = is_showing_details;
       break;
-    case OAUTH_DETAILS:
-      is_showing_details_for_oauth_[index] = is_showing_details;
-      break;
     case RETAINED_FILES_DETAILS:
       is_showing_details_for_retained_files_ = is_showing_details;
       break;
   }
 }
 
-void ExtensionInstallPrompt::Prompt::SetOAuthIssueAdvice(
-    const IssueAdviceInfo& issue_advice) {
-  is_showing_details_for_oauth_.clear();
-  for (size_t i = 0; i < issue_advice.size(); ++i)
-    is_showing_details_for_oauth_.push_back(false);
-
-  oauth_issue_advice_ = issue_advice;
-}
-
-void ExtensionInstallPrompt::Prompt::SetUserNameFromProfile(Profile* profile) {
-  // |profile| can be NULL in unit tests.
-  if (profile) {
-    oauth_user_name_ = base::UTF8ToUTF16(profile->GetPrefs()->GetString(
-        prefs::kGoogleServicesUsername));
-  } else {
-    oauth_user_name_.clear();
-  }
-}
-
-void ExtensionInstallPrompt::Prompt::SetInlineInstallWebstoreData(
+void ExtensionInstallPrompt::Prompt::SetWebstoreData(
     const std::string& localized_user_count,
     bool show_user_count,
     double average_rating,
     int rating_count) {
-  CHECK_EQ(INLINE_INSTALL_PROMPT, type_);
+  CHECK(type_ == INLINE_INSTALL_PROMPT || type_ == EXTERNAL_INSTALL_PROMPT);
   localized_user_count_ = localized_user_count;
   show_user_count_ = show_user_count;
   average_rating_ = average_rating;
   rating_count_ = rating_count;
+  has_webstore_data_ = true;
 }
 
 base::string16 ExtensionInstallPrompt::Prompt::GetDialogTitle() const {
@@ -278,6 +271,11 @@ base::string16 ExtensionInstallPrompt::Prompt::GetDialogTitle() const {
   } else if (type_ == EXTERNAL_INSTALL_PROMPT) {
     return l10n_util::GetStringFUTF16(
         resource_id, base::UTF8ToUTF16(extension_->name()));
+  } else if (type_ == REMOTE_INSTALL_PROMPT) {
+    if (extension_->is_app())
+      resource_id = IDS_EXTENSION_REMOTE_INSTALL_APP_PROMPT_TITLE;
+    else
+      resource_id = IDS_EXTENSION_REMOTE_INSTALL_EXTENSION_PROMPT_TITLE;
   }
 
   return l10n_util::GetStringUTF16(resource_id);
@@ -360,10 +358,6 @@ base::string16 ExtensionInstallPrompt::Prompt::GetPermissionsHeading() const {
   return l10n_util::GetStringUTF16(kPermissionsHeaderIds[type_]);
 }
 
-base::string16 ExtensionInstallPrompt::Prompt::GetOAuthHeading() const {
-  return l10n_util::GetStringFUTF16(kOAuthHeaderIds[type_], oauth_user_name_);
-}
-
 base::string16 ExtensionInstallPrompt::Prompt::GetRetainedFilesHeading() const {
   const int kRetainedFilesMessageIDs[6] = {
       IDS_EXTENSION_PROMPT_RETAINED_FILES_DEFAULT,
@@ -387,7 +381,7 @@ bool ExtensionInstallPrompt::Prompt::ShouldShowPermissions() const {
 void ExtensionInstallPrompt::Prompt::AppendRatingStars(
     StarAppender appender, void* data) const {
   CHECK(appender);
-  CHECK_EQ(INLINE_INSTALL_PROMPT, type_);
+  CHECK(type_ == INLINE_INSTALL_PROMPT || type_ == EXTERNAL_INSTALL_PROMPT);
   int rating_integer = floor(average_rating_);
   double rating_fractional = average_rating_ - rating_integer;
 
@@ -414,13 +408,13 @@ void ExtensionInstallPrompt::Prompt::AppendRatingStars(
 }
 
 base::string16 ExtensionInstallPrompt::Prompt::GetRatingCount() const {
-  CHECK_EQ(INLINE_INSTALL_PROMPT, type_);
+  CHECK(type_ == INLINE_INSTALL_PROMPT || type_ == EXTERNAL_INSTALL_PROMPT);
   return l10n_util::GetStringFUTF16(IDS_EXTENSION_RATING_COUNT,
                                     base::IntToString16(rating_count_));
 }
 
 base::string16 ExtensionInstallPrompt::Prompt::GetUserCount() const {
-  CHECK_EQ(INLINE_INSTALL_PROMPT, type_);
+  CHECK(type_ == INLINE_INSTALL_PROMPT || type_ == EXTERNAL_INSTALL_PROMPT);
 
   if (show_user_count_) {
     return l10n_util::GetStringFUTF16(IDS_EXTENSION_USER_COUNT,
@@ -455,25 +449,12 @@ bool ExtensionInstallPrompt::Prompt::GetIsShowingDetails(
     case PERMISSIONS_DETAILS:
       CHECK_LT(index, is_showing_details_for_permissions_.size());
       return is_showing_details_for_permissions_[index];
-    case OAUTH_DETAILS:
-      CHECK_LT(index, is_showing_details_for_oauth_.size());
-      return is_showing_details_for_oauth_[index];
     case RETAINED_FILES_DETAILS:
       return is_showing_details_for_retained_files_;
   }
   return false;
 }
 
-size_t ExtensionInstallPrompt::Prompt::GetOAuthIssueCount() const {
-  return oauth_issue_advice_.size();
-}
-
-const IssueAdviceInfoEntry& ExtensionInstallPrompt::Prompt::GetOAuthIssue(
-    size_t index) const {
-  CHECK_LT(index, oauth_issue_advice_.size());
-  return oauth_issue_advice_[index];
-}
-
 size_t ExtensionInstallPrompt::Prompt::GetRetainedFileCount() const {
   return retained_files_.size();
 }
@@ -533,32 +514,25 @@ scoped_refptr<Extension>
       error);
 }
 
-ExtensionInstallPrompt::ExtensionInstallPrompt(
-    content::WebContents* contents)
-    : OAuth2TokenService::Consumer("extensions_install"),
-      record_oauth2_grant_(false),
-      ui_loop_(base::MessageLoop::current()),
+ExtensionInstallPrompt::ExtensionInstallPrompt(content::WebContents* contents)
+    : ui_loop_(base::MessageLoop::current()),
       extension_(NULL),
+      bundle_(NULL),
       install_ui_(ExtensionInstallUI::Create(ProfileForWebContents(contents))),
       show_params_(contents),
-      delegate_(NULL),
-      prompt_(UNSET_PROMPT_TYPE) {
-  prompt_.SetUserNameFromProfile(install_ui_->profile());
+      delegate_(NULL) {
 }
 
 ExtensionInstallPrompt::ExtensionInstallPrompt(
     Profile* profile,
     gfx::NativeWindow native_window,
     content::PageNavigator* navigator)
-    : OAuth2TokenService::Consumer("extensions_install"),
-      record_oauth2_grant_(false),
-      ui_loop_(base::MessageLoop::current()),
+    : ui_loop_(base::MessageLoop::current()),
       extension_(NULL),
+      bundle_(NULL),
       install_ui_(ExtensionInstallUI::Create(profile)),
       show_params_(native_window, navigator),
-      delegate_(NULL),
-      prompt_(UNSET_PROMPT_TYPE) {
-  prompt_.SetUserNameFromProfile(install_ui_->profile());
+      delegate_(NULL) {
 }
 
 ExtensionInstallPrompt::~ExtensionInstallPrompt() {
@@ -571,7 +545,7 @@ void ExtensionInstallPrompt::ConfirmBundleInstall(
   bundle_ = bundle;
   permissions_ = permissions;
   delegate_ = bundle;
-  prompt_.set_type(BUNDLE_INSTALL_PROMPT);
+  prompt_ = new Prompt(BUNDLE_INSTALL_PROMPT);
 
   ShowConfirmation();
 }
@@ -580,10 +554,10 @@ void ExtensionInstallPrompt::ConfirmStandaloneInstall(
     Delegate* delegate,
     const Extension* extension,
     SkBitmap* icon,
-    const ExtensionInstallPrompt::Prompt& prompt) {
+    scoped_refptr<Prompt> prompt) {
   DCHECK(ui_loop_ == base::MessageLoop::current());
   extension_ = extension;
-  permissions_ = extension->GetActivePermissions();
+  permissions_ = extension->permissions_data()->active_permissions();
   delegate_ = delegate;
   prompt_ = prompt;
 
@@ -609,9 +583,9 @@ void ExtensionInstallPrompt::ConfirmInstall(
     const ShowDialogCallback& show_dialog_callback) {
   DCHECK(ui_loop_ == base::MessageLoop::current());
   extension_ = extension;
-  permissions_ = extension->GetActivePermissions();
+  permissions_ = extension->permissions_data()->active_permissions();
   delegate_ = delegate;
-  prompt_.set_type(INSTALL_PROMPT);
+  prompt_ = new Prompt(INSTALL_PROMPT);
   show_dialog_callback_ = show_dialog_callback;
 
   // We special-case themes to not show any confirm UI. Instead they are
@@ -636,10 +610,23 @@ void ExtensionInstallPrompt::ConfirmReEnable(Delegate* delegate,
                                              const Extension* extension) {
   DCHECK(ui_loop_ == base::MessageLoop::current());
   extension_ = extension;
-  permissions_ = extension->GetActivePermissions();
+  permissions_ = extension->permissions_data()->active_permissions();
   delegate_ = delegate;
-  prompt_.set_type(extension->is_ephemeral() ? LAUNCH_PROMPT :
-                                               RE_ENABLE_PROMPT);
+  bool is_remote_install =
+      install_ui_->profile() &&
+      extensions::ExtensionPrefs::Get(install_ui_->profile())->HasDisableReason(
+          extension->id(), extensions::Extension::DISABLE_REMOTE_INSTALL);
+  bool is_ephemeral =
+      extensions::util::IsEphemeralApp(extension->id(), install_ui_->profile());
+
+  PromptType type = UNSET_PROMPT_TYPE;
+  if (is_ephemeral)
+    type = LAUNCH_PROMPT;
+  else if (is_remote_install)
+    type = REMOTE_INSTALL_PROMPT;
+  else
+    type = RE_ENABLE_PROMPT;
+  prompt_ = new Prompt(type);
 
   LoadImageIfNeeded();
 }
@@ -647,12 +634,13 @@ void ExtensionInstallPrompt::ConfirmReEnable(Delegate* delegate,
 void ExtensionInstallPrompt::ConfirmExternalInstall(
     Delegate* delegate,
     const Extension* extension,
-    const ShowDialogCallback& show_dialog_callback) {
+    const ShowDialogCallback& show_dialog_callback,
+    scoped_refptr<Prompt> prompt) {
   DCHECK(ui_loop_ == base::MessageLoop::current());
   extension_ = extension;
-  permissions_ = extension->GetActivePermissions();
+  permissions_ = extension->permissions_data()->active_permissions();
   delegate_ = delegate;
-  prompt_.set_type(EXTERNAL_INSTALL_PROMPT);
+  prompt_ = prompt;
   show_dialog_callback_ = show_dialog_callback;
 
   LoadImageIfNeeded();
@@ -666,22 +654,7 @@ void ExtensionInstallPrompt::ConfirmPermissions(
   extension_ = extension;
   permissions_ = permissions;
   delegate_ = delegate;
-  prompt_.set_type(PERMISSIONS_PROMPT);
-
-  LoadImageIfNeeded();
-}
-
-void ExtensionInstallPrompt::ConfirmIssueAdvice(
-    Delegate* delegate,
-    const Extension* extension,
-    const IssueAdviceInfo& issue_advice) {
-  DCHECK(ui_loop_ == base::MessageLoop::current());
-  extension_ = extension;
-  delegate_ = delegate;
-  prompt_.set_type(PERMISSIONS_PROMPT);
-
-  record_oauth2_grant_ = true;
-  prompt_.SetOAuthIssueAdvice(issue_advice);
+  prompt_ = new Prompt(PERMISSIONS_PROMPT);
 
   LoadImageIfNeeded();
 }
@@ -692,10 +665,10 @@ void ExtensionInstallPrompt::ReviewPermissions(
     const std::vector<base::FilePath>& retained_file_paths) {
   DCHECK(ui_loop_ == base::MessageLoop::current());
   extension_ = extension;
-  permissions_ = extension->GetActivePermissions();
-  prompt_.set_retained_files(retained_file_paths);
+  permissions_ = extension->permissions_data()->active_permissions();
+  prompt_ = new Prompt(POST_INSTALL_PERMISSIONS_PROMPT);
+  prompt_->set_retained_files(retained_file_paths);
   delegate_ = delegate;
-  prompt_.set_type(POST_INSTALL_PERMISSIONS_PROMPT);
 
   LoadImageIfNeeded();
 }
@@ -739,97 +712,62 @@ void ExtensionInstallPrompt::LoadImageIfNeeded() {
     return;
   }
 
-  // Load the image asynchronously. For the response, check OnImageLoaded.
   extensions::ExtensionResource image = extensions::IconsInfo::GetIconResource(
       extension_,
       extension_misc::EXTENSION_ICON_LARGE,
       ExtensionIconSet::MATCH_BIGGER);
-  // Load the icon whose pixel size is large enough to be displayed under
-  // maximal supported scale factor. UI code will scale the icon down if needed.
-  // TODO(tbarzic): We should use IconImage here and load the required bitmap
-  //     lazily.
-  int pixel_size = GetSizeForMaxScaleFactor(kIconSize);
-  extensions::ImageLoader::Get(install_ui_->profile())->LoadImageAsync(
-      extension_, image, gfx::Size(pixel_size, pixel_size),
-      base::Bind(&ExtensionInstallPrompt::OnImageLoaded, AsWeakPtr()));
-}
 
-void ExtensionInstallPrompt::OnGetTokenSuccess(
-    const OAuth2TokenService::Request* request,
-    const std::string& access_token,
-    const base::Time& expiration_time) {
-  DCHECK_EQ(login_token_request_.get(), request);
-  login_token_request_.reset();
-
-  const extensions::OAuth2Info& oauth2_info =
-      extensions::OAuth2Info::GetOAuth2Info(extension_);
-
-  token_flow_.reset(new OAuth2MintTokenFlow(
-      install_ui_->profile()->GetRequestContext(),
-      this,
-      OAuth2MintTokenFlow::Parameters(
-          access_token,
-          extension_->id(),
-          oauth2_info.client_id,
-          oauth2_info.scopes,
-          OAuth2MintTokenFlow::MODE_ISSUE_ADVICE)));
-  token_flow_->Start();
-}
-
-void ExtensionInstallPrompt::OnGetTokenFailure(
-    const OAuth2TokenService::Request* request,
-    const GoogleServiceAuthError& error) {
-  DCHECK_EQ(login_token_request_.get(), request);
-  login_token_request_.reset();
-  ShowConfirmation();
-}
-
-void ExtensionInstallPrompt::OnIssueAdviceSuccess(
-    const IssueAdviceInfo& advice_info) {
-  prompt_.SetOAuthIssueAdvice(advice_info);
-  record_oauth2_grant_ = true;
-  ShowConfirmation();
-}
-
-void ExtensionInstallPrompt::OnMintTokenFailure(
-    const GoogleServiceAuthError& error) {
-  ShowConfirmation();
+  // Load the image asynchronously. The response will be sent to OnImageLoaded.
+  extensions::ImageLoader* loader =
+      extensions::ImageLoader::Get(install_ui_->profile());
+
+  std::vector<extensions::ImageLoader::ImageRepresentation> images_list;
+  images_list.push_back(extensions::ImageLoader::ImageRepresentation(
+      image,
+      extensions::ImageLoader::ImageRepresentation::NEVER_RESIZE,
+      gfx::Size(),
+      ui::SCALE_FACTOR_100P));
+  loader->LoadImagesAsync(
+      extension_,
+      images_list,
+      base::Bind(&ExtensionInstallPrompt::OnImageLoaded, AsWeakPtr()));
 }
 
 void ExtensionInstallPrompt::ShowConfirmation() {
-  if (prompt_.type() == INSTALL_PROMPT)
-    prompt_.set_experiment(ExtensionInstallPromptExperiment::Find());
+  if (prompt_->type() == INSTALL_PROMPT)
+    prompt_->set_experiment(ExtensionInstallPromptExperiment::Find());
   else
-    prompt_.set_experiment(ExtensionInstallPromptExperiment::ControlGroup());
+    prompt_->set_experiment(ExtensionInstallPromptExperiment::ControlGroup());
 
   if (permissions_.get() &&
       (!extension_ ||
        !extensions::PermissionsData::ShouldSkipPermissionWarnings(
-           extension_))) {
-    Manifest::Type extension_type = extension_ ?
-        extension_->GetType() : Manifest::TYPE_UNKNOWN;
-    prompt_.SetPermissions(
-        extensions::PermissionMessageProvider::Get()->
-            GetWarningMessages(permissions_, extension_type));
-    prompt_.SetPermissionsDetails(
-        extensions::PermissionMessageProvider::Get()->
-            GetWarningMessagesDetails(permissions_, extension_type));
+           extension_->id()))) {
+    Manifest::Type type =
+        extension_ ? extension_->GetType() : Manifest::TYPE_UNKNOWN;
+    const extensions::PermissionMessageProvider* message_provider =
+        extensions::PermissionMessageProvider::Get();
+    prompt_->SetPermissions(
+        message_provider->GetWarningMessages(permissions_, type));
+    prompt_->SetPermissionsDetails(
+        message_provider->GetWarningMessagesDetails(permissions_, type));
   }
 
-  switch (prompt_.type()) {
+  switch (prompt_->type()) {
     case PERMISSIONS_PROMPT:
     case RE_ENABLE_PROMPT:
     case INLINE_INSTALL_PROMPT:
     case EXTERNAL_INSTALL_PROMPT:
     case INSTALL_PROMPT:
     case LAUNCH_PROMPT:
-    case POST_INSTALL_PERMISSIONS_PROMPT: {
-      prompt_.set_extension(extension_);
-      prompt_.set_icon(gfx::Image::CreateFrom1xBitmap(icon_));
+    case POST_INSTALL_PERMISSIONS_PROMPT:
+    case REMOTE_INSTALL_PROMPT: {
+      prompt_->set_extension(extension_);
+      prompt_->set_icon(gfx::Image::CreateFrom1xBitmap(icon_));
       break;
     }
     case BUNDLE_INSTALL_PROMPT: {
-      prompt_.set_bundle(bundle_);
+      prompt_->set_bundle(bundle_);
       break;
     }
     default: