Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1366)

Unified Diff: chrome/browser/extensions/webstore_bundle.h

Issue 8391004: Add webstorePrivate API for installing bundles of extensions. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/webstore_bundle.h
diff --git a/chrome/browser/extensions/webstore_bundle.h b/chrome/browser/extensions/webstore_bundle.h
new file mode 100644
index 0000000000000000000000000000000000000000..6969bb0daa608e519c66bc7c4c15554bc9a47fdb
--- /dev/null
+++ b/chrome/browser/extensions/webstore_bundle.h
@@ -0,0 +1,249 @@
+// Copyright (c) 2011 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_WEBSTORE_BUNDLE_H_
+#define CHROME_BROWSER_EXTENSIONS_WEBSTORE_BUNDLE_H_
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include "base/memory/scoped_vector.h"
+#include "chrome/browser/extensions/extension_install_ui.h"
+#include "chrome/browser/extensions/webstore_installer.h"
+#include "chrome/browser/extensions/webstore_install_helper.h"
+#include "chrome/common/extensions/extension.h"
+#include "content/public/browser/notification_registrar.h"
+
+class Browser;
+class Profile;
+
+// Manages the installation life cycle for bundles of extensions.
+//
+// The normal flow for successful installs is:
+//
+// Part A: user approval
+// 1. A WebstoreBundle is created with a list of items in STATE_INITIAL.
+// 2. PromptForApproval: starts parsing all the extension manifest data.
+// 3. OnWebstoreParseSuccess: creates the dummy extension out of the parsed
+// manifest data, moving items into STATE_PARSED. If no more items are in
+// STATE_INITIAL, calls ShowPrompt to display the install prompt.
+// 4. ShowPrompt: calculates the total permissions for items in STATE_PARSED,
+// and displays the install prompt.
+// 5. InstallUIProceed: transitions all STATE_PARSED items to STATE_APPROVED and
+// notifies the delegate via OnBundleInstallApproved.
+//
+// Part B: download and install
+// 1. CompleteInstall: starts installing the items by calling InstallNextItem.
+// 2. InstallNextItem: downloads and installs the first item in STATE_APPROVED.
+// 3. OnExtensionInstallSuccess: moves the item to STATE_INSTALLED and starts
+// installing the next item via InstallNextItem.
+// 4. InstallNextItem: when no more items are in STATE_APPROVED, this calls
+// ShowInstalledBubble to display the status bubble.
+// 5. ShowInstalledBubble: platform specific implementation that shows which
+// items succeeded and failed via the installed bubble.
+//
+// The normal state transitions for items are:
+// STATE_INITIAL -> STATE_PARSED -> STATE_APPROVED -> STATE_INSTALLED
+//
+// Items transition to STATE_NOT_INSTALLED if they fail any step of the flow.
+//
+class WebstoreBundle : public WebstoreInstallHelper::Delegate,
+ public ExtensionInstallUI::Delegate,
+ public WebstoreInstaller::Delegate,
+ public base::RefCounted<WebstoreBundle> {
+ public:
+ // Auto approve or cancel the permission prompt.
+ // Note: this should only be used for testing!
+ static void SetAutoApproveForTesting(bool approve);
+
+ class Delegate {
+ public:
+ virtual void OnBundleInstallApproved() {}
+ virtual void OnBundleInstallCanceled(bool user_initiated) {}
+ virtual void OnBundleInstallCompleted() {}
+ };
+
+ // Represents an individual member of the bundle.
+ // TODO(jstritar): we can probably combine this with WebstoreInstaller, and
+ // have one class that handles the life cycle of a single extension install.
+ class Item {
+ public:
+ enum State {
+ STATE_INITIAL = 0,
+
+ // The item's manfiest has been parsed and dummy extension created.
+ STATE_PARSED,
+
+ // The user has approved the item's permissions.
+ STATE_APPROVED,
+
+ // The item has been downloaded and installed successfully.
+ STATE_INSTALLED,
+
+ // The item has failed at any step.
+ STATE_NOT_INSTALLED
+ };
+
+ Item(const std::string& id,
+ const std::string& manifest,
+ const std::string& localized_name);
+ ~Item();
+
+ // Parses a dummy extension from the |parsed_manifest|.
+ void SetDummyExtension(base::DictionaryValue* parsed_manifest);
+
+ void MarkApproved() { state_ = STATE_APPROVED; }
+ void MarkInstalled() { state_ = STATE_INSTALLED; }
+ void MarkNotInstalled() { state_ = STATE_NOT_INSTALLED; }
+
+ State state() const { return state_; }
+
+ const std::string& id() const { return id_; }
+ const std::string& manifest() const { return manifest_; }
+ const std::string& localized_name() const { return localized_name_; }
+
+ // These two fields are only available after the STATE_PARSED stage.
+ // The dummy extension is created from the parsed manifest, and is used
+ // when displaying the install prompt.
+ scoped_refptr<Extension> dummy_extension() const {
+ return dummy_extension_;
+ }
+ base::DictionaryValue* parsed_manifest() const {
+ return parsed_manifest_.get();
+ }
+
+ private:
+ std::string id_;
+ std::string manifest_;
+ std::string localized_name_;
+
+ State state_;
+ scoped_ptr<base::DictionaryValue> parsed_manifest_;
+ scoped_refptr<Extension> dummy_extension_;
+
+ DISALLOW_COPY_AND_ASSIGN(Item);
+ };
+
+ enum ItemMatcher {
+ MATCH_EXTENSIONS = 1 << 0,
+ MATCH_APPS = 1 << 1,
+ MATCH_ALL = (1 << 2) - 1
+ };
+
+ typedef ScopedVector<Item> ItemList;
+
+ // Passes ownership of the items.
+ WebstoreBundle(Profile* profile, ItemList* items);
+ virtual ~WebstoreBundle();
+
+ // Parses the extension manifests and then prompts the user to approve their
+ // permissions. One of OnBundleInstallApproved or OnBundleInstallCanceled
+ // will be called when complete if |delegate| is not NULL.
+ // Note: the |delegate| must stay alive until receiving the callback.
+ void PromptForApproval(Delegate* delegate);
+
+ // If the bundle has been approved, this downloads and installs the member
+ // extensions. OnBundleInstallComplete will be called when the process is
+ // complete and |delegate| is not NULL. The download process uses the
+ // specified |controller|.
+ // Note: the |delegate| must stay alive until receiving the callback.
+ void CompleteInstall(NavigationController* controller, Delegate* delegate);
+
+ // Returns true if this is the same bundle as |ids|.
+ bool IsSameBundle(const std::vector<std::string>& ids);
+
+ // Returns the list of member items in the given |state| that match
+ // the specified |matcher| flags.
+ // Note: the WebstoreBundle retains ownership of the items.
+ std::vector<const Item*> GetItemsInState(
+ Item::State state, int matcher) const;
+
+ // Gets the prompt heading text for the bundle of items to be installed.
+ string16 GetHeadingTextForPrompt() const;
+
+ // Gets the installed bubble heading text for the bundle items that were
+ // successfully installed, or an empty string if none were.
+ string16 GetInstalledHeadingTextForBubble() const;
+
+ // Gets the installed bubble heading text for the bundle items that failed to
+ // install, or an empty string if they all succeeded.
+ string16 GetFailedHeadingTextForBubble() const;
+
+ // Returns true if this has apps that are in |state|.
+ bool HasAppsInState(Item::State state) const;
+
+ // Returns true if this has extensions that are in |state|.
+ bool HasExtensionsInState(Item::State state) const;
+
+ // WebstoreInstallHelper::Delegate implementation:
+ virtual void OnWebstoreParseSuccess(
+ const std::string& id,
+ const SkBitmap& icon,
+ base::DictionaryValue* parsed_manifest) OVERRIDE;
+ virtual void OnWebstoreParseFailure(
+ const std::string& id,
+ InstallHelperResultCode result_code,
+ const std::string& error_message) OVERRIDE;
+
+ // ExtensionInstallUI::Delegate implementation:
+ virtual void InstallUIProceed() OVERRIDE;
+ virtual void InstallUIAbort(bool user_initiated) OVERRIDE;
+
+ // WebstoreInstaller::Delegate implementation:
+ virtual void OnExtensionInstallSuccess(const std::string& id) OVERRIDE;
+ virtual void OnExtensionInstallFailure(const std::string& id,
+ const std::string& error) OVERRIDE;
+
+ private:
+ // Gets the item for the given extension |id|.
+ Item* GetItemById(const std::string& id);
+
+ // Parses the member item's manifests using the WebstoreInstallHelper.
+ void ParseManifests();
+
+ // Only one WebstoreInstaller can be active for a given controller, so
+ // we install extensions in series. This method starts downloading the next
+ // extension in STATE_APPROVED.
+ void InstallNextItem();
+
+ // Notifies the delegate that the installation has been approved.
+ void ReportApproved();
+
+ // Notifies the delegate that the installation was canceled.
+ void ReportCanceled(bool user_initiated);
+
+ // Notifies the delegate that the installation is complete.
+ void ReportComplete();
+
+ // Prompts the user to install the bundle if there are no more member items in
+ // STATE_INITIAL.
+ void ShowPromptIfDoneParsing();
+
+ // Prompts the user to install the bundle.
+ void ShowPrompt();
+
+ // Displays the install bubble if all member items are in STATE_INSTALLED or
+ // STATE_NOT_INSTALLED.
+ void ShowInstalledBubbleIfDone();
+
+ // Displays the install bubble for |bundle| on |browser|.
+ // Note: this is a platform specific implementation.
+ static void ShowInstalledBubble(const WebstoreBundle* bundle,
+ Browser* browser);
+
+ ItemList items_;
+
+ // The profile that the bundle should be installed in.
+ Profile* profile_;
+
+ // The controller that the webstore installer should use.
+ NavigationController* controller_;
+
+ Delegate* delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebstoreBundle);
+};
+
+#endif // CHROME_BROWSER_EXTENSIONS_WEBSTORE_BUNDLE_H_
« no previous file with comments | « chrome/browser/extensions/extension_webstore_private_api.cc ('k') | chrome/browser/extensions/webstore_bundle.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698