15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/master_preferences.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/environment.h"
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_string_value_serializer.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/env_vars.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/pref_names.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/master_preferences_constants.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/util_constants.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kFirstRunTabs[] = "first_run_tabs";
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::LazyInstance<installer::MasterPreferences> g_master_preferences =
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LAZY_INSTANCE_INITIALIZER;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool GetURLFromValue(const base::Value* in_value, std::string* out_value) {
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return in_value && out_value && in_value->GetAsString(out_value);
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::vector<std::string> GetNamedList(const char* name,
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                      const base::DictionaryValue* prefs) {
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> list;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!prefs)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return list;
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const base::ListValue* value_list = NULL;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!prefs->GetList(name, &value_list))
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return list;
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  list.reserve(value_list->GetSize());
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < value_list->GetSize(); ++i) {
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const base::Value* entry;
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string url_entry;
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!value_list->Get(i, &entry) || !GetURLFromValue(entry, &url_entry)) {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    list.push_back(url_entry);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return list;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbase::DictionaryValue* ParseDistributionPreferences(
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::string& json_data) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  JSONStringValueSerializer json(json_data);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error;
57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<base::Value> root(json.Deserialize(NULL, &error));
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!root.get()) {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(WARNING) << "Failed to parse master prefs file: " << error;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!root->IsType(base::Value::TYPE_DICTIONARY)) {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(WARNING) << "Failed to parse master prefs file: "
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << "Root item must be a dictionary.";
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return static_cast<base::DictionaryValue*>(root.release());
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace installer {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MasterPreferences::MasterPreferences() : distribution_(NULL),
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         preferences_read_from_file_(false),
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         chrome_(true),
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         chrome_app_launcher_(false),
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         multi_install_(false) {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeFromCommandLine(*CommandLine::ForCurrentProcess());
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MasterPreferences::MasterPreferences(const CommandLine& cmd_line)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : distribution_(NULL),
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      preferences_read_from_file_(false),
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome_(true),
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      chrome_app_launcher_(false),
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      multi_install_(false) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeFromCommandLine(cmd_line);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MasterPreferences::MasterPreferences(const base::FilePath& prefs_path)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : distribution_(NULL),
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      preferences_read_from_file_(false),
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome_(true),
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      chrome_app_launcher_(false),
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      multi_install_(false) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string json_data;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Failure to read the file is ignored as |json_data| will be the empty string
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // and the remainder of this MasterPreferences object should still be
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // initialized as best as possible.
1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (base::PathExists(prefs_path) &&
10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      !base::ReadFileToString(prefs_path, &json_data)) {
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR) << "Failed to read preferences from " << prefs_path.value();
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (InitializeFromString(json_data))
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    preferences_read_from_file_ = true;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MasterPreferences::MasterPreferences(const std::string& prefs)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : distribution_(NULL),
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      preferences_read_from_file_(false),
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      chrome_(true),
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      chrome_app_launcher_(false),
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      multi_install_(false) {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeFromString(prefs);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MasterPreferences::~MasterPreferences() {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MasterPreferences::InitializeFromCommandLine(const CommandLine& cmd_line) {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cmd_line.HasSwitch(installer::switches::kInstallerData)) {
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath prefs_path(cmd_line.GetSwitchValuePath(
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        installer::switches::kInstallerData));
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this->MasterPreferences::MasterPreferences(prefs_path);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    master_dictionary_.reset(new base::DictionaryValue());
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(master_dictionary_.get());
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A simple map from command line switches to equivalent switches in the
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // distribution dictionary.  Currently all switches added will be set to
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 'true'.
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const struct CmdLineSwitchToDistributionSwitch {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* cmd_line_switch;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* distribution_switch;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } translate_switches[] = {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { installer::switches::kAutoLaunchChrome,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      installer::master_preferences::kAutoLaunchChrome },
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { installer::switches::kChromeAppHostDeprecated,
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      installer::master_preferences::kChromeAppHostDeprecated },
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { installer::switches::kChromeAppLauncher,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      installer::master_preferences::kChromeAppLauncher },
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { installer::switches::kChrome,
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      installer::master_preferences::kChrome },
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { installer::switches::kDisableLogging,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      installer::master_preferences::kDisableLogging },
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { installer::switches::kMsi,
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      installer::master_preferences::kMsi },
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { installer::switches::kMultiInstall,
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      installer::master_preferences::kMultiInstall },
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { installer::switches::kDoNotRegisterForUpdateLaunch,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      installer::master_preferences::kDoNotRegisterForUpdateLaunch },
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { installer::switches::kDoNotLaunchChrome,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      installer::master_preferences::kDoNotLaunchChrome },
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { installer::switches::kMakeChromeDefault,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      installer::master_preferences::kMakeChromeDefault },
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { installer::switches::kSystemLevel,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      installer::master_preferences::kSystemLevel },
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { installer::switches::kVerboseLogging,
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      installer::master_preferences::kVerboseLogging },
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string name(installer::master_preferences::kDistroDict);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < arraysize(translate_switches); ++i) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cmd_line.HasSwitch(translate_switches[i].cmd_line_switch)) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      name.assign(installer::master_preferences::kDistroDict);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      name.append(".").append(translate_switches[i].distribution_switch);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      master_dictionary_->SetBoolean(name, true);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See if the log file path was specified on the command line.
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wstring str_value(cmd_line.GetSwitchValueNative(
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      installer::switches::kLogFile));
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!str_value.empty()) {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    name.assign(installer::master_preferences::kDistroDict);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    name.append(".").append(installer::master_preferences::kLogFile);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    master_dictionary_->SetString(name, str_value);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handle the special case of --system-level being implied by the presence of
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the kGoogleUpdateIsMachineEnvVar environment variable.
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Environment> env(base::Environment::Create());
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (env != NULL) {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string is_machine_var;
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    env->GetVar(env_vars::kGoogleUpdateIsMachineEnvVar, &is_machine_var);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!is_machine_var.empty() && is_machine_var[0] == '1') {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      VLOG(1) << "Taking system-level from environment.";
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      name.assign(installer::master_preferences::kDistroDict);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      name.append(".").append(installer::master_preferences::kSystemLevel);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      master_dictionary_->SetBoolean(name, true);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cache a pointer to the distribution dictionary. Ignore errors if any.
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  master_dictionary_->GetDictionary(installer::master_preferences::kDistroDict,
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    &distribution_);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeProductFlags();
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MasterPreferences::InitializeFromString(const std::string& json_data) {
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!json_data.empty())
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    master_dictionary_.reset(ParseDistributionPreferences(json_data));
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool data_is_valid = true;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!master_dictionary_.get()) {
212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    master_dictionary_.reset(new base::DictionaryValue());
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data_is_valid = false;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Cache a pointer to the distribution dictionary.
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    master_dictionary_->GetDictionary(
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        installer::master_preferences::kDistroDict, &distribution_);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeProductFlags();
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EnforceLegacyPreferences();
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return data_is_valid;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MasterPreferences::InitializeProductFlags() {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure we start out with the correct defaults.
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  multi_install_ = false;
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chrome_app_launcher_ = false;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome_ = true;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetBool(installer::master_preferences::kMultiInstall, &multi_install_);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetBool(installer::master_preferences::kChromeAppLauncher,
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &chrome_app_launcher_);
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The deprecated switch --app-host behaves like --app-launcher.
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool chrome_app_host = false;
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetBool(installer::master_preferences::kChromeAppHostDeprecated,
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &chrome_app_host);
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chrome_app_launcher_ = chrome_app_launcher_ || chrome_app_host;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When multi-install is specified, the checks are pretty simple (in theory):
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In order to be installed/uninstalled, each product must have its switch
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // present on the command line.
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // When multi-install is not set, operate on Chrome.
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (multi_install_) {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!GetBool(installer::master_preferences::kChrome, &chrome_))
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome_ = false;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    chrome_ = true;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MasterPreferences::EnforceLegacyPreferences() {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If create_all_shortcuts was explicitly set to false, set
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // do_not_create_(desktop|quick_launch)_shortcut to true.
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool create_all_shortcuts = true;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetBool(installer::master_preferences::kCreateAllShortcuts,
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &create_all_shortcuts);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!create_all_shortcuts) {
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    distribution_->SetBoolean(
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        installer::master_preferences::kDoNotCreateDesktopShortcut, true);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    distribution_->SetBoolean(
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        installer::master_preferences::kDoNotCreateQuickLaunchShortcut, true);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // If there is no entry for kURLsToRestoreOnStartup and there is one for
2680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // kURLsToRestoreOnStartupOld, copy the old to the new.
2690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  const base::ListValue* startup_urls_list = NULL;
2700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (master_dictionary_ &&
2710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      !master_dictionary_->GetList(prefs::kURLsToRestoreOnStartup, NULL) &&
2720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      master_dictionary_->GetList(prefs::kURLsToRestoreOnStartupOld,
2730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                  &startup_urls_list) &&
2740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      startup_urls_list) {
2750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::ListValue* new_startup_urls_list = startup_urls_list->DeepCopy();
2760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    master_dictionary_->Set(prefs::kURLsToRestoreOnStartup,
2770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                            new_startup_urls_list);
2780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MasterPreferences::GetBool(const std::string& name, bool* value) const {
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ret = false;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (distribution_)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = distribution_->GetBoolean(name, value);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ret;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MasterPreferences::GetInt(const std::string& name, int* value) const {
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ret = false;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (distribution_)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = distribution_->GetInteger(name, value);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ret;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MasterPreferences::GetString(const std::string& name,
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  std::string* value) const {
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ret = false;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (distribution_)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = (distribution_->GetString(name, value) && !value->empty());
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ret;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::vector<std::string> MasterPreferences::GetFirstRunTabs() const {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetNamedList(kFirstRunTabs, master_dictionary_.get());
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool MasterPreferences::GetExtensionsBlock(
308eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::DictionaryValue** extensions) const {
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return master_dictionary_->GetDictionary(
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      master_preferences::kExtensionsBlock, extensions);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string MasterPreferences::GetVariationsSeed() const {
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return ExtractPrefString(prefs::kVariationsSeed);
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string MasterPreferences::GetVariationsSeedSignature() const {
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return ExtractPrefString(prefs::kVariationsSeedSignature);
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string MasterPreferences::ExtractPrefString(
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& name) const {
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string result;
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<base::Value> pref_value;
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (master_dictionary_->Remove(name, &pref_value)) {
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!pref_value->GetAsString(&result))
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NOTREACHED();
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return result;
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const MasterPreferences& MasterPreferences::ForCurrentProcess() {
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_master_preferences.Get();
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace installer
338