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 20class PrefRegistrySimple; 21class Profile; 22 23namespace base { 24class DictionaryValue; 25class FilePath; 26} 27 28namespace extensions { 29class ExternalLoader; 30} 31 32namespace net { 33class URLFetcher; 34} 35 36namespace user_prefs { 37class PrefRegistrySyncable; 38} 39 40namespace chromeos { 41 42class CustomizationWallpaperDownloader; 43class ServicesCustomizationExternalLoader; 44 45void InitStartupCustomizationDocumentForTesting(const std::string& manifest); 46 47namespace system { 48class StatisticsProvider; 49} // system 50 51// Base class for OEM customization document classes. 52class CustomizationDocument { 53 public: 54 virtual ~CustomizationDocument(); 55 56 // Return true if the document was successfully fetched and parsed. 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). 83class 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" . 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; 100 const std::string& initial_timezone() const { return initial_timezone_; } 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. 141class 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