customization_document.h revision 0529e5d033099cbfc42635f6f6183833b09dff6e
15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Use of this source code is governed by a BSD-style license that can be
35c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// found in the LICENSE file.
45c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#ifndef CHROME_BROWSER_CHROMEOS_CUSTOMIZATION_DOCUMENT_H_
66e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#define CHROME_BROWSER_CHROMEOS_CUSTOMIZATION_DOCUMENT_H_
75c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <string>
9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <vector>
106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/compiler_specific.h"
126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/gtest_prod_util.h"
135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/memory/scoped_ptr.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/memory/singleton.h"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/memory/weak_ptr.h"
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/values.h"
175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "net/url_request/url_fetcher_delegate.h"
185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "url/gurl.h"
195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class PrefRegistrySimple;
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class Profile;
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace base {
245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass DictionaryValue;
255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass FilePath;
265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace extensions {
295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass ExternalLoader;
305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace net {
335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass URLFetcher;
345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace user_prefs {
37f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class PrefRegistrySyncable;
38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// This test is in global namespace so it must be declared here.
41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void Test__InitStartupCustomizationDocument(const std::string& manifest);
42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace chromeos {
44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class CustomizationWallpaperDownloader;
46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class ServicesCustomizationExternalLoader;
47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace system {
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class StatisticsProvider;
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // system
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Base class for OEM customization document classes.
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class CustomizationDocument {
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual ~CustomizationDocument();
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Return true if the document was successfully fetched and parsed.
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool IsReady() const { return root_.get(); }
595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu protected:
615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  explicit CustomizationDocument(const std::string& accepted_version);
625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual bool LoadManifestFromFile(const base::FilePath& manifest_path);
645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual bool LoadManifestFromString(const std::string& manifest);
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::string GetLocaleSpecificString(const std::string& locale,
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                      const std::string& dictionary_name,
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      const std::string& entry_name) const;
695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_ptr<base::DictionaryValue> root_;
715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Value of the "version" attribute that is supported.
735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Otherwise config is not loaded.
746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::string accepted_version_;
756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 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 private:
198  friend struct DefaultSingletonTraits<ServicesCustomizationDocument>;
199
200  typedef std::vector<base::WeakPtr<ServicesCustomizationExternalLoader> >
201      ExternalLoaders;
202
203  // Guard for a single application task (wallpaper downloading, for example).
204  class ApplyingTask;
205
206  // C-tor for singleton construction.
207  ServicesCustomizationDocument();
208
209  // C-tor for test construction.
210  explicit ServicesCustomizationDocument(const std::string& manifest);
211
212  virtual ~ServicesCustomizationDocument();
213
214  // Save applied state in machine settings.
215  static void SetApplied(bool val);
216
217  // Overriden from CustomizationDocument:
218  virtual bool LoadManifestFromString(const std::string& manifest) OVERRIDE;
219
220  // Overriden from net::URLFetcherDelegate:
221  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
222
223  // Initiate file fetching. Wait for online status.
224  void StartFileFetch();
225
226  // Initiate file fetching. Don't wait for online status.
227  void DoStartFileFetch();
228
229  // Executes on FILE thread and reads file to string.
230  static void ReadFileInBackground(
231      base::WeakPtr<ServicesCustomizationDocument> self,
232      const base::FilePath& file);
233
234  // Called on UI thread with results of ReadFileInBackground.
235  void OnManifesteRead(const std::string& manifest);
236
237  // Method called when manifest was successfully loaded.
238  void OnManifestLoaded();
239
240  // Returns list of default apps in ExternalProvider format.
241  static scoped_ptr<base::DictionaryValue> GetDefaultAppsInProviderFormat(
242      const base::DictionaryValue& root);
243
244  // Update cached manifest for |profile|.
245  void UpdateCachedManifest(Profile* profile);
246
247  // Customization document not found for give ID.
248  void OnCustomizationNotFound();
249
250  // Set OEM apps folder name for AppListSyncableService for |profile|.
251  void SetOemFolderName(Profile* profile, const base::DictionaryValue& root);
252
253  // Returns the name of the folder for OEM apps for given |locale|.
254  std::string GetOemAppsFolderNameImpl(
255      const std::string& locale,
256      const base::DictionaryValue& root) const;
257
258  // Start download of wallpaper image if needed.
259  void StartOEMWallpaperDownload(const GURL& wallpaper_url,
260                                 scoped_ptr<ApplyingTask> applying);
261
262  // Check that current customized wallpaper cache exists. Once wallpaper is
263  // downloaded, it's never updated (even if manifest is re-fetched).
264  // Start wallpaper download if needed.
265  void CheckAndApplyWallpaper();
266
267  // Intermediate function to pass the result of PathExists to ApplyWallpaper.
268  void OnCheckedWallpaperCacheExists(scoped_ptr<bool> exists,
269                                     scoped_ptr<ApplyingTask> applying);
270
271  // Called after downloaded wallpaper has been checked.
272  void ApplyWallpaper(bool default_wallpaper_file_exists,
273                      scoped_ptr<ApplyingTask> applying);
274
275  // Set Shell default wallpaper to customized.
276  // It's wrapped as a callback and passed as a parameter to
277  // CustomizationWallpaperDownloader.
278  void OnOEMWallpaperDownloaded(scoped_ptr<ApplyingTask> applying,
279                                bool success,
280                                const GURL& wallpaper_url);
281
282  // Register one of Customization applying tasks.
283  void ApplyingTaskStarted();
284
285  // Mark task finished and check for "all customization applied".
286  void ApplyingTaskFinished(bool success);
287
288  // Services customization manifest URL.
289  GURL url_;
290
291  // URLFetcher instance.
292  scoped_ptr<net::URLFetcher> url_fetcher_;
293
294  // How many times we already tried to fetch customization manifest file.
295  int num_retries_;
296
297  // Manifest fetch is already in progress.
298  bool fetch_started_;
299
300  // Delay between checks for network online state.
301  base::TimeDelta network_delay_;
302
303  // Known external loaders.
304  ExternalLoaders external_loaders_;
305
306  scoped_ptr<CustomizationWallpaperDownloader> wallpaper_downloader_;
307
308  // This is barrier until customization is applied.
309  // When number of finished tasks match number of started - customization is
310  // applied.
311  size_t apply_tasks_started_;
312  size_t apply_tasks_finished_;
313
314  // This is the number of successfully finished customization tasks.
315  // If it matches number of tasks finished - customization is applied
316  // successfully.
317  size_t apply_tasks_success_;
318
319  // Weak factory for callbacks.
320  base::WeakPtrFactory<ServicesCustomizationDocument> weak_ptr_factory_;
321
322  DISALLOW_COPY_AND_ASSIGN(ServicesCustomizationDocument);
323};
324
325}  // namespace chromeos
326
327#endif  // CHROME_BROWSER_CHROMEOS_CUSTOMIZATION_DOCUMENT_H_
328