Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / extension_install_prompt.cc
index 82678d9..6edea03 100644 (file)
 #include "chrome/browser/extensions/bundle_installer.h"
 #include "chrome/browser/extensions/extension_install_ui.h"
 #include "chrome/browser/extensions/extension_util.h"
+#include "chrome/browser/extensions/permissions_updater.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
+#include "chrome/grit/chromium_strings.h"
+#include "chrome/grit/generated_resources.h"
 #include "content/public/browser/web_contents.h"
 #include "extensions/browser/extension_prefs.h"
 #include "extensions/browser/extension_util.h"
@@ -37,8 +40,6 @@
 #include "extensions/common/permissions/permission_set.h"
 #include "extensions/common/permissions/permissions_data.h"
 #include "extensions/common/url_pattern.h"
-#include "grit/chromium_strings.h"
-#include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
@@ -51,6 +52,12 @@ using extensions::PermissionSet;
 
 namespace {
 
+bool AllowWebstoreData(ExtensionInstallPrompt::PromptType type) {
+  return type == ExtensionInstallPrompt::INLINE_INSTALL_PROMPT ||
+         type == ExtensionInstallPrompt::EXTERNAL_INSTALL_PROMPT ||
+         type == ExtensionInstallPrompt::REPAIR_PROMPT;
+}
+
 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,
@@ -61,6 +68,7 @@ static const int kTitleIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
     IDS_EXTENSION_POST_INSTALL_PERMISSIONS_PROMPT_TITLE,
     IDS_EXTENSION_LAUNCH_APP_PROMPT_TITLE,
     0,  // The remote install prompt depends on what's being installed.
+    0,  // The repair install prompt depends on what's being installed.
 };
 static const int kHeadingIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
     IDS_EXTENSION_INSTALL_PROMPT_HEADING,
@@ -72,6 +80,7 @@ static const int kHeadingIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
     IDS_EXTENSION_POST_INSTALL_PERMISSIONS_PROMPT_HEADING,
     IDS_EXTENSION_LAUNCH_APP_PROMPT_HEADING,
     IDS_EXTENSION_REMOTE_INSTALL_PROMPT_HEADING,
+    IDS_EXTENSION_REPAIR_PROMPT_HEADING
 };
 static const int kButtons[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
     ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL,
@@ -83,6 +92,7 @@ static const int kButtons[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
     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,
 };
 static const int kAcceptButtonIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
     IDS_EXTENSION_PROMPT_INSTALL_BUTTON,
@@ -94,6 +104,7 @@ static const int kAcceptButtonIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
     IDS_EXTENSION_PROMPT_PERMISSIONS_CLEAR_RETAINED_FILES_BUTTON,
     IDS_EXTENSION_PROMPT_LAUNCH_BUTTON,
     IDS_EXTENSION_PROMPT_REMOTE_INSTALL_BUTTON,
+    IDS_EXTENSION_PROMPT_REPAIR_BUTTON,
 };
 static const int kAbortButtonIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
     0,  // These all use the platform's default cancel label.
@@ -105,6 +116,7 @@ static const int kAbortButtonIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
     IDS_CLOSE,
     0,  // Platform dependent cancel button.
     0,
+    0,
 };
 static const int
     kPermissionsHeaderIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
@@ -117,6 +129,7 @@ static const int
         IDS_EXTENSION_PROMPT_CAN_ACCESS,
         IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
         IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO,
+        IDS_EXTENSION_PROMPT_CAN_ACCESS,
 };
 
 // Returns bitmap for the default icon with size equal to the default icon's
@@ -172,6 +185,13 @@ gfx::NativeWindow NativeWindowForWebContents(content::WebContents* contents) {
 
 }  // namespace
 
+ExtensionInstallPrompt::Prompt::InstallPromptPermissions::
+    InstallPromptPermissions() {
+}
+ExtensionInstallPrompt::Prompt::InstallPromptPermissions::
+    ~InstallPromptPermissions() {
+}
+
 // static
 ExtensionInstallPrompt::AutoConfirmForTests
 ExtensionInstallPrompt::g_auto_confirm_for_tests = ExtensionInstallPrompt::NONE;
