blob: 61bf273aeb05f322ce13810cb9b8138891fafadf [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_EXTENSIONS_BUNDLE_INSTALLER_H_
#define CHROME_BROWSER_EXTENSIONS_BUNDLE_INSTALLER_H_
#include <string>
#include <vector>
#include "base/callback_forward.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
#include "chrome/browser/extensions/extension_install_prompt.h"
#include "chrome/browser/extensions/webstore_install_helper.h"
#include "chrome/browser/extensions/webstore_installer.h"
#include "chrome/browser/ui/browser_list_observer.h"
#include "chrome/browser/ui/host_desktop.h"
#include "extensions/common/extension.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "url/gurl.h"
namespace base {
class DictionaryValue;
} // namespace base
namespace content {
class WebContents;
} // namespace content
class Browser;
class Profile;
namespace extensions {
// Manages the installation life cycle for extension bundles.
//
// We install bundles in two steps:
// 1) PromptForApproval: parse manifests and prompt the user
// 2) CompleteInstall: install the CRXs and show confirmation bubble
//
class BundleInstaller : public WebstoreInstallHelper::Delegate,
public ExtensionInstallPrompt::Delegate,
public WebstoreInstaller::Delegate,
public chrome::BrowserListObserver {
public:
// Auto approve or cancel the permission prompt.
static void SetAutoApproveForTesting(bool approve);
// Represents an individual member of the bundle.
struct Item {
// Items are in the PENDING state until they've been installed, or the
// install has failed or been canceled.
enum State {
STATE_PENDING,
STATE_INSTALLED,
STATE_FAILED
};
Item();
~Item();
// Gets the localized name, formatted for display in the bubble.
base::string16 GetNameForDisplay() const;
std::string id;
std::string manifest;
std::string localized_name;
GURL icon_url;
SkBitmap icon;
State state;
};
enum ApprovalState {
APPROVED,
USER_CANCELED,
APPROVAL_ERROR
};
typedef base::Callback<void(ApprovalState)> ApprovalCallback;
typedef std::vector<Item> ItemList;
BundleInstaller(Browser* browser,
const std::string& localized_name,
const SkBitmap& icon,
const std::string& authuser,
const std::string& delegated_username,
const ItemList& items);
~BundleInstaller() override;
// Returns true if the user has approved the bundle's permissions.
bool approved() const { return approved_; }
// Returns the browser window associated with the bundle's installation.
// Can return null if the browser is closed during the installation.
Browser* browser() { return browser_; }
// Gets the items in the given |state|.
ItemList GetItemsWithState(Item::State state) const;
// Returns whether there is at least one item with the given |state|.
bool HasItemWithState(Item::State state) const;
// Returns the number of items with the given |state|.
size_t CountItemsWithState(Item::State state) const;
// Parses the extension manifests and then prompts the user to approve their
// permissions.
void PromptForApproval(const ApprovalCallback& callback);
// If the bundle has been approved, this downloads and installs the member
// extensions. The download process uses the NavigationController of the
// specified |web_contents|. When complete, we show a confirmation bubble.
void CompleteInstall(content::WebContents* web_contents,
const base::Closure& callback);
// We change the headings in the install prompt and installed bubble depending
// on whether the bundle contains apps, extensions or both. This method gets
// the correct heading for the items in the specified |state|, or an empty
// string if no items are in the |state|.
// STATE_PENDING - install prompt
// STATE_INSTALLED - installed bubble successful installs list
// STATE_FAILED - installed bubble failed installs list
base::string16 GetHeadingTextFor(Item::State state) const;
private:
typedef std::map<std::string, Item> ItemMap;
typedef std::map<std::string, linked_ptr<base::DictionaryValue> > ManifestMap;
// Displays the install bubble for |bundle| on |browser|.
// Note: this is a platform specific implementation.
static void ShowInstalledBubble(const BundleInstaller* bundle,
Browser* browser);
// Parses the manifests using WebstoreInstallHelper.
void ParseManifests();
// Prompts the user to install the bundle once we have dummy extensions for
// all the pending items.
void ShowPromptIfDoneParsing();
// Prompts the user to install the bundle.
void ShowPrompt();
// Displays the installed bubble once all items have installed or failed.
void ShowInstalledBubbleIfDone();
// WebstoreInstallHelper::Delegate implementation:
void OnWebstoreParseSuccess(const std::string& id,
const SkBitmap& icon,
base::DictionaryValue* parsed_manifest) override;
void OnWebstoreParseFailure(const std::string& id,
InstallHelperResultCode result_code,
const std::string& error_message) override;
// ExtensionInstallPrompt::Delegate implementation:
void InstallUIProceed() override;
void InstallUIAbort(bool user_initiated) override;
// WebstoreInstaller::Delegate implementation:
void OnExtensionInstallSuccess(const std::string& id) override;
void OnExtensionInstallFailure(
const std::string& id,
const std::string& error,
WebstoreInstaller::FailureReason reason) override;
// chrome::BrowserListObserver implementation:
void OnBrowserRemoved(Browser* browser) override;
// Holds the Extensions used to generate the permission warnings.
ExtensionList dummy_extensions_;
// Holds the parsed manifests, indexed by the extension ids.
ManifestMap parsed_manifests_;
// True if the user has approved the bundle.
bool approved_;
// Holds the bundle's Items, indexed by their ids.
ItemMap items_;
// The browser to show the confirmation bubble for.
Browser* browser_;
// The bundle's display name.
std::string name_;
// The bundle's icon.
SkBitmap icon_;
// The authuser query parameter value which should be used with CRX download
// requests. May be empty.
std::string authuser_;
// The display name of the user for which this install happens, in the case
// of delegated installs. Empty for regular installs.
std::string delegated_username_;
// The desktop type of the browser.
chrome::HostDesktopType host_desktop_type_;
// The profile that the bundle should be installed in.
Profile* profile_;
// The UI that shows the confirmation prompt.
scoped_ptr<ExtensionInstallPrompt> install_ui_;
ApprovalCallback approval_callback_;
base::Closure install_callback_;
DISALLOW_COPY_AND_ASSIGN(BundleInstaller);
};
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_BUNDLE_INSTALLER_H_