1// Copyright (c) 2011 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#pragma once
8
9#include <map>
10#include <string>
11
12#include "base/gtest_prod_util.h"
13#include "base/memory/scoped_ptr.h"
14#include "base/memory/singleton.h"
15#include "base/timer.h"
16#include "base/values.h"
17#include "chrome/common/net/url_fetcher.h"
18#include "googleurl/src/gurl.h"
19
20class DictionaryValue;
21class FilePath;
22class ListValue;
23class PrefService;
24
25namespace base {
26  class Time;
27}
28
29namespace chromeos {
30
31class SystemAccess;
32
33// Base class for OEM customization document classes.
34class CustomizationDocument {
35 public:
36  virtual ~CustomizationDocument() {}
37
38  // Return true if the document was successfully fetched and parsed.
39  bool IsReady() const { return root_.get(); }
40
41 protected:
42  CustomizationDocument() {}
43
44  virtual bool LoadManifestFromFile(const FilePath& manifest_path);
45  virtual bool LoadManifestFromString(const std::string& manifest);
46
47  std::string GetLocaleSpecificString(const std::string& locale,
48                                      const std::string& dictionary_name,
49                                      const std::string& entry_name) const;
50
51  scoped_ptr<DictionaryValue> root_;
52
53 private:
54  DISALLOW_COPY_AND_ASSIGN(CustomizationDocument);
55};
56
57// OEM startup customization document class.
58// Now StartupCustomizationDocument is loaded in c-tor so just after create it
59// may be ready or not (if manifest is missing or corrupted) and this state
60// won't be changed later (i.e. IsReady() always return the same value).
61class StartupCustomizationDocument : public CustomizationDocument {
62 public:
63  static StartupCustomizationDocument* GetInstance();
64
65  const std::string& initial_locale() const { return initial_locale_; }
66  const std::string& initial_timezone() const { return initial_timezone_; }
67  const std::string& keyboard_layout() const { return keyboard_layout_; }
68  const std::string& registration_url() const { return registration_url_; }
69
70  std::string GetHelpPage(const std::string& locale) const;
71  std::string GetEULAPage(const std::string& locale) const;
72
73 private:
74  FRIEND_TEST(StartupCustomizationDocumentTest, Basic);
75  FRIEND_TEST(StartupCustomizationDocumentTest, VPD);
76  FRIEND_TEST(StartupCustomizationDocumentTest, BadManifest);
77  friend struct DefaultSingletonTraits<StartupCustomizationDocument>;
78
79  // C-tor for singleton construction.
80  StartupCustomizationDocument();
81
82  // C-tor for test construction.
83  StartupCustomizationDocument(SystemAccess* system_access,
84                               const std::string& manifest);
85
86  void Init(SystemAccess* system_access);
87
88  // If |attr| exists in machine stat, assign it to |value|.
89  void InitFromMachineStatistic(const char* attr, std::string* value);
90
91  std::string initial_locale_;
92  std::string initial_timezone_;
93  std::string keyboard_layout_;
94  std::string registration_url_;
95
96  DISALLOW_COPY_AND_ASSIGN(StartupCustomizationDocument);
97};
98
99// OEM services customization document class.
100// ServicesCustomizationDocument is fetched from network or local file but on
101// FILE thread therefore it may not be ready just after creation. Fetching of
102// the manifest should be initiated outside this class by calling
103// StartFetching() method. User of the file should check IsReady before use it.
104class ServicesCustomizationDocument : public CustomizationDocument,
105                                      private URLFetcher::Delegate {
106 public:
107  // OEM specific carrier deal.
108  struct CarrierDeal {
109    explicit CarrierDeal(DictionaryValue* deal_dict);
110
111    // Returns string with the specified |locale| and |id|.
112    // If there's no version for |locale|, default one is returned.
113    // If there's no string with specified |id|, empty string is returned.
114    std::string GetLocalizedString(const std::string& locale,
115                                   const std::string& id) const;
116
117    std::string deal_locale;
118    std::string top_up_url;
119    int notification_count;
120    base::Time expire_date;
121    DictionaryValue* localized_strings;
122  };
123
124  // Carrier ID (ex. "Verizon (us)") mapping to carrier deals.
125  typedef std::map<std::string, CarrierDeal*> CarrierDeals;
126
127  static ServicesCustomizationDocument* GetInstance();
128
129  // Registers preferences.
130  static void RegisterPrefs(PrefService* local_state);
131
132  // Return true if the customization was applied. Customization is applied only
133  // once per machine.
134  static bool WasApplied();
135
136  // Start fetching customization document.
137  void StartFetching();
138
139  // Apply customization and save in machine options that customization was
140  // applied successfully. Return true if customization was applied.
141  bool ApplyCustomization();
142
143  std::string GetInitialStartPage(const std::string& locale) const;
144  std::string GetSupportPage(const std::string& locale) const;
145
146  // Returns carrier deal by specified |carrier_id|.
147  // Also checks deal restrictions, such as deal locale (launch locale) and
148  // deal expiration date if |check_restrictions| is true.
149  const ServicesCustomizationDocument::CarrierDeal* GetCarrierDeal(
150      const std::string& carrier_id, bool check_restrictions) const;
151
152 protected:
153  virtual bool LoadManifestFromString(const std::string& manifest) OVERRIDE;
154
155 private:
156  FRIEND_TEST(ServicesCustomizationDocumentTest, Basic);
157  FRIEND_TEST(ServicesCustomizationDocumentTest, BadManifest);
158  FRIEND_TEST(ServicesCustomizationDocumentTest, DealOtherLocale);
159  FRIEND_TEST(ServicesCustomizationDocumentTest, NoDealRestrictions);
160  FRIEND_TEST(ServicesCustomizationDocumentTest, OldDeal);
161  friend struct DefaultSingletonTraits<ServicesCustomizationDocument>;
162
163  // C-tor for singleton construction.
164  ServicesCustomizationDocument();
165
166  // C-tor for test construction.
167  ServicesCustomizationDocument(const std::string& manifest,
168                                const std::string& initial_locale);
169
170  // Save applied state in machine settings.
171  static void SetApplied(bool val);
172
173  // Overriden from URLFetcher::Delegate:
174  virtual void OnURLFetchComplete(const URLFetcher* source,
175                                  const GURL& url,
176                                  const net::URLRequestStatus& status,
177                                  int response_code,
178                                  const ResponseCookies& cookies,
179                                  const std::string& data);
180
181  // Initiate file fetching.
182  void StartFileFetch();
183
184  // Executes on FILE thread and reads file to string.
185  void ReadFileInBackground(const FilePath& file);
186
187  // Services customization manifest URL.
188  GURL url_;
189
190  // URLFetcher instance.
191  scoped_ptr<URLFetcher> url_fetcher_;
192
193  // Timer to retry fetching file if network is not available.
194  base::OneShotTimer<ServicesCustomizationDocument> retry_timer_;
195
196  // How many times we already tried to fetch customization manifest file.
197  int num_retries_;
198
199  // Carrier-specific deals.
200  CarrierDeals carrier_deals_;
201
202  // Initial locale value.
203  std::string initial_locale_;
204
205  DISALLOW_COPY_AND_ASSIGN(ServicesCustomizationDocument);
206};
207
208}  // namespace chromeos
209
210#endif  // CHROME_BROWSER_CHROMEOS_CUSTOMIZATION_DOCUMENT_H_
211