Support remote installation of extensions and apps.
To enable this support, the following things are changed:
* ExtensionSyncData, and the ExtensionSpecifics protobuf have a new
remote_install field, to mark a remotely installed extension.
* A new DISABLE_REMOTE_INSTALL reason is added to track this state
locally.
* CrxInstaller::allow_silent_install is changed from a bool to a
three-state enum, where the options are:
- install after showing a permission prompt,
- install and grant all permissions without a prompt and
- install without a prompt and don't grant any permissions
* AddExtensionDisabledError is modified to keep track of the disable
reasons, and change the text that is displayed accordingly.
* ExtensionInstallPrompt has a new prompt type with different text
for remotely installed extensions.
BUG=365737
Review URL: https://codereview.chromium.org/264763002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@270900 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/extensions/app_sync_data.cc b/chrome/browser/extensions/app_sync_data.cc
index 5b1623e..1ecbb24c 100644
--- a/chrome/browser/extensions/app_sync_data.cc
+++ b/chrome/browser/extensions/app_sync_data.cc
@@ -27,10 +27,14 @@
AppSyncData::AppSyncData(const Extension& extension,
bool enabled,
bool incognito_enabled,
+ bool remote_install,
const syncer::StringOrdinal& app_launch_ordinal,
const syncer::StringOrdinal& page_ordinal,
extensions::LaunchType launch_type)
- : extension_sync_data_(extension, enabled, incognito_enabled),
+ : extension_sync_data_(extension,
+ enabled,
+ incognito_enabled,
+ remote_install),
app_launch_ordinal_(app_launch_ordinal),
page_ordinal_(page_ordinal),
launch_type_(launch_type) {
diff --git a/chrome/browser/extensions/app_sync_data.h b/chrome/browser/extensions/app_sync_data.h
index d1164c7..b8499e7 100644
--- a/chrome/browser/extensions/app_sync_data.h
+++ b/chrome/browser/extensions/app_sync_data.h
@@ -32,6 +32,7 @@
AppSyncData(const Extension& extension,
bool enabled,
bool incognito_enabled,
+ bool remote_install,
const syncer::StringOrdinal& app_launch_ordinal,
const syncer::StringOrdinal& page_ordinal,
extensions::LaunchType launch_type);
@@ -63,11 +64,11 @@
const std::string& bookmark_app_url() const {
return bookmark_app_url_;
- };
+ }
const std::string& bookmark_app_description() const {
return bookmark_app_description_;
- };
+ }
private:
// Convert an AppSyncData back out to a sync structure.
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc
index 14bd23f..7b5ff2d 100644
--- a/chrome/browser/extensions/crx_installer.cc
+++ b/chrome/browser/extensions/crx_installer.cc
@@ -105,10 +105,9 @@
return new CrxInstaller(service->AsWeakPtr(), client.Pass(), approval);
}
-CrxInstaller::CrxInstaller(
- base::WeakPtr<ExtensionService> service_weak,
- scoped_ptr<ExtensionInstallPrompt> client,
- const WebstoreInstaller::Approval* approval)
+CrxInstaller::CrxInstaller(base::WeakPtr<ExtensionService> service_weak,
+ scoped_ptr<ExtensionInstallPrompt> client,
+ const WebstoreInstaller::Approval* approval)
: install_directory_(service_weak->install_directory()),
install_source_(Manifest::INTERNAL),
approved_(false),
@@ -123,6 +122,7 @@
client_(client.release()),
apps_require_extension_mime_type_(false),
allow_silent_install_(false),
+ grant_permissions_(true),
install_cause_(extension_misc::INSTALL_CAUSE_UNSET),
creation_flags_(Extension::NO_FLAGS),
off_store_install_allow_reason_(OffStoreInstallDisallowed),
@@ -802,7 +802,7 @@
// We update the extension's granted permissions if the user already
// approved the install (client_ is non NULL), or we are allowed to install
// this silently.
- if (client_ || allow_silent_install_) {
+ if ((client_ || allow_silent_install_) && grant_permissions_) {
PermissionsUpdater perms_updater(profile());
perms_updater.GrantActivePermissions(extension());
}
diff --git a/chrome/browser/extensions/crx_installer.h b/chrome/browser/extensions/crx_installer.h
index 8e3575b..42700931 100644
--- a/chrome/browser/extensions/crx_installer.h
+++ b/chrome/browser/extensions/crx_installer.h
@@ -133,6 +133,9 @@
bool allow_silent_install() const { return allow_silent_install_; }
void set_allow_silent_install(bool val) { allow_silent_install_ = val; }
+ bool grant_permissions() const { return grant_permissions_; }
+ void set_grant_permissions(bool val) { grant_permissions_ = val; }
+
bool is_gallery_install() const {
return (creation_flags_ & Extension::FROM_WEBSTORE) > 0;
}
@@ -344,10 +347,14 @@
bool apps_require_extension_mime_type_;
// Allows for the possibility of a normal install (one in which a |client|
- // is provided in the ctor) to procede without showing the permissions prompt
+ // is provided in the ctor) to proceed without showing the permissions prompt
// dialog.
bool allow_silent_install_;
+ // Allows for the possibility of an installation without granting any
+ // permissions to the extension.
+ bool grant_permissions_;
+
// The value of the content type header sent with the CRX.
// Ignorred unless |require_extension_mime_type_| is true.
std::string original_mime_type_;
diff --git a/chrome/browser/extensions/extension_disabled_ui.cc b/chrome/browser/extensions/extension_disabled_ui.cc
index ece2144a..09bfaf6 100644
--- a/chrome/browser/extensions/extension_disabled_ui.cc
+++ b/chrome/browser/extensions/extension_disabled_ui.cc
@@ -142,6 +142,7 @@
public:
ExtensionDisabledGlobalError(ExtensionService* service,
const Extension* extension,
+ bool is_remote_install,
const gfx::Image& icon);
virtual ~ExtensionDisabledGlobalError();
@@ -172,6 +173,7 @@
private:
ExtensionService* service_;
const Extension* extension_;
+ bool is_remote_install_;
gfx::Image icon_;
// How the user responded to the error; used for metrics.
@@ -195,9 +197,11 @@
ExtensionDisabledGlobalError::ExtensionDisabledGlobalError(
ExtensionService* service,
const Extension* extension,
+ bool is_remote_install,
const gfx::Image& icon)
: service_(service),
extension_(extension),
+ is_remote_install_(is_remote_install),
icon_(icon),
user_response_(IGNORED),
menu_command_id_(GetMenuCommandID()) {
@@ -219,9 +223,15 @@
ExtensionDisabledGlobalError::~ExtensionDisabledGlobalError() {
ReleaseMenuCommandID(menu_command_id_);
- UMA_HISTOGRAM_ENUMERATION("Extensions.DisabledUIUserResponse",
- user_response_,
- EXTENSION_DISABLED_UI_BUCKET_BOUNDARY);
+ if (is_remote_install_) {
+ UMA_HISTOGRAM_ENUMERATION("Extensions.DisabledUIUserResponseRemoteInstall",
+ user_response_,
+ EXTENSION_DISABLED_UI_BUCKET_BOUNDARY);
+ } else {
+ UMA_HISTOGRAM_ENUMERATION("Extensions.DisabledUIUserResponse",
+ user_response_,
+ EXTENSION_DISABLED_UI_BUCKET_BOUNDARY);
+ }
}
GlobalError::Severity ExtensionDisabledGlobalError::GetSeverity() {
@@ -237,8 +247,14 @@
}
base::string16 ExtensionDisabledGlobalError::MenuItemLabel() {
- return l10n_util::GetStringFUTF16(IDS_EXTENSION_DISABLED_ERROR_TITLE,
- base::UTF8ToUTF16(extension_->name()));
+ if (is_remote_install_) {
+ return l10n_util::GetStringFUTF16(
+ IDS_EXTENSION_DISABLED_REMOTE_INSTALL_ERROR_TITLE,
+ base::UTF8ToUTF16(extension_->name()));
+ } else {
+ return l10n_util::GetStringFUTF16(IDS_EXTENSION_DISABLED_ERROR_TITLE,
+ base::UTF8ToUTF16(extension_->name()));
+ }
}
void ExtensionDisabledGlobalError::ExecuteMenuItem(Browser* browser) {
@@ -250,22 +266,39 @@
}
base::string16 ExtensionDisabledGlobalError::GetBubbleViewTitle() {
- return l10n_util::GetStringFUTF16(IDS_EXTENSION_DISABLED_ERROR_TITLE,
- base::UTF8ToUTF16(extension_->name()));
+ if (is_remote_install_) {
+ return l10n_util::GetStringFUTF16(
+ IDS_EXTENSION_DISABLED_REMOTE_INSTALL_ERROR_TITLE,
+ base::UTF8ToUTF16(extension_->name()));
+ } else {
+ return l10n_util::GetStringFUTF16(IDS_EXTENSION_DISABLED_ERROR_TITLE,
+ base::UTF8ToUTF16(extension_->name()));
+ }
}
std::vector<base::string16>
ExtensionDisabledGlobalError::GetBubbleViewMessages() {
std::vector<base::string16> messages;
- messages.push_back(l10n_util::GetStringFUTF16(
- extension_->is_app() ?
- IDS_APP_DISABLED_ERROR_LABEL : IDS_EXTENSION_DISABLED_ERROR_LABEL,
- base::UTF8ToUTF16(extension_->name())));
- messages.push_back(l10n_util::GetStringUTF16(
- IDS_EXTENSION_PROMPT_WILL_NOW_HAVE_ACCESS_TO));
std::vector<base::string16> permission_warnings =
extensions::PermissionMessageProvider::Get()->GetWarningMessages(
extension_->GetActivePermissions(), extension_->GetType());
+ if (is_remote_install_) {
+ messages.push_back(l10n_util::GetStringFUTF16(
+ extension_->is_app()
+ ? IDS_APP_DISABLED_REMOTE_INSTALL_ERROR_LABEL
+ : IDS_EXTENSION_DISABLED_REMOTE_INSTALL_ERROR_LABEL,
+ base::UTF8ToUTF16(extension_->name())));
+ if (!permission_warnings.empty())
+ messages.push_back(
+ l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO));
+ } else {
+ messages.push_back(l10n_util::GetStringFUTF16(
+ extension_->is_app() ? IDS_APP_DISABLED_ERROR_LABEL
+ : IDS_EXTENSION_DISABLED_ERROR_LABEL,
+ base::UTF8ToUTF16(extension_->name())));
+ messages.push_back(l10n_util::GetStringUTF16(
+ IDS_EXTENSION_PROMPT_WILL_NOW_HAVE_ACCESS_TO));
+ }
for (size_t i = 0; i < permission_warnings.size(); ++i) {
messages.push_back(l10n_util::GetStringFUTF16(
IDS_EXTENSION_PERMISSION_LINE, permission_warnings[i]));
@@ -274,7 +307,12 @@
}
base::string16 ExtensionDisabledGlobalError::GetBubbleViewAcceptButtonLabel() {
- return l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_RE_ENABLE_BUTTON);
+ if (is_remote_install_) {
+ return l10n_util::GetStringUTF16(
+ IDS_EXTENSION_PROMPT_REMOTE_INSTALL_BUTTON);
+ } else {
+ return l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_RE_ENABLE_BUTTON);
+ }
}
base::string16 ExtensionDisabledGlobalError::GetBubbleViewCancelButtonLabel() {
@@ -339,19 +377,21 @@
void AddExtensionDisabledErrorWithIcon(base::WeakPtr<ExtensionService> service,
const std::string& extension_id,
+ bool is_remote_install,
const gfx::Image& icon) {
if (!service.get())
return;
const Extension* extension = service->GetInstalledExtension(extension_id);
if (extension) {
GlobalErrorServiceFactory::GetForProfile(service->profile())
- ->AddGlobalError(
- new ExtensionDisabledGlobalError(service.get(), extension, icon));
+ ->AddGlobalError(new ExtensionDisabledGlobalError(
+ service.get(), extension, is_remote_install, icon));
}
}
void AddExtensionDisabledError(ExtensionService* service,
- const Extension* extension) {
+ const Extension* extension,
+ bool is_remote_install) {
// Do not display notifications for ephemeral apps that have been disabled.
// Instead, a prompt will be shown the next time the app is launched.
if (extension->is_ephemeral())
@@ -360,10 +400,14 @@
extensions::ExtensionResource image = extensions::IconsInfo::GetIconResource(
extension, kIconSize, ExtensionIconSet::MATCH_BIGGER);
gfx::Size size(kIconSize, kIconSize);
- ImageLoader::Get(service->profile())->LoadImageAsync(
- extension, image, size,
- base::Bind(&AddExtensionDisabledErrorWithIcon,
- service->AsWeakPtr(), extension->id()));
+ ImageLoader::Get(service->profile())
+ ->LoadImageAsync(extension,
+ image,
+ size,
+ base::Bind(&AddExtensionDisabledErrorWithIcon,
+ service->AsWeakPtr(),
+ extension->id(),
+ is_remote_install));
}
void ShowExtensionDisabledDialog(ExtensionService* service,
diff --git a/chrome/browser/extensions/extension_disabled_ui.h b/chrome/browser/extensions/extension_disabled_ui.h
index f71bcc9..08380585 100644
--- a/chrome/browser/extensions/extension_disabled_ui.h
+++ b/chrome/browser/extensions/extension_disabled_ui.h
@@ -17,8 +17,11 @@
// Adds a global error to inform the user that an extension was
// disabled after upgrading to higher permissions.
+// If |is_remote_install| is true, the extension was disabled because
+// it was installed remotely.
void AddExtensionDisabledError(ExtensionService* service,
- const Extension* extension);
+ const Extension* extension,
+ bool is_remote_install);
// Shows the extension install dialog.
void ShowExtensionDisabledDialog(ExtensionService* service,
diff --git a/chrome/browser/extensions/extension_disabled_ui_browsertest.cc b/chrome/browser/extensions/extension_disabled_ui_browsertest.cc
index b6f58fd..5cd748a 100644
--- a/chrome/browser/extensions/extension_disabled_ui_browsertest.cc
+++ b/chrome/browser/extensions/extension_disabled_ui_browsertest.cc
@@ -24,6 +24,8 @@
#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension.h"
#include "net/url_request/url_fetcher.h"
+#include "sync/protocol/extension_specifics.pb.h"
+#include "sync/protocol/sync.pb.h"
using extensions::Extension;
using extensions::ExtensionRegistry;
@@ -234,3 +236,54 @@
->GetDisableReasons(extension_id));
EXPECT_TRUE(GetExtensionDisabledGlobalError());
}
+
+// Test that an error appears if an extension gets installed server side.
+IN_PROC_BROWSER_TEST_F(ExtensionDisabledGlobalErrorTest, RemoteInstall) {
+ static const char* extension_id = "pgdpcfcocojkjfbgpiianjngphoopgmo";
+ ExtensionSyncService* sync_service =
+ ExtensionSyncService::Get(browser()->profile());
+
+ // Note: This interceptor gets requests on the IO thread.
+ content::URLLocalHostRequestPrepackagedInterceptor interceptor;
+ net::URLFetcher::SetEnableInterceptionForTests(true);
+ interceptor.SetResponseIgnoreQuery(
+ GURL("http://localhost/autoupdate/updates.xml"),
+ test_data_dir_.AppendASCII("permissions_increase")
+ .AppendASCII("updates.xml"));
+ interceptor.SetResponseIgnoreQuery(
+ GURL("http://localhost/autoupdate/v2.crx"),
+ scoped_temp_dir_.path().AppendASCII("permissions2.crx"));
+
+ extensions::ExtensionUpdater::CheckParams params;
+ service_->updater()->set_default_check_params(params);
+
+ sync_pb::EntitySpecifics specifics;
+ specifics.mutable_extension()->set_id(extension_id);
+ specifics.mutable_extension()->set_enabled(false);
+ specifics.mutable_extension()->set_remote_install(true);
+ specifics.mutable_extension()->set_update_url(
+ "http://localhost/autoupdate/updates.xml");
+ specifics.mutable_extension()->set_version("2");
+ syncer::SyncData sync_data =
+ syncer::SyncData::CreateRemoteData(1234567,
+ specifics,
+ base::Time::Now(),
+ syncer::AttachmentIdList(),
+ syncer::AttachmentServiceProxy());
+ // Sync is installing a new extension, so it pends.
+ EXPECT_FALSE(sync_service->ProcessExtensionSyncData(
+ extensions::ExtensionSyncData(sync_data)));
+
+ WaitForExtensionInstall();
+ content::BrowserThread::GetBlockingPool()->FlushForTesting();
+ base::RunLoop().RunUntilIdle();
+
+ const Extension* extension = service_->GetExtensionById(extension_id, true);
+ ASSERT_TRUE(extension);
+ EXPECT_EQ("2", extension->VersionString());
+ EXPECT_EQ(1u, registry_->disabled_extensions().size());
+ EXPECT_EQ(Extension::DISABLE_REMOTE_INSTALL,
+ ExtensionPrefs::Get(service_->profile())
+ ->GetDisableReasons(extension_id));
+ EXPECT_TRUE(GetExtensionDisabledGlobalError());
+}
diff --git a/chrome/browser/extensions/extension_install_prompt.cc b/chrome/browser/extensions/extension_install_prompt.cc
index 76f5a37..76cb03d 100644
--- a/chrome/browser/extensions/extension_install_prompt.cc
+++ b/chrome/browser/extensions/extension_install_prompt.cc
@@ -26,6 +26,7 @@
#include "chrome/common/pref_names.h"
#include "components/signin/core/browser/profile_oauth2_token_service.h"
#include "content/public/browser/web_contents.h"
+#include "extensions/browser/extension_prefs.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_icon_set.h"
@@ -53,75 +54,82 @@
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,
+ 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,
+ IDS_EXTENSION_PROMPT_OAUTH_HEADER,
};
// Size of extension icon in top left of dialog.
@@ -280,6 +288,11 @@
} 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);
@@ -641,9 +654,16 @@
extension_ = extension;
permissions_ = extension->GetActivePermissions();
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);
+ if (extension->is_ephemeral())
+ prompt_.set_type(LAUNCH_PROMPT);
+ else if (is_remote_install)
+ prompt_.set_type(REMOTE_INSTALL_PROMPT);
+ else
+ prompt_.set_type(RE_ENABLE_PROMPT);
LoadImageIfNeeded();
}
@@ -827,7 +847,8 @@
case EXTERNAL_INSTALL_PROMPT:
case INSTALL_PROMPT:
case LAUNCH_PROMPT:
- case POST_INSTALL_PERMISSIONS_PROMPT: {
+ case POST_INSTALL_PERMISSIONS_PROMPT:
+ case REMOTE_INSTALL_PROMPT: {
prompt_.set_extension(extension_);
prompt_.set_icon(gfx::Image::CreateFrom1xBitmap(icon_));
break;
diff --git a/chrome/browser/extensions/extension_install_prompt.h b/chrome/browser/extensions/extension_install_prompt.h
index 4de81862..c8d91e35 100644
--- a/chrome/browser/extensions/extension_install_prompt.h
+++ b/chrome/browser/extensions/extension_install_prompt.h
@@ -67,6 +67,7 @@
EXTERNAL_INSTALL_PROMPT,
POST_INSTALL_PERMISSIONS_PROMPT,
LAUNCH_PROMPT,
+ REMOTE_INSTALL_PROMPT,
NUM_PROMPT_TYPES
};
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index 4cb01bf..5463968 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -547,6 +547,8 @@
installer->set_install_source(pending_extension_info->install_source());
if (pending_extension_info->install_silently())
installer->set_allow_silent_install(true);
+ if (pending_extension_info->remote_install())
+ installer->set_grant_permissions(false);
creation_flags = pending_extension_info->creation_flags();
if (pending_extension_info->mark_acknowledged())
AcknowledgeExternalExtension(id);
@@ -1495,11 +1497,17 @@
content::Source<Profile>(profile_),
content::Details<const Extension>(extension));
- // Show the extension disabled error if a permissions increase was the
- // only reason it was disabled.
- if (extension_prefs_->GetDisableReasons(extension->id()) ==
- Extension::DISABLE_PERMISSIONS_INCREASE) {
- extensions::AddExtensionDisabledError(this, extension);
+ // Show the extension disabled error if a permissions increase or a remote
+ // installation is the reason it was disabled, and no other reasons exist.
+ int reasons = extension_prefs_->GetDisableReasons(extension->id());
+ const int kReasonMask = Extension::DISABLE_PERMISSIONS_INCREASE |
+ Extension::DISABLE_REMOTE_INSTALL;
+ if (reasons & kReasonMask && !(reasons & ~kReasonMask)) {
+ extensions::AddExtensionDisabledError(
+ this,
+ extension,
+ extension_prefs_->HasDisableReason(
+ extension->id(), Extension::DISABLE_REMOTE_INSTALL));
}
} else if (reloading) {
// Replace the old extension with the new version.
@@ -1661,8 +1669,13 @@
}
// Extension has changed permissions significantly. Disable it. A
- // notification should be sent by the caller.
- if (is_privilege_increase) {
+ // notification should be sent by the caller. If the extension is already
+ // disabled because it was installed remotely, don't add another disable
+ // reason, but instead always set the "did escalate permissions" flag, to
+ // ensure enabling it will always show a warning.
+ if (disable_reasons == Extension::DISABLE_REMOTE_INSTALL) {
+ extension_prefs_->SetDidExtensionEscalatePermissions(extension, true);
+ } else if (is_privilege_increase) {
disable_reasons |= Extension::DISABLE_PERMISSIONS_INCREASE;
if (!extension_prefs_->DidExtensionEscalatePermissions(extension->id())) {
RecordPermissionMessagesHistogram(
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc
index 41fea0f..ce441ed 100644
--- a/chrome/browser/extensions/extension_service_unittest.cc
+++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -3027,10 +3027,14 @@
const std::string kFakeId(all_zero);
const GURL kFakeUpdateURL("http:://fake.update/url");
const bool kFakeInstallSilently(true);
+ const bool kFakeRemoteInstall(false);
- EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
- kFakeId, kFakeUpdateURL, &IsExtension,
- kFakeInstallSilently));
+ EXPECT_TRUE(
+ service_->pending_extension_manager()->AddFromSync(kFakeId,
+ kFakeUpdateURL,
+ &IsExtension,
+ kFakeInstallSilently,
+ kFakeRemoteInstall));
const extensions::PendingExtensionInfo* pending_extension_info;
ASSERT_TRUE((pending_extension_info = service_->pending_extension_manager()->
@@ -3038,6 +3042,7 @@
EXPECT_EQ(kFakeUpdateURL, pending_extension_info->update_url());
EXPECT_EQ(&IsExtension, pending_extension_info->should_allow_install_);
EXPECT_EQ(kFakeInstallSilently, pending_extension_info->install_silently());
+ EXPECT_EQ(kFakeRemoteInstall, pending_extension_info->remote_install());
}
namespace {
@@ -3045,14 +3050,18 @@
const char kGoodUpdateURL[] = "http://good.update/url";
const bool kGoodIsFromSync = true;
const bool kGoodInstallSilently = true;
+const bool kGoodRemoteInstall = false;
} // namespace
// Test updating a pending extension.
TEST_F(ExtensionServiceTest, UpdatePendingExtension) {
InitializeEmptyExtensionService();
- EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
- kGoodId, GURL(kGoodUpdateURL), &IsExtension,
- kGoodInstallSilently));
+ EXPECT_TRUE(
+ service_->pending_extension_manager()->AddFromSync(kGoodId,
+ GURL(kGoodUpdateURL),
+ &IsExtension,
+ kGoodInstallSilently,
+ kGoodRemoteInstall));
EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(kGoodId));
base::FilePath path = data_dir_.AppendASCII("good.crx");
@@ -3077,7 +3086,7 @@
TEST_F(ExtensionServiceTest, DISABLED_UpdatePendingTheme) {
InitializeEmptyExtensionService();
EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
- theme_crx, GURL(), &IsTheme, false));
+ theme_crx, GURL(), &IsTheme, false, false));
EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
base::FilePath path = data_dir_.AppendASCII("theme.crx");
@@ -3136,9 +3145,12 @@
InitializeEmptyExtensionService();
// Add a crx to be installed from the update mechanism.
- EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
- kGoodId, GURL(kGoodUpdateURL), &IsExtension,
- kGoodInstallSilently));
+ EXPECT_TRUE(
+ service_->pending_extension_manager()->AddFromSync(kGoodId,
+ GURL(kGoodUpdateURL),
+ &IsExtension,
+ kGoodInstallSilently,
+ kGoodRemoteInstall));
// Check that there is a pending crx, with is_from_sync set to true.
const extensions::PendingExtensionInfo* pending_extension_info;
@@ -3163,9 +3175,12 @@
pending_extension_info->install_source());
// Add a crx to be installed from the update mechanism.
- EXPECT_FALSE(service_->pending_extension_manager()->AddFromSync(
- kGoodId, GURL(kGoodUpdateURL), &IsExtension,
- kGoodInstallSilently));
+ EXPECT_FALSE(
+ service_->pending_extension_manager()->AddFromSync(kGoodId,
+ GURL(kGoodUpdateURL),
+ &IsExtension,
+ kGoodInstallSilently,
+ kGoodRemoteInstall));
// Check that the external, non-sync update was not overridden.
ASSERT_TRUE((pending_extension_info = service_->pending_extension_manager()->
@@ -3180,7 +3195,7 @@
TEST_F(ExtensionServiceTest, UpdatePendingCrxThemeMismatch) {
InitializeEmptyExtensionService();
EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
- theme_crx, GURL(), &IsExtension, true));
+ theme_crx, GURL(), &IsExtension, true, false));
EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
@@ -3201,8 +3216,12 @@
TEST_F(ExtensionServiceTest, UpdatePendingExtensionFailedShouldInstallTest) {
InitializeEmptyExtensionService();
// Add pending extension with a flipped is_theme.
- EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
- kGoodId, GURL(kGoodUpdateURL), &IsTheme, kGoodInstallSilently));
+ EXPECT_TRUE(
+ service_->pending_extension_manager()->AddFromSync(kGoodId,
+ GURL(kGoodUpdateURL),
+ &IsTheme,
+ kGoodInstallSilently,
+ kGoodRemoteInstall));
EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(kGoodId));
base::FilePath path = data_dir_.AppendASCII("good.crx");
@@ -3249,7 +3268,8 @@
kGoodInstallSilently,
Manifest::INTERNAL,
Extension::NO_FLAGS,
- false);
+ false,
+ kGoodRemoteInstall);
UpdateExtension(good->id(), path, ENABLED);
EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
@@ -5461,7 +5481,8 @@
const Extension* extension = service_->GetExtensionById(good0, true);
ASSERT_TRUE(extension);
ASSERT_TRUE(service_->IsExtensionEnabled(good0));
- extensions::ExtensionSyncData disable_good_crx(*extension, false, false);
+ extensions::ExtensionSyncData disable_good_crx(
+ *extension, false, false, false);
// Then sync data arrives telling us to disable |good0|.
syncer::SyncDataList sync_data;
@@ -5508,7 +5529,8 @@
// Now sync data comes in that says to disable good0. This should be
// ignored.
- extensions::ExtensionSyncData disable_good_crx(*extension, false, false);
+ extensions::ExtensionSyncData disable_good_crx(
+ *extension, false, false, false);
syncer::SyncDataList sync_data;
sync_data.push_back(disable_good_crx.GetSyncData());
extension_sync_service_->MergeDataAndStartSyncing(
@@ -6508,7 +6530,11 @@
// Fake a request from sync to install an extension.
bool AddPendingSyncInstall() {
return service_->pending_extension_manager()->AddFromSync(
- crx_id_, GURL(kGoodUpdateURL), &IsExtension, kGoodInstallSilently);
+ crx_id_,
+ GURL(kGoodUpdateURL),
+ &IsExtension,
+ kGoodInstallSilently,
+ kGoodRemoteInstall);
}
// Fake a policy install.
diff --git a/chrome/browser/extensions/extension_sync_data.cc b/chrome/browser/extensions/extension_sync_data.cc
index 0ebe72e..aaf1244 100644
--- a/chrome/browser/extensions/extension_sync_data.cc
+++ b/chrome/browser/extensions/extension_sync_data.cc
@@ -31,8 +31,8 @@
}
ExtensionSyncData::ExtensionSyncData(const syncer::SyncChange& sync_change)
- : uninstalled_(
- sync_change.change_type() == syncer::SyncChange::ACTION_DELETE),
+ : uninstalled_(sync_change.change_type() ==
+ syncer::SyncChange::ACTION_DELETE),
enabled_(false),
incognito_enabled_(false),
remote_install_(false) {
@@ -41,12 +41,13 @@
ExtensionSyncData::ExtensionSyncData(const Extension& extension,
bool enabled,
- bool incognito_enabled)
- : id_(extension.id()),
+ bool incognito_enabled,
+ bool remote_install)
+ : id_(extension.id()),
uninstalled_(false),
enabled_(enabled),
incognito_enabled_(incognito_enabled),
- remote_install_(false),
+ remote_install_(remote_install),
version_(extension.from_bookmark() ? base::Version("0")
: *extension.version()),
update_url_(ManifestURL::GetUpdateURL(&extension)),
diff --git a/chrome/browser/extensions/extension_sync_data.h b/chrome/browser/extensions/extension_sync_data.h
index 04c4b18d..9165e75 100644
--- a/chrome/browser/extensions/extension_sync_data.h
+++ b/chrome/browser/extensions/extension_sync_data.h
@@ -31,7 +31,8 @@
explicit ExtensionSyncData(const syncer::SyncChange& sync_change);
ExtensionSyncData(const Extension& extension,
bool enabled,
- bool incognito_enabled);
+ bool incognito_enabled,
+ bool remote_install);
~ExtensionSyncData();
// Retrieve sync data from this class.
@@ -56,6 +57,7 @@
bool uninstalled() const { return uninstalled_; }
bool enabled() const { return enabled_; }
bool incognito_enabled() const { return incognito_enabled_; }
+ bool remote_install() const { return remote_install_; }
// Version-dependent properties (i.e., should be used only when the
// version of the currenty-installed extension matches |version|).
diff --git a/chrome/browser/extensions/extension_sync_service.cc b/chrome/browser/extensions/extension_sync_service.cc
index 7dbe613..8ac5c07 100644
--- a/chrome/browser/extensions/extension_sync_service.cc
+++ b/chrome/browser/extensions/extension_sync_service.cc
@@ -254,7 +254,9 @@
return extensions::ExtensionSyncData(
extension,
extension_service_->IsExtensionEnabled(extension.id()),
- extensions::util::IsIncognitoEnabled(extension.id(), profile_));
+ extensions::util::IsIncognitoEnabled(extension.id(), profile_),
+ extension_prefs_->HasDisableReason(extension.id(),
+ Extension::DISABLE_REMOTE_INSTALL));
}
extensions::AppSyncData ExtensionSyncService::GetAppSyncData(
@@ -263,6 +265,8 @@
extension,
extension_service_->IsExtensionEnabled(extension.id()),
extensions::util::IsIncognitoEnabled(extension.id(), profile_),
+ extension_prefs_->HasDisableReason(extension.id(),
+ Extension::DISABLE_REMOTE_INSTALL),
extension_prefs_->app_sorting()->GetAppLaunchOrdinal(extension.id()),
extension_prefs_->app_sorting()->GetPageOrdinal(extension.id()),
extensions::GetLaunchTypePrefValue(extension_prefs_, extension.id()));
@@ -465,11 +469,21 @@
// been installed yet, so we don't know if the disable reason was a
// permissions increase. That will be updated once CheckPermissionsIncrease
// is called for it.
+ // However if the extension is marked as a remote install in sync, we know
+ // what the disable reason is, so set it to that directly. Note that when
+ // CheckPermissionsIncrease runs, it might still add permissions increase
+ // as a disable reason for the extension.
if (extension_sync_data.enabled())
extension_service_->EnableExtension(id);
- else if (!IsPendingEnable(id))
- extension_service_->DisableExtension(
- id, Extension::DISABLE_UNKNOWN_FROM_SYNC);
+ else if (!IsPendingEnable(id)) {
+ if (extension_sync_data.remote_install()) {
+ extension_service_->DisableExtension(id,
+ Extension::DISABLE_REMOTE_INSTALL);
+ } else {
+ extension_service_->DisableExtension(
+ id, Extension::DISABLE_UNKNOWN_FROM_SYNC);
+ }
+ }
// We need to cache some version information here because setting the
// incognito flag invalidates the |extension| pointer (it reloads the
@@ -501,7 +515,8 @@
id,
extension_sync_data.update_url(),
filter,
- kInstallSilently)) {
+ kInstallSilently,
+ extension_sync_data.remote_install())) {
LOG(WARNING) << "Could not add pending extension for " << id;
// This means that the extension is already pending installation, with a
// non-INTERNAL location. Add to pending_sync_data, even though it will
diff --git a/chrome/browser/extensions/pending_extension_info.cc b/chrome/browser/extensions/pending_extension_info.cc
index 0fa105b..b0c052f0 100644
--- a/chrome/browser/extensions/pending_extension_info.cc
+++ b/chrome/browser/extensions/pending_extension_info.cc
@@ -18,7 +18,8 @@
bool install_silently,
Manifest::Location install_source,
int creation_flags,
- bool mark_acknowledged)
+ bool mark_acknowledged,
+ bool remote_install)
: id_(id),
update_url_(update_url),
version_(version),
@@ -28,14 +29,20 @@
install_silently_(install_silently),
install_source_(install_source),
creation_flags_(creation_flags),
- mark_acknowledged_(mark_acknowledged) {}
+ mark_acknowledged_(mark_acknowledged),
+ remote_install_(remote_install) {
+}
PendingExtensionInfo::PendingExtensionInfo()
: update_url_(),
should_allow_install_(NULL),
is_from_sync_(true),
install_silently_(false),
- install_source_(Manifest::INVALID_LOCATION) {}
+ install_source_(Manifest::INVALID_LOCATION),
+ creation_flags_(0),
+ mark_acknowledged_(false),
+ remote_install_(false) {
+}
PendingExtensionInfo::~PendingExtensionInfo() {}
diff --git a/chrome/browser/extensions/pending_extension_info.h b/chrome/browser/extensions/pending_extension_info.h
index a3ea47b1..11c159a 100644
--- a/chrome/browser/extensions/pending_extension_info.h
+++ b/chrome/browser/extensions/pending_extension_info.h
@@ -36,7 +36,8 @@
bool install_silently,
Manifest::Location install_source,
int creation_flags,
- bool mark_acknowledged);
+ bool mark_acknowledged,
+ bool remote_install);
// Required for STL container membership. Should not be used directly.
PendingExtensionInfo();
@@ -65,6 +66,7 @@
Manifest::Location install_source() const { return install_source_; }
int creation_flags() const { return creation_flags_; }
bool mark_acknowledged() const { return mark_acknowledged_; }
+ bool remote_install() const { return remote_install_; }
// Returns -1, 0 or 1 if |this| has lower, equal or higher precedence than
// |other|, respectively. "Equal" precedence means that the version and the
@@ -90,6 +92,7 @@
Manifest::Location install_source_;
int creation_flags_;
bool mark_acknowledged_;
+ bool remote_install_;
FRIEND_TEST_ALL_PREFIXES(::ExtensionServiceTest, AddPendingExtensionFromSync);
};
diff --git a/chrome/browser/extensions/pending_extension_manager.cc b/chrome/browser/extensions/pending_extension_manager.cc
index 1a4ed42..c91c1fea 100644
--- a/chrome/browser/extensions/pending_extension_manager.cc
+++ b/chrome/browser/extensions/pending_extension_manager.cc
@@ -89,7 +89,8 @@
const std::string& id,
const GURL& update_url,
PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install,
- bool install_silently) {
+ bool install_silently,
+ bool remote_install) {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (service_.GetInstalledExtension(id)) {
@@ -119,7 +120,8 @@
install_silently,
kSyncLocation,
Extension::NO_FLAGS,
- kMarkAcknowledged);
+ kMarkAcknowledged,
+ remote_install);
}
bool PendingExtensionManager::AddFromExtensionImport(
@@ -138,6 +140,7 @@
const bool kInstallSilently = true;
const Manifest::Location kManifestLocation = Manifest::INTERNAL;
const bool kMarkAcknowledged = false;
+ const bool kRemoteInstall = false;
return AddExtensionImpl(id,
std::string(),
@@ -148,7 +151,8 @@
kInstallSilently,
kManifestLocation,
Extension::NO_FLAGS,
- kMarkAcknowledged);
+ kMarkAcknowledged,
+ kRemoteInstall);
}
bool PendingExtensionManager::AddFromExternalUpdateUrl(
@@ -162,6 +166,7 @@
const bool kIsFromSync = false;
const bool kInstallSilently = true;
+ const bool kRemoteInstall = false;
const Extension* extension = service_.GetInstalledExtension(id);
if (extension && location == Manifest::GetHigherPriorityLocation(
@@ -188,7 +193,8 @@
kInstallSilently,
location,
creation_flags,
- mark_acknowledged);
+ mark_acknowledged,
+ kRemoteInstall);
}
@@ -203,8 +209,9 @@
// made sure it is not installed. Make all AddFrom*() methods
// consistent.
GURL kUpdateUrl = GURL();
- bool kIsFromSync = false;
- bool kInstallSilently = true;
+ const bool kIsFromSync = false;
+ const bool kInstallSilently = true;
+ const bool kRemoteInstall = false;
return AddExtensionImpl(id,
std::string(),
@@ -215,7 +222,8 @@
kInstallSilently,
install_source,
creation_flags,
- mark_acknowledged);
+ mark_acknowledged,
+ kRemoteInstall);
}
void PendingExtensionManager::GetPendingIdsForUpdateCheck(
@@ -247,7 +255,8 @@
bool install_silently,
Manifest::Location install_source,
int creation_flags,
- bool mark_acknowledged) {
+ bool mark_acknowledged,
+ bool remote_install) {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
PendingExtensionInfo info(id,
@@ -259,7 +268,8 @@
install_silently,
install_source,
creation_flags,
- mark_acknowledged);
+ mark_acknowledged,
+ remote_install);
if (const PendingExtensionInfo* pending = GetById(id)) {
// Bugs in this code will manifest as sporadic incorrect extension
diff --git a/chrome/browser/extensions/pending_extension_manager.h b/chrome/browser/extensions/pending_extension_manager.h
index 96dfa6e..bf2e1fc7 100644
--- a/chrome/browser/extensions/pending_extension_manager.h
+++ b/chrome/browser/extensions/pending_extension_manager.h
@@ -84,7 +84,8 @@
const std::string& id,
const GURL& update_url,
PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install,
- bool install_silently);
+ bool install_silently,
+ bool remote_install);
// Adds an extension that was depended on by another extension.
bool AddFromExtensionImport(
@@ -132,7 +133,8 @@
bool install_silently,
Manifest::Location install_source,
int creation_flags,
- bool mark_acknowledged);
+ bool mark_acknowledged,
+ bool remote_install);
// Add a pending extension record directly. Used for unit tests that need
// to set an inital state. Use friendship to allow the tests to call this
diff --git a/chrome/browser/extensions/updater/extension_updater_unittest.cc b/chrome/browser/extensions/updater/extension_updater_unittest.cc
index 6bdf5e4..d1d42871 100644
--- a/chrome/browser/extensions/updater/extension_updater_unittest.cc
+++ b/chrome/browser/extensions/updater/extension_updater_unittest.cc
@@ -352,6 +352,7 @@
const bool kIsFromSync = true;
const bool kInstallSilently = true;
const bool kMarkAcknowledged = false;
+ const bool kRemoteInstall = false;
std::string id = id_util::GenerateId(base::StringPrintf("extension%i", i));
pending_extension_manager->AddForTesting(
@@ -364,7 +365,8 @@
kInstallSilently,
Manifest::INTERNAL,
Extension::NO_FLAGS,
- kMarkAcknowledged));
+ kMarkAcknowledged,
+ kRemoteInstall));
}
}
@@ -1056,6 +1058,7 @@
const bool kIsFromSync = true;
const bool kInstallSilently = true;
const bool kMarkAcknowledged = false;
+ const bool kRemoteInstall = false;
PendingExtensionManager* pending_extension_manager =
service->pending_extension_manager();
pending_extension_manager->AddForTesting(
@@ -1068,7 +1071,8 @@
kInstallSilently,
Manifest::INTERNAL,
Extension::NO_FLAGS,
- kMarkAcknowledged));
+ kMarkAcknowledged,
+ kRemoteInstall));
}
// Call back the ExtensionUpdater with a 200 response and some test data
diff --git a/chrome/browser/sync/test/integration/two_client_apps_sync_test.cc b/chrome/browser/sync/test/integration/two_client_apps_sync_test.cc
index 4e1464a..74ddb900 100644
--- a/chrome/browser/sync/test/integration/two_client_apps_sync_test.cc
+++ b/chrome/browser/sync/test/integration/two_client_apps_sync_test.cc
@@ -501,6 +501,7 @@
*extension,
original_data.extension_sync_data().enabled(),
original_data.extension_sync_data().incognito_enabled(),
+ original_data.extension_sync_data().remote_install(),
original_data.app_launch_ordinal(),
original_data.page_ordinal(),
extensions::NUM_LAUNCH_TYPES);
diff --git a/chrome/browser/themes/theme_syncable_service.cc b/chrome/browser/themes/theme_syncable_service.cc
index fe14051..82550f9a 100644
--- a/chrome/browser/themes/theme_syncable_service.cc
+++ b/chrome/browser/themes/theme_syncable_service.cc
@@ -235,8 +235,9 @@
// so by adding it as a pending extension and then triggering an
// auto-update cycle.
const bool kInstallSilently = true;
+ const bool kRemoteInstall = false;
if (!extensions_service->pending_extension_manager()->AddFromSync(
- id, update_url, &IsTheme, kInstallSilently)) {
+ id, update_url, &IsTheme, kInstallSilently, kRemoteInstall)) {
LOG(WARNING) << "Could not add pending extension for " << id;
return;
}