| Index: chrome/browser/extensions/updater/extension_downloader.cc
|
| diff --git a/chrome/browser/extensions/updater/extension_downloader.cc b/chrome/browser/extensions/updater/extension_downloader.cc
|
| index a0ea581d14b933cf521eb9512bedca6791e58fac..1e2d7414bed4ef7dcf8cfe09528fdca5460ae740 100644
|
| --- a/chrome/browser/extensions/updater/extension_downloader.cc
|
| +++ b/chrome/browser/extensions/updater/extension_downloader.cc
|
| @@ -35,6 +35,7 @@
|
| using base::Time;
|
| using base::TimeDelta;
|
| using content::BrowserThread;
|
| +using extensions::ManifestFetchData;
|
|
|
| namespace extensions {
|
|
|
| @@ -106,14 +107,17 @@ ExtensionDownloader::ExtensionFetch::ExtensionFetch()
|
| : id(""),
|
| url(),
|
| package_hash(""),
|
| - version("") {}
|
| + version(""),
|
| + is_sync(false) {}
|
|
|
| ExtensionDownloader::ExtensionFetch::ExtensionFetch(
|
| const std::string& id,
|
| const GURL& url,
|
| const std::string& package_hash,
|
| - const std::string& version)
|
| - : id(id), url(url), package_hash(package_hash), version(version) {}
|
| + const std::string& version,
|
| + const bool is_sync)
|
| + : id(id), url(url), package_hash(package_hash), version(version),
|
| + is_sync(is_sync) {}
|
|
|
| ExtensionDownloader::ExtensionFetch::~ExtensionFetch() {}
|
|
|
| @@ -152,18 +156,20 @@ bool ExtensionDownloader::AddExtension(const Extension& extension) {
|
|
|
| return AddExtensionData(extension.id(), *extension.version(),
|
| extension.GetType(), extension.update_url(),
|
| - update_url_data);
|
| + update_url_data, false);
|
| }
|
|
|
| bool ExtensionDownloader::AddPendingExtension(const std::string& id,
|
| - const GURL& update_url) {
|
| + const GURL& update_url,
|
| + bool is_sync) {
|
| // Use a zero version to ensure that a pending extension will always
|
| // be updated, and thus installed (assuming all extensions have
|
| // non-zero versions).
|
| Version version("0.0.0.0");
|
| DCHECK(version.IsValid());
|
|
|
| - return AddExtensionData(id, version, Extension::TYPE_UNKNOWN, update_url, "");
|
| + return AddExtensionData(id, version, Extension::TYPE_UNKNOWN, update_url, "",
|
| + is_sync);
|
| }
|
|
|
| void ExtensionDownloader::StartAllPending() {
|
| @@ -181,15 +187,14 @@ void ExtensionDownloader::StartAllPending() {
|
| }
|
|
|
| void ExtensionDownloader::StartBlacklistUpdate(
|
| - const std::string& version,
|
| - const ManifestFetchData::PingData& ping_data) {
|
| + const std::string& version, const ManifestFetchData::PingData& ping_data) {
|
| // Note: it is very important that we use the https version of the update
|
| // url here to avoid DNS hijacking of the blacklist, which is not validated
|
| // by a public key signature like .crx files are.
|
| ManifestFetchData* blacklist_fetch =
|
| new ManifestFetchData(extension_urls::GetWebstoreUpdateUrl(true));
|
| blacklist_fetch->AddExtension(kBlacklistAppID, version, &ping_data, "",
|
| - kDefaultInstallSource);
|
| + kDefaultInstallSource, false /* is_sync */);
|
| StartUpdateCheck(blacklist_fetch);
|
| }
|
|
|
| @@ -197,7 +202,8 @@ bool ExtensionDownloader::AddExtensionData(const std::string& id,
|
| const Version& version,
|
| Extension::Type extension_type,
|
| GURL update_url,
|
| - const std::string& update_url_data) {
|
| + const std::string& update_url_data,
|
| + bool is_sync) {
|
| // Skip extensions with non-empty invalid update URLs.
|
| if (!update_url.is_empty() && !update_url.is_valid()) {
|
| LOG(WARNING) << "Extension " << id << " has invalid update url "
|
| @@ -271,7 +277,7 @@ bool ExtensionDownloader::AddExtensionData(const std::string& id,
|
| ManifestFetchData* existing_fetch = existing_iter->second.back();
|
| if (existing_fetch->AddExtension(id, version.GetString(),
|
| optional_ping_data, update_url_data,
|
| - install_source)) {
|
| + install_source, is_sync)) {
|
| fetch = existing_fetch;
|
| }
|
| }
|
| @@ -283,7 +289,8 @@ bool ExtensionDownloader::AddExtensionData(const std::string& id,
|
| bool added = fetch->AddExtension(id, version.GetString(),
|
| optional_ping_data,
|
| update_url_data,
|
| - install_source);
|
| + install_source,
|
| + is_sync);
|
| DCHECK(added);
|
| }
|
| }
|
| @@ -310,11 +317,12 @@ void ExtensionDownloader::ReportStats() const {
|
|
|
| void ExtensionDownloader::StartUpdateCheck(ManifestFetchData* fetch_data) {
|
| scoped_ptr<ManifestFetchData> scoped_fetch_data(fetch_data);
|
| - const std::set<std::string>& id_set(fetch_data->extension_ids());
|
| + const ManifestFetchData::ExtensionInfoMap& id_map(
|
| + fetch_data->extension_infos());
|
|
|
| if (CommandLine::ForCurrentProcess()->HasSwitch(
|
| switches::kDisableBackgroundNetworking)) {
|
| - NotifyExtensionsDownloadFailed(id_set,
|
| + NotifyExtensionsDownloadFailed(id_map,
|
| ExtensionDownloaderDelegate::DISABLED);
|
| return;
|
| }
|
| @@ -336,10 +344,12 @@ void ExtensionDownloader::StartUpdateCheck(ManifestFetchData* fetch_data) {
|
| fetch_data->full_url().possibly_invalid_spec().length());
|
|
|
| if (VLOG_IS_ON(2)) {
|
| - std::vector<std::string> id_vector(id_set.begin(), id_set.end());
|
| + std::vector<std::string> id_vector;
|
| + ManifestFetchData::ExtensionInfoMap::const_iterator it;
|
| + for (it = id_map.begin(); it != id_map.end(); ++it)
|
| + id_vector.push_back(it->first);
|
| std::string id_list = JoinString(id_vector, ',');
|
| - VLOG(2) << "Fetching " << fetch_data->full_url() << " for "
|
| - << id_list;
|
| + VLOG(2) << "Fetching " << fetch_data->full_url() << " for " << id_list;
|
| }
|
|
|
| current_manifest_fetch_.swap(scoped_fetch_data);
|
| @@ -397,7 +407,7 @@ void ExtensionDownloader::OnManifestFetchComplete(
|
| VLOG(1) << "Failed to fetch manifest '" << url.possibly_invalid_spec()
|
| << "' response code:" << response_code;
|
| NotifyExtensionsDownloadFailed(
|
| - current_manifest_fetch_->extension_ids(),
|
| + current_manifest_fetch_->extension_infos(),
|
| ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED);
|
| }
|
| manifest_fetcher_.reset();
|
| @@ -416,7 +426,7 @@ void ExtensionDownloader::HandleManifestResults(
|
| const UpdateManifest::Results* results) {
|
| // Keep a list of extensions that will not be updated, so that the |delegate_|
|
| // can be notified once we're done here.
|
| - std::set<std::string> not_updated(fetch_data.extension_ids());
|
| + ManifestFetchData::ExtensionInfoMap not_updated(fetch_data.extension_infos());
|
|
|
| if (!results) {
|
| NotifyExtensionsDownloadFailed(
|
| @@ -431,6 +441,7 @@ void ExtensionDownloader::HandleManifestResults(
|
| for (size_t i = 0; i < updates.size(); i++) {
|
| const UpdateManifest::Result* update = &(results->list.at(updates[i]));
|
| const std::string& id = update->extension_id;
|
| + bool is_sync = not_updated[id].is_sync;
|
| not_updated.erase(id);
|
| if (id != kBlacklistAppID) {
|
| NotifyUpdateFound(update->extension_id);
|
| @@ -442,7 +453,8 @@ void ExtensionDownloader::HandleManifestResults(
|
| << update->crx_url;
|
| }
|
| FetchUpdatedExtension(update->extension_id, update->crx_url,
|
| - update->package_hash, update->version);
|
| + update->package_hash, update->version,
|
| + is_sync);
|
| }
|
|
|
| // If the manifest response included a <daystart> element, we want to save
|
| @@ -452,10 +464,11 @@ void ExtensionDownloader::HandleManifestResults(
|
| Time day_start =
|
| Time::Now() - TimeDelta::FromSeconds(results->daystart_elapsed_seconds);
|
|
|
| - const std::set<std::string>& extension_ids = fetch_data.extension_ids();
|
| - std::set<std::string>::const_iterator i;
|
| + const ManifestFetchData::ExtensionInfoMap& extension_ids =
|
| + fetch_data.extension_infos();
|
| + ManifestFetchData::ExtensionInfoMap::const_iterator i;
|
| for (i = extension_ids.begin(); i != extension_ids.end(); i++) {
|
| - const std::string& id = *i;
|
| + const std::string& id = i->first;
|
| ExtensionDownloaderDelegate::PingResult& result = ping_results_[id];
|
| result.did_ping = fetch_data.DidPing(id, ManifestFetchData::ROLLCALL);
|
| result.day_start = day_start;
|
| @@ -541,7 +554,8 @@ void ExtensionDownloader::DetermineUpdates(
|
| void ExtensionDownloader::FetchUpdatedExtension(const std::string& id,
|
| const GURL& url,
|
| const std::string& hash,
|
| - const std::string& version) {
|
| + const std::string& version,
|
| + const bool is_sync) {
|
| if (!url.is_valid()) {
|
| // TODO(asargent): This can sometimes be invalid. See crbug.com/130881.
|
| LOG(ERROR) << "Invalid URL: '" << url.possibly_invalid_spec()
|
| @@ -559,7 +573,8 @@ void ExtensionDownloader::FetchUpdatedExtension(const std::string& id,
|
|
|
| if (extension_fetcher_.get() != NULL) {
|
| if (extension_fetcher_->GetURL() != url) {
|
| - extensions_pending_.push_back(ExtensionFetch(id, url, hash, version));
|
| + extensions_pending_.push_back(ExtensionFetch(id, url, hash, version,
|
| + is_sync));
|
| }
|
| } else {
|
| extension_fetcher_.reset(net::URLFetcher::Create(
|
| @@ -578,7 +593,7 @@ void ExtensionDownloader::FetchUpdatedExtension(const std::string& id,
|
| VLOG(2) << "Starting fetch of " << url << " for " << id;
|
|
|
| extension_fetcher_->Start();
|
| - current_extension_fetch_ = ExtensionFetch(id, url, hash, version);
|
| + current_extension_fetch_ = ExtensionFetch(id, url, hash, version, is_sync);
|
| }
|
| }
|
|
|
| @@ -614,7 +629,8 @@ void ExtensionDownloader::OnCRXFetchComplete(
|
| RecordCRXWriteHistogram(true, crx_path);
|
| delegate_->OnExtensionDownloadFinished(id, crx_path, url,
|
| current_extension_fetch_.version,
|
| - ping);
|
| + ping,
|
| + current_extension_fetch_.is_sync);
|
| }
|
| } else {
|
| // TODO(asargent) do things like exponential backoff, handling
|
| @@ -634,17 +650,19 @@ void ExtensionDownloader::OnCRXFetchComplete(
|
| if (!extensions_pending_.empty()) {
|
| ExtensionFetch next = extensions_pending_.front();
|
| extensions_pending_.pop_front();
|
| - FetchUpdatedExtension(next.id, next.url, next.package_hash, next.version);
|
| + FetchUpdatedExtension(next.id, next.url, next.package_hash, next.version,
|
| + next.is_sync);
|
| }
|
| }
|
|
|
| void ExtensionDownloader::NotifyExtensionsDownloadFailed(
|
| - const std::set<std::string>& extension_ids,
|
| + const ManifestFetchData::ExtensionInfoMap& extension_ids,
|
| ExtensionDownloaderDelegate::Error error) {
|
| - for (std::set<std::string>::const_iterator it = extension_ids.begin();
|
| - it != extension_ids.end(); ++it) {
|
| - delegate_->OnExtensionDownloadFailed(*it, error, ping_results_[*it]);
|
| - ping_results_.erase(*it);
|
| + ManifestFetchData::ExtensionInfoMap::const_iterator it;
|
| + for (it = extension_ids.begin(); it != extension_ids.end(); ++it) {
|
| + delegate_->OnExtensionDownloadFailed(it->first, error,
|
| + ping_results_[it->first]);
|
| + ping_results_.erase(it->first);
|
| }
|
| }
|
|
|
|
|