@@ -197,6 +217,8 @@ std::string ExtensionInstallPrompt::PromptTypeToString(PromptType type) {
       return "LAUNCH_PROMPT";
     case ExtensionInstallPrompt::REMOTE_INSTALL_PROMPT:
       return "REMOTE_INSTALL_PROMPT";
+    case ExtensionInstallPrompt::REPAIR_PROMPT:
+      return "REPAIR_PROMPT";
     case ExtensionInstallPrompt::UNSET_PROMPT_TYPE:
     case ExtensionInstallPrompt::NUM_PROMPT_TYPES:
       break;
@@ -219,16 +241,20 @@ ExtensionInstallPrompt::Prompt::~Prompt() {
 }
 
 void ExtensionInstallPrompt::Prompt::SetPermissions(
-    const std::vector<base::string16>& permissions) {
-  permissions_ = permissions;
+    const std::vector<base::string16>& permissions,
+    PermissionsType permissions_type) {
+  GetPermissionsForType(permissions_type).permissions = permissions;
 }
 
 void ExtensionInstallPrompt::Prompt::SetPermissionsDetails(
-    const std::vector<base::string16>& details) {
-  details_ = details;
-  is_showing_details_for_permissions_.clear();
-  for (size_t i = 0; i < details.size(); ++i)
-    is_showing_details_for_permissions_.push_back(false);
+    const std::vector<base::string16>& details,
+    PermissionsType permissions_type) {
+  InstallPromptPermissions& install_permissions =
+      GetPermissionsForType(permissions_type);
+  install_permissions.details = details;
+  install_permissions.is_showing_details.clear();
+  install_permissions.is_showing_details.insert(
+      install_permissions.is_showing_details.begin(), details.size(), false);
 }
 
 void ExtensionInstallPrompt::Prompt::SetIsShowingDetails(
@@ -237,7 +263,11 @@ void ExtensionInstallPrompt::Prompt::SetIsShowingDetails(
     bool is_showing_details) {
   switch (type) {
     case PERMISSIONS_DETAILS:
-      is_showing_details_for_permissions_[index] = is_showing_details;
+      prompt_permissions_.is_showing_details[index] = is_showing_details;
+      break;
+    case WITHHELD_PERMISSIONS_DETAILS:
+      withheld_prompt_permissions_.is_showing_details[index] =
+          is_showing_details;
       break;
     case RETAINED_FILES_DETAILS:
       is_showing_details_for_retained_files_ = is_showing_details;
@@ -250,7 +280,7 @@ void ExtensionInstallPrompt::Prompt::SetWebstoreData(
     bool show_user_count,
     double average_rating,
     int rating_count) {
-  CHECK(type_ == INLINE_INSTALL_PROMPT || type_ == EXTERNAL_INSTALL_PROMPT);
+  CHECK(AllowWebstoreData(type_));
   localized_user_count_ = localized_user_count;
   show_user_count_ = show_user_count;
   average_rating_ = average_rating;
@@ -276,6 +306,11 @@ base::string16 ExtensionInstallPrompt::Prompt::GetDialogTitle() const {
       resource_id = IDS_EXTENSION_REMOTE_INSTALL_APP_PROMPT_TITLE;
     else
       resource_id = IDS_EXTENSION_REMOTE_INSTALL_EXTENSION_PROMPT_TITLE;
+  } else if (type_ == REPAIR_PROMPT) {
+    if (extension_->is_app())
+      resource_id = IDS_EXTENSION_REPAIR_APP_PROMPT_TITLE;
+    else
+      resource_id = IDS_EXTENSION_REPAIR_EXTENSION_PROMPT_TITLE;
   }
 
   return l10n_util::GetStringUTF16(resource_id);
@@ -311,8 +346,8 @@ int ExtensionInstallPrompt::Prompt::GetDialogButtons() const {
 }
 
 bool ExtensionInstallPrompt::Prompt::ShouldShowExplanationText() const {
-   return type_ == INSTALL_PROMPT &&
-       extension_->is_extension() && experiment_ && experiment_->text_only();
+  return type_ == INSTALL_PROMPT && extension_->is_extension() &&
+         experiment_.get() && experiment_->text_only();
 }
 
 bool ExtensionInstallPrompt::Prompt::HasAcceptButtonLabel() const {
@@ -354,8 +389,18 @@ base::string16 ExtensionInstallPrompt::Prompt::GetAbortButtonLabel() const {
   return l10n_util::GetStringUTF16(kAbortButtonIds[type_]);
 }
 
-base::string16 ExtensionInstallPrompt::Prompt::GetPermissionsHeading() const {
-  return l10n_util::GetStringUTF16(kPermissionsHeaderIds[type_]);
+base::string16 ExtensionInstallPrompt::Prompt::GetPermissionsHeading(
+    PermissionsType permissions_type) const {
+  switch (permissions_type) {
+    case REGULAR_PERMISSIONS:
+      return l10n_util::GetStringUTF16(kPermissionsHeaderIds[type_]);
+    case WITHHELD_PERMISSIONS:
+      return l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WITHHELD);
+    case ALL_PERMISSIONS:
+    default:
+      NOTREACHED();
+      return base::string16();
+  }
 }
 
 base::string16 ExtensionInstallPrompt::Prompt::GetRetainedFilesHeading() const {
@@ -375,13 +420,14 @@ base::string16 ExtensionInstallPrompt::Prompt::GetRetainedFilesHeading() const {
 }
 
 bool ExtensionInstallPrompt::Prompt::ShouldShowPermissions() const {
-  return GetPermissionCount() > 0 || type_ == POST_INSTALL_PERMISSIONS_PROMPT;
+  return GetPermissionCount(ALL_PERMISSIONS) > 0 ||
+         type_ == POST_INSTALL_PERMISSIONS_PROMPT;
 }
 
 void ExtensionInstallPrompt::Prompt::AppendRatingStars(
     StarAppender appender, void* data) const {
   CHECK(appender);
-  CHECK(type_ == INLINE_INSTALL_PROMPT || type_ == EXTERNAL_INSTALL_PROMPT);
+  CHECK(AllowWebstoreData(type_));
   int rating_integer = floor(average_rating_);
   double rating_fractional = average_rating_ - rating_integer;
 
@@ -408,13 +454,13 @@ void ExtensionInstallPrompt::Prompt::AppendRatingStars(
 }
 
 base::string16 ExtensionInstallPrompt::Prompt::GetRatingCount() const {
-  CHECK(type_ == INLINE_INSTALL_PROMPT || type_ == EXTERNAL_INSTALL_PROMPT);
+  CHECK(AllowWebstoreData(type_));
   return l10n_util::GetStringFUTF16(IDS_EXTENSION_RATING_COUNT,
                                     base::IntToString16(rating_count_));
 }
 
 base::string16 ExtensionInstallPrompt::Prompt::GetUserCount() const {
-  CHECK(type_ == INLINE_INSTALL_PROMPT || type_ == EXTERNAL_INSTALL_PROMPT);
+  CHECK(AllowWebstoreData(type_));
 
   if (show_user_count_) {
     return l10n_util::GetStringFUTF16(IDS_EXTENSION_USER_COUNT,
@@ -423,32 +469,65 @@ base::string16 ExtensionInstallPrompt::Prompt::GetUserCount() const {
   return base::string16();
 }
 
-size_t ExtensionInstallPrompt::Prompt::GetPermissionCount() const {
-  return permissions_.size();
+size_t ExtensionInstallPrompt::Prompt::GetPermissionCount(
+    PermissionsType permissions_type) const {
+  switch (permissions_type) {
+    case REGULAR_PERMISSIONS:
+      return prompt_permissions_.permissions.size();
+    case WITHHELD_PERMISSIONS:
+      return withheld_prompt_permissions_.permissions.size();
+    case ALL_PERMISSIONS:
+      return prompt_permissions_.permissions.size() +
+             withheld_prompt_permissions_.permissions.size();
+    default:
+      NOTREACHED();
+      return 0u;
+  }
 }
 
-size_t ExtensionInstallPrompt::Prompt::GetPermissionsDetailsCount() const {
-  return details_.size();
+size_t ExtensionInstallPrompt::Prompt::GetPermissionsDetailsCount(
+    PermissionsType permissions_type) const {
+  switch (permissions_type) {
+    case REGULAR_PERMISSIONS:
+      return prompt_permissions_.details.size();
+    case WITHHELD_PERMISSIONS:
+      return withheld_prompt_permissions_.details.size();
+    case ALL_PERMISSIONS:
+      return prompt_permissions_.details.size() +
+             withheld_prompt_permissions_.details.size();
+    default:
+      NOTREACHED();
+      return 0u;
+  }
 }
 
-base::string16 ExtensionInstallPrompt::Prompt::GetPermission(size_t index)
-    const {
-  CHECK_LT(index, permissions_.size());
-  return permissions_[index];
+base::string16 ExtensionInstallPrompt::Prompt::GetPermission(
+    size_t index,
+    PermissionsType permissions_type) const {
+  const InstallPromptPermissions& install_permissions =
+      GetPermissionsForType(permissions_type);
+  CHECK_LT(index, install_permissions.permissions.size());
+  return install_permissions.permissions[index];
 }
 
 base::string16 ExtensionInstallPrompt::Prompt::GetPermissionsDetails(
-    size_t index) const {
-  CHECK_LT(index, details_.size());
-  return details_[index];
+    size_t index,
+    PermissionsType permissions_type) const {
+  const InstallPromptPermissions& install_permissions =
+      GetPermissionsForType(permissions_type);
+  CHECK_LT(index, install_permissions.details.size());
+  return install_permissions.details[index];
 }
 
 bool ExtensionInstallPrompt::Prompt::GetIsShowingDetails(
     DetailsType type, size_t index) const {
   switch (type) {
     case PERMISSIONS_DETAILS:
-      CHECK_LT(index, is_showing_details_for_permissions_.size());
-      return is_showing_details_for_permissions_[index];
+      CHECK_LT(index, prompt_permissions_.is_showing_details.size());
+      return prompt_permissions_.is_showing_details[index];
+    case WITHHELD_PERMISSIONS_DETAILS:
+      CHECK_LT(index, withheld_prompt_permissions_.is_showing_details.size());
+      return withheld_prompt_permissions_.is_showing_details[index];
     case RETAINED_FILES_DETAILS:
       return is_showing_details_for_retained_files_;
   }
@@ -465,6 +544,22 @@ base::string16 ExtensionInstallPrompt::Prompt::GetRetainedFile(size_t index)
   return retained_files_[index].AsUTF16Unsafe();
 }
 
+ExtensionInstallPrompt::Prompt::InstallPromptPermissions&
+ExtensionInstallPrompt::Prompt::GetPermissionsForType(
+    PermissionsType permissions_type) {
+  DCHECK_NE(ALL_PERMISSIONS, permissions_type);
+  return permissions_type == REGULAR_PERMISSIONS ? prompt_permissions_
+                                                 : withheld_prompt_permissions_;
+}
+
+const ExtensionInstallPrompt::Prompt::InstallPromptPermissions&
+ExtensionInstallPrompt::Prompt::GetPermissionsForType(
+    PermissionsType permissions_type) const {
+  DCHECK_NE(ALL_PERMISSIONS, permissions_type);
+  return permissions_type == REGULAR_PERMISSIONS ? prompt_permissions_
+                                                 : withheld_prompt_permissions_;
+}
+
 bool ExtensionInstallPrompt::Prompt::ShouldDisplayRevokeFilesButton() const {
   return !retained_files_.empty();
 }
@@ -543,7 +638,7 @@ void ExtensionInstallPrompt::ConfirmBundleInstall(
     const PermissionSet* permissions) {
   DCHECK(ui_loop_ == base::MessageLoop::current());
   bundle_ = bundle;
-  permissions_ = permissions;
+  custom_permissions_ = permissions;
   delegate_ = bundle;
   prompt_ = new Prompt(BUNDLE_INSTALL_PROMPT);
 
@@ -557,7 +652,6 @@ void ExtensionInstallPrompt::ConfirmStandaloneInstall(
     scoped_refptr<Prompt> prompt) {
   DCHECK(ui_loop_ == base::MessageLoop::current());
   extension_ = extension;
-  permissions_ = extension->permissions_data()->active_permissions();
   delegate_ = delegate;
   prompt_ = prompt;
 
@@ -583,7 +677,6 @@ void ExtensionInstallPrompt::ConfirmInstall(
     const ShowDialogCallback& show_dialog_callback) {
   DCHECK(ui_loop_ == base::MessageLoop::current());
   extension_ = extension;
-  permissions_ = extension->permissions_data()->active_permissions();
   delegate_ = delegate;
   prompt_ = new Prompt(INSTALL_PROMPT);
   show_dialog_callback_ = show_dialog_callback;
@@ -610,7 +703,6 @@ void ExtensionInstallPrompt::ConfirmReEnable(Delegate* delegate,
                                              const Extension* extension) {
   DCHECK(ui_loop_ == base::MessageLoop::current());
   extension_ = extension;
-  permissions_ = extension->permissions_data()->active_permissions();
   delegate_ = delegate;
   bool is_remote_install =
       install_ui_->profile() &&
@@ -638,7 +730,6 @@ void ExtensionInstallPrompt::ConfirmExternalInstall(
     scoped_refptr<Prompt> prompt) {
   DCHECK(ui_loop_ == base::MessageLoop::current());
   extension_ = extension;
-  permissions_ = extension->permissions_data()->active_permissions();
   delegate_ = delegate;
   prompt_ = prompt;
   show_dialog_callback_ = show_dialog_callback;
@@ -652,7 +743,7 @@ void ExtensionInstallPrompt::ConfirmPermissions(
     const PermissionSet* permissions) {
   DCHECK(ui_loop_ == base::MessageLoop::current());
   extension_ = extension;
-  permissions_ = permissions;
+  custom_permissions_ = permissions;
   delegate_ = delegate;
   prompt_ = new Prompt(PERMISSIONS_PROMPT);
 
@@ -665,7 +756,6 @@ void ExtensionInstallPrompt::ReviewPermissions(
     const std::vector<base::FilePath>& retained_file_paths) {
   DCHECK(ui_loop_ == base::MessageLoop::current());
   extension_ = extension;
-  permissions_ = extension->permissions_data()->active_permissions();
   prompt_ = new Prompt(POST_INSTALL_PERMISSIONS_PROMPT);
   prompt_->set_retained_files(retained_file_paths);
   delegate_ = delegate;
@@ -739,7 +829,21 @@ void ExtensionInstallPrompt::ShowConfirmation() {
   else
     prompt_->set_experiment(ExtensionInstallPromptExperiment::ControlGroup());
 
-  if (permissions_.get() &&
+  scoped_refptr<const PermissionSet> permissions_to_display;
+  if (custom_permissions_.get()) {
+    permissions_to_display = custom_permissions_;
+  } else if (extension_) {
+    // Initialize permissions if they have not already been set so that
+    // withheld permissions are displayed properly in the install prompt.
+    extensions::PermissionsUpdater(
+        install_ui_->profile(),
+        extensions::PermissionsUpdater::INIT_FLAG_TRANSIENT)
+        .InitializePermissions(extension_);
+    permissions_to_display =
+        extension_->permissions_data()->active_permissions();
+  }
+
+  if (permissions_to_display.get() &&
       (!extension_ ||
        !extensions::PermissionsData::ShouldSkipPermissionWarnings(
            extension_->id()))) {
@@ -747,10 +851,23 @@ void ExtensionInstallPrompt::ShowConfirmation() {
         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));
+    prompt_->SetPermissions(message_provider->GetWarningMessages(
+                                permissions_to_display.get(), type),
+                            REGULAR_PERMISSIONS);
+    prompt_->SetPermissionsDetails(message_provider->GetWarningMessagesDetails(
+                                       permissions_to_display.get(), type),
+                                   REGULAR_PERMISSIONS);
+
+    scoped_refptr<const extensions::PermissionSet> withheld =
+        extension_->permissions_data()->withheld_permissions();
+    if (!withheld->IsEmpty()) {
+      prompt_->SetPermissions(
+          message_provider->GetWarningMessages(withheld.get(), type),
+          PermissionsType::WITHHELD_PERMISSIONS);
+      prompt_->SetPermissionsDetails(
+          message_provider->GetWarningMessagesDetails(withheld.get(), type),
+          PermissionsType::WITHHELD_PERMISSIONS);
+    }
   }
 
   switch (prompt_->type()) {
@@ -761,7 +878,8 @@ void ExtensionInstallPrompt::ShowConfirmation() {
     case INSTALL_PROMPT:
     case LAUNCH_PROMPT:
     case POST_INSTALL_PERMISSIONS_PROMPT:
-    case REMOTE_INSTALL_PROMPT: {
+    case REMOTE_INSTALL_PROMPT:
+    case REPAIR_PROMPT: {
       prompt_->set_extension(extension_);
       prompt_->set_icon(gfx::Image::CreateFrom1xBitmap(icon_));
       break;