OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |