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 40// This test is in global namespace so it must be declared here. 41void Test__InitStartupCustomizationDocument(const std::string& manifest); 42 43namespace chromeos { 44 45class CustomizationWallpaperDownloader; 46class ServicesCustomizationExternalLoader; 47 48namespace system { 49class StatisticsProvider; 50} // system 51 52// Base class for OEM customization document classes. 53class 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). 84class 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. 142class 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