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_); |