1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/customization_document.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/file_path.h" 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_util.h" 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/json/json_reader.h" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/string_tokenizer.h" 12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/string_util.h" 13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/time.h" 14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/utf_string_conversions.h" 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/browser_process.h" 16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/chromeos/cros/cros_library.h" 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/chromeos/cros/network_library.h" 18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/chromeos/login/wizard_controller.h" 19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/chromeos/system_access.h" 20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/prefs/pref_service.h" 21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/profiles/profile_manager.h" 22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/browser_thread.h" 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Manifest attributes names. 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst char kVersionAttr[] = "version"; 29dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenconst char kDefaultAttr[] = "default"; 303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst char kInitialLocaleAttr[] = "initial_locale"; 313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst char kInitialTimezoneAttr[] = "initial_timezone"; 32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char kKeyboardLayoutAttr[] = "keyboard_layout"; 333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst char kRegistrationUrlAttr[] = "registration_url"; 34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char kHwidMapAttr[] = "hwid_map"; 35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char kHwidMaskAttr[] = "hwid_mask"; 363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst char kSetupContentAttr[] = "setup_content"; 373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst char kHelpPageAttr[] = "help_page"; 383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst char kEulaPageAttr[] = "eula_page"; 39dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenconst char kAppContentAttr[] = "app_content"; 403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst char kInitialStartPageAttr[] = "initial_start_page"; 413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst char kSupportPageAttr[] = "support_page"; 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kAcceptedManifestVersion[] = "1.0"; 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char kHwid[] = "hwid"; 46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Carrier deals attributes. 48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char kCarrierDealsAttr[] = "carrier_deals"; 49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char kDealLocaleAttr[] = "deal_locale"; 50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char kTopUpURLAttr[] = "top_up_url"; 51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char kNotificationCountAttr[] = "notification_count"; 52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char kDealExpireDateAttr[] = "expire_date"; 53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char kLocalizedContentAttr[] = "localized_content"; 54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char kNotificationTextAttr[] = "notification_text"; 55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Path to OEM partner startup customization manifest. 57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char kStartupCustomizationManifestPath[] = 58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "/opt/oem/etc/startup_manifest.json"; 59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// URL where to fetch OEM services customization manifest from. 61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char kServicesCustomizationManifestUrl[] = 62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "file:///opt/oem/etc/services_manifest.json"; 63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Name of local state option that tracks if services customization has been 65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// applied. 66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char kServicesCustomizationAppliedPref[] = "ServicesCustomizationApplied"; 67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Maximum number of retries to fetch file if network is not available. 69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst int kMaxFetchRetries = 3; 70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Delay between file fetch retries if network is not available. 72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst int kRetriesDelayInSec = 2; 73dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // anonymous namespace 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenDISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::ServicesCustomizationDocument); 77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace chromeos { 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// CustomizationDocument implementation. --------------------------------------- 81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool CustomizationDocument::LoadManifestFromFile( 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const FilePath& manifest_path) { 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string manifest; 85dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!file_util::ReadFileToString(manifest_path, &manifest)) 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return LoadManifestFromString(manifest); 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool CustomizationDocument::LoadManifestFromString( 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& manifest) { 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<Value> root(base::JSONReader::Read(manifest, true)); 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(root.get() != NULL); 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (root.get() == NULL) 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(root->GetType() == Value::TYPE_DICTIONARY); 97dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (root->GetType() == Value::TYPE_DICTIONARY) { 98dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen root_.reset(static_cast<DictionaryValue*>(root.release())); 99dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string result; 100dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (root_->GetString(kVersionAttr, &result) && 101dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen result == kAcceptedManifestVersion) 102dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return true; 103dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 104dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(ERROR) << "Wrong customization manifest version"; 105dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen root_.reset(NULL); 106dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 107dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return false; 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 110dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstd::string CustomizationDocument::GetLocaleSpecificString( 111dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const std::string& locale, 112dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const std::string& dictionary_name, 113dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const std::string& entry_name) const { 114dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DictionaryValue* dictionary_content = NULL; 115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!root_.get() || 116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !root_->GetDictionary(dictionary_name, &dictionary_content)) 117dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return std::string(); 118dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 119dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DictionaryValue* locale_dictionary = NULL; 120dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (dictionary_content->GetDictionary(locale, &locale_dictionary)) { 121dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string result; 122dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (locale_dictionary->GetString(entry_name, &result)) 123dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return result; 124dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 126dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DictionaryValue* default_dictionary = NULL; 127dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (dictionary_content->GetDictionary(kDefaultAttr, &default_dictionary)) { 128dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string result; 129dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (default_dictionary->GetString(entry_name, &result)) 130dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return result; 1313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 133dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return std::string(); 134dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// StartupCustomizationDocument implementation. -------------------------------- 137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenStartupCustomizationDocument::StartupCustomizationDocument() { 139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { 140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Loading manifest causes us to do blocking IO on UI thread. 141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Temporarily allow it until we fix http://crosbug.com/11103 142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::ThreadRestrictions::ScopedAllowIO allow_io; 143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LoadManifestFromFile(FilePath(kStartupCustomizationManifestPath)); 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Init(SystemAccess::GetInstance()); 146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenStartupCustomizationDocument::StartupCustomizationDocument( 149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SystemAccess* system_access, const std::string& manifest) { 150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LoadManifestFromString(manifest); 151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Init(system_access); 152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenStartupCustomizationDocument* StartupCustomizationDocument::GetInstance() { 155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return Singleton<StartupCustomizationDocument, 156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DefaultSingletonTraits<StartupCustomizationDocument> >::get(); 157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid StartupCustomizationDocument::Init(SystemAccess* system_access) { 160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!IsReady()) 161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 163dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen root_->GetString(kInitialLocaleAttr, &initial_locale_); 164dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen root_->GetString(kInitialTimezoneAttr, &initial_timezone_); 165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen root_->GetString(kKeyboardLayoutAttr, &keyboard_layout_); 166dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen root_->GetString(kRegistrationUrlAttr, ®istration_url_); 167dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string hwid; 169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (system_access->GetMachineStatistic(kHwid, &hwid)) { 170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ListValue* hwid_list = NULL; 171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (root_->GetList(kHwidMapAttr, &hwid_list)) { 172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (size_t i = 0; i < hwid_list->GetSize(); ++i) { 173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* hwid_dictionary = NULL; 174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string hwid_mask; 175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (hwid_list->GetDictionary(i, &hwid_dictionary) && 176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen hwid_dictionary->GetString(kHwidMaskAttr, &hwid_mask)) { 177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (MatchPattern(hwid, hwid_mask)) { 178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If HWID for this machine matches some mask, use HWID specific 179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // settings. 180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string result; 181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (hwid_dictionary->GetString(kInitialLocaleAttr, &result)) 182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen initial_locale_ = result; 183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (hwid_dictionary->GetString(kInitialTimezoneAttr, &result)) 185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen initial_timezone_ = result; 186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (hwid_dictionary->GetString(kKeyboardLayoutAttr, &result)) 188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen keyboard_layout_ = result; 189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Don't break here to allow other entires to be applied if match. 191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LOG(ERROR) << "Syntax error in customization manifest"; 193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 194dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 196dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else { 197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LOG(ERROR) << "HWID is missing in machine statistics"; 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen system_access->GetMachineStatistic(kInitialLocaleAttr, &initial_locale_); 201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen system_access->GetMachineStatistic(kInitialTimezoneAttr, &initial_timezone_); 202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen system_access->GetMachineStatistic(kKeyboardLayoutAttr, &keyboard_layout_); 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 205dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstd::string StartupCustomizationDocument::GetHelpPage( 206dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const std::string& locale) const { 207dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return GetLocaleSpecificString(locale, kSetupContentAttr, kHelpPageAttr); 208dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 210dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstd::string StartupCustomizationDocument::GetEULAPage( 211dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const std::string& locale) const { 212dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return GetLocaleSpecificString(locale, kSetupContentAttr, kEulaPageAttr); 213dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// ServicesCustomizationDocument implementation. ------------------------------- 216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenServicesCustomizationDocument::CarrierDeal::CarrierDeal( 218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* deal_dict) 219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen : notification_count(0), 220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen localized_strings(NULL) { 221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen deal_dict->GetString(kDealLocaleAttr, &deal_locale); 222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen deal_dict->GetString(kTopUpURLAttr, &top_up_url); 223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen deal_dict->GetInteger(kNotificationCountAttr, ¬ification_count); 224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string date_string; 225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (deal_dict->GetString(kDealExpireDateAttr, &date_string)) { 226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!base::Time::FromString(ASCIIToWide(date_string).c_str(), &expire_date)) 227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LOG(ERROR) << "Error parsing deal_expire_date: " << date_string; 228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen deal_dict->GetDictionary(kLocalizedContentAttr, &localized_strings); 230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstd::string ServicesCustomizationDocument::CarrierDeal::GetLocalizedString( 233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::string& locale, const std::string& id) const { 234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string result; 235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (localized_strings) { 236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* locale_dict = NULL; 237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (localized_strings->GetDictionary(locale, &locale_dict) && 238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen locale_dict->GetString(id, &result)) { 239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return result; 240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else if (localized_strings->GetDictionary(kDefaultAttr, &locale_dict) && 241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen locale_dict->GetString(id, &result)) { 242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return result; 243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return result; 246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenServicesCustomizationDocument::ServicesCustomizationDocument() 249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen : url_(kServicesCustomizationManifestUrl), 250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen initial_locale_(WizardController::GetInitialLocale()) { 251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenServicesCustomizationDocument::ServicesCustomizationDocument( 254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::string& manifest, const std::string& initial_locale) 255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen : initial_locale_(initial_locale) { 256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LoadManifestFromString(manifest); 257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static 260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenServicesCustomizationDocument* ServicesCustomizationDocument::GetInstance() { 261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return Singleton<ServicesCustomizationDocument, 262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DefaultSingletonTraits<ServicesCustomizationDocument> >::get(); 263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static 266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ServicesCustomizationDocument::RegisterPrefs(PrefService* local_state) { 267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen local_state->RegisterBooleanPref(kServicesCustomizationAppliedPref, false); 268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static 271ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ServicesCustomizationDocument::WasApplied() { 272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PrefService* prefs = g_browser_process->local_state(); 273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return prefs->GetBoolean(kServicesCustomizationAppliedPref); 274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static 277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ServicesCustomizationDocument::SetApplied(bool val) { 278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PrefService* prefs = g_browser_process->local_state(); 279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs->SetBoolean(kServicesCustomizationAppliedPref, val); 280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ServicesCustomizationDocument::StartFetching() { 283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (url_.SchemeIsFile()) { 284ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 285ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NewRunnableMethod(this, 286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &ServicesCustomizationDocument::ReadFileInBackground, 287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FilePath(url_.path()))); 288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen StartFileFetch(); 290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ServicesCustomizationDocument::ReadFileInBackground(const FilePath& file) { 294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string manifest; 297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (file_util::ReadFileToString(file, &manifest)) { 298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NewRunnableMethod( 300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this, 301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &ServicesCustomizationDocument::LoadManifestFromString, 302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen manifest)); 303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen VLOG(1) << "Failed to load services customization manifest from: " 305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen << file.value(); 306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ServicesCustomizationDocument::StartFileFetch() { 310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(url_.is_valid()); 311ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen url_fetcher_.reset(new URLFetcher(url_, URLFetcher::GET, this)); 312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen url_fetcher_->set_request_context( 313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ProfileManager::GetDefaultProfile()->GetRequestContext()); 314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen url_fetcher_->Start(); 315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ServicesCustomizationDocument::OnURLFetchComplete( 318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const URLFetcher* source, 319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const GURL& url, 320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const net::URLRequestStatus& status, 321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int response_code, 322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const ResponseCookies& cookies, 323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::string& data) { 324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (response_code == 200) { 325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LoadManifestFromString(data); 326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 327ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NetworkLibrary* network = CrosLibrary::Get()->GetNetworkLibrary(); 328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!network->Connected() && num_retries_ < kMaxFetchRetries) { 329ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen num_retries_++; 330ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen retry_timer_.Start(base::TimeDelta::FromSeconds(kRetriesDelayInSec), 331ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this, &ServicesCustomizationDocument::StartFileFetch); 332ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 334ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LOG(ERROR) << "URL fetch for services customization failed:" 335ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen << " response code = " << response_code 336ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen << " URL = " << url.spec(); 337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ServicesCustomizationDocument::ApplyCustomization() { 341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // TODO(dpolukhin): apply customized apps, exts and support page. 342ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SetApplied(true); 343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 345ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 346dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstd::string ServicesCustomizationDocument::GetInitialStartPage( 347dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const std::string& locale) const { 348dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return GetLocaleSpecificString( 349dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen locale, kAppContentAttr, kInitialStartPageAttr); 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 352dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstd::string ServicesCustomizationDocument::GetSupportPage( 353dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const std::string& locale) const { 354dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return GetLocaleSpecificString( 355dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen locale, kAppContentAttr, kSupportPageAttr); 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 358ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst ServicesCustomizationDocument::CarrierDeal* 359ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenServicesCustomizationDocument::GetCarrierDeal(const std::string& carrier_id, 360ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool check_restrictions) const { 361ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CarrierDeals::const_iterator iter = carrier_deals_.find(carrier_id); 362ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (iter != carrier_deals_.end()) { 363ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CarrierDeal* deal = iter->second; 364ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (check_restrictions) { 365ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Deal locale has to match initial_locale (= launch country). 366ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (initial_locale_ != deal->deal_locale) 367ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return NULL; 368ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Make sure that deal is still active, 369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // i.e. if deal expire date is defined, check it. 370ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!deal->expire_date.is_null() && 371ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen deal->expire_date <= base::Time::Now()) { 372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return NULL; 373ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 374ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 375ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return deal; 376ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 377ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return NULL; 378ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 379ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 380ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 381ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ServicesCustomizationDocument::LoadManifestFromString( 382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::string& manifest) { 383ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!CustomizationDocument::LoadManifestFromString(manifest)) 384ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 385ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 386ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* carriers = NULL; 387ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (root_.get() && root_->GetDictionary(kCarrierDealsAttr, &carriers)) { 388ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (DictionaryValue::key_iterator iter = carriers->begin_keys(); 389ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen iter != carriers->end_keys(); ++iter) { 390ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* carrier_deal = NULL; 391ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (carriers->GetDictionary(*iter, &carrier_deal)) { 392ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen carrier_deals_[*iter] = new CarrierDeal(carrier_deal); 393ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 394ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 395ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 396ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 397ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 398ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace chromeos 400