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 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_CHROMEOS_CUSTOMIZATION_DOCUMENT_H_ 6 #define CHROME_BROWSER_CHROMEOS_CUSTOMIZATION_DOCUMENT_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "base/compiler_specific.h" 12 #include "base/gtest_prod_util.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/singleton.h" 15 #include "base/memory/weak_ptr.h" 16 #include "base/values.h" 17 #include "net/url_request/url_fetcher_delegate.h" 18 #include "url/gurl.h" 19 20 class PrefRegistrySimple; 21 class Profile; 22 23 namespace base { 24 class DictionaryValue; 25 class FilePath; 26 } 27 28 namespace extensions { 29 class ExternalLoader; 30 } 31 32 namespace net { 33 class URLFetcher; 34 } 35 36 namespace user_prefs { 37 class PrefRegistrySyncable; 38 } 39 40 namespace chromeos { 41 42 class CustomizationWallpaperDownloader; 43 class ServicesCustomizationExternalLoader; 44 45 void InitStartupCustomizationDocumentForTesting(const std::string& manifest); 46 47 namespace system { 48 class StatisticsProvider; 49 } // system 50 51 // Base class for OEM customization document classes. 52 class CustomizationDocument { 53 public: 54 virtual ~CustomizationDocument(); 55 56 // Return true if the document was successfully fetched and parsed. IsReady()57 bool IsReady() const { return root_.get(); } 58 59 protected: 60 explicit CustomizationDocument(const std::string& accepted_version); 61 62 virtual bool LoadManifestFromFile(const base::FilePath& manifest_path); 63 virtual bool LoadManifestFromString(const std::string& manifest); 64 65 std::string GetLocaleSpecificString(const std::string& locale, 66 const std::string& dictionary_name, 67 const std::string& entry_name) const; 68 69 scoped_ptr<base::DictionaryValue> root_; 70 71 // Value of the "version" attribute that is supported. 72 // Otherwise config is not loaded. 73 std::string accepted_version_; 74 75 private: 76 DISALLOW_COPY_AND_ASSIGN(CustomizationDocument); 77 }; 78 79 // OEM startup customization document class. 80 // Now StartupCustomizationDocument is loaded in c-tor so just after create it 81 // may be ready or not (if manifest is missing or corrupted) and this state 82 // won't be changed later (i.e. IsReady() always return the same value). 83 class StartupCustomizationDocument : public CustomizationDocument { 84 public: 85 static StartupCustomizationDocument* GetInstance(); 86 87 std::string GetEULAPage(const std::string& locale) const; 88 89 // These methods can be called even if !IsReady(), in this case VPD values 90 // will be returned. 91 // 92 // Raw value of "initial_locale" like initial_locale="en-US,sv,da,fi,no" . initial_locale()93 const std::string& initial_locale() const { return initial_locale_; } 94 95 // Vector of individual locale values. 96 const std::vector<std::string>& configured_locales() const; 97 98 // Default locale value (first value in initial_locale list). 99 const std::string& initial_locale_default() const; initial_timezone()100 const std::string& initial_timezone() const { return initial_timezone_; } keyboard_layout()101 const std::string& keyboard_layout() const { return keyboard_layout_; } 102 103 private: 104 FRIEND_TEST_ALL_PREFIXES(StartupCustomizationDocumentTest, Basic); 105 FRIEND_TEST_ALL_PREFIXES(StartupCustomizationDocumentTest, VPD); 106 FRIEND_TEST_ALL_PREFIXES(StartupCustomizationDocumentTest, BadManifest); 107 FRIEND_TEST_ALL_PREFIXES(ServicesCustomizationDocumentTest, MultiLanguage); 108 friend class OobeLocalizationTest; 109 friend void InitStartupCustomizationDocumentForTesting( 110 const std::string& manifest); 111 friend struct DefaultSingletonTraits<StartupCustomizationDocument>; 112 113 // C-tor for singleton construction. 114 StartupCustomizationDocument(); 115 116 // C-tor for test construction. 117 StartupCustomizationDocument(system::StatisticsProvider* provider, 118 const std::string& manifest); 119 120 virtual ~StartupCustomizationDocument(); 121 122 void Init(system::StatisticsProvider* provider); 123 124 // If |attr| exists in machine stat, assign it to |value|. 125 void InitFromMachineStatistic(const char* attr, std::string* value); 126 127 std::string initial_locale_; 128 std::vector<std::string> configured_locales_; 129 std::string initial_timezone_; 130 std::string keyboard_layout_; 131 132 DISALLOW_COPY_AND_ASSIGN(StartupCustomizationDocument); 133 }; 134 135 // OEM services customization document class. 136 // ServicesCustomizationDocument is fetched from network therefore it is not 137 // ready just after creation. Fetching of the manifest should be initiated 138 // outside this class by calling StartFetching() or EnsureCustomizationApplied() 139 // methods. 140 // User of the file should check IsReady before use it. 141 class ServicesCustomizationDocument : public CustomizationDocument, 142 private net::URLFetcherDelegate { 143 public: 144 static ServicesCustomizationDocument* GetInstance(); 145 146 // Registers preferences. 147 static void RegisterPrefs(PrefRegistrySimple* registry); 148 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); 149 150 static const char kManifestUrl[]; 151 152 // Return true if the customization was applied. Customization is applied only 153 // once per machine. 154 static bool WasOOBECustomizationApplied(); 155 156 // If customization has not been applied, start fetching and applying. 157 void EnsureCustomizationApplied(); 158 159 // Returns Closure with the EnsureCustomizationApplied() method. 160 base::Closure EnsureCustomizationAppliedClosure(); 161 162 // Start fetching customization document. 163 void StartFetching(); 164 165 // Apply customization and save in machine options that customization was 166 // applied successfully. Return true if customization was applied. 167 bool ApplyOOBECustomization(); 168 169 // Returns true if default wallpaper URL attribute found in manifest. 170 // |out_url| is set to attribute value. 171 bool GetDefaultWallpaperUrl(GURL* out_url) const; 172 173 // Returns list of default apps. 174 bool GetDefaultApps(std::vector<std::string>* ids) const; 175 176 // Creates an extensions::ExternalLoader that will provide OEM default apps. 177 // Cache of OEM default apps stored in profile preferences. 178 extensions::ExternalLoader* CreateExternalLoader(Profile* profile); 179 180 // Returns the name of the folder for OEM apps for given |locale|. 181 std::string GetOemAppsFolderName(const std::string& locale) const; 182 183 // Initialize instance of ServicesCustomizationDocument for tests that will 184 // override singleton until ShutdownForTesting is called. 185 static void InitializeForTesting(); 186 187 // Remove instance of ServicesCustomizationDocument for tests. 188 static void ShutdownForTesting(); 189 190 // These methods are also called by WallpaperManager to get "global default" 191 // customized wallpaper path (and to init default wallpaper path from it) 192 // before first wallpaper is shown. 193 static base::FilePath GetCustomizedWallpaperCacheDir(); 194 static base::FilePath GetCustomizedWallpaperDownloadedFileName(); 195 196 CustomizationWallpaperDownloader* wallpaper_downloader_for_testing() { 197 return wallpaper_downloader_.get(); 198 } 199 200 private: 201 friend struct DefaultSingletonTraits<ServicesCustomizationDocument>; 202 FRIEND_TEST_ALL_PREFIXES(CustomizationWallpaperDownloaderBrowserTest, 203 OEMWallpaperIsPresent); 204 FRIEND_TEST_ALL_PREFIXES(CustomizationWallpaperDownloaderBrowserTest, 205 OEMWallpaperRetryFetch); 206 207 typedef std::vector<base::WeakPtr<ServicesCustomizationExternalLoader> > 208 ExternalLoaders; 209 210 // Guard for a single application task (wallpaper downloading, for example). 211 class ApplyingTask; 212 213 // C-tor for singleton construction. 214 ServicesCustomizationDocument(); 215 216 // C-tor for test construction. 217 explicit ServicesCustomizationDocument(const std::string& manifest); 218 219 virtual ~ServicesCustomizationDocument(); 220 221 // Save applied state in machine settings. 222 static void SetApplied(bool val); 223 224 // Overriden from CustomizationDocument: 225 virtual bool LoadManifestFromString(const std::string& manifest) OVERRIDE; 226 227 // Overriden from net::URLFetcherDelegate: 228 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; 229 230 // Initiate file fetching. Wait for online status. 231 void StartFileFetch(); 232 233 // Initiate file fetching. Don't wait for online status. 234 void DoStartFileFetch(); 235 236 // Executes on FILE thread and reads file to string. 237 static void ReadFileInBackground( 238 base::WeakPtr<ServicesCustomizationDocument> self, 239 const base::FilePath& file); 240 241 // Called on UI thread with results of ReadFileInBackground. 242 void OnManifesteRead(const std::string& manifest); 243 244 // Method called when manifest was successfully loaded. 245 void OnManifestLoaded(); 246 247 // Returns list of default apps in ExternalProvider format. 248 static scoped_ptr<base::DictionaryValue> GetDefaultAppsInProviderFormat( 249 const base::DictionaryValue& root); 250 251 // Update cached manifest for |profile|. 252 void UpdateCachedManifest(Profile* profile); 253 254 // Customization document not found for give ID. 255 void OnCustomizationNotFound(); 256 257 // Set OEM apps folder name for AppListSyncableService for |profile|. 258 void SetOemFolderName(Profile* profile, const base::DictionaryValue& root); 259 260 // Returns the name of the folder for OEM apps for given |locale|. 261 std::string GetOemAppsFolderNameImpl( 262 const std::string& locale, 263 const base::DictionaryValue& root) const; 264 265 // Start download of wallpaper image if needed. 266 void StartOEMWallpaperDownload(const GURL& wallpaper_url, 267 scoped_ptr<ApplyingTask> applying); 268 269 // Check that current customized wallpaper cache exists. Once wallpaper is 270 // downloaded, it's never updated (even if manifest is re-fetched). 271 // Start wallpaper download if needed. 272 void CheckAndApplyWallpaper(); 273 274 // Intermediate function to pass the result of PathExists to ApplyWallpaper. 275 void OnCheckedWallpaperCacheExists(scoped_ptr<bool> exists, 276 scoped_ptr<ApplyingTask> applying); 277 278 // Called after downloaded wallpaper has been checked. 279 void ApplyWallpaper(bool default_wallpaper_file_exists, 280 scoped_ptr<ApplyingTask> applying); 281 282 // Set Shell default wallpaper to customized. 283 // It's wrapped as a callback and passed as a parameter to 284 // CustomizationWallpaperDownloader. 285 void OnOEMWallpaperDownloaded(scoped_ptr<ApplyingTask> applying, 286 bool success, 287 const GURL& wallpaper_url); 288 289 // Register one of Customization applying tasks. 290 void ApplyingTaskStarted(); 291 292 // Mark task finished and check for "all customization applied". 293 void ApplyingTaskFinished(bool success); 294 295 // Services customization manifest URL. 296 GURL url_; 297 298 // URLFetcher instance. 299 scoped_ptr<net::URLFetcher> url_fetcher_; 300 301 // How many times we already tried to fetch customization manifest file. 302 int num_retries_; 303 304 // Manifest fetch is already in progress. 305 bool fetch_started_; 306 307 // Delay between checks for network online state. 308 base::TimeDelta network_delay_; 309 310 // Known external loaders. 311 ExternalLoaders external_loaders_; 312 313 scoped_ptr<CustomizationWallpaperDownloader> wallpaper_downloader_; 314 315 // This is barrier until customization is applied. 316 // When number of finished tasks match number of started - customization is 317 // applied. 318 size_t apply_tasks_started_; 319 size_t apply_tasks_finished_; 320 321 // This is the number of successfully finished customization tasks. 322 // If it matches number of tasks finished - customization is applied 323 // successfully. 324 size_t apply_tasks_success_; 325 326 // Weak factory for callbacks. 327 base::WeakPtrFactory<ServicesCustomizationDocument> weak_ptr_factory_; 328 329 DISALLOW_COPY_AND_ASSIGN(ServicesCustomizationDocument); 330 }; 331 332 } // namespace chromeos 333 334 #endif // CHROME_BROWSER_CHROMEOS_CUSTOMIZATION_DOCUMENT_H_ 335