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/chromeos/customization_document.h" | 5 #include "chrome/browser/chromeos/customization_document.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
11 #include "base/file_util.h" | 11 #include "base/file_util.h" |
12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
13 #include "base/json/json_reader.h" | 13 #include "base/json/json_reader.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/memory/weak_ptr.h" | 15 #include "base/memory/weak_ptr.h" |
16 #include "base/metrics/histogram.h" | 16 #include "base/metrics/histogram.h" |
| 17 #include "base/path_service.h" |
17 #include "base/prefs/pref_registry_simple.h" | 18 #include "base/prefs/pref_registry_simple.h" |
18 #include "base/prefs/pref_service.h" | 19 #include "base/prefs/pref_service.h" |
19 #include "base/strings/string_split.h" | 20 #include "base/strings/string_split.h" |
20 #include "base/strings/string_util.h" | 21 #include "base/strings/string_util.h" |
21 #include "base/strings/stringprintf.h" | 22 #include "base/strings/stringprintf.h" |
22 #include "base/strings/utf_string_conversions.h" | 23 #include "base/strings/utf_string_conversions.h" |
23 #include "base/time/time.h" | 24 #include "base/time/time.h" |
24 #include "chrome/browser/browser_process.h" | 25 #include "chrome/browser/browser_process.h" |
| 26 #include "chrome/browser/chromeos/customization_wallpaper_downloader.h" |
25 #include "chrome/browser/chromeos/extensions/default_app_order.h" | 27 #include "chrome/browser/chromeos/extensions/default_app_order.h" |
| 28 #include "chrome/browser/chromeos/login/wallpaper_manager.h" |
26 #include "chrome/browser/chromeos/login/wizard_controller.h" | 29 #include "chrome/browser/chromeos/login/wizard_controller.h" |
27 #include "chrome/browser/chromeos/net/delay_network_call.h" | 30 #include "chrome/browser/chromeos/net/delay_network_call.h" |
28 #include "chrome/browser/extensions/external_loader.h" | 31 #include "chrome/browser/extensions/external_loader.h" |
29 #include "chrome/browser/extensions/external_provider_impl.h" | 32 #include "chrome/browser/extensions/external_provider_impl.h" |
30 #include "chrome/browser/profiles/profile.h" | 33 #include "chrome/browser/profiles/profile.h" |
31 #include "chrome/browser/ui/app_list/app_list_syncable_service.h" | 34 #include "chrome/browser/ui/app_list/app_list_syncable_service.h" |
32 #include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h" | 35 #include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h" |
| 36 #include "chrome/common/chrome_paths.h" |
33 #include "chrome/common/extensions/extension_constants.h" | 37 #include "chrome/common/extensions/extension_constants.h" |
| 38 #include "chrome/common/pref_names.h" |
34 #include "chromeos/network/network_state.h" | 39 #include "chromeos/network/network_state.h" |
35 #include "chromeos/network/network_state_handler.h" | 40 #include "chromeos/network/network_state_handler.h" |
36 #include "chromeos/system/statistics_provider.h" | 41 #include "chromeos/system/statistics_provider.h" |
37 #include "components/user_prefs/pref_registry_syncable.h" | 42 #include "components/user_prefs/pref_registry_syncable.h" |
38 #include "content/public/browser/browser_thread.h" | 43 #include "content/public/browser/browser_thread.h" |
39 #include "net/base/load_flags.h" | 44 #include "net/base/load_flags.h" |
40 #include "net/http/http_response_headers.h" | 45 #include "net/http/http_response_headers.h" |
41 #include "net/http/http_status_code.h" | 46 #include "net/http/http_status_code.h" |
42 #include "net/url_request/url_fetcher.h" | 47 #include "net/url_request/url_fetcher.h" |
43 #include "ui/base/l10n/l10n_util.h" | 48 #include "ui/base/l10n/l10n_util.h" |
(...skipping 17 matching lines...) Expand all Loading... |
61 const char kDefaultAppsAttr[] = "default_apps"; | 66 const char kDefaultAppsAttr[] = "default_apps"; |
62 const char kLocalizedContent[] = "localized_content"; | 67 const char kLocalizedContent[] = "localized_content"; |
63 const char kDefaultAppsFolderName[] = "default_apps_folder_name"; | 68 const char kDefaultAppsFolderName[] = "default_apps_folder_name"; |
64 | 69 |
65 const char kAcceptedManifestVersion[] = "1.0"; | 70 const char kAcceptedManifestVersion[] = "1.0"; |
66 | 71 |
67 // Path to OEM partner startup customization manifest. | 72 // Path to OEM partner startup customization manifest. |
68 const char kStartupCustomizationManifestPath[] = | 73 const char kStartupCustomizationManifestPath[] = |
69 "/opt/oem/etc/startup_manifest.json"; | 74 "/opt/oem/etc/startup_manifest.json"; |
70 | 75 |
| 76 // This is subdirectory relative to PathService(DIR_CHROMEOS_CUSTOM_WALLPAPERS), |
| 77 // where downloaded (and resized) wallpaper is stored. |
| 78 const char kCustomizationDefaultWallpaperDir[] = "customization"; |
| 79 |
| 80 // The original downloaded image file is stored under this name. |
| 81 const char kCustomizationDefaultWallpaperDownloadedFile[] = |
| 82 "default_downloaded_wallpaper.bin"; |
| 83 |
71 // Name of local state option that tracks if services customization has been | 84 // Name of local state option that tracks if services customization has been |
72 // applied. | 85 // applied. |
73 const char kServicesCustomizationAppliedPref[] = "ServicesCustomizationApplied"; | 86 const char kServicesCustomizationAppliedPref[] = "ServicesCustomizationApplied"; |
74 | 87 |
75 // Maximum number of retries to fetch file if network is not available. | 88 // Maximum number of retries to fetch file if network is not available. |
76 const int kMaxFetchRetries = 3; | 89 const int kMaxFetchRetries = 3; |
77 | 90 |
78 // Delay between file fetch retries if network is not available. | 91 // Delay between file fetch retries if network is not available. |
79 const int kRetriesDelayInSec = 2; | 92 const int kRetriesDelayInSec = 2; |
80 | 93 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 const base::DictionaryValue* default_dictionary = NULL; | 136 const base::DictionaryValue* default_dictionary = NULL; |
124 if (dictionary_content->GetDictionary(kDefaultAttr, &default_dictionary)) { | 137 if (dictionary_content->GetDictionary(kDefaultAttr, &default_dictionary)) { |
125 std::string result; | 138 std::string result; |
126 if (default_dictionary->GetString(entry_name, &result)) | 139 if (default_dictionary->GetString(entry_name, &result)) |
127 return result; | 140 return result; |
128 } | 141 } |
129 | 142 |
130 return std::string(); | 143 return std::string(); |
131 } | 144 } |
132 | 145 |
| 146 void CheckWallpaperCacheExists(const base::FilePath& path, bool* exists) { |
| 147 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); |
| 148 DCHECK(exists); |
| 149 *exists = base::PathExists(path); |
| 150 } |
| 151 |
133 } // anonymous namespace | 152 } // anonymous namespace |
134 | 153 |
135 // Template URL where to fetch OEM services customization manifest from. | 154 // Template URL where to fetch OEM services customization manifest from. |
136 const char ServicesCustomizationDocument::kManifestUrl[] = | 155 const char ServicesCustomizationDocument::kManifestUrl[] = |
137 "https://ssl.gstatic.com/chrome/chromeos-customization/%s.json"; | 156 "https://ssl.gstatic.com/chrome/chromeos-customization/%s.json"; |
138 | 157 |
139 // A custom extensions::ExternalLoader that the ServicesCustomizationDocument | 158 // A custom extensions::ExternalLoader that the ServicesCustomizationDocument |
140 // creates and uses to publish OEM default apps to the extensions system. | 159 // creates and uses to publish OEM default apps to the extensions system. |
141 class ServicesCustomizationExternalLoader | 160 class ServicesCustomizationExternalLoader |
142 : public extensions::ExternalLoader, | 161 : public extensions::ExternalLoader, |
(...skipping 10 matching lines...) Expand all Loading... |
153 is_apps_set_ = true; | 172 is_apps_set_ = true; |
154 StartLoading(); | 173 StartLoading(); |
155 } | 174 } |
156 | 175 |
157 // Implementation of extensions::ExternalLoader: | 176 // Implementation of extensions::ExternalLoader: |
158 virtual void StartLoading() OVERRIDE { | 177 virtual void StartLoading() OVERRIDE { |
159 if (!is_apps_set_) { | 178 if (!is_apps_set_) { |
160 ServicesCustomizationDocument::GetInstance()->StartFetching(); | 179 ServicesCustomizationDocument::GetInstance()->StartFetching(); |
161 // In case of missing customization ID, SetCurrentApps will be called | 180 // In case of missing customization ID, SetCurrentApps will be called |
162 // synchronously from StartFetching and this function will be called | 181 // synchronously from StartFetching and this function will be called |
163 // recursively so we need to return to don't call LoadFinished twice. | 182 // recursively so we need to return to avoid calling LoadFinished twice. |
164 // In case of async load it is safe to return empty list because this | 183 // In case of async load it is safe to return empty list because this |
165 // provider didn't install any app yet so no app can be removed due to | 184 // provider didn't install any app yet so no app can be removed due to |
166 // returning empty list. | 185 // returning empty list. |
167 if (is_apps_set_) | 186 if (is_apps_set_) |
168 return; | 187 return; |
169 } | 188 } |
170 | 189 |
171 prefs_.reset(apps_.DeepCopy()); | 190 prefs_.reset(apps_.DeepCopy()); |
172 VLOG(1) << "ServicesCustomization extension loader publishing " | 191 VLOG(1) << "ServicesCustomization extension loader publishing " |
173 << apps_.size() << " apps."; | 192 << apps_.size() << " apps."; |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 return configured_locales_.front(); | 353 return configured_locales_.front(); |
335 } | 354 } |
336 | 355 |
337 std::string StartupCustomizationDocument::GetEULAPage( | 356 std::string StartupCustomizationDocument::GetEULAPage( |
338 const std::string& locale) const { | 357 const std::string& locale) const { |
339 return GetLocaleSpecificString(locale, kSetupContentAttr, kEulaPageAttr); | 358 return GetLocaleSpecificString(locale, kSetupContentAttr, kEulaPageAttr); |
340 } | 359 } |
341 | 360 |
342 // ServicesCustomizationDocument implementation. ------------------------------- | 361 // ServicesCustomizationDocument implementation. ------------------------------- |
343 | 362 |
| 363 class ServicesCustomizationDocument::ApplyingTask { |
| 364 public: |
| 365 // Registers in ServicesCustomizationDocument; |
| 366 explicit ApplyingTask(ServicesCustomizationDocument* document); |
| 367 |
| 368 // Do not automatically deregister as we might be called on invalid thread. |
| 369 ~ApplyingTask(); |
| 370 |
| 371 // Mark task finished and check for customization applied. |
| 372 void Finished(bool success); |
| 373 |
| 374 private: |
| 375 ServicesCustomizationDocument* document_; |
| 376 |
| 377 // This is error-checking flag to prevent destroying unfinished task |
| 378 // or double finish. |
| 379 bool engaged_; |
| 380 }; |
| 381 |
| 382 ServicesCustomizationDocument::ApplyingTask::ApplyingTask( |
| 383 ServicesCustomizationDocument* document) |
| 384 : document_(document), engaged_(true) { |
| 385 document->ApplyingTaskStarted(); |
| 386 } |
| 387 |
| 388 ServicesCustomizationDocument::ApplyingTask::~ApplyingTask() { |
| 389 DCHECK(!engaged_); |
| 390 } |
| 391 |
| 392 void ServicesCustomizationDocument::ApplyingTask::Finished(bool success) { |
| 393 DCHECK(engaged_); |
| 394 if (engaged_) { |
| 395 engaged_ = false; |
| 396 document_->ApplyingTaskFinished(success); |
| 397 } |
| 398 } |
| 399 |
344 ServicesCustomizationDocument::ServicesCustomizationDocument() | 400 ServicesCustomizationDocument::ServicesCustomizationDocument() |
345 : CustomizationDocument(kAcceptedManifestVersion), | 401 : CustomizationDocument(kAcceptedManifestVersion), |
346 num_retries_(0), | 402 num_retries_(0), |
347 fetch_started_(false), | 403 fetch_started_(false), |
348 network_delay_(base::TimeDelta::FromMilliseconds( | 404 network_delay_( |
349 kDefaultNetworkRetryDelayMS)), | 405 base::TimeDelta::FromMilliseconds(kDefaultNetworkRetryDelayMS)), |
| 406 apply_tasks_started_(0), |
| 407 apply_tasks_finished_(0), |
| 408 apply_tasks_success_(0), |
350 weak_ptr_factory_(this) { | 409 weak_ptr_factory_(this) { |
351 } | 410 } |
352 | 411 |
353 ServicesCustomizationDocument::ServicesCustomizationDocument( | 412 ServicesCustomizationDocument::ServicesCustomizationDocument( |
354 const std::string& manifest) | 413 const std::string& manifest) |
355 : CustomizationDocument(kAcceptedManifestVersion), | 414 : CustomizationDocument(kAcceptedManifestVersion), |
356 network_delay_(base::TimeDelta::FromMilliseconds( | 415 network_delay_( |
357 kDefaultNetworkRetryDelayMS)), | 416 base::TimeDelta::FromMilliseconds(kDefaultNetworkRetryDelayMS)), |
| 417 apply_tasks_started_(0), |
| 418 apply_tasks_finished_(0), |
| 419 apply_tasks_success_(0), |
358 weak_ptr_factory_(this) { | 420 weak_ptr_factory_(this) { |
359 LoadManifestFromString(manifest); | 421 LoadManifestFromString(manifest); |
360 } | 422 } |
361 | 423 |
362 ServicesCustomizationDocument::~ServicesCustomizationDocument() {} | 424 ServicesCustomizationDocument::~ServicesCustomizationDocument() {} |
363 | 425 |
364 // static | 426 // static |
365 ServicesCustomizationDocument* ServicesCustomizationDocument::GetInstance() { | 427 ServicesCustomizationDocument* ServicesCustomizationDocument::GetInstance() { |
366 if (g_test_services_customization_document) | 428 if (g_test_services_customization_document) |
367 return g_test_services_customization_document; | 429 return g_test_services_customization_document; |
368 | 430 |
369 return Singleton<ServicesCustomizationDocument, | 431 return Singleton<ServicesCustomizationDocument, |
370 DefaultSingletonTraits<ServicesCustomizationDocument> >::get(); | 432 DefaultSingletonTraits<ServicesCustomizationDocument> >::get(); |
371 } | 433 } |
372 | 434 |
373 // static | 435 // static |
374 void ServicesCustomizationDocument::RegisterPrefs( | 436 void ServicesCustomizationDocument::RegisterPrefs( |
375 PrefRegistrySimple* registry) { | 437 PrefRegistrySimple* registry) { |
376 registry->RegisterBooleanPref(kServicesCustomizationAppliedPref, false); | 438 registry->RegisterBooleanPref(kServicesCustomizationAppliedPref, false); |
| 439 registry->RegisterStringPref(prefs::kCustomizationDefaultWallpaperURL, |
| 440 std::string()); |
377 } | 441 } |
378 | 442 |
379 // static | 443 // static |
380 void ServicesCustomizationDocument::RegisterProfilePrefs( | 444 void ServicesCustomizationDocument::RegisterProfilePrefs( |
381 user_prefs::PrefRegistrySyncable* registry) { | 445 user_prefs::PrefRegistrySyncable* registry) { |
382 registry->RegisterDictionaryPref( | 446 registry->RegisterDictionaryPref( |
383 kServicesCustomizationKey, | 447 kServicesCustomizationKey, |
384 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 448 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
385 } | 449 } |
386 | 450 |
387 // static | 451 // static |
388 bool ServicesCustomizationDocument::WasOOBECustomizationApplied() { | 452 bool ServicesCustomizationDocument::WasOOBECustomizationApplied() { |
389 PrefService* prefs = g_browser_process->local_state(); | 453 PrefService* prefs = g_browser_process->local_state(); |
390 // prefs can be NULL in some tests. | 454 // prefs can be NULL in some tests. |
391 if (prefs) | 455 if (prefs) |
392 return prefs->GetBoolean(kServicesCustomizationAppliedPref); | 456 return prefs->GetBoolean(kServicesCustomizationAppliedPref); |
393 else | 457 else |
394 return false; | 458 return false; |
395 } | 459 } |
396 | 460 |
397 // static | 461 // static |
398 void ServicesCustomizationDocument::SetApplied(bool val) { | 462 void ServicesCustomizationDocument::SetApplied(bool val) { |
399 PrefService* prefs = g_browser_process->local_state(); | 463 PrefService* prefs = g_browser_process->local_state(); |
400 // prefs can be NULL in some tests. | 464 // prefs can be NULL in some tests. |
401 if (prefs) | 465 if (prefs) |
402 prefs->SetBoolean(kServicesCustomizationAppliedPref, val); | 466 prefs->SetBoolean(kServicesCustomizationAppliedPref, val); |
403 } | 467 } |
404 | 468 |
| 469 // static |
| 470 base::FilePath ServicesCustomizationDocument::GetCustomizedWallpaperCacheDir() { |
| 471 base::FilePath custom_wallpaper_dir; |
| 472 if (!PathService::Get(chrome::DIR_CHROMEOS_CUSTOM_WALLPAPERS, |
| 473 &custom_wallpaper_dir)) { |
| 474 LOG(DFATAL) << "Unable to get custom wallpaper dir."; |
| 475 return base::FilePath(); |
| 476 } |
| 477 return custom_wallpaper_dir.Append(kCustomizationDefaultWallpaperDir); |
| 478 } |
| 479 |
| 480 // static |
| 481 base::FilePath |
| 482 ServicesCustomizationDocument::GetCustomizedWallpaperDownloadedFileName() { |
| 483 const base::FilePath dir = GetCustomizedWallpaperCacheDir(); |
| 484 if (dir.empty()) { |
| 485 NOTREACHED(); |
| 486 return dir; |
| 487 } |
| 488 return dir.Append(kCustomizationDefaultWallpaperDownloadedFile); |
| 489 } |
| 490 |
| 491 void ServicesCustomizationDocument::EnsureCustomizationApplied() { |
| 492 if (WasOOBECustomizationApplied()) |
| 493 return; |
| 494 |
| 495 // When customization manifest is fetched, applying will start automatically. |
| 496 if (IsReady()) |
| 497 return; |
| 498 |
| 499 StartFetching(); |
| 500 } |
| 501 |
| 502 base::Closure |
| 503 ServicesCustomizationDocument::EnsureCustomizationAppliedClosure() { |
| 504 return base::Bind(&ServicesCustomizationDocument::EnsureCustomizationApplied, |
| 505 weak_ptr_factory_.GetWeakPtr()); |
| 506 } |
| 507 |
405 void ServicesCustomizationDocument::StartFetching() { | 508 void ServicesCustomizationDocument::StartFetching() { |
406 if (IsReady() || fetch_started_) | 509 if (IsReady() || fetch_started_) |
407 return; | 510 return; |
408 | 511 |
409 if (!url_.is_valid()) { | 512 if (!url_.is_valid()) { |
410 std::string customization_id; | 513 std::string customization_id; |
411 chromeos::system::StatisticsProvider* provider = | 514 chromeos::system::StatisticsProvider* provider = |
412 chromeos::system::StatisticsProvider::GetInstance(); | 515 chromeos::system::StatisticsProvider::GetInstance(); |
413 if (provider->GetMachineStatistic(system::kCustomizationIdKey, | 516 if (provider->GetMachineStatistic(system::kCustomizationIdKey, |
414 &customization_id) && | 517 &customization_id) && |
415 !customization_id.empty()) { | 518 !customization_id.empty()) { |
416 url_ = GURL(base::StringPrintf( | 519 url_ = GURL(base::StringPrintf( |
417 kManifestUrl, StringToLowerASCII(customization_id).c_str())); | 520 kManifestUrl, StringToLowerASCII(customization_id).c_str())); |
418 } else { | 521 } else { |
419 // There is no customization ID in VPD remember that. | 522 // Remember that there is no customization ID in VPD. |
420 OnCustomizationNotFound(); | 523 OnCustomizationNotFound(); |
421 return; | 524 return; |
422 } | 525 } |
423 } | 526 } |
424 | 527 |
425 if (url_.is_valid()) { | 528 if (url_.is_valid()) { |
426 fetch_started_ = true; | 529 fetch_started_ = true; |
427 if (url_.SchemeIsFile()) { | 530 if (url_.SchemeIsFile()) { |
428 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 531 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
429 base::Bind(&ServicesCustomizationDocument::ReadFileInBackground, | 532 base::Bind(&ServicesCustomizationDocument::ReadFileInBackground, |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
486 LogManifestLoadResult(HISTOGRAM_LOAD_RESULT_SUCCESS); | 589 LogManifestLoadResult(HISTOGRAM_LOAD_RESULT_SUCCESS); |
487 OnManifestLoaded(); | 590 OnManifestLoaded(); |
488 return true; | 591 return true; |
489 } | 592 } |
490 | 593 |
491 LogManifestLoadResult(HISTOGRAM_LOAD_RESULT_PARSING_ERROR); | 594 LogManifestLoadResult(HISTOGRAM_LOAD_RESULT_PARSING_ERROR); |
492 return false; | 595 return false; |
493 } | 596 } |
494 | 597 |
495 void ServicesCustomizationDocument::OnManifestLoaded() { | 598 void ServicesCustomizationDocument::OnManifestLoaded() { |
496 if (!ServicesCustomizationDocument::WasOOBECustomizationApplied()) | 599 if (!WasOOBECustomizationApplied()) |
497 ApplyOOBECustomization(); | 600 ApplyOOBECustomization(); |
498 | 601 |
499 scoped_ptr<base::DictionaryValue> prefs = | 602 scoped_ptr<base::DictionaryValue> prefs = |
500 GetDefaultAppsInProviderFormat(*root_); | 603 GetDefaultAppsInProviderFormat(*root_); |
501 for (ExternalLoaders::iterator it = external_loaders_.begin(); | 604 for (ExternalLoaders::iterator it = external_loaders_.begin(); |
502 it != external_loaders_.end(); ++it) { | 605 it != external_loaders_.end(); ++it) { |
503 if (*it) { | 606 if (*it) { |
504 UpdateCachedManifest((*it)->profile()); | 607 UpdateCachedManifest((*it)->profile()); |
505 (*it)->SetCurrentApps( | 608 (*it)->SetCurrentApps( |
506 scoped_ptr<base::DictionaryValue>(prefs->DeepCopy())); | 609 scoped_ptr<base::DictionaryValue>(prefs->DeepCopy())); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 LOG(ERROR) << "URL fetch for services customization failed:" | 641 LOG(ERROR) << "URL fetch for services customization failed:" |
539 << " response code = " << source->GetResponseCode() | 642 << " response code = " << source->GetResponseCode() |
540 << " URL = " << source->GetURL().spec(); | 643 << " URL = " << source->GetURL().spec(); |
541 | 644 |
542 LogManifestLoadResult(HISTOGRAM_LOAD_RESULT_RETRIES_FAIL); | 645 LogManifestLoadResult(HISTOGRAM_LOAD_RESULT_RETRIES_FAIL); |
543 } | 646 } |
544 fetch_started_ = false; | 647 fetch_started_ = false; |
545 } | 648 } |
546 | 649 |
547 bool ServicesCustomizationDocument::ApplyOOBECustomization() { | 650 bool ServicesCustomizationDocument::ApplyOOBECustomization() { |
548 // TODO(dpolukhin): apply default wallpaper, crbug.com/348136. | 651 if (apply_tasks_started_) |
549 SetApplied(true); | 652 return false; |
| 653 |
| 654 CheckAndApplyWallpaper(); |
| 655 return false; |
| 656 } |
| 657 |
| 658 bool ServicesCustomizationDocument::GetDefaultWallpaperUrl( |
| 659 GURL* out_url) const { |
| 660 if (!IsReady()) |
| 661 return false; |
| 662 |
| 663 std::string url; |
| 664 if (!root_->GetString(kDefaultWallpaperAttr, &url)) |
| 665 return false; |
| 666 |
| 667 *out_url = GURL(url); |
550 return true; | 668 return true; |
551 } | 669 } |
552 | 670 |
553 GURL ServicesCustomizationDocument::GetDefaultWallpaperUrl() const { | |
554 if (!IsReady()) | |
555 return GURL(); | |
556 | |
557 std::string url; | |
558 root_->GetString(kDefaultWallpaperAttr, &url); | |
559 return GURL(url); | |
560 } | |
561 | |
562 bool ServicesCustomizationDocument::GetDefaultApps( | 671 bool ServicesCustomizationDocument::GetDefaultApps( |
563 std::vector<std::string>* ids) const { | 672 std::vector<std::string>* ids) const { |
564 ids->clear(); | 673 ids->clear(); |
565 if (!IsReady()) | 674 if (!IsReady()) |
566 return false; | 675 return false; |
567 | 676 |
568 base::ListValue* apps_list = NULL; | 677 base::ListValue* apps_list = NULL; |
569 if (!root_->GetList(kDefaultAppsAttr, &apps_list)) | 678 if (!root_->GetList(kDefaultAppsAttr, &apps_list)) |
570 return false; | 679 return false; |
571 | 680 |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
682 g_test_services_customization_document = new ServicesCustomizationDocument; | 791 g_test_services_customization_document = new ServicesCustomizationDocument; |
683 g_test_services_customization_document->network_delay_ = base::TimeDelta(); | 792 g_test_services_customization_document->network_delay_ = base::TimeDelta(); |
684 } | 793 } |
685 | 794 |
686 // static | 795 // static |
687 void ServicesCustomizationDocument::ShutdownForTesting() { | 796 void ServicesCustomizationDocument::ShutdownForTesting() { |
688 delete g_test_services_customization_document; | 797 delete g_test_services_customization_document; |
689 g_test_services_customization_document = NULL; | 798 g_test_services_customization_document = NULL; |
690 } | 799 } |
691 | 800 |
| 801 void ServicesCustomizationDocument::StartOEMWallpaperDownload( |
| 802 const GURL& wallpaper_url, |
| 803 scoped_ptr<ServicesCustomizationDocument::ApplyingTask> applying) { |
| 804 DCHECK(wallpaper_url.is_valid()); |
| 805 |
| 806 const base::FilePath dir = GetCustomizedWallpaperCacheDir(); |
| 807 const base::FilePath file = GetCustomizedWallpaperDownloadedFileName(); |
| 808 if (dir.empty() || file.empty()) { |
| 809 NOTREACHED(); |
| 810 applying->Finished(false); |
| 811 return; |
| 812 } |
| 813 |
| 814 wallpaper_downloader_.reset(new CustomizationWallpaperDownloader( |
| 815 g_browser_process->system_request_context(), |
| 816 wallpaper_url, |
| 817 dir, |
| 818 file, |
| 819 base::Bind(&ServicesCustomizationDocument::OnOEMWallpaperDownloaded, |
| 820 weak_ptr_factory_.GetWeakPtr(), |
| 821 base::Passed(applying.Pass())))); |
| 822 |
| 823 wallpaper_downloader_->Start(); |
| 824 } |
| 825 |
| 826 void ServicesCustomizationDocument::CheckAndApplyWallpaper() { |
| 827 if (wallpaper_downloader_.get()) { |
| 828 VLOG(1) << "CheckAndApplyWallpaper(): download has already started."; |
| 829 return; |
| 830 } |
| 831 scoped_ptr<ServicesCustomizationDocument::ApplyingTask> applying( |
| 832 new ServicesCustomizationDocument::ApplyingTask(this)); |
| 833 |
| 834 GURL wallpaper_url; |
| 835 if (!GetDefaultWallpaperUrl(&wallpaper_url)) { |
| 836 PrefService* pref_service = g_browser_process->local_state(); |
| 837 std::string current_url = |
| 838 pref_service->GetString(prefs::kCustomizationDefaultWallpaperURL); |
| 839 if (!current_url.empty()) { |
| 840 VLOG(1) << "ServicesCustomizationDocument::CheckAndApplyWallpaper() : " |
| 841 << "No wallpaper URL attribute in customization document, " |
| 842 << "but current value is non-empty: '" << current_url |
| 843 << "'. Ignored."; |
| 844 } |
| 845 applying->Finished(true); |
| 846 return; |
| 847 } |
| 848 |
| 849 // Should fail if this ever happens in tests. |
| 850 DCHECK(wallpaper_url.is_valid()); |
| 851 if (!wallpaper_url.is_valid()) { |
| 852 if (!wallpaper_url.is_empty()) { |
| 853 LOG(WARNING) << "Invalid Customized Wallpaper URL '" |
| 854 << wallpaper_url.spec() << "'."; |
| 855 } |
| 856 applying->Finished(false); |
| 857 return; |
| 858 } |
| 859 |
| 860 scoped_ptr<bool> exists(new bool(false)); |
| 861 |
| 862 base::Closure check_file_exists = |
| 863 base::Bind(&CheckWallpaperCacheExists, |
| 864 GetCustomizedWallpaperDownloadedFileName(), |
| 865 base::Unretained(exists.get())); |
| 866 base::Closure on_checked_closure = |
| 867 base::Bind(&ServicesCustomizationDocument::OnCheckedWallpaperCacheExists, |
| 868 weak_ptr_factory_.GetWeakPtr(), |
| 869 base::Passed(exists.Pass()), |
| 870 base::Passed(applying.Pass())); |
| 871 if (!content::BrowserThread::PostBlockingPoolTaskAndReply( |
| 872 FROM_HERE, check_file_exists, on_checked_closure)) { |
| 873 LOG(WARNING) << "Failed to start check Wallpaper cache exists."; |
| 874 } |
| 875 } |
| 876 |
| 877 void ServicesCustomizationDocument::OnCheckedWallpaperCacheExists( |
| 878 scoped_ptr<bool> exists, |
| 879 scoped_ptr<ServicesCustomizationDocument::ApplyingTask> applying) { |
| 880 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 881 DCHECK(exists); |
| 882 DCHECK(applying); |
| 883 |
| 884 ApplyWallpaper(*exists, applying.Pass()); |
| 885 } |
| 886 |
| 887 void ServicesCustomizationDocument::ApplyWallpaper( |
| 888 bool default_wallpaper_file_exists, |
| 889 scoped_ptr<ServicesCustomizationDocument::ApplyingTask> applying) { |
| 890 GURL wallpaper_url; |
| 891 const bool wallpaper_url_present = GetDefaultWallpaperUrl(&wallpaper_url); |
| 892 |
| 893 PrefService* pref_service = g_browser_process->local_state(); |
| 894 |
| 895 std::string current_url = |
| 896 pref_service->GetString(prefs::kCustomizationDefaultWallpaperURL); |
| 897 if (current_url != wallpaper_url.spec()) { |
| 898 if (wallpaper_url_present) { |
| 899 VLOG(1) << "ServicesCustomizationDocument::ApplyWallpaper() : " |
| 900 << "Wallpaper URL in customization document '" |
| 901 << wallpaper_url.spec() << "' differs from current '" |
| 902 << current_url << "'." |
| 903 << (GURL(current_url).is_valid() && default_wallpaper_file_exists |
| 904 ? " Ignored." |
| 905 : " Will refetch."); |
| 906 } else { |
| 907 VLOG(1) << "ServicesCustomizationDocument::ApplyWallpaper() : " |
| 908 << "No wallpaper URL attribute in customization document, " |
| 909 << "but current value is non-empty: '" << current_url |
| 910 << "'. Ignored."; |
| 911 } |
| 912 } |
| 913 if (!wallpaper_url_present) { |
| 914 applying->Finished(true); |
| 915 return; |
| 916 } |
| 917 |
| 918 DCHECK(wallpaper_url.is_valid()); |
| 919 |
| 920 // Never update system-wide wallpaper (i.e. do not check |
| 921 // current_url == wallpaper_url.spec() ) |
| 922 if (GURL(current_url).is_valid() && default_wallpaper_file_exists) { |
| 923 VLOG(1) |
| 924 << "ServicesCustomizationDocument::ApplyWallpaper() : reuse existing"; |
| 925 OnOEMWallpaperDownloaded(applying.Pass(), true, GURL(current_url)); |
| 926 } else { |
| 927 VLOG(1) |
| 928 << "ServicesCustomizationDocument::ApplyWallpaper() : start download"; |
| 929 StartOEMWallpaperDownload(wallpaper_url, applying.Pass()); |
| 930 } |
| 931 } |
| 932 |
| 933 void ServicesCustomizationDocument::OnOEMWallpaperDownloaded( |
| 934 scoped_ptr<ServicesCustomizationDocument::ApplyingTask> applying, |
| 935 bool success, |
| 936 const GURL& wallpaper_url) { |
| 937 if (success) { |
| 938 DCHECK(wallpaper_url.is_valid()); |
| 939 |
| 940 VLOG(1) << "Setting default wallpaper to '" |
| 941 << GetCustomizedWallpaperDownloadedFileName().value() << "' ('" |
| 942 << wallpaper_url.spec() << "')"; |
| 943 WallpaperManager::Get()->SetCustomizedDefaultWallpaper( |
| 944 wallpaper_url, |
| 945 GetCustomizedWallpaperDownloadedFileName(), |
| 946 GetCustomizedWallpaperCacheDir()); |
| 947 } |
| 948 wallpaper_downloader_.reset(); |
| 949 applying->Finished(success); |
| 950 } |
| 951 |
| 952 void ServicesCustomizationDocument::ApplyingTaskStarted() { |
| 953 ++apply_tasks_started_; |
| 954 } |
| 955 |
| 956 void ServicesCustomizationDocument::ApplyingTaskFinished(bool success) { |
| 957 DCHECK_GT(apply_tasks_started_, apply_tasks_finished_); |
| 958 ++apply_tasks_finished_; |
| 959 |
| 960 apply_tasks_success_ += success; |
| 961 |
| 962 if (apply_tasks_started_ != apply_tasks_finished_) |
| 963 return; |
| 964 |
| 965 if (apply_tasks_success_ == apply_tasks_finished_) |
| 966 SetApplied(true); |
| 967 } |
| 968 |
692 } // namespace chromeos | 969 } // namespace chromeos |
OLD | NEW |