#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
+#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
-#include "chrome/browser/extensions/crx_installer_error.h"
#include "chrome/browser/extensions/extension_install_prompt_experiment.h"
#include "extensions/common/url_pattern.h"
-#include "google_apis/gaia/oauth2_mint_token_flow.h"
-#include "google_apis/gaia/oauth2_token_service.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/native_widget_types.h"
-class Browser;
-class ExtensionInstallUI;
+class ExtensionInstallPromptShowParams;
class Profile;
namespace base {
} // namespace base
namespace content {
-class PageNavigator;
class WebContents;
}
namespace extensions {
class BundleInstaller;
+class CrxInstallerError;
class Extension;
+class ExtensionInstallUI;
class ExtensionWebstorePrivateApiTest;
class MockGetAuthTokenFunction;
class PermissionSet;
// Displays all the UI around extension installation.
class ExtensionInstallPrompt
- : public OAuth2MintTokenFlow::Delegate,
- public OAuth2TokenService::Consumer,
- public base::SupportsWeakPtr<ExtensionInstallPrompt> {
+ : public base::SupportsWeakPtr<ExtensionInstallPrompt> {
public:
+ // A setting to cause extension/app installs from the webstore skip the normal
+ // confirmation dialog. This should only be used in tests.
+ enum AutoConfirmForTests {
+ NONE, // The prompt will show normally.
+ ACCEPT, // The prompt will always accept.
+ CANCEL, // The prompt will always cancel.
+ };
+ static AutoConfirmForTests g_auto_confirm_for_tests;
+
// This enum is associated with Extensions.InstallPrompt_Type UMA histogram.
// Do not modify existing values and add new values only to the end.
enum PromptType {
EXTERNAL_INSTALL_PROMPT,
POST_INSTALL_PERMISSIONS_PROMPT,
LAUNCH_PROMPT,
+ REMOTE_INSTALL_PROMPT,
+ REPAIR_PROMPT,
NUM_PROMPT_TYPES
};
+ // Enumeration for permissions and retained files details.
enum DetailsType {
PERMISSIONS_DETAILS = 0,
- OAUTH_DETAILS,
+ WITHHELD_PERMISSIONS_DETAILS,
RETAINED_FILES_DETAILS,
+ RETAINED_DEVICES_DETAILS,
};
+ // This enum is used to differentiate regular and withheld permissions for
+ // segregation in the install prompt.
+ enum PermissionsType {
+ REGULAR_PERMISSIONS = 0,
+ WITHHELD_PERMISSIONS,
+ ALL_PERMISSIONS,
+ };
+
+ static std::string PromptTypeToString(PromptType type);
+
// Extra information needed to display an installation or uninstallation
// prompt. Gets populated with raw data and exposes getters for formatted
// strings so that the GTK/views/Cocoa install dialogs don't have to repeat
// that logic.
- class Prompt {
+ // Ref-counted because we pass around the prompt independent of the full
+ // ExtensionInstallPrompt.
+ class Prompt : public base::RefCountedThreadSafe<Prompt> {
public:
explicit Prompt(PromptType type);
- ~Prompt();
// Sets the permission list for this prompt.
- void SetPermissions(const std::vector<base::string16>& permissions);
+ void SetPermissions(const std::vector<base::string16>& permissions,
+ PermissionsType permissions_type);
// Sets the permission list details for this prompt.
- void SetPermissionsDetails(const std::vector<base::string16>& details);
+ void SetPermissionsDetails(const std::vector<base::string16>& details,
+ PermissionsType permissions_type);
void SetIsShowingDetails(DetailsType type,
size_t index,
bool is_showing_details);
bool show_user_count,
double average_rating,
int rating_count);
- void SetOAuthIssueAdvice(const IssueAdviceInfo& issue_advice);
void SetUserNameFromProfile(Profile* profile);
PromptType type() const { return type_; }
base::string16 GetAcceptButtonLabel() const;
bool HasAbortButtonLabel() const;
base::string16 GetAbortButtonLabel() const;
- base::string16 GetPermissionsHeading() const;
- base::string16 GetOAuthHeading() const;
+ base::string16 GetPermissionsHeading(
+ PermissionsType permissions_type) const;
base::string16 GetRetainedFilesHeading() const;
+ base::string16 GetRetainedDevicesHeading() const;
bool ShouldShowPermissions() const;
bool ShouldShowExplanationText() const;
void AppendRatingStars(StarAppender appender, void* data) const;
base::string16 GetRatingCount() const;
base::string16 GetUserCount() const;
- size_t GetPermissionCount() const;
- size_t GetPermissionsDetailsCount() const;
- base::string16 GetPermission(size_t index) const;
- base::string16 GetPermissionsDetails(size_t index) const;
+ size_t GetPermissionCount(PermissionsType permissions_type) const;
+ size_t GetPermissionsDetailsCount(PermissionsType permissions_type) const;
+ base::string16 GetPermission(size_t index,
+ PermissionsType permissions_type) const;
+ base::string16 GetPermissionsDetails(
+ size_t index,
+ PermissionsType permissions_type) const;
bool GetIsShowingDetails(DetailsType type, size_t index) const;
- size_t GetOAuthIssueCount() const;
- const IssueAdviceInfoEntry& GetOAuthIssue(size_t index) const;
size_t GetRetainedFileCount() const;
base::string16 GetRetainedFile(size_t index) const;
+ size_t GetRetainedDeviceCount() const;
+ base::string16 GetRetainedDeviceMessageString(size_t index) const;
// Populated for BUNDLE_INSTALL_PROMPT.
const extensions::BundleInstaller* bundle() const { return bundle_; }
void set_retained_files(const std::vector<base::FilePath>& retained_files) {
retained_files_ = retained_files;
}
+ void set_retained_device_messages(
+ const std::vector<base::string16>& retained_device_messages) {
+ retained_device_messages_ = retained_device_messages;
+ }
const gfx::Image& icon() const { return icon_; }
void set_icon(const gfx::Image& icon) { icon_ = icon; }
bool has_webstore_data() const { return has_webstore_data_; }
const ExtensionInstallPromptExperiment* experiment() const {
- return experiment_;
+ return experiment_.get();
}
void set_experiment(ExtensionInstallPromptExperiment* experiment) {
experiment_ = experiment;
}
private:
+ friend class base::RefCountedThreadSafe<Prompt>;
+
+ struct InstallPromptPermissions {
+ InstallPromptPermissions();
+ ~InstallPromptPermissions();
+
+ std::vector<base::string16> permissions;
+ std::vector<base::string16> details;
+ std::vector<bool> is_showing_details;
+ };
+
+ virtual ~Prompt();
+
+ bool ShouldDisplayRevokeButton() const;
+
+ // Returns the InstallPromptPermissions corresponding to
+ // |permissions_type|.
+ InstallPromptPermissions& GetPermissionsForType(
+ PermissionsType permissions_type);
+ const InstallPromptPermissions& GetPermissionsForType(
+ PermissionsType permissions_type) const;
+
bool ShouldDisplayRevokeFilesButton() const;
PromptType type_;
// Permissions that are being requested (may not be all of an extension's
// permissions if only additional ones are being requested)
- std::vector<base::string16> permissions_;
- std::vector<base::string16> details_;
- std::vector<bool> is_showing_details_for_permissions_;
- std::vector<bool> is_showing_details_for_oauth_;
- bool is_showing_details_for_retained_files_;
+ InstallPromptPermissions prompt_permissions_;
+ // Permissions that will be withheld upon install.
+ InstallPromptPermissions withheld_prompt_permissions_;
- // Descriptions and details for OAuth2 permissions to display to the user.
- // These correspond to permission scopes.
- IssueAdviceInfo oauth_issue_advice_;
-
- // User name to be used in Oauth heading label.
- base::string16 oauth_user_name_;
+ bool is_showing_details_for_retained_files_;
+ bool is_showing_details_for_retained_devices_;
// The extension or bundle being installed.
const extensions::Extension* extension_;
bool has_webstore_data_;
std::vector<base::FilePath> retained_files_;
+ std::vector<base::string16> retained_device_messages_;
scoped_refptr<ExtensionInstallPromptExperiment> experiment_;
+
+ DISALLOW_COPY_AND_ASSIGN(Prompt);
};
static const int kMinExtensionRating = 0;
virtual ~Delegate() {}
};
- // Parameters to show a prompt dialog. Two sets of the
- // parameters are supported: either use a parent WebContents or use a
- // parent NativeWindow + a PageNavigator.
- struct ShowParams {
- explicit ShowParams(content::WebContents* contents);
- ShowParams(gfx::NativeWindow window, content::PageNavigator* navigator);
-
- // Parent web contents of the install UI dialog. This can be NULL.
- content::WebContents* parent_web_contents;
-
- // NativeWindow parent and navigator. If initialized using a parent web
- // contents, these are derived from it.
- gfx::NativeWindow parent_window;
- content::PageNavigator* navigator;
- };
-
- typedef base::Callback<void(const ExtensionInstallPrompt::ShowParams&,
+ typedef base::Callback<void(ExtensionInstallPromptShowParams*,
ExtensionInstallPrompt::Delegate*,
- const ExtensionInstallPrompt::Prompt&)>
+ scoped_refptr<ExtensionInstallPrompt::Prompt>)>
ShowDialogCallback;
// Callback to show the default extension install dialog.
// Creates a prompt with a parent web content.
explicit ExtensionInstallPrompt(content::WebContents* contents);
- // Creates a prompt with a profile, a native window and a page navigator.
- ExtensionInstallPrompt(Profile* profile,
- gfx::NativeWindow native_window,
- content::PageNavigator* navigator);
+ // Creates a prompt with a profile and a native window. The most recently
+ // active browser window (or a new browser window if there are no browser
+ // windows) is used if a new tab needs to be opened.
+ ExtensionInstallPrompt(Profile* profile, gfx::NativeWindow native_window);
virtual ~ExtensionInstallPrompt();
- ExtensionInstallUI* install_ui() const { return install_ui_.get(); }
-
- bool record_oauth2_grant() const { return record_oauth2_grant_; }
-
- content::WebContents* parent_web_contents() const {
- return show_params_.parent_web_contents;
+ extensions::ExtensionInstallUI* install_ui() const {
+ return install_ui_.get();
}
// This is called by the bundle installer to verify whether the bundle
virtual void ConfirmStandaloneInstall(Delegate* delegate,
const extensions::Extension* extension,
SkBitmap* icon,
- const Prompt& prompt);
+ scoped_refptr<Prompt> prompt);
// This is called by the installer to verify whether the installation from
// the webstore should proceed. |show_dialog_callback| is optional and can be
Delegate* delegate,
const extensions::Extension* extension,
const ShowDialogCallback& show_dialog_callback,
- const Prompt& prompt);
+ scoped_refptr<Prompt> prompt);
// This is called by the extension permissions API to verify whether an
// extension may be granted additional permissions.
const extensions::Extension* extension,
const extensions::PermissionSet* permissions);
- // This is called by the extension identity API to verify whether an
- // extension can be granted an OAuth2 token.
- //
- // We *MUST* eventually call either Proceed() or Abort() on |delegate|.
- virtual void ConfirmIssueAdvice(Delegate* delegate,
- const extensions::Extension* extension,
- const IssueAdviceInfo& issue_advice);
-
// This is called by the app handler launcher to review what permissions the
// extension or app currently has.
//
virtual void ReviewPermissions(
Delegate* delegate,
const extensions::Extension* extension,
- const std::vector<base::FilePath>& retained_file_paths);
+ const std::vector<base::FilePath>& retained_file_paths,
+ const std::vector<base::string16>& retained_device_messages);
// Installation was successful. This is declared virtual for testing.
virtual void OnInstallSuccess(const extensions::Extension* extension,
// Installation failed. This is declared virtual for testing.
virtual void OnInstallFailure(const extensions::CrxInstallerError& error);
+ void set_callback_for_test(const ShowDialogCallback& show_dialog_callback) {
+ show_dialog_callback_ = show_dialog_callback;
+ }
+
protected:
friend class extensions::ExtensionWebstorePrivateApiTest;
- friend class extensions::MockGetAuthTokenFunction;
friend class WebstoreStartupInstallUnpackFailureTest;
// Whether or not we should record the oauth2 grant upon successful install.
// 2) Handle the load icon response and show the UI (OnImageLoaded).
void LoadImageIfNeeded();
- // OAuth2TokenService::Consumer implementation:
- virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
- const std::string& access_token,
- const base::Time& expiration_time) OVERRIDE;
- virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
- const GoogleServiceAuthError& error) OVERRIDE;
-
- // OAuth2MintTokenFlow::Delegate implementation:
- virtual void OnIssueAdviceSuccess(
- const IssueAdviceInfo& issue_advice) OVERRIDE;
- virtual void OnMintTokenFailure(
- const GoogleServiceAuthError& error) OVERRIDE;
-
// Shows the actual UI (the icon should already be loaded).
void ShowConfirmation();
+ Profile* profile_;
+
base::MessageLoop* ui_loop_;
// The extensions installation icon.
// The bundle we are showing the UI for, if type BUNDLE_INSTALL_PROMPT.
const extensions::BundleInstaller* bundle_;
- // The permissions being prompted for.
- scoped_refptr<const extensions::PermissionSet> permissions_;
+ // A custom set of permissions to show in the install prompt instead of the
+ // extension's active permissions.
+ scoped_refptr<const extensions::PermissionSet> custom_permissions_;
// The object responsible for doing the UI specific actions.
- scoped_ptr<ExtensionInstallUI> install_ui_;
+ scoped_ptr<extensions::ExtensionInstallUI> install_ui_;
// Parameters to show the confirmation UI.
- ShowParams show_params_;
+ scoped_ptr<ExtensionInstallPromptShowParams> show_params_;
// The delegate we will call Proceed/Abort on after confirmation UI.
Delegate* delegate_;
// A pre-filled prompt.
- Prompt prompt_;
-
- scoped_ptr<OAuth2TokenService::Request> login_token_request_;
- scoped_ptr<OAuth2MintTokenFlow> token_flow_;
+ scoped_refptr<Prompt> prompt_;
// Used to show the confirm dialog.
ShowDialogCallback show_dialog_callback_;