Home | History | Annotate | Download | only in chromeos
      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.
     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" .
     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.
    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