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

Side by Side Diff: chrome/browser/policy/app_pack_updater.cc

Issue 11572044: Automatically retry the following URLFetchers when the network changes: (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Document the retry behavior Created 8 years 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 | Annotate | Revision Log
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/policy/app_pack_updater.h" 5 #include "chrome/browser/policy/app_pack_updater.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/file_util.h" 9 #include "base/file_util.h"
10 #include "base/location.h" 10 #include "base/location.h"
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 weak_ptr_factory_.GetWeakPtr())); 95 weak_ptr_factory_.GetWeakPtr()));
96 } else { 96 } else {
97 // Linger until the device switches to DEVICE_MODE_KIOSK and the app pack 97 // Linger until the device switches to DEVICE_MODE_KIOSK and the app pack
98 // device setting appears. 98 // device setting appears.
99 } 99 }
100 } 100 }
101 101
102 AppPackUpdater::~AppPackUpdater() { 102 AppPackUpdater::~AppPackUpdater() {
103 chromeos::CrosSettings::Get()->RemoveSettingsObserver( 103 chromeos::CrosSettings::Get()->RemoveSettingsObserver(
104 chromeos::kAppPack, this); 104 chromeos::kAppPack, this);
105 net::NetworkChangeNotifier::RemoveIPAddressObserver(this);
106 } 105 }
107 106
108 extensions::ExternalLoader* AppPackUpdater::CreateExternalLoader() { 107 extensions::ExternalLoader* AppPackUpdater::CreateExternalLoader() {
109 if (created_extension_loader_) { 108 if (created_extension_loader_) {
110 NOTREACHED(); 109 NOTREACHED();
111 return NULL; 110 return NULL;
112 } 111 }
113 created_extension_loader_ = true; 112 created_extension_loader_ = true;
114 AppPackExternalLoader* loader = new AppPackExternalLoader(); 113 AppPackExternalLoader* loader = new AppPackExternalLoader();
115 extension_loader_ = loader->AsWeakPtr(); 114 extension_loader_ = loader->AsWeakPtr();
(...skipping 18 matching lines...) Expand all
134 void AppPackUpdater::Init() { 133 void AppPackUpdater::Init() {
135 if (initialized_) 134 if (initialized_)
136 return; 135 return;
137 136
138 initialized_ = true; 137 initialized_ = true;
139 worker_pool_token_ = BrowserThread::GetBlockingPool()->GetSequenceToken(); 138 worker_pool_token_ = BrowserThread::GetBlockingPool()->GetSequenceToken();
140 notification_registrar_.Add( 139 notification_registrar_.Add(
141 this, 140 this,
142 chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR, 141 chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR,
143 content::NotificationService::AllBrowserContextsAndSources()); 142 content::NotificationService::AllBrowserContextsAndSources());
144 net::NetworkChangeNotifier::AddIPAddressObserver(this);
145 LoadPolicy(); 143 LoadPolicy();
146 } 144 }
147 145
148 void AppPackUpdater::Observe(int type, 146 void AppPackUpdater::Observe(int type,
149 const content::NotificationSource& source, 147 const content::NotificationSource& source,
150 const content::NotificationDetails& details) { 148 const content::NotificationDetails& details) {
151 switch (type) { 149 switch (type) {
152 case chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED: 150 case chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED:
153 DCHECK_EQ(chromeos::kAppPack, 151 DCHECK_EQ(chromeos::kAppPack,
154 *content::Details<const std::string>(details).ptr()); 152 *content::Details<const std::string>(details).ptr());
(...skipping 10 matching lines...) Expand all
165 content::Source<extensions::CrxInstaller>(source).ptr(); 163 content::Source<extensions::CrxInstaller>(source).ptr();
166 OnDamagedFileDetected(installer->source_file()); 164 OnDamagedFileDetected(installer->source_file());
167 break; 165 break;
168 } 166 }
169 167
170 default: 168 default:
171 NOTREACHED(); 169 NOTREACHED();
172 } 170 }
173 } 171 }
174 172
175 void AppPackUpdater::OnIPAddressChanged() {
176 // Check if the AppPack has been fully downloaded whenever the network
177 // changes. This allows the AppPack to recover in case the network wasn't
178 // ready early during startup.
179 // To avoid performing too many update checks in case the network conditions
180 // change too often, an update is only triggered now if there are extensions
181 // configured via policy that haven't been checked for updates yet.
182 for (PolicyEntryMap::iterator it = app_pack_extensions_.begin();
183 it != app_pack_extensions_.end(); ++it) {
184 if (!it->second.update_checked) {
185 // |id| is configured via policy, but hasn't been updated before.
186 // Drop any pending requests and start a full check now.
187 VLOG(1) << "Extension " << it->first << " hasn't been checked yet, "
188 << "new update triggered now by network change notification.";
189 downloader_.reset();
190 weak_ptr_factory_.InvalidateWeakPtrs();
191 LoadPolicy();
192 break;
193 }
194 }
195 }
196
197 void AppPackUpdater::LoadPolicy() { 173 void AppPackUpdater::LoadPolicy() {
198 chromeos::CrosSettings* settings = chromeos::CrosSettings::Get(); 174 chromeos::CrosSettings* settings = chromeos::CrosSettings::Get();
199 if (chromeos::CrosSettingsProvider::TRUSTED != settings->PrepareTrustedValues( 175 if (chromeos::CrosSettingsProvider::TRUSTED != settings->PrepareTrustedValues(
200 base::Bind(&AppPackUpdater::LoadPolicy, 176 base::Bind(&AppPackUpdater::LoadPolicy,
201 weak_ptr_factory_.GetWeakPtr()))) { 177 weak_ptr_factory_.GetWeakPtr()))) {
202 return; 178 return;
203 } 179 }
204 180
205 app_pack_extensions_.clear(); 181 app_pack_extensions_.clear();
206 const base::Value* value = settings->GetPref(chromeos::kAppPack); 182 const base::Value* value = settings->GetPref(chromeos::kAppPack);
207 const base::ListValue* list = NULL; 183 const base::ListValue* list = NULL;
208 if (value && value->GetAsList(&list)) { 184 if (value && value->GetAsList(&list)) {
209 for (base::ListValue::const_iterator it = list->begin(); 185 for (base::ListValue::const_iterator it = list->begin();
210 it != list->end(); ++it) { 186 it != list->end(); ++it) {
211 base::DictionaryValue* dict = NULL; 187 base::DictionaryValue* dict = NULL;
212 if (!(*it)->GetAsDictionary(&dict)) { 188 if (!(*it)->GetAsDictionary(&dict)) {
213 LOG(WARNING) << "AppPack entry is not a dictionary, ignoring."; 189 LOG(WARNING) << "AppPack entry is not a dictionary, ignoring.";
214 continue; 190 continue;
215 } 191 }
216 std::string id; 192 std::string id;
217 std::string update_url; 193 std::string update_url;
218 if (dict->GetString(kExtensionId, &id) && 194 if (dict->GetString(kExtensionId, &id) &&
219 dict->GetString(kUpdateUrl, &update_url)) { 195 dict->GetString(kUpdateUrl, &update_url)) {
220 app_pack_extensions_[id].update_url = update_url; 196 app_pack_extensions_[id] = update_url;
221 app_pack_extensions_[id].update_checked = false;
222 } else { 197 } else {
223 LOG(WARNING) << "Failed to read required fields for an AppPack entry, " 198 LOG(WARNING) << "Failed to read required fields for an AppPack entry, "
224 << "ignoring."; 199 << "ignoring.";
225 } 200 }
226 } 201 }
227 } 202 }
228 203
229 VLOG(1) << "Refreshed AppPack policy, got " << app_pack_extensions_.size() 204 VLOG(1) << "Refreshed AppPack policy, got " << app_pack_extensions_.size()
230 << " entries."; 205 << " entries.";
231 206
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 base::DictionaryValue* dict = new base::DictionaryValue(); 373 base::DictionaryValue* dict = new base::DictionaryValue();
399 dict->SetString(extensions::ExternalProviderImpl::kExternalCrx, 374 dict->SetString(extensions::ExternalProviderImpl::kExternalCrx,
400 it->second.path); 375 it->second.path);
401 dict->SetString(extensions::ExternalProviderImpl::kExternalVersion, 376 dict->SetString(extensions::ExternalProviderImpl::kExternalVersion,
402 it->second.cached_version); 377 it->second.cached_version);
403 378
404 // Include this optional flag if the extension's update url is the Webstore. 379 // Include this optional flag if the extension's update url is the Webstore.
405 PolicyEntryMap::iterator policy_entry = app_pack_extensions_.find(id); 380 PolicyEntryMap::iterator policy_entry = app_pack_extensions_.find(id);
406 if (policy_entry != app_pack_extensions_.end() && 381 if (policy_entry != app_pack_extensions_.end() &&
407 extension_urls::IsWebstoreUpdateUrl( 382 extension_urls::IsWebstoreUpdateUrl(
408 GURL(policy_entry->second.update_url))) { 383 GURL(policy_entry->second))) {
409 dict->SetBoolean(extensions::ExternalProviderImpl::kIsFromWebstore, true); 384 dict->SetBoolean(extensions::ExternalProviderImpl::kIsFromWebstore, true);
410 } 385 }
411 386
412 prefs->Set(it->first, dict); 387 prefs->Set(it->first, dict);
413 388
414 VLOG(1) << "Updating AppPack extension loader, added " << it->second.path; 389 VLOG(1) << "Updating AppPack extension loader, added " << it->second.path;
415 } 390 }
416 391
417 extension_loader_->SetCurrentAppPackExtensions(prefs.Pass()); 392 extension_loader_->SetCurrentAppPackExtensions(prefs.Pass());
418 } 393 }
419 394
420 void AppPackUpdater::DownloadMissingExtensions() { 395 void AppPackUpdater::DownloadMissingExtensions() {
421 // Check for updates for all extensions configured by the policy. Some of 396 // Check for updates for all extensions configured by the policy. Some of
422 // them may already be in the cache; only those with updated version will be 397 // them may already be in the cache; only those with updated version will be
423 // downloaded, in that case. 398 // downloaded, in that case.
424 if (!downloader_.get()) { 399 if (!downloader_.get()) {
425 downloader_.reset(new extensions::ExtensionDownloader(this, 400 downloader_.reset(new extensions::ExtensionDownloader(this,
426 request_context_)); 401 request_context_));
427 } 402 }
428 for (PolicyEntryMap::iterator it = app_pack_extensions_.begin(); 403 for (PolicyEntryMap::iterator it = app_pack_extensions_.begin();
429 it != app_pack_extensions_.end(); ++it) { 404 it != app_pack_extensions_.end(); ++it) {
430 downloader_->AddPendingExtension(it->first, GURL(it->second.update_url), 0); 405 downloader_->AddPendingExtension(it->first, GURL(it->second), 0);
431 } 406 }
432 VLOG(1) << "Downloading AppPack update manifest now"; 407 VLOG(1) << "Downloading AppPack update manifest now";
433 downloader_->StartAllPending(); 408 downloader_->StartAllPending();
434 } 409 }
435 410
436 void AppPackUpdater::OnExtensionDownloadFailed( 411 void AppPackUpdater::OnExtensionDownloadFailed(
437 const std::string& id, 412 const std::string& id,
438 extensions::ExtensionDownloaderDelegate::Error error, 413 extensions::ExtensionDownloaderDelegate::Error error,
439 const extensions::ExtensionDownloaderDelegate::PingResult& ping_result, 414 const extensions::ExtensionDownloaderDelegate::PingResult& ping_result,
440 const std::set<int>& request_ids) { 415 const std::set<int>& request_ids) {
441 if (error == NO_UPDATE_AVAILABLE) { 416 if (error == NO_UPDATE_AVAILABLE) {
442 if (!ContainsKey(cached_extensions_, id)) 417 if (!ContainsKey(cached_extensions_, id))
443 LOG(ERROR) << "AppPack extension " << id << " not found on update server"; 418 LOG(ERROR) << "AppPack extension " << id << " not found on update server";
444 SetUpdateChecked(id);
445 } else { 419 } else {
446 LOG(ERROR) << "AppPack failed to download extension " << id 420 LOG(ERROR) << "AppPack failed to download extension " << id
447 << ", error " << error; 421 << ", error " << error;
448 } 422 }
449 } 423 }
450 424
451 void AppPackUpdater::OnExtensionDownloadFinished( 425 void AppPackUpdater::OnExtensionDownloadFinished(
452 const std::string& id, 426 const std::string& id,
453 const FilePath& path, 427 const FilePath& path,
454 const GURL& download_url, 428 const GURL& download_url,
455 const std::string& version, 429 const std::string& version,
456 const extensions::ExtensionDownloaderDelegate::PingResult& ping_result, 430 const extensions::ExtensionDownloaderDelegate::PingResult& ping_result,
457 const std::set<int>& request_ids) { 431 const std::set<int>& request_ids) {
458 // Just downloaded the latest version, no need to do further update checks
459 // for this extension.
460 SetUpdateChecked(id);
461
462 // The explicit copy ctors are to make sure that Bind() binds a copy and not 432 // The explicit copy ctors are to make sure that Bind() binds a copy and not
463 // a reference to the arguments. 433 // a reference to the arguments.
464 PostBlockingTask(FROM_HERE, 434 PostBlockingTask(FROM_HERE,
465 base::Bind(&AppPackUpdater::BlockingInstallCacheEntry, 435 base::Bind(&AppPackUpdater::BlockingInstallCacheEntry,
466 weak_ptr_factory_.GetWeakPtr(), 436 weak_ptr_factory_.GetWeakPtr(),
467 std::string(id), 437 std::string(id),
468 FilePath(path), 438 FilePath(path),
469 std::string(version))); 439 std::string(version)));
470 } 440 }
471 441
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 562
593 void AppPackUpdater::SetScreenSaverPath(const FilePath& path) { 563 void AppPackUpdater::SetScreenSaverPath(const FilePath& path) {
594 // Don't invoke the callback if the path isn't changing. 564 // Don't invoke the callback if the path isn't changing.
595 if (path != screen_saver_path_) { 565 if (path != screen_saver_path_) {
596 screen_saver_path_ = path; 566 screen_saver_path_ = path;
597 if (!screen_saver_update_callback_.is_null()) 567 if (!screen_saver_update_callback_.is_null())
598 screen_saver_update_callback_.Run(screen_saver_path_); 568 screen_saver_update_callback_.Run(screen_saver_path_);
599 } 569 }
600 } 570 }
601 571
602 void AppPackUpdater::SetUpdateChecked(const std::string& id) {
603 PolicyEntryMap::iterator entry = app_pack_extensions_.find(id);
604 if (entry != app_pack_extensions_.end())
605 entry->second.update_checked = true;
606 }
607
608 } // namespace policy 572 } // namespace policy
OLDNEW
« no previous file with comments | « chrome/browser/policy/app_pack_updater.h ('k') | chrome/browser/policy/device_management_service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698