summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/default_apps.cc
blob: fbd85fed6d72795d4ada06950858cc0cd0eb3f03 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/default_apps.h"

#include "base/command_line.h"
#include "base/metrics/field_trial.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/extensions/default_apps_trial.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "ui/base/l10n/l10n_util.h"

static bool ShouldInstallInProfile(Profile* profile) {
  // We decide to install or not install default apps based on the following
  // criteria, from highest priority to lowest priority:
  //
  // - If this instance of chrome is participating in the default apps
  //   field trial, then install apps based on the group.
  // - The command line option.  Tests use this option to disable installation
  //   of default apps in some cases.
  // - If the locale is not compatible with the defaults, don't install them.
  // - If the profile says to either always install or never install default
  //   apps, obey.
  // - The kDefaultApps preferences value in the profile.  This value is
  //   usually set in the master_preferences file.
  bool install_apps =
      profile->GetPrefs()->GetString(prefs::kDefaultApps) == "install";

  default_apps::InstallState state =
      static_cast<default_apps::InstallState>(profile->GetPrefs()->GetInteger(
          prefs::kDefaultAppsInstallState));
  switch (state) {
    case default_apps::kUnknown: {
      // We get here for either new profile, or profiles created before the
      // default apps feature was implemented.  In the former case, we always
      // want to install default apps.  In the latter case, we don't want to
      // disturb a user that has already installed and possibly curated a list
      // of favourite apps, so we only install if there are no apps in the
      // profile.  We can check for both these cases by looking to see if
      // any apps already exist.
      ExtensionService* extension_service = profile->GetExtensionService();
      if (extension_service && extension_service->HasApps())
        install_apps = false;
      break;
    }
    case default_apps::kAlwaysProvideDefaultApps:
      install_apps = true;
      break;
    case default_apps::kNeverProvideDefaultApps:
      install_apps = false;
      break;
    default:
      NOTREACHED();
  }

  if (install_apps) {
    // Don't bother installing default apps in locales where it is known that
    // they don't work.
    // TODO(rogerta): Do this check dynamically once the webstore can expose
    // an API. See http://crbug.com/101357
    const std::string& locale = g_browser_process->GetApplicationLocale();
    static const char* unsupported_locales[] = {"CN", "TR", "IR"};
    for (size_t i = 0; i < arraysize(unsupported_locales); ++i) {
      if (EndsWith(locale, unsupported_locales[i], false)) {
        install_apps = false;
        break;
      }
    }
  }

  if (CommandLine::ForCurrentProcess()->HasSwitch(
      switches::kDisableDefaultApps)) {
    install_apps = false;
  }

  if (base::FieldTrialList::TrialExists(kDefaultAppsTrial_Name)) {
    install_apps = base::FieldTrialList::Find(
        kDefaultAppsTrial_Name)->group_name() != kDefaultAppsTrial_NoAppsGroup;
  }

  // Save the state if needed.
  if (state == default_apps::kUnknown) {
    if (install_apps) {
      profile->GetPrefs()->SetInteger(prefs::kDefaultAppsInstallState,
                                      default_apps::kAlwaysProvideDefaultApps);
    } else {
      profile->GetPrefs()->SetInteger(prefs::kDefaultAppsInstallState,
                                      default_apps::kNeverProvideDefaultApps);
    }
    profile->GetPrefs()->ScheduleSavePersistentPrefs();
  }

  return install_apps;
}

namespace default_apps {

void RegisterUserPrefs(PrefService* prefs) {
  prefs->RegisterIntegerPref(prefs::kDefaultAppsInstallState, kUnknown,
                             PrefService::UNSYNCABLE_PREF);
}

Provider::Provider(Profile* profile,
                   VisitorInterface* service,
                   ExternalExtensionLoader* loader,
                   Extension::Location crx_location,
                   Extension::Location download_location,
                   int creation_flags)
    : ExternalExtensionProviderImpl(service, loader, crx_location,
                                    download_location, creation_flags),
      profile_(profile) {
  DCHECK(profile);
}

void Provider::VisitRegisteredExtension() {
  if (!profile_ || !ShouldInstallInProfile(profile_)) {
    base::DictionaryValue* prefs = new base::DictionaryValue;
    SetPrefs(prefs);
    return;
  }

  ExternalExtensionProviderImpl::VisitRegisteredExtension();
}

}  // namespace default_apps