summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/default_apps.cc
blob: 71d0c2d9518cced53f03c73268f138b0b227a3de (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
130
131
132
133
134
135
136
137
138
139
140
// 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/first_run/first_run.h"
#include "chrome/browser/extensions/default_apps_trial.h"
#include "chrome/browser/prefs/pref_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: {
      // This is the first time the default apps feature runs on this profile.
      // Determine if we want to install them or not. The best check would be
      // to see if this is a newly created profile, but its not possible to do
      // that.  The next best thing is to see if this is a chrome first run.
      // However, this means that multi-profile support is broken: secondary
      // profiles will not get default apps.
      // TODO(rogerta): add support for multiple profiles.
      if (!first_run::IsChromeFirstRun())
        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(kDefaultAppsTrialName)) {
    install_apps = base::FieldTrialList::Find(
        kDefaultAppsTrialName)->group_name() != kDefaultAppsTrialNoAppsGroup;
  }

  // Save the state if needed.  Once it is decided whether we are installing
  // default apps or not, we want to always respond with same value.  Therefore
  // on first run of this feature (i.e. the current state is kUnknown) the
  // state is updated to remember the choice that was made at this time.  The
  // next time chrome runs it will use the same decision.
  //
  // The reason for responding with the same value is that once an external
  // extenson provider has provided apps for a given profile, it must continue
  // to provide those extensions on each subsequent run.  Otherwise the
  // extension manager will automatically uninstall the apps.  The extension
  // manager is smart enough to know not to reinstall the apps on all
  // subsequent runs of chrome.
  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);
    }
  }

  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);
  set_auto_acknowledge(true);
}

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

  ExternalExtensionProviderImpl::VisitRegisteredExtension();
}

}  // namespace default_apps