1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
|
// Copyright 2012 The Chromium Authors
// 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_INSTALLER_H_
#define CHROME_BROWSER_EXTENSIONS_WEBSTORE_INSTALLER_H_
#include <list>
#include <memory>
#include <string>
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "base/timer/timer.h"
#include "base/version.h"
#include "components/download/public/common/download_interrupt_reasons.h"
#include "components/download/public/common/download_item.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/extension_registry_observer.h"
#include "extensions/browser/install/crx_install_error.h"
#include "extensions/buildflags/buildflags.h"
#include "extensions/common/manifest_handlers/shared_module_info.h"
#include "url/gurl.h"
static_assert(BUILDFLAG(ENABLE_EXTENSIONS_CORE));
class Profile;
namespace base {
class FilePath;
}
namespace content {
class WebContents;
}
namespace extensions {
class CrxInstaller;
class Extension;
class ExtensionRegistry;
struct InstallApproval;
// Downloads and installs extensions from the web store.
class WebstoreInstaller : public ExtensionRegistryObserver,
public download::DownloadItem::Observer,
public base::RefCountedThreadSafe<
WebstoreInstaller,
content::BrowserThread::DeleteOnUIThread> {
public:
enum InstallSource {
// Inline installs trigger slightly different behavior (install source
// is different, download referrers are the item's page in the gallery).
// TODO(ackermanb): Remove once server side metrics (omaha) tracking with
// this enum is figured out with any of the subclasses of
// WebstoreStandaloneInstaller.
INSTALL_SOURCE_INLINE,
INSTALL_SOURCE_APP_LAUNCHER,
INSTALL_SOURCE_OTHER
};
enum FailureReason {
FAILURE_REASON_CANCELLED,
FAILURE_REASON_DEPENDENCY_NOT_FOUND,
FAILURE_REASON_DEPENDENCY_NOT_SHARED_MODULE,
FAILURE_REASON_OTHER
};
using SuccessCallback = base::OnceCallback<void(const std::string&)>;
using FailureCallback = base::OnceCallback<
void(const std::string&, const std::string&, FailureReason)>;
// Gets the InstallApproval associated with the `download`, or nullptr if
// there's none. Note that the InstallApproval is owned by `download`.
static const InstallApproval* GetAssociatedApproval(
const download::DownloadItem& download);
// Creates a WebstoreInstaller for downloading and installing the extension
// with the given `id` from the Chrome Web Store. The `success_callback` and
// `failure_callback` parameters must not be null. This also associates the
// `approval` with this install.
WebstoreInstaller(Profile* profile,
SuccessCallback success_callback,
FailureCallback failure_callback,
content::WebContents* web_contents,
const std::string& id,
std::unique_ptr<InstallApproval> approval,
InstallSource source);
// Starts downloading and installing the extension.
void Start();
// ExtensionRegistryObserver.
void OnExtensionInstalled(content::BrowserContext* browser_context,
const Extension* extension,
bool is_update) override;
// Instead of using the default download directory, use `directory` instead.
// This does *not* transfer ownership of `directory`.
static void SetDownloadDirectoryForTests(base::FilePath* directory);
protected:
// For testing.
~WebstoreInstaller() override;
private:
FRIEND_TEST_ALL_PREFIXES(WebstoreInstallerTest, PlatformParams);
friend struct content::BrowserThread::DeleteOnThread<
content::BrowserThread::UI>;
friend class base::DeleteHelper<WebstoreInstaller>;
// Helper to get install URL.
static GURL GetWebstoreInstallURL(const std::string& extension_id,
InstallSource source);
// DownloadManager::DownloadUrl callback.
void OnDownloadStarted(const std::string& extension_id,
download::DownloadItem* item,
download::DownloadInterruptReason interrupt_reason);
// DownloadItem::Observer implementation:
void OnDownloadUpdated(download::DownloadItem* download) override;
void OnDownloadDestroyed(download::DownloadItem* download) override;
// Downloads next pending module in `pending_modules_`.
void DownloadNextPendingModule();
// Downloads and installs a single Crx with the given `extension_id`.
// This function is used for both the extension Crx and dependences.
void DownloadCrx(const std::string& extension_id, InstallSource source);
// Starts downloading the extension with ID `extension_id` to `file_path`.
void StartDownload(const std::string& extension_id,
const base::FilePath& file_path);
// Updates the InstallTracker with the latest download progress.
void UpdateDownloadProgress();
// Creates and starts CrxInstaller for the downloaded extension package.
void StartCrxInstaller(const download::DownloadItem& item);
// Reports an install `error` to the delegate for the given extension if this
// managed its installation. This also removes the associated PendingInstall.
void ReportFailure(const std::string& error, FailureReason reason);
// Reports a successful install to the delegate for the given extension if
// this managed its installation. This also removes the associated
// PendingInstall.
void ReportSuccess();
// Called when crx_installer_->InstallCrx() finishes.
void OnInstallerDone(const std::optional<CrxInstallError>& error);
base::ScopedObservation<ExtensionRegistry, ExtensionRegistryObserver>
extension_registry_observation_{this};
base::WeakPtr<content::WebContents> web_contents_;
raw_ptr<Profile> profile_;
SuccessCallback success_callback_;
FailureCallback failure_callback_;
std::string id_;
InstallSource install_source_;
// The DownloadItem is owned by the DownloadManager and is valid from when
// OnDownloadStarted is called (with no error) until OnDownloadDestroyed().
raw_ptr<download::DownloadItem, DanglingUntriaged> download_item_ = nullptr;
// Used to periodically update the extension's download status. This will
// trigger at least every second, though sometimes more frequently (depending
// on number of modules, etc).
base::OneShotTimer download_progress_timer_;
std::unique_ptr<InstallApproval> approval_;
GURL download_url_;
scoped_refptr<CrxInstaller> crx_installer_;
// Pending modules.
std::list<SharedModuleInfo::ImportInfo> pending_modules_;
// Total extension modules we need download and install (the main module and
// depedences).
int total_modules_ = 0;
bool download_started_ = false;
base::WeakPtrFactory<WebstoreInstaller> weak_ptr_factory_{this};
};
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_WEBSTORE_INSTALLER_H_
|