#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"
#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"
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,
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,
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,
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,
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.
IDS_CLOSE,
0, // Platform dependent cancel button.
0,
+ 0,
};
static const int
kPermissionsHeaderIds[ExtensionInstallPrompt::NUM_PROMPT_TYPES] = {
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
} // namespace
+ExtensionInstallPrompt::Prompt::InstallPromptPermissions::
+ InstallPromptPermissions() {
+}
+ExtensionInstallPrompt::Prompt::InstallPromptPermissions::
+ ~InstallPromptPermissions() {
+}
+
// static
ExtensionInstallPrompt::AutoConfirmForTests
ExtensionInstallPrompt::g_auto_confirm_for_tests = ExtensionInstallPrompt::NONE;
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;
}
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(
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;
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;
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);
}
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 {
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 {
}
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;
}
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,
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_;
}
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();
}
const PermissionSet* permissions) {
DCHECK(ui_loop_ == base::MessageLoop::current());
bundle_ = bundle;
- permissions_ = permissions;
+ custom_permissions_ = permissions;
delegate_ = bundle;
prompt_ = new Prompt(BUNDLE_INSTALL_PROMPT);
scoped_refptr<Prompt> prompt) {
DCHECK(ui_loop_ == base::MessageLoop::current());
extension_ = extension;
- permissions_ = extension->permissions_data()->active_permissions();
delegate_ = delegate;
prompt_ = prompt;
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;
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() &&
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;
const PermissionSet* permissions) {
DCHECK(ui_loop_ == base::MessageLoop::current());
extension_ = extension;
- permissions_ = permissions;
+ custom_permissions_ = permissions;
delegate_ = delegate;
prompt_ = new Prompt(PERMISSIONS_PROMPT);
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;
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()))) {
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()) {
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;