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 189 190 191 192 193 194 195 196
|
// Copyright 2017 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_ASH_EXTENSIONS_EXTERNAL_CACHE_IMPL_H_
#define CHROME_BROWSER_ASH_EXTENSIONS_EXTERNAL_CACHE_IMPL_H_
#include <memory>
#include <set>
#include <string>
#include <vector>
#include "base/callback_list.h"
#include "base/files/file_path.h"
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/task/sequenced_task_runner.h"
#include "chrome/browser/ash/extensions/external_cache.h"
#include "chrome/browser/extensions/updater/local_extension_cache.h"
#include "extensions/browser/updater/extension_downloader_delegate.h"
#include "extensions/common/extension_id.h"
#include "net/base/backoff_entry.h"
namespace content {
class BrowserContext;
}
namespace extensions {
class ExtensionDownloader;
}
namespace network {
class SharedURLLoaderFactory;
}
namespace chromeos {
class ExternalCacheDelegate;
// The ExternalCacheImpl manages a cache for external extensions.
class ExternalCacheImpl : public ExternalCache,
public extensions::ExtensionDownloaderDelegate {
public:
// The |url_loader_factory| is used for update checks. All file I/O is done
// via the |backend_task_runner|. If |always_check_updates| is |false|, update
// checks are performed for extensions that have an |external_update_url|
// only. If |wait_for_cache_initialization| is |true|, the cache contents will
// not be read until a flag file appears in the cache directory, signaling
// that the cache is ready. By default ExternalCacheImpl updates the cache at
// startup and when policy changes (UpdateExtensionsList is called). However,
// if both |allow_scheduled_updates| and the KioskCRXManifestUpdateURLIgnored
// are|true|, the ExternalCache will run additional update checks from time
// to time (about very 5 hours, as per kDefaultUpdateFrequencySeconds).
// Currently it's only enabled for Chrome App Kiosk, see description of the
// KioskCRXManifestUpdateURLIgnored policy for details.
// TODO(https://crbug.com/1262158) Postpone starting new update check when the
// previous one is not finished yet.
ExternalCacheImpl(
const base::FilePath& cache_dir,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
const scoped_refptr<base::SequencedTaskRunner>& backend_task_runner,
ExternalCacheDelegate* delegate,
bool always_check_updates,
bool wait_for_cache_initialization,
bool allow_scheduled_updates);
ExternalCacheImpl(const ExternalCacheImpl&) = delete;
ExternalCacheImpl& operator=(const ExternalCacheImpl&) = delete;
~ExternalCacheImpl() override;
// Implementation of ExternalCache:
const base::Value::Dict& GetCachedExtensions() override;
void Shutdown(base::OnceClosure callback) override;
void UpdateExtensionsList(base::Value::Dict prefs) override;
void OnDamagedFileDetected(const base::FilePath& path) override;
void RemoveExtensions(
const std::vector<extensions::ExtensionId>& ids) override;
bool GetExtension(const extensions::ExtensionId& id,
base::FilePath* file_path,
std::string* version) override;
bool ExtensionFetchPending(const extensions::ExtensionId& id) override;
void PutExternalExtension(const extensions::ExtensionId& id,
const base::FilePath& crx_file_path,
const std::string& version,
PutExternalExtensionCallback callback) override;
void SetBackoffPolicy(
std::optional<net::BackoffEntry::Policy> backoff_policy) override;
// Implementation of ExtensionDownloaderDelegate:
void OnExtensionDownloadFailed(const extensions::ExtensionId& id,
Error error,
const PingResult& ping_result,
const std::set<int>& request_ids,
const FailureData& data) override;
void OnExtensionDownloadFinished(const extensions::CRXFileInfo& file,
bool file_ownership_passed,
const GURL& download_url,
const PingResult& ping_result,
const std::set<int>& request_ids,
InstallCallback callback) override;
bool IsExtensionPending(const extensions::ExtensionId& id) override;
bool GetExtensionExistingVersion(const extensions::ExtensionId& id,
std::string* version) override;
RequestRollbackResult RequestRollback(
const extensions::ExtensionId& id) override;
void set_flush_on_put(bool flush_on_put) { flush_on_put_ = flush_on_put; }
private:
class AnyInstallFailureObserver;
// Notifies the that the cache has been updated, providing
// extensions loader with an updated list of extensions.
void UpdateExtensionLoader();
// Checks the cache contents and initiate download if needed.
void CheckCache();
// Schedule a new cache check in some near future (around 5 hours, according
// to kDefaultUpdateFrequencySeconds) if a corresponding policy and flag
// enable this.
void MaybeScheduleNextCacheCheck();
// Invoked on the UI thread when a new entry has been installed in the cache.
void OnPutExtension(const extensions::ExtensionId& id,
const base::FilePath& file_path,
bool file_ownership_passed);
// Invoked on the UI thread when the external extension has been installed
// in the local cache by calling PutExternalExtension.
void OnPutExternalExtension(const extensions::ExtensionId& id,
PutExternalExtensionCallback callback,
const base::FilePath& file_path,
bool file_ownership_passed);
// Removes the cached file for |id| from |cached_extensions_| and
// |local_cache_| and notifies the |delegate_|. This method should be followed
// by a call to UpdateExtensionLoader().
void RemoveCachedExtension(const extensions::ExtensionId& id);
void OnCrxInstallFailure(content::BrowserContext* context,
const base::FilePath& source_file);
std::unique_ptr<AnyInstallFailureObserver> any_install_failure_observer_;
extensions::LocalExtensionCache local_cache_;
// URL lader factory used by the |downloader_|.
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
// Task runner for executing file I/O tasks.
const scoped_refptr<base::SequencedTaskRunner> backend_task_runner_;
// Delegate that would like to get notifications about cache updates.
raw_ptr<ExternalCacheDelegate> delegate_;
// Updates needs to be check for the extensions with external_crx too.
bool always_check_updates_;
// Set to true if cache should wait for initialization flag file.
bool wait_for_cache_initialization_;
// Set to true if scheduled updated are possible, currently in kiosk mode.
bool allow_scheduled_updates_;
// Whether to flush the crx file after putting into |local_cache_|.
bool flush_on_put_ = false;
// This is the list of extensions currently configured.
base::Value::Dict extensions_;
// This contains extensions that are both currently configured
// and that have a valid crx in the cache.
base::Value::Dict cached_extensions_;
// Used to download the extensions and to check for updates.
std::unique_ptr<extensions::ExtensionDownloader> downloader_;
// Backoff policy of extension downloader.
std::optional<net::BackoffEntry::Policy> backoff_policy_;
// Used to observe CrosSettings.
base::CallbackListSubscription kiosk_crx_updates_from_policy_subscription_;
// Weak factody for scheduled updates.
base::WeakPtrFactory<ExternalCacheImpl> scheduler_weak_ptr_factory_{this};
// Weak factory for callbacks.
base::WeakPtrFactory<ExternalCacheImpl> weak_ptr_factory_{this};
};
} // namespace chromeos
#endif // CHROME_BROWSER_ASH_EXTENSIONS_EXTERNAL_CACHE_IMPL_H_
|