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 // 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