15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/customization_document.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include <algorithm> 8c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_reader.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/memory/weak_ptr.h" 16effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/metrics/histogram.h" 170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/path_service.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_registry_simple.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/string_split.h" 215e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h" 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/strings/stringprintf.h" 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h" 260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/chromeos/customization_wallpaper_downloader.h" 27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/chromeos/extensions/default_app_order.h" 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/login/wizard_controller.h" 30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "chrome/browser/chromeos/net/delay_network_call.h" 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/extensions/external_loader.h" 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/extensions/external_provider_impl.h" 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 34effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "chrome/browser/ui/app_list/app_list_syncable_service.h" 35effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h" 360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/common/chrome_paths.h" 370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/common/pref_names.h" 384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chromeos/system/statistics_provider.h" 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/pref_registry/pref_registry_syncable.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/extension_urls.h" 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/base/load_flags.h" 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/http/http_response_headers.h" 44effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "net/http/http_status_code.h" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_fetcher.h" 46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/base/l10n/l10n_util.h" 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace chromeos { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Manifest attributes names. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kVersionAttr[] = "version"; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kDefaultAttr[] = "default"; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInitialLocaleAttr[] = "initial_locale"; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInitialTimezoneAttr[] = "initial_timezone"; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kKeyboardLayoutAttr[] = "keyboard_layout"; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kHwidMapAttr[] = "hwid_map"; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kHwidMaskAttr[] = "hwid_mask"; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kSetupContentAttr[] = "setup_content"; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kEulaPageAttr[] = "eula_page"; 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const char kDefaultWallpaperAttr[] = "default_wallpaper"; 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const char kDefaultAppsAttr[] = "default_apps"; 65effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochconst char kLocalizedContent[] = "localized_content"; 66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochconst char kDefaultAppsFolderName[] = "default_apps_folder_name"; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kAcceptedManifestVersion[] = "1.0"; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Path to OEM partner startup customization manifest. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kStartupCustomizationManifestPath[] = 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "/opt/oem/etc/startup_manifest.json"; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// This is subdirectory relative to PathService(DIR_CHROMEOS_CUSTOM_WALLPAPERS), 750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// where downloaded (and resized) wallpaper is stored. 760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochconst char kCustomizationDefaultWallpaperDir[] = "customization"; 770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// The original downloaded image file is stored under this name. 790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochconst char kCustomizationDefaultWallpaperDownloadedFile[] = 800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch "default_downloaded_wallpaper.bin"; 810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Name of local state option that tracks if services customization has been 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// applied. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kServicesCustomizationAppliedPref[] = "ServicesCustomizationApplied"; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Maximum number of retries to fetch file if network is not available. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxFetchRetries = 3; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Delay between file fetch retries if network is not available. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kRetriesDelayInSec = 2; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Name of profile option that tracks cached version of service customization. 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const char kServicesCustomizationKey[] = "customization.manifest_cache"; 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Empty customization document that doesn't customize anything. 96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochconst char kEmptyServicesCustomizationManifest[] = "{ \"version\": \"1.0\" }"; 97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 98effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Global overrider for ServicesCustomizationDocument for tests. 99effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochServicesCustomizationDocument* g_test_services_customization_document = NULL; 100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Services customization document load results reported via the 102effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// "ServicesCustomization.LoadResult" histogram. 103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// It is append-only enum due to use in a histogram! 104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochenum HistogramServicesCustomizationLoadResult { 105effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch HISTOGRAM_LOAD_RESULT_SUCCESS = 0, 106effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch HISTOGRAM_LOAD_RESULT_FILE_NOT_FOUND = 1, 107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch HISTOGRAM_LOAD_RESULT_PARSING_ERROR = 2, 108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch HISTOGRAM_LOAD_RESULT_RETRIES_FAIL = 3, 109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch HISTOGRAM_LOAD_RESULT_MAX_VALUE = 4 110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid LogManifestLoadResult(HistogramServicesCustomizationLoadResult result) { 113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch UMA_HISTOGRAM_ENUMERATION("ServicesCustomization.LoadResult", 114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch result, 115effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch HISTOGRAM_LOAD_RESULT_MAX_VALUE); 116effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 117effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochstd::string GetLocaleSpecificStringImpl( 119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const base::DictionaryValue* root, 120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const std::string& locale, 121effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const std::string& dictionary_name, 122effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const std::string& entry_name) { 123effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const base::DictionaryValue* dictionary_content = NULL; 124effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!root || !root->GetDictionary(dictionary_name, &dictionary_content)) 125effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return std::string(); 126effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 127effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const base::DictionaryValue* locale_dictionary = NULL; 128effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (dictionary_content->GetDictionary(locale, &locale_dictionary)) { 129effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch std::string result; 130effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (locale_dictionary->GetString(entry_name, &result)) 131effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return result; 132effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 133effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 134effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const base::DictionaryValue* default_dictionary = NULL; 135effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (dictionary_content->GetDictionary(kDefaultAttr, &default_dictionary)) { 136effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch std::string result; 137effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (default_dictionary->GetString(entry_name, &result)) 138effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return result; 139effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 140effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 141effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return std::string(); 142effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid CheckWallpaperCacheExists(const base::FilePath& path, bool* exists) { 1450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); 1460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(exists); 1470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch *exists = base::PathExists(path); 1480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 1490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 150effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} // anonymous namespace 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Template URL where to fetch OEM services customization manifest from. 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const char ServicesCustomizationDocument::kManifestUrl[] = 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "https://ssl.gstatic.com/chrome/chromeos-customization/%s.json"; 155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// A custom extensions::ExternalLoader that the ServicesCustomizationDocument 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// creates and uses to publish OEM default apps to the extensions system. 158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class ServicesCustomizationExternalLoader 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : public extensions::ExternalLoader, 160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public base::SupportsWeakPtr<ServicesCustomizationExternalLoader> { 161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) explicit ServicesCustomizationExternalLoader(Profile* profile) 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : is_apps_set_(false), profile_(profile) {} 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Profile* profile() { return profile_; } 166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Used by the ServicesCustomizationDocument to update the current apps. 168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void SetCurrentApps(scoped_ptr<base::DictionaryValue> prefs) { 169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) apps_.Swap(prefs.get()); 170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) is_apps_set_ = true; 171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) StartLoading(); 172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Implementation of extensions::ExternalLoader: 175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void StartLoading() OVERRIDE { 176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!is_apps_set_) { 177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ServicesCustomizationDocument::GetInstance()->StartFetching(); 178a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // In case of missing customization ID, SetCurrentApps will be called 179a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // synchronously from StartFetching and this function will be called 1800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // recursively so we need to return to avoid calling LoadFinished twice. 181a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // In case of async load it is safe to return empty list because this 182a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // provider didn't install any app yet so no app can be removed due to 183a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // returning empty list. 184a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (is_apps_set_) 185a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return; 186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) prefs_.reset(apps_.DeepCopy()); 189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "ServicesCustomization extension loader publishing " 190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << apps_.size() << " apps."; 191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LoadFinished(); 192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) protected: 195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual ~ServicesCustomizationExternalLoader() {} 196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private: 198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool is_apps_set_; 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::DictionaryValue apps_; 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Profile* profile_; 201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ServicesCustomizationExternalLoader); 203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CustomizationDocument implementation. --------------------------------------- 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CustomizationDocument::CustomizationDocument( 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& accepted_version) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : accepted_version_(accepted_version) {} 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CustomizationDocument::~CustomizationDocument() {} 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CustomizationDocument::LoadManifestFromFile( 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& manifest_path) { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string manifest; 21658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!base::ReadFileToString(manifest_path, &manifest)) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LoadManifestFromString(manifest); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CustomizationDocument::LoadManifestFromString( 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& manifest) { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int error_code = 0; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string error; 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::Value> root(base::JSONReader::ReadAndReturnError(manifest, 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::JSON_ALLOW_TRAILING_COMMAS, &error_code, &error)); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error_code != base::JSONReader::JSON_NO_ERROR) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << error; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(root.get() != NULL); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (root.get() == NULL) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(root->GetType() == base::Value::TYPE_DICTIONARY); 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (root->GetType() == base::Value::TYPE_DICTIONARY) { 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) root_.reset(static_cast<base::DictionaryValue*>(root.release())); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string result; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (root_->GetString(kVersionAttr, &result) && 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result == accepted_version_) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Wrong customization manifest version"; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_.reset(NULL); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string CustomizationDocument::GetLocaleSpecificString( 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& locale, 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& dictionary_name, 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& entry_name) const { 250effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return GetLocaleSpecificStringImpl( 251effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch root_.get(), locale, dictionary_name, entry_name); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// StartupCustomizationDocument implementation. -------------------------------- 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StartupCustomizationDocument::StartupCustomizationDocument() 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : CustomizationDocument(kAcceptedManifestVersion) { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Loading manifest causes us to do blocking IO on UI thread. 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Temporarily allow it until we fix http://crosbug.com/11103 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ThreadRestrictions::ScopedAllowIO allow_io; 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LoadManifestFromFile(base::FilePath(kStartupCustomizationManifestPath)); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Init(system::StatisticsProvider::GetInstance()); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StartupCustomizationDocument::StartupCustomizationDocument( 268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) system::StatisticsProvider* statistics_provider, 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& manifest) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : CustomizationDocument(kAcceptedManifestVersion) { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadManifestFromString(manifest); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Init(statistics_provider); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StartupCustomizationDocument::~StartupCustomizationDocument() {} 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StartupCustomizationDocument* StartupCustomizationDocument::GetInstance() { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Singleton<StartupCustomizationDocument, 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DefaultSingletonTraits<StartupCustomizationDocument> >::get(); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StartupCustomizationDocument::Init( 283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) system::StatisticsProvider* statistics_provider) { 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsReady()) { 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_->GetString(kInitialLocaleAttr, &initial_locale_); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_->GetString(kInitialTimezoneAttr, &initial_timezone_); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_->GetString(kKeyboardLayoutAttr, &keyboard_layout_); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string hwid; 290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (statistics_provider->GetMachineStatistic( 291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) system::kHardwareClassKey, &hwid)) { 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue* hwid_list = NULL; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (root_->GetList(kHwidMapAttr, &hwid_list)) { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < hwid_list->GetSize(); ++i) { 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* hwid_dictionary = NULL; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string hwid_mask; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hwid_list->GetDictionary(i, &hwid_dictionary) && 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hwid_dictionary->GetString(kHwidMaskAttr, &hwid_mask)) { 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (MatchPattern(hwid, hwid_mask)) { 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If HWID for this machine matches some mask, use HWID specific 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // settings. 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string result; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hwid_dictionary->GetString(kInitialLocaleAttr, &result)) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initial_locale_ = result; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hwid_dictionary->GetString(kInitialTimezoneAttr, &result)) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initial_timezone_ = result; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hwid_dictionary->GetString(kKeyboardLayoutAttr, &result)) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keyboard_layout_ = result; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't break here to allow other entires to be applied if match. 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Syntax error in customization manifest"; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "HWID is missing in machine statistics"; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If manifest doesn't exist still apply values from VPD. 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) statistics_provider->GetMachineStatistic(kInitialLocaleAttr, 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &initial_locale_); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) statistics_provider->GetMachineStatistic(kInitialTimezoneAttr, 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &initial_timezone_); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) statistics_provider->GetMachineStatistic(kKeyboardLayoutAttr, 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &keyboard_layout_); 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) configured_locales_.resize(0); 3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::SplitString(initial_locale_, ',', &configured_locales_); 332c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 333c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Convert ICU locale to chrome ("en_US" to "en-US", etc.). 334c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch std::for_each(configured_locales_.begin(), 335c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch configured_locales_.end(), 336c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch l10n_util::GetCanonicalLocale); 337c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Let's always have configured_locales_.front() a valid entry. 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (configured_locales_.size() == 0) 3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) configured_locales_.push_back(std::string()); 3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const std::vector<std::string>& 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)StartupCustomizationDocument::configured_locales() const { 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return configured_locales_; 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const std::string& StartupCustomizationDocument::initial_locale_default() 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const { 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(configured_locales_.size() > 0); 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return configured_locales_.front(); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string StartupCustomizationDocument::GetEULAPage( 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& locale) const { 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetLocaleSpecificString(locale, kSetupContentAttr, kEulaPageAttr); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ServicesCustomizationDocument implementation. ------------------------------- 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass ServicesCustomizationDocument::ApplyingTask { 3620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public: 3630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Registers in ServicesCustomizationDocument; 3640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch explicit ApplyingTask(ServicesCustomizationDocument* document); 3650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 3660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Do not automatically deregister as we might be called on invalid thread. 3670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ~ApplyingTask(); 3680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 3690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Mark task finished and check for customization applied. 3700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch void Finished(bool success); 3710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 3720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private: 3730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ServicesCustomizationDocument* document_; 3740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 3750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // This is error-checking flag to prevent destroying unfinished task 3760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // or double finish. 3770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch bool engaged_; 3780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}; 3790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 3800529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochServicesCustomizationDocument::ApplyingTask::ApplyingTask( 3810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ServicesCustomizationDocument* document) 3820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch : document_(document), engaged_(true) { 3830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch document->ApplyingTaskStarted(); 3840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 3850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 3860529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochServicesCustomizationDocument::ApplyingTask::~ApplyingTask() { 3870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(!engaged_); 3880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 3890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 3900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ServicesCustomizationDocument::ApplyingTask::Finished(bool success) { 3910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(engaged_); 3920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (engaged_) { 3930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch engaged_ = false; 3940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch document_->ApplyingTaskFinished(success); 3950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 3960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 3970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ServicesCustomizationDocument::ServicesCustomizationDocument() 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : CustomizationDocument(kAcceptedManifestVersion), 400a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) num_retries_(0), 401effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch fetch_started_(false), 4020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch network_delay_( 4030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::TimeDelta::FromMilliseconds(kDefaultNetworkRetryDelayMS)), 4040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch apply_tasks_started_(0), 4050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch apply_tasks_finished_(0), 4060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch apply_tasks_success_(0), 407effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch weak_ptr_factory_(this) { 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ServicesCustomizationDocument::ServicesCustomizationDocument( 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& manifest) 412effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch : CustomizationDocument(kAcceptedManifestVersion), 4130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch network_delay_( 4140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::TimeDelta::FromMilliseconds(kDefaultNetworkRetryDelayMS)), 4150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch apply_tasks_started_(0), 4160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch apply_tasks_finished_(0), 4170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch apply_tasks_success_(0), 418effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch weak_ptr_factory_(this) { 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadManifestFromString(manifest); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ServicesCustomizationDocument::~ServicesCustomizationDocument() {} 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ServicesCustomizationDocument* ServicesCustomizationDocument::GetInstance() { 426effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (g_test_services_customization_document) 427effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return g_test_services_customization_document; 428effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Singleton<ServicesCustomizationDocument, 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DefaultSingletonTraits<ServicesCustomizationDocument> >::get(); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ServicesCustomizationDocument::RegisterPrefs( 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PrefRegistrySimple* registry) { 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registry->RegisterBooleanPref(kServicesCustomizationAppliedPref, false); 4370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch registry->RegisterStringPref(prefs::kCustomizationDefaultWallpaperURL, 4380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch std::string()); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 442a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServicesCustomizationDocument::RegisterProfilePrefs( 443a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) user_prefs::PrefRegistrySyncable* registry) { 444a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) registry->RegisterDictionaryPref( 445a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kServicesCustomizationKey, 446a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 447a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 448a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 449a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static 450a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ServicesCustomizationDocument::WasOOBECustomizationApplied() { 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefService* prefs = g_browser_process->local_state(); 452a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // prefs can be NULL in some tests. 453a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (prefs) 454a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return prefs->GetBoolean(kServicesCustomizationAppliedPref); 455a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch else 456a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return false; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ServicesCustomizationDocument::SetApplied(bool val) { 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefService* prefs = g_browser_process->local_state(); 462a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // prefs can be NULL in some tests. 463a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (prefs) 464a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch prefs->SetBoolean(kServicesCustomizationAppliedPref, val); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// static 4680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbase::FilePath ServicesCustomizationDocument::GetCustomizedWallpaperCacheDir() { 4690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::FilePath custom_wallpaper_dir; 4700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!PathService::Get(chrome::DIR_CHROMEOS_CUSTOM_WALLPAPERS, 4710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch &custom_wallpaper_dir)) { 4720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch LOG(DFATAL) << "Unable to get custom wallpaper dir."; 4730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return base::FilePath(); 4740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 4750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return custom_wallpaper_dir.Append(kCustomizationDefaultWallpaperDir); 4760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 4770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 4780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// static 4790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbase::FilePath 4800529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochServicesCustomizationDocument::GetCustomizedWallpaperDownloadedFileName() { 4810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const base::FilePath dir = GetCustomizedWallpaperCacheDir(); 4820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (dir.empty()) { 4830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch NOTREACHED(); 4840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return dir; 4850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 4860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return dir.Append(kCustomizationDefaultWallpaperDownloadedFile); 4870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 4880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 4890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ServicesCustomizationDocument::EnsureCustomizationApplied() { 4900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (WasOOBECustomizationApplied()) 4910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 4920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 4930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // When customization manifest is fetched, applying will start automatically. 4940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (IsReady()) 4950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 4960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 4970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch StartFetching(); 4980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 4990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 5000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbase::Closure 5010529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochServicesCustomizationDocument::EnsureCustomizationAppliedClosure() { 5020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return base::Bind(&ServicesCustomizationDocument::EnsureCustomizationApplied, 5030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch weak_ptr_factory_.GetWeakPtr()); 5040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 5050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ServicesCustomizationDocument::StartFetching() { 507effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (IsReady() || fetch_started_) 508effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return; 509effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 510effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!url_.is_valid()) { 511effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch std::string customization_id; 512effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch chromeos::system::StatisticsProvider* provider = 513effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch chromeos::system::StatisticsProvider::GetInstance(); 514effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (provider->GetMachineStatistic(system::kCustomizationIdKey, 515effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch &customization_id) && 516effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch !customization_id.empty()) { 517effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch url_ = GURL(base::StringPrintf( 5186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) kManifestUrl, base::StringToLowerASCII(customization_id).c_str())); 519a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } else { 5200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Remember that there is no customization ID in VPD. 521a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch OnCustomizationNotFound(); 522a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return; 523a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 524effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 525a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 526effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (url_.is_valid()) { 527effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch fetch_started_ = true; 528effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (url_.SchemeIsFile()) { 529effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 530effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Bind(&ServicesCustomizationDocument::ReadFileInBackground, 531effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch weak_ptr_factory_.GetWeakPtr(), 532effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::FilePath(url_.path()))); 533effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } else { 534effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch StartFileFetch(); 535a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 539effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// static 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ServicesCustomizationDocument::ReadFileInBackground( 541effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::WeakPtr<ServicesCustomizationDocument> self, 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& file) { 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string manifest; 546a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!base::ReadFileToString(file, &manifest)) { 547a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) manifest.clear(); 548a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(ERROR) << "Failed to load services customization manifest from: " 549a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << file.value(); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 551a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 552a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 553a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&ServicesCustomizationDocument::OnManifesteRead, 554effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch self, 555a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) manifest)); 556a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 557a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 558a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServicesCustomizationDocument::OnManifesteRead( 559a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& manifest) { 560a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!manifest.empty()) 561a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LoadManifestFromString(manifest); 562a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 563a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) fetch_started_ = false; 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ServicesCustomizationDocument::StartFileFetch() { 567effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DelayNetworkCall(base::Bind(&ServicesCustomizationDocument::DoStartFileFetch, 568effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch weak_ptr_factory_.GetWeakPtr()), 569effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch network_delay_); 570effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 571effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 572effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ServicesCustomizationDocument::DoStartFileFetch() { 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_fetcher_.reset(net::URLFetcher::Create( 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_, net::URLFetcher::GET, this)); 5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) url_fetcher_->SetRequestContext(g_browser_process->system_request_context()); 576a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) url_fetcher_->AddExtraRequestHeader("Accept: application/json"); 577a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | 578a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::LOAD_DO_NOT_SAVE_COOKIES | 579a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::LOAD_DISABLE_CACHE | 580a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::LOAD_DO_NOT_SEND_AUTH_DATA); 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_fetcher_->Start(); 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 584a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ServicesCustomizationDocument::LoadManifestFromString( 585a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& manifest) { 586a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (CustomizationDocument::LoadManifestFromString(manifest)) { 587effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch LogManifestLoadResult(HISTOGRAM_LOAD_RESULT_SUCCESS); 588a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OnManifestLoaded(); 589a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 590a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 591effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 592effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch LogManifestLoadResult(HISTOGRAM_LOAD_RESULT_PARSING_ERROR); 593a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 594a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 595a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 596a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServicesCustomizationDocument::OnManifestLoaded() { 5970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!WasOOBECustomizationApplied()) 598a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ApplyOOBECustomization(); 599a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 600a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<base::DictionaryValue> prefs = 601a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GetDefaultAppsInProviderFormat(*root_); 602a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (ExternalLoaders::iterator it = external_loaders_.begin(); 603a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) it != external_loaders_.end(); ++it) { 604a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (*it) { 605a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) UpdateCachedManifest((*it)->profile()); 606a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) (*it)->SetCurrentApps( 607a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<base::DictionaryValue>(prefs->DeepCopy())); 608effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch SetOemFolderName((*it)->profile(), *root_); 609a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 610a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 611a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 612a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ServicesCustomizationDocument::OnURLFetchComplete( 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::URLFetcher* source) { 615a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string mime_type; 616a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string data; 617a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (source->GetStatus().is_success() && 618effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch source->GetResponseCode() == net::HTTP_OK && 619a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) source->GetResponseHeaders()->GetMimeType(&mime_type) && 620a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) mime_type == "application/json" && 621a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) source->GetResponseAsString(&data)) { 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadManifestFromString(data); 623effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } else if (source->GetResponseCode() == net::HTTP_NOT_FOUND) { 624effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch LOG(ERROR) << "Customization manifest is missing on server: " 625effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch << source->GetURL().spec(); 626effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch OnCustomizationNotFound(); 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 628effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (num_retries_ < kMaxFetchRetries) { 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_retries_++; 630effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch content::BrowserThread::PostDelayedTask( 631effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch content::BrowserThread::UI, 632effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch FROM_HERE, 633effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Bind(&ServicesCustomizationDocument::StartFileFetch, 634effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch weak_ptr_factory_.GetWeakPtr()), 635effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::TimeDelta::FromSeconds(kRetriesDelayInSec)); 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 638effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // This doesn't stop fetching manifest on next restart. 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "URL fetch for services customization failed:" 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " response code = " << source->GetResponseCode() 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " URL = " << source->GetURL().spec(); 642effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 643effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch LogManifestLoadResult(HISTOGRAM_LOAD_RESULT_RETRIES_FAIL); 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 645effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch fetch_started_ = false; 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 648a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ServicesCustomizationDocument::ApplyOOBECustomization() { 6490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (apply_tasks_started_) 6500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return false; 6510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 6520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch CheckAndApplyWallpaper(); 6530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return false; 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbool ServicesCustomizationDocument::GetDefaultWallpaperUrl( 6570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch GURL* out_url) const { 658a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!IsReady()) 6590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return false; 660a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 661a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string url; 6620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!root_->GetString(kDefaultWallpaperAttr, &url)) 6630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return false; 6640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 6650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch *out_url = GURL(url); 6660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return true; 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 669a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ServicesCustomizationDocument::GetDefaultApps( 670a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<std::string>* ids) const { 671a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ids->clear(); 672a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!IsReady()) 673a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 674a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 675a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::ListValue* apps_list = NULL; 676a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!root_->GetList(kDefaultAppsAttr, &apps_list)) 677a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 678a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 679a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (size_t i = 0; i < apps_list->GetSize(); ++i) { 680a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string app_id; 681a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (apps_list->GetString(i, &app_id)) { 682a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ids->push_back(app_id); 683a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 684a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(ERROR) << "Wrong format of default application list"; 685a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 686a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 687a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 688a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 689a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 690a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 691a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 692effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochstd::string ServicesCustomizationDocument::GetOemAppsFolderName( 693effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const std::string& locale) const { 694effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!IsReady()) 695effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return std::string(); 696effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 697effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return GetOemAppsFolderNameImpl(locale, *root_); 698effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 699effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 700a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)scoped_ptr<base::DictionaryValue> 701a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ServicesCustomizationDocument::GetDefaultAppsInProviderFormat( 702a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::DictionaryValue& root) { 703a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<base::DictionaryValue> prefs(new base::DictionaryValue); 704a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::ListValue* apps_list = NULL; 705a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (root.GetList(kDefaultAppsAttr, &apps_list)) { 706a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (size_t i = 0; i < apps_list->GetSize(); ++i) { 707a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string app_id; 708a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (apps_list->GetString(i, &app_id)) { 709a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::DictionaryValue* entry = new base::DictionaryValue; 710a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) entry->SetString(extensions::ExternalProviderImpl::kExternalUpdateUrl, 711a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) extension_urls::GetWebstoreUpdateUrl().spec()); 712a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) prefs->Set(app_id, entry); 713a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 714a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(ERROR) << "Wrong format of default application list"; 715a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) prefs->Clear(); 716a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 717a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 718a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 719a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 720a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 721a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return prefs.Pass(); 722a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 723a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 724a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServicesCustomizationDocument::UpdateCachedManifest(Profile* profile) { 725a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) profile->GetPrefs()->Set(kServicesCustomizationKey, *root_); 726a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 727a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 728a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)extensions::ExternalLoader* ServicesCustomizationDocument::CreateExternalLoader( 729a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Profile* profile) { 730a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ServicesCustomizationExternalLoader* loader = 731a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new ServicesCustomizationExternalLoader(profile); 732a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) external_loaders_.push_back(loader->AsWeakPtr()); 733a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 734a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (IsReady()) { 735a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) UpdateCachedManifest(profile); 736a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) loader->SetCurrentApps(GetDefaultAppsInProviderFormat(*root_)); 737effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch SetOemFolderName(profile, *root_); 738a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 739a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::DictionaryValue* root = 740a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) profile->GetPrefs()->GetDictionary(kServicesCustomizationKey); 741a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string version; 742a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (root && root->GetString(kVersionAttr, &version)) { 743a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // If version exists, profile has cached version of customization. 744a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) loader->SetCurrentApps(GetDefaultAppsInProviderFormat(*root)); 745effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch SetOemFolderName(profile, *root); 746a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 747a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // StartFetching will be called from ServicesCustomizationExternalLoader 748a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // when StartLoading is called. We can't initiate manifest fetch here 749a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // because caller may never call StartLoading for the provider. 750a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 751a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 752a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 753a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return loader; 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 756effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ServicesCustomizationDocument::OnCustomizationNotFound() { 757effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch LogManifestLoadResult(HISTOGRAM_LOAD_RESULT_FILE_NOT_FOUND); 758effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch LoadManifestFromString(kEmptyServicesCustomizationManifest); 759effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 760effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 761effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ServicesCustomizationDocument::SetOemFolderName( 762effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch Profile* profile, 763effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const base::DictionaryValue& root) { 764effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch std::string locale = g_browser_process->GetApplicationLocale(); 765effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch std::string name = GetOemAppsFolderNameImpl(locale, root); 766c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (name.empty()) 767c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch name = default_app_order::GetOemAppsFolderName(); 768effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!name.empty()) { 769effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch app_list::AppListSyncableService* service = 770effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch app_list::AppListSyncableServiceFactory::GetForProfile(profile); 771effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!service) { 772effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch LOG(WARNING) << "AppListSyncableService is not ready for setting OEM " 773effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch "folder name"; 774effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return; 775effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 776effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch service->SetOemFolderName(name); 777effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 778effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 779effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 780effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochstd::string ServicesCustomizationDocument::GetOemAppsFolderNameImpl( 781effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const std::string& locale, 782effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const base::DictionaryValue& root) const { 783effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return GetLocaleSpecificStringImpl( 784effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch &root, locale, kLocalizedContent, kDefaultAppsFolderName); 785effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 786effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 787effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// static 788effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ServicesCustomizationDocument::InitializeForTesting() { 789effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch g_test_services_customization_document = new ServicesCustomizationDocument; 790effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch g_test_services_customization_document->network_delay_ = base::TimeDelta(); 791effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 792effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 793effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// static 794effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ServicesCustomizationDocument::ShutdownForTesting() { 795effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch delete g_test_services_customization_document; 796effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch g_test_services_customization_document = NULL; 797effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 798effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 7990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ServicesCustomizationDocument::StartOEMWallpaperDownload( 8000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const GURL& wallpaper_url, 8010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_ptr<ServicesCustomizationDocument::ApplyingTask> applying) { 8020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(wallpaper_url.is_valid()); 8030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 8040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const base::FilePath dir = GetCustomizedWallpaperCacheDir(); 8050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const base::FilePath file = GetCustomizedWallpaperDownloadedFileName(); 8060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (dir.empty() || file.empty()) { 8070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch NOTREACHED(); 8080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch applying->Finished(false); 8090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 8100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 8110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 8120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch wallpaper_downloader_.reset(new CustomizationWallpaperDownloader( 8130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch g_browser_process->system_request_context(), 8140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch wallpaper_url, 8150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch dir, 8160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch file, 8170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::Bind(&ServicesCustomizationDocument::OnOEMWallpaperDownloaded, 8180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch weak_ptr_factory_.GetWeakPtr(), 8190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::Passed(applying.Pass())))); 8200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 8210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch wallpaper_downloader_->Start(); 8220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 8230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 8240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ServicesCustomizationDocument::CheckAndApplyWallpaper() { 8250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (wallpaper_downloader_.get()) { 8260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VLOG(1) << "CheckAndApplyWallpaper(): download has already started."; 8270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 8280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 8290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_ptr<ServicesCustomizationDocument::ApplyingTask> applying( 8300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch new ServicesCustomizationDocument::ApplyingTask(this)); 8310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 8320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch GURL wallpaper_url; 8330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!GetDefaultWallpaperUrl(&wallpaper_url)) { 8340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch PrefService* pref_service = g_browser_process->local_state(); 8350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch std::string current_url = 8360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch pref_service->GetString(prefs::kCustomizationDefaultWallpaperURL); 8370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!current_url.empty()) { 8380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VLOG(1) << "ServicesCustomizationDocument::CheckAndApplyWallpaper() : " 8390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch << "No wallpaper URL attribute in customization document, " 8400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch << "but current value is non-empty: '" << current_url 8410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch << "'. Ignored."; 8420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 8430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch applying->Finished(true); 8440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 8450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 8460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 8470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Should fail if this ever happens in tests. 8480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(wallpaper_url.is_valid()); 8490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!wallpaper_url.is_valid()) { 8500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!wallpaper_url.is_empty()) { 8510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch LOG(WARNING) << "Invalid Customized Wallpaper URL '" 8520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch << wallpaper_url.spec() << "'."; 8530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 8540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch applying->Finished(false); 8550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 8560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 8570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 8580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_ptr<bool> exists(new bool(false)); 8590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 8600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::Closure check_file_exists = 8610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::Bind(&CheckWallpaperCacheExists, 8620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch GetCustomizedWallpaperDownloadedFileName(), 8630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::Unretained(exists.get())); 8640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::Closure on_checked_closure = 8650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::Bind(&ServicesCustomizationDocument::OnCheckedWallpaperCacheExists, 8660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch weak_ptr_factory_.GetWeakPtr(), 8670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::Passed(exists.Pass()), 8680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::Passed(applying.Pass())); 8690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!content::BrowserThread::PostBlockingPoolTaskAndReply( 8700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch FROM_HERE, check_file_exists, on_checked_closure)) { 8710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch LOG(WARNING) << "Failed to start check Wallpaper cache exists."; 8720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 8730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 8740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 8750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ServicesCustomizationDocument::OnCheckedWallpaperCacheExists( 8760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_ptr<bool> exists, 8770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_ptr<ServicesCustomizationDocument::ApplyingTask> applying) { 8780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 8790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(exists); 8800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(applying); 8810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 8820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ApplyWallpaper(*exists, applying.Pass()); 8830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 8840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 8850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ServicesCustomizationDocument::ApplyWallpaper( 8860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch bool default_wallpaper_file_exists, 8870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_ptr<ServicesCustomizationDocument::ApplyingTask> applying) { 8880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch GURL wallpaper_url; 8890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const bool wallpaper_url_present = GetDefaultWallpaperUrl(&wallpaper_url); 8900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 8910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch PrefService* pref_service = g_browser_process->local_state(); 8920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 8930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch std::string current_url = 8940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch pref_service->GetString(prefs::kCustomizationDefaultWallpaperURL); 8950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (current_url != wallpaper_url.spec()) { 8960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (wallpaper_url_present) { 8970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VLOG(1) << "ServicesCustomizationDocument::ApplyWallpaper() : " 8980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch << "Wallpaper URL in customization document '" 8990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch << wallpaper_url.spec() << "' differs from current '" 9000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch << current_url << "'." 9010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch << (GURL(current_url).is_valid() && default_wallpaper_file_exists 9020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ? " Ignored." 9030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch : " Will refetch."); 9040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } else { 9050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VLOG(1) << "ServicesCustomizationDocument::ApplyWallpaper() : " 9060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch << "No wallpaper URL attribute in customization document, " 9070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch << "but current value is non-empty: '" << current_url 9080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch << "'. Ignored."; 9090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 9100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 9110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!wallpaper_url_present) { 9120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch applying->Finished(true); 9130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 9140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 9150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 9160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(wallpaper_url.is_valid()); 9170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 9180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Never update system-wide wallpaper (i.e. do not check 9190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // current_url == wallpaper_url.spec() ) 9200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (GURL(current_url).is_valid() && default_wallpaper_file_exists) { 9210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VLOG(1) 9220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch << "ServicesCustomizationDocument::ApplyWallpaper() : reuse existing"; 9230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch OnOEMWallpaperDownloaded(applying.Pass(), true, GURL(current_url)); 9240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } else { 9250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VLOG(1) 9260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch << "ServicesCustomizationDocument::ApplyWallpaper() : start download"; 9270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch StartOEMWallpaperDownload(wallpaper_url, applying.Pass()); 9280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 9290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 9300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 9310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ServicesCustomizationDocument::OnOEMWallpaperDownloaded( 9320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_ptr<ServicesCustomizationDocument::ApplyingTask> applying, 9330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch bool success, 9340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const GURL& wallpaper_url) { 9350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (success) { 9360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(wallpaper_url.is_valid()); 9370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 9380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VLOG(1) << "Setting default wallpaper to '" 9390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch << GetCustomizedWallpaperDownloadedFileName().value() << "' ('" 9400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch << wallpaper_url.spec() << "')"; 9410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch WallpaperManager::Get()->SetCustomizedDefaultWallpaper( 9420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch wallpaper_url, 9430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch GetCustomizedWallpaperDownloadedFileName(), 9440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch GetCustomizedWallpaperCacheDir()); 9450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 9460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch wallpaper_downloader_.reset(); 9470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch applying->Finished(success); 9480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 9490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 9500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ServicesCustomizationDocument::ApplyingTaskStarted() { 9510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ++apply_tasks_started_; 9520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 9530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 9540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ServicesCustomizationDocument::ApplyingTaskFinished(bool success) { 9550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK_GT(apply_tasks_started_, apply_tasks_finished_); 9560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ++apply_tasks_finished_; 9570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 9580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch apply_tasks_success_ += success; 9590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 9600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (apply_tasks_started_ != apply_tasks_finished_) 9610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 9620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 9630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (apply_tasks_success_ == apply_tasks_finished_) 9640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch SetApplied(true); 9650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 9660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace chromeos 968