Chromium Code Reviews| Index: chrome/browser/extensions/updater/extension_updater.cc |
| diff --git a/chrome/browser/extensions/updater/extension_updater.cc b/chrome/browser/extensions/updater/extension_updater.cc |
| index 1c64bc9bb74f59401e14b8aa2fbe7837b7224da2..71813db585fabaef12fadbd289168a5b52aa1221 100644 |
| --- a/chrome/browser/extensions/updater/extension_updater.cc |
| +++ b/chrome/browser/extensions/updater/extension_updater.cc |
| @@ -8,6 +8,8 @@ |
| #include <set> |
| #include "base/bind.h" |
| +#include "base/files/file_enumerator.h" |
| +#include "base/files/file_util.h" |
| #include "base/logging.h" |
| #include "base/metrics/histogram.h" |
| #include "base/prefs/pref_service.h" |
| @@ -22,6 +24,7 @@ |
| #include "chrome/browser/extensions/pending_extension_manager.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/common/pref_names.h" |
| +#include "components/omaha_query_params/omaha_query_params.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/notification_details.h" |
| #include "content/public/browser/notification_service.h" |
| @@ -40,6 +43,9 @@ using base::RandInt; |
| using base::Time; |
| using base::TimeDelta; |
| using content::BrowserThread; |
| +using extensions::Extension; |
| +using extensions::ExtensionSet; |
| +using omaha_query_params::OmahaQueryParams; |
| typedef extensions::ExtensionDownloaderDelegate::Error Error; |
| typedef extensions::ExtensionDownloaderDelegate::PingResult PingResult; |
| @@ -60,6 +66,10 @@ const int kMaxUpdateFrequencySeconds = 60 * 60 * 24 * 7; // 7 days |
| // checks. |
| const int kMinUpdateThrottleTime = 5; |
| +// The installsource query parameter to use when forcing updates due to NaCl |
| +// arch mismatch. |
| +const char kWrongMultiCrxInstallSource[] = "wrong_multi_crx"; |
| + |
| // When we've computed a days value, we want to make sure we don't send a |
| // negative value (due to the system clock being set backwards, etc.), since -1 |
| // is a special sentinel value that means "never pinged", and other negative |
| @@ -88,6 +98,71 @@ int CalculateActivePingDays(const Time& last_active_ping_day, |
| return SanitizeDays((Time::Now() - last_active_ping_day).InDays()); |
| } |
| +void RespondWithForcedUpdates( |
| + const base::Callback<void(const std::set<std::string>&)>& callback, |
| + scoped_ptr<std::set<std::string> > forced_updates) { |
| + callback.Run(*forced_updates.get()); |
| +} |
| + |
| +void DetermineForcedUpdatesOnBlockingPool( |
| + scoped_ptr<std::vector<scoped_refptr<const Extension> > > extensions, |
| + const base::Callback<void(const std::set<std::string>&)>& callback) { |
|
Yoyo Zhou
2014/09/04 22:41:26
Consider DCHECKing that we're on a non-UI thread.
Ken Rockot(use gerrit already)
2014/09/05 01:41:34
Done.
|
| + scoped_ptr<std::set<std::string> > forced_updates( |
| + new std::set<std::string>()); |
| + for (std::vector<scoped_refptr<const Extension> >::const_iterator iter = |
| + extensions->begin(); |
| + iter != extensions->end(); |
| + ++iter) { |
| + scoped_refptr<const Extension> extension = *iter; |
| + base::FilePath platform_specific_path = extension->path().Append( |
| + extensions::kPlatformSpecificFolder); |
| + if (base::PathExists(platform_specific_path)) { |
| + bool force = true; |
| + base::FileEnumerator all_archs(platform_specific_path, |
| + false, |
| + base::FileEnumerator::DIRECTORIES); |
| + base::FilePath arch; |
| + while (!(arch = all_archs.Next()).empty()) { |
| + std::string arch_name = arch.BaseName().AsUTF8Unsafe(); |
| + std::replace(arch_name.begin(), arch_name.end(), '_', '-'); |
| + if (arch_name == OmahaQueryParams::GetNaclArch()) |
| + force = false; |
| + } |
| + |
| + if (force) |
| + forced_updates->insert(extension->id()); |
| + } |
| + } |
| + BrowserThread::PostTask( |
| + BrowserThread::UI, |
| + FROM_HERE, |
| + base::Bind(&RespondWithForcedUpdates, |
| + callback, |
| + base::Passed(&forced_updates))); |
| +} |
| + |
| +void CollectExtensionsFromSet( |
| + const ExtensionSet& extensions, |
| + std::vector<scoped_refptr<const Extension> >* paths) { |
| + std::copy(extensions.begin(), extensions.end(), std::back_inserter(*paths)); |
| +} |
| + |
| +void DetermineForcedUpdates( |
| + content::BrowserContext* browser_context, |
| + const base::Callback<void(const std::set<std::string>&)>& callback) { |
| + scoped_ptr<std::vector<scoped_refptr<const Extension> > > extensions( |
| + new std::vector<scoped_refptr<const Extension> >()); |
| + const extensions::ExtensionRegistry* registry = |
| + extensions::ExtensionRegistry::Get(browser_context); |
| + CollectExtensionsFromSet(registry->enabled_extensions(), extensions.get()); |
|
Yoyo Zhou
2014/09/04 22:41:26
Why not use registry->GenerateInstalledExtensionsS
Ken Rockot(use gerrit already)
2014/09/05 01:41:34
Because I totally missed it when looking over the
|
| + CollectExtensionsFromSet(registry->disabled_extensions(), extensions.get()); |
| + BrowserThread::PostBlockingPoolTask( |
| + FROM_HERE, |
| + base::Bind(&DetermineForcedUpdatesOnBlockingPool, |
| + base::Passed(&extensions), |
| + callback)); |
| +} |
| + |
| } // namespace |
| namespace extensions { |
| @@ -335,6 +410,16 @@ void ExtensionUpdater::AddToDownloader( |
| } |
| void ExtensionUpdater::CheckNow(const CheckParams& params) { |
| + DetermineForcedUpdates( |
| + profile_, |
| + base::Bind(&ExtensionUpdater::OnForcedUpdatesDetermined, |
| + weak_ptr_factory_.GetWeakPtr(), |
| + params)); |
| +} |
| + |
| +void ExtensionUpdater::OnForcedUpdatesDetermined( |
| + const CheckParams& params, |
| + const std::set<std::string>& forced_updates) { |
| int request_id = next_request_id_++; |
| VLOG(2) << "Starting update check " << request_id; |
| @@ -349,6 +434,8 @@ void ExtensionUpdater::CheckNow(const CheckParams& params) { |
| EnsureDownloaderCreated(); |
| + forced_updates_ = forced_updates; |
| + |
| // Add fetch records for extensions that should be fetched by an update URL. |
| // These extensions are not yet installed. They come from group policy |
| // and external install sources. |
| @@ -536,6 +623,18 @@ bool ExtensionUpdater::GetExtensionExistingVersion(const std::string& id, |
| return true; |
| } |
| +bool ExtensionUpdater::ShouldForceUpdate( |
| + const std::string& extension_id, |
| + std::string* source) { |
| + bool force = forced_updates_.find(extension_id) != forced_updates_.end(); |
| + // Currently the only reason to force is a NaCl arch mismatch with the |
| + // installed extension contents. |
| + if (force) { |
| + *source = kWrongMultiCrxInstallSource; |
| + } |
| + return force; |
| +} |
| + |
| void ExtensionUpdater::UpdatePingData(const std::string& id, |
| const PingResult& ping_result) { |
| DCHECK(alive_); |