• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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