customization_document.cc revision 513209b27ff55e2841eac0e4120199c23acce758
1// Copyright (c) 2010 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#include "chrome/browser/chromeos/customization_document.h"
6
7#include <string>
8
9#include "base/file_util.h"
10#include "base/json/json_reader.h"
11#include "base/logging.h"
12#include "base/string_number_conversions.h"
13#include "base/values.h"
14
15// Manifest attributes names.
16
17namespace {
18
19const char kVersionAttr[] = "version";
20const char kProductSkuAttr[] = "product_sku";
21const char kInitialLocaleAttr[] = "initial_locale";
22const char kInitialTimezoneAttr[] = "initial_timezone";
23const char kBackgroundColorAttr[] = "background_color";
24const char kRegistrationUrlAttr[] = "registration_url";
25const char kSetupContentAttr[] = "setup_content";
26const char kContentLocaleAttr[] = "content_locale";
27const char kHelpPageAttr[] = "help_page";
28const char kEulaPageAttr[] = "eula_page";
29const char kAppMenuAttr[] = "app_menu";
30const char kInitialStartPageAttr[] = "initial_start_page";
31const char kSectionTitleAttr[] = "section_title";
32const char kWebAppsAttr[] = "web_apps";
33const char kSupportPageAttr[] = "support_page";
34const char kExtensionsAttr[] = "extensions";
35
36const char kAcceptedManifestVersion[] = "1.0";
37
38}  // anonymous namespace
39
40namespace chromeos {
41
42// CustomizationDocument implementation.
43
44bool CustomizationDocument::LoadManifestFromFile(
45    const FilePath& manifest_path) {
46  std::string manifest;
47  bool read_success = file_util::ReadFileToString(manifest_path, &manifest);
48  if (!read_success) {
49    return false;
50  }
51  return LoadManifestFromString(manifest);
52}
53
54bool CustomizationDocument::LoadManifestFromString(
55    const std::string& manifest) {
56  scoped_ptr<Value> root(base::JSONReader::Read(manifest, true));
57  DCHECK(root.get() != NULL);
58  if (root.get() == NULL)
59    return false;
60  DCHECK(root->GetType() == Value::TYPE_DICTIONARY);
61  return ParseFromJsonValue(static_cast<DictionaryValue*>(root.get()));
62}
63
64bool CustomizationDocument::ParseFromJsonValue(const DictionaryValue* root) {
65  // Partner customization manifests share only one required field -
66  // version string.
67  version_.clear();
68  bool result = root->GetString(kVersionAttr, &version_);
69  return result && version_ == kAcceptedManifestVersion;
70}
71
72// StartupCustomizationDocument implementation.
73
74bool StartupCustomizationDocument::LoadManifestFromFile(
75    const FilePath& manifest_path) {
76  if (CustomizationDocument::LoadManifestFromFile(manifest_path)) {
77    manifest_path_ = manifest_path;
78    return true;
79  } else {
80    return false;
81  }
82}
83
84bool StartupCustomizationDocument::ParseFromJsonValue(
85    const DictionaryValue* root) {
86  if (!CustomizationDocument::ParseFromJsonValue(root))
87    return false;
88
89  // Required fields.
90  product_sku_.clear();
91  if (!root->GetString(kProductSkuAttr, &product_sku_))
92    return false;
93
94  // Optional fields.
95  initial_locale_.clear();
96  root->GetString(kInitialLocaleAttr, &initial_locale_);
97
98  initial_timezone_.clear();
99  root->GetString(kInitialTimezoneAttr, &initial_timezone_);
100
101  std::string background_color_string;
102  root->GetString(kBackgroundColorAttr, &background_color_string);
103  if (!background_color_string.empty()) {
104    if (background_color_string[0] == '#') {
105      int background_int;
106      base::HexStringToInt(background_color_string.begin() + 1,
107                           background_color_string.end(),
108                           &background_int);
109      background_color_ = static_cast<SkColor>(0xff000000 | background_int);
110    } else {
111      // Literal color constants are not supported yet.
112      return false;
113    }
114  }
115
116  registration_url_.clear();
117  root->GetString(kRegistrationUrlAttr, &registration_url_);
118
119  ListValue* setup_content_value = NULL;
120  root->GetList(kSetupContentAttr, &setup_content_value);
121  if (setup_content_value != NULL) {
122    for (ListValue::const_iterator iter = setup_content_value->begin();
123         iter != setup_content_value->end();
124         ++iter) {
125      const DictionaryValue* dict = NULL;
126      dict = static_cast<const DictionaryValue*>(*iter);
127      DCHECK(dict->GetType() == Value::TYPE_DICTIONARY);
128      std::string content_locale;
129      if (!dict->GetString(kContentLocaleAttr, &content_locale))
130        return false;
131      SetupContent content;
132      if (!dict->GetString(kHelpPageAttr, &content.help_page_path))
133        return false;
134      if (!dict->GetString(kEulaPageAttr, &content.eula_page_path))
135        return false;
136      setup_content_[content_locale] = content;
137    }
138  }
139
140  return true;
141}
142
143FilePath StartupCustomizationDocument::GetSetupPagePath(
144    const std::string& locale, std::string SetupContent::* page_path) const {
145  SetupContentMap::const_iterator content_iter = setup_content_.find(locale);
146  if (content_iter != setup_content_.end()) {
147    return manifest_path_.DirName().Append(content_iter->second.*page_path);
148  } else {
149    return FilePath();
150  }
151}
152
153// ServicesCustomizationDocument implementation.
154
155bool ServicesCustomizationDocument::ParseFromJsonValue(
156    const DictionaryValue* root) {
157  if (!CustomizationDocument::ParseFromJsonValue(root))
158    return false;
159
160  // Required app menu settings.
161  DictionaryValue* app_menu_value = NULL;
162  root->GetDictionary(kAppMenuAttr, &app_menu_value);
163  if (app_menu_value == NULL)
164    return false;
165
166  app_menu_section_title_.clear();
167  if (!app_menu_value->GetString(kSectionTitleAttr,
168                                 &app_menu_section_title_))
169    return false;
170  app_menu_support_page_url_.clear();
171  if (!app_menu_value->GetString(kSupportPageAttr,
172                                 &app_menu_support_page_url_))
173    return false;
174
175  ListValue* web_apps_value = NULL;
176  app_menu_value->GetList(kWebAppsAttr, &web_apps_value);
177  if (!ParseStringListFromJsonValue(web_apps_value, &web_apps_))
178    return false;
179
180  ListValue* extensions_value = NULL;
181  app_menu_value->GetList(kExtensionsAttr, &extensions_value);
182  if (!ParseStringListFromJsonValue(extensions_value, &extensions_))
183    return false;
184
185  // Optional fields.
186  initial_start_page_url_.clear();
187  root->GetString(kInitialStartPageAttr, &initial_start_page_url_);
188
189  return true;
190}
191
192bool ServicesCustomizationDocument::ParseStringListFromJsonValue(
193    const ListValue* list_value,
194    StringList* string_list) {
195  if (list_value == NULL || string_list == NULL)
196    return false;
197  DCHECK(list_value->GetType() == Value::TYPE_LIST);
198  string_list->clear();
199  for (ListValue::const_iterator iter = list_value->begin();
200       iter != list_value->end();
201       ++iter) {
202    std::string url;
203    if ((*iter)->GetAsString(&url))
204      string_list->push_back(url);
205  }
206  return true;
207}
208
209}  // namespace chromeos
210