Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Side by Side Diff: chrome/browser/extensions/updater/extension_updater.cc

Issue 540673002: Enable forced extension updates on NaCl arch mismatch. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: kill stale comment Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/updater/extension_updater.h" 5 #include "chrome/browser/extensions/updater/extension_updater.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/files/file_enumerator.h"
12 #include "base/files/file_util.h"
11 #include "base/logging.h" 13 #include "base/logging.h"
12 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
13 #include "base/prefs/pref_service.h" 15 #include "base/prefs/pref_service.h"
14 #include "base/rand_util.h" 16 #include "base/rand_util.h"
15 #include "base/stl_util.h" 17 #include "base/stl_util.h"
16 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/string_split.h" 19 #include "base/strings/string_split.h"
18 #include "chrome/browser/chrome_notification_types.h" 20 #include "chrome/browser/chrome_notification_types.h"
19 #include "chrome/browser/extensions/api/module/module.h" 21 #include "chrome/browser/extensions/api/module/module.h"
20 #include "chrome/browser/extensions/crx_installer.h" 22 #include "chrome/browser/extensions/crx_installer.h"
21 #include "chrome/browser/extensions/extension_service.h" 23 #include "chrome/browser/extensions/extension_service.h"
22 #include "chrome/browser/extensions/pending_extension_manager.h" 24 #include "chrome/browser/extensions/pending_extension_manager.h"
23 #include "chrome/browser/profiles/profile.h" 25 #include "chrome/browser/profiles/profile.h"
24 #include "chrome/common/pref_names.h" 26 #include "chrome/common/pref_names.h"
27 #include "components/omaha_query_params/omaha_query_params.h"
25 #include "content/public/browser/browser_thread.h" 28 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/notification_details.h" 29 #include "content/public/browser/notification_details.h"
27 #include "content/public/browser/notification_service.h" 30 #include "content/public/browser/notification_service.h"
28 #include "content/public/browser/notification_source.h" 31 #include "content/public/browser/notification_source.h"
29 #include "crypto/sha2.h" 32 #include "crypto/sha2.h"
30 #include "extensions/browser/extension_prefs.h" 33 #include "extensions/browser/extension_prefs.h"
31 #include "extensions/browser/extension_registry.h" 34 #include "extensions/browser/extension_registry.h"
32 #include "extensions/browser/pref_names.h" 35 #include "extensions/browser/pref_names.h"
33 #include "extensions/common/constants.h" 36 #include "extensions/common/constants.h"
34 #include "extensions/common/extension.h" 37 #include "extensions/common/extension.h"
35 #include "extensions/common/extension_set.h" 38 #include "extensions/common/extension_set.h"
36 #include "extensions/common/manifest.h" 39 #include "extensions/common/manifest.h"
37 40
38 using base::RandDouble; 41 using base::RandDouble;
39 using base::RandInt; 42 using base::RandInt;
40 using base::Time; 43 using base::Time;
41 using base::TimeDelta; 44 using base::TimeDelta;
42 using content::BrowserThread; 45 using content::BrowserThread;
46 using extensions::Extension;
47 using extensions::ExtensionSet;
48 using omaha_query_params::OmahaQueryParams;
43 49
44 typedef extensions::ExtensionDownloaderDelegate::Error Error; 50 typedef extensions::ExtensionDownloaderDelegate::Error Error;
45 typedef extensions::ExtensionDownloaderDelegate::PingResult PingResult; 51 typedef extensions::ExtensionDownloaderDelegate::PingResult PingResult;
46 52
47 namespace { 53 namespace {
48 54
49 // Wait at least 5 minutes after browser startup before we do any checks. If you 55 // Wait at least 5 minutes after browser startup before we do any checks. If you
50 // change this value, make sure to update comments where it is used. 56 // change this value, make sure to update comments where it is used.
51 const int kStartupWaitSeconds = 60 * 5; 57 const int kStartupWaitSeconds = 60 * 5;
52 58
53 // For sanity checking on update frequency - enforced in release mode only. 59 // For sanity checking on update frequency - enforced in release mode only.
54 #if defined(NDEBUG) 60 #if defined(NDEBUG)
55 const int kMinUpdateFrequencySeconds = 30; 61 const int kMinUpdateFrequencySeconds = 30;
56 #endif 62 #endif
57 const int kMaxUpdateFrequencySeconds = 60 * 60 * 24 * 7; // 7 days 63 const int kMaxUpdateFrequencySeconds = 60 * 60 * 24 * 7; // 7 days
58 64
59 // Require at least 5 seconds between consecutive non-succesful extension update 65 // Require at least 5 seconds between consecutive non-succesful extension update
60 // checks. 66 // checks.
61 const int kMinUpdateThrottleTime = 5; 67 const int kMinUpdateThrottleTime = 5;
62 68
69 // The installsource query parameter to use when forcing updates due to NaCl
70 // arch mismatch.
71 const char kWrongMultiCrxInstallSource[] = "wrong_multi_crx";
72
63 // When we've computed a days value, we want to make sure we don't send a 73 // When we've computed a days value, we want to make sure we don't send a
64 // negative value (due to the system clock being set backwards, etc.), since -1 74 // negative value (due to the system clock being set backwards, etc.), since -1
65 // is a special sentinel value that means "never pinged", and other negative 75 // is a special sentinel value that means "never pinged", and other negative
66 // values don't make sense. 76 // values don't make sense.
67 int SanitizeDays(int days) { 77 int SanitizeDays(int days) {
68 if (days < 0) 78 if (days < 0)
69 return 0; 79 return 0;
70 return days; 80 return days;
71 } 81 }
72 82
73 // Calculates the value to use for the ping days parameter. 83 // Calculates the value to use for the ping days parameter.
74 int CalculatePingDays(const Time& last_ping_day) { 84 int CalculatePingDays(const Time& last_ping_day) {
75 int days = extensions::ManifestFetchData::kNeverPinged; 85 int days = extensions::ManifestFetchData::kNeverPinged;
76 if (!last_ping_day.is_null()) { 86 if (!last_ping_day.is_null()) {
77 days = SanitizeDays((Time::Now() - last_ping_day).InDays()); 87 days = SanitizeDays((Time::Now() - last_ping_day).InDays());
78 } 88 }
79 return days; 89 return days;
80 } 90 }
81 91
82 int CalculateActivePingDays(const Time& last_active_ping_day, 92 int CalculateActivePingDays(const Time& last_active_ping_day,
83 bool hasActiveBit) { 93 bool hasActiveBit) {
84 if (!hasActiveBit) 94 if (!hasActiveBit)
85 return 0; 95 return 0;
86 if (last_active_ping_day.is_null()) 96 if (last_active_ping_day.is_null())
87 return extensions::ManifestFetchData::kNeverPinged; 97 return extensions::ManifestFetchData::kNeverPinged;
88 return SanitizeDays((Time::Now() - last_active_ping_day).InDays()); 98 return SanitizeDays((Time::Now() - last_active_ping_day).InDays());
89 } 99 }
90 100
101 void RespondWithForcedUpdates(
102 const base::Callback<void(const std::set<std::string>&)>& callback,
103 scoped_ptr<std::set<std::string> > forced_updates) {
104 callback.Run(*forced_updates.get());
105 }
106
107 void DetermineForcedUpdatesOnBlockingPool(
108 scoped_ptr<std::vector<scoped_refptr<const Extension> > > extensions,
109 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.
110 scoped_ptr<std::set<std::string> > forced_updates(
111 new std::set<std::string>());
112 for (std::vector<scoped_refptr<const Extension> >::const_iterator iter =
113 extensions->begin();
114 iter != extensions->end();
115 ++iter) {
116 scoped_refptr<const Extension> extension = *iter;
117 base::FilePath platform_specific_path = extension->path().Append(
118 extensions::kPlatformSpecificFolder);
119 if (base::PathExists(platform_specific_path)) {
120 bool force = true;
121 base::FileEnumerator all_archs(platform_specific_path,
122 false,
123 base::FileEnumerator::DIRECTORIES);
124 base::FilePath arch;
125 while (!(arch = all_archs.Next()).empty()) {
126 std::string arch_name = arch.BaseName().AsUTF8Unsafe();
127 std::replace(arch_name.begin(), arch_name.end(), '_', '-');
128 if (arch_name == OmahaQueryParams::GetNaclArch())
129 force = false;
130 }
131
132 if (force)
133 forced_updates->insert(extension->id());
134 }
135 }
136 BrowserThread::PostTask(
137 BrowserThread::UI,
138 FROM_HERE,
139 base::Bind(&RespondWithForcedUpdates,
140 callback,
141 base::Passed(&forced_updates)));
142 }
143
144 void CollectExtensionsFromSet(
145 const ExtensionSet& extensions,
146 std::vector<scoped_refptr<const Extension> >* paths) {
147 std::copy(extensions.begin(), extensions.end(), std::back_inserter(*paths));
148 }
149
150 void DetermineForcedUpdates(
151 content::BrowserContext* browser_context,
152 const base::Callback<void(const std::set<std::string>&)>& callback) {
153 scoped_ptr<std::vector<scoped_refptr<const Extension> > > extensions(
154 new std::vector<scoped_refptr<const Extension> >());
155 const extensions::ExtensionRegistry* registry =
156 extensions::ExtensionRegistry::Get(browser_context);
157 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
158 CollectExtensionsFromSet(registry->disabled_extensions(), extensions.get());
159 BrowserThread::PostBlockingPoolTask(
160 FROM_HERE,
161 base::Bind(&DetermineForcedUpdatesOnBlockingPool,
162 base::Passed(&extensions),
163 callback));
164 }
165
91 } // namespace 166 } // namespace
92 167
93 namespace extensions { 168 namespace extensions {
94 169
95 ExtensionUpdater::CheckParams::CheckParams() 170 ExtensionUpdater::CheckParams::CheckParams()
96 : install_immediately(false) {} 171 : install_immediately(false) {}
97 172
98 ExtensionUpdater::CheckParams::~CheckParams() {} 173 ExtensionUpdater::CheckParams::~CheckParams() {}
99 174
100 ExtensionUpdater::FetchedCRXFile::FetchedCRXFile( 175 ExtensionUpdater::FetchedCRXFile::FetchedCRXFile(
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 std::list<std::string>::const_iterator pending_id_iter = std::find( 403 std::list<std::string>::const_iterator pending_id_iter = std::find(
329 pending_ids.begin(), pending_ids.end(), extension.id()); 404 pending_ids.begin(), pending_ids.end(), extension.id());
330 if (pending_id_iter == pending_ids.end()) { 405 if (pending_id_iter == pending_ids.end()) {
331 if (downloader_->AddExtension(extension, request_id)) 406 if (downloader_->AddExtension(extension, request_id))
332 request.in_progress_ids_.push_back(extension.id()); 407 request.in_progress_ids_.push_back(extension.id());
333 } 408 }
334 } 409 }
335 } 410 }
336 411
337 void ExtensionUpdater::CheckNow(const CheckParams& params) { 412 void ExtensionUpdater::CheckNow(const CheckParams& params) {
413 DetermineForcedUpdates(
414 profile_,
415 base::Bind(&ExtensionUpdater::OnForcedUpdatesDetermined,
416 weak_ptr_factory_.GetWeakPtr(),
417 params));
418 }
419
420 void ExtensionUpdater::OnForcedUpdatesDetermined(
421 const CheckParams& params,
422 const std::set<std::string>& forced_updates) {
338 int request_id = next_request_id_++; 423 int request_id = next_request_id_++;
339 424
340 VLOG(2) << "Starting update check " << request_id; 425 VLOG(2) << "Starting update check " << request_id;
341 if (params.ids.empty()) 426 if (params.ids.empty())
342 NotifyStarted(); 427 NotifyStarted();
343 428
344 DCHECK(alive_); 429 DCHECK(alive_);
345 430
346 InProgressCheck& request = requests_in_progress_[request_id]; 431 InProgressCheck& request = requests_in_progress_[request_id];
347 request.callback = params.callback; 432 request.callback = params.callback;
348 request.install_immediately = params.install_immediately; 433 request.install_immediately = params.install_immediately;
349 434
350 EnsureDownloaderCreated(); 435 EnsureDownloaderCreated();
351 436
437 forced_updates_ = forced_updates;
438
352 // Add fetch records for extensions that should be fetched by an update URL. 439 // Add fetch records for extensions that should be fetched by an update URL.
353 // These extensions are not yet installed. They come from group policy 440 // These extensions are not yet installed. They come from group policy
354 // and external install sources. 441 // and external install sources.
355 const PendingExtensionManager* pending_extension_manager = 442 const PendingExtensionManager* pending_extension_manager =
356 service_->pending_extension_manager(); 443 service_->pending_extension_manager();
357 444
358 std::list<std::string> pending_ids; 445 std::list<std::string> pending_ids;
359 446
360 if (params.ids.empty()) { 447 if (params.ids.empty()) {
361 // If no extension ids are specified, check for updates for all extensions. 448 // If no extension ids are specified, check for updates for all extensions.
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 if (!extension) 616 if (!extension)
530 return false; 617 return false;
531 const Extension* update = service_->GetPendingExtensionUpdate(id); 618 const Extension* update = service_->GetPendingExtensionUpdate(id);
532 if (update) 619 if (update)
533 *version = update->VersionString(); 620 *version = update->VersionString();
534 else 621 else
535 *version = extension->VersionString(); 622 *version = extension->VersionString();
536 return true; 623 return true;
537 } 624 }
538 625
626 bool ExtensionUpdater::ShouldForceUpdate(
627 const std::string& extension_id,
628 std::string* source) {
629 bool force = forced_updates_.find(extension_id) != forced_updates_.end();
630 // Currently the only reason to force is a NaCl arch mismatch with the
631 // installed extension contents.
632 if (force) {
633 *source = kWrongMultiCrxInstallSource;
634 }
635 return force;
636 }
637
539 void ExtensionUpdater::UpdatePingData(const std::string& id, 638 void ExtensionUpdater::UpdatePingData(const std::string& id,
540 const PingResult& ping_result) { 639 const PingResult& ping_result) {
541 DCHECK(alive_); 640 DCHECK(alive_);
542 if (ping_result.did_ping) 641 if (ping_result.did_ping)
543 extension_prefs_->SetLastPingDay(id, ping_result.day_start); 642 extension_prefs_->SetLastPingDay(id, ping_result.day_start);
544 if (extension_prefs_->GetActiveBit(id)) { 643 if (extension_prefs_->GetActiveBit(id)) {
545 extension_prefs_->SetActiveBit(id, false); 644 extension_prefs_->SetActiveBit(id, false);
546 extension_prefs_->SetLastActivePingDay(id, ping_result.day_start); 645 extension_prefs_->SetLastActivePingDay(id, ping_result.day_start);
547 } 646 }
548 } 647 }
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 const InProgressCheck& request = requests_in_progress_[request_id]; 741 const InProgressCheck& request = requests_in_progress_[request_id];
643 if (request.in_progress_ids_.empty()) { 742 if (request.in_progress_ids_.empty()) {
644 VLOG(2) << "Finished update check " << request_id; 743 VLOG(2) << "Finished update check " << request_id;
645 if (!request.callback.is_null()) 744 if (!request.callback.is_null())
646 request.callback.Run(); 745 request.callback.Run();
647 requests_in_progress_.erase(request_id); 746 requests_in_progress_.erase(request_id);
648 } 747 }
649 } 748 }
650 749
651 } // namespace extensions 750 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698