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