blob: bcd35900b7930346ad758fcd64c4b4ae5ad885f7 [file] [log] [blame]
[email protected]73285952012-05-25 20:46:401// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]86c6b9e32011-10-25 17:09:102// 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/extensions/default_apps.h"
6
7#include "base/command_line.h"
8#include "base/metrics/field_trial.h"
9#include "chrome/browser/browser_process.h"
[email protected]22768322011-12-21 22:28:2310#include "chrome/browser/first_run/first_run.h"
[email protected]86c6b9e32011-10-25 17:09:1011#include "chrome/browser/extensions/default_apps_trial.h"
[email protected]22768322011-12-21 22:28:2312#include "chrome/browser/prefs/pref_service.h"
[email protected]86c6b9e32011-10-25 17:09:1013#include "chrome/browser/profiles/profile.h"
14#include "chrome/common/chrome_switches.h"
[email protected]73285952012-05-25 20:46:4015#include "chrome/common/chrome_version_info.h"
[email protected]1c321ee52012-05-21 03:02:3416#include "chrome/common/extensions/extension.h"
[email protected]86c6b9e32011-10-25 17:09:1017#include "chrome/common/pref_names.h"
18#include "ui/base/l10n/l10n_util.h"
19
[email protected]937cf9d2012-08-30 03:51:5520namespace {
21
22const char kGmailId[] = "pjkljhegncpnkpknbcohdijeoejaedia";
23const char kSearchId[] = "coobgpohoikkiipiblmjeljniedjpjpf";
24const char kYoutubeId[] = "blpcfgokakmgnkcojhhkbfbldkacnbeo";
25
26// Returns true if the app was a default app in Chrome 22
27bool IsOldDefaultApp(const std::string& extension_id) {
28 return extension_id == kGmailId || extension_id == kSearchId
29 || extension_id == kYoutubeId;
30}
31
32bool IsLocaleSupported() {
33 // Don't bother installing default apps in locales where it is known that
34 // they don't work.
35 // TODO(rogerta): Do this check dynamically once the webstore can expose
36 // an API. See http://crbug.com/101357
37 const std::string& locale = g_browser_process->GetApplicationLocale();
38 static const char* unsupported_locales[] = {"CN", "TR", "IR"};
39 for (size_t i = 0; i < arraysize(unsupported_locales); ++i) {
40 if (EndsWith(locale, unsupported_locales[i], false)) {
41 return false;
42 }
43 }
44 return true;
45}
46
47} // namespace
48
[email protected]910f72ce2012-08-24 01:38:3549namespace default_apps {
50
[email protected]937cf9d2012-08-30 03:51:5551void RegisterUserPrefs(PrefService* prefs) {
52 prefs->RegisterIntegerPref(prefs::kDefaultAppsInstallState, kUnknown,
53 PrefService::UNSYNCABLE_PREF);
54}
55
56bool Provider::ShouldInstallInProfile() {
[email protected]86c6b9e32011-10-25 17:09:1057 // We decide to install or not install default apps based on the following
58 // criteria, from highest priority to lowest priority:
59 //
60 // - If this instance of chrome is participating in the default apps
61 // field trial, then install apps based on the group.
62 // - The command line option. Tests use this option to disable installation
63 // of default apps in some cases.
64 // - If the locale is not compatible with the defaults, don't install them.
[email protected]86c6b9e32011-10-25 17:09:1065 // - The kDefaultApps preferences value in the profile. This value is
66 // usually set in the master_preferences file.
67 bool install_apps =
[email protected]937cf9d2012-08-30 03:51:5568 profile_->GetPrefs()->GetString(prefs::kDefaultApps) == "install";
[email protected]86c6b9e32011-10-25 17:09:1069
[email protected]937cf9d2012-08-30 03:51:5570 InstallState state =
71 static_cast<InstallState>(profile_->GetPrefs()->GetInteger(
[email protected]d190cef2011-11-09 02:09:2472 prefs::kDefaultAppsInstallState));
[email protected]910f72ce2012-08-24 01:38:3573
[email protected]937cf9d2012-08-30 03:51:5574 is_migration_ = (state == kProvideLegacyDefaultApps);
75
[email protected]86c6b9e32011-10-25 17:09:1076 switch (state) {
[email protected]937cf9d2012-08-30 03:51:5577 case kUnknown: {
[email protected]22768322011-12-21 22:28:2378 // This is the first time the default apps feature runs on this profile.
[email protected]73285952012-05-25 20:46:4079 // Determine if we want to install them or not.
80 chrome::VersionInfo version_info;
[email protected]937cf9d2012-08-30 03:51:5581 if (!profile_->WasCreatedByVersionOrLater(version_info.Version().c_str()))
[email protected]86c6b9e32011-10-25 17:09:1082 install_apps = false;
83 break;
84 }
[email protected]910f72ce2012-08-24 01:38:3585
86 // The old default apps were provided as external extensions and were
87 // installed everytime Chrome was run. Thus, changing the list of default
88 // apps affected all users. Migrate old default apps to new mechanism where
89 // they are installed only once as INTERNAL.
90 // TODO(grv) : remove after Q1-2013.
[email protected]937cf9d2012-08-30 03:51:5591 case kProvideLegacyDefaultApps:
92 profile_->GetPrefs()->SetInteger(
[email protected]910f72ce2012-08-24 01:38:3593 prefs::kDefaultAppsInstallState,
[email protected]937cf9d2012-08-30 03:51:5594 kAlreadyInstalledDefaultApps);
[email protected]86c6b9e32011-10-25 17:09:1095 break;
[email protected]910f72ce2012-08-24 01:38:3596
[email protected]937cf9d2012-08-30 03:51:5597 case kAlreadyInstalledDefaultApps:
98 case kNeverInstallDefaultApps:
[email protected]86c6b9e32011-10-25 17:09:1099 install_apps = false;
100 break;
101 default:
102 NOTREACHED();
103 }
104
[email protected]937cf9d2012-08-30 03:51:55105 if (install_apps && !IsLocaleSupported()) {
[email protected]910f72ce2012-08-24 01:38:35106 install_apps = false;
[email protected]86c6b9e32011-10-25 17:09:10107 }
108
109 if (CommandLine::ForCurrentProcess()->HasSwitch(
110 switches::kDisableDefaultApps)) {
111 install_apps = false;
112 }
113
[email protected]568c3312011-12-06 15:36:04114 if (base::FieldTrialList::TrialExists(kDefaultAppsTrialName)) {
[email protected]86c6b9e32011-10-25 17:09:10115 install_apps = base::FieldTrialList::Find(
[email protected]568c3312011-12-06 15:36:04116 kDefaultAppsTrialName)->group_name() != kDefaultAppsTrialNoAppsGroup;
[email protected]86c6b9e32011-10-25 17:09:10117 }
118
[email protected]910f72ce2012-08-24 01:38:35119 // Default apps are only installed on profile creation or a new chrome
120 // download.
[email protected]937cf9d2012-08-30 03:51:55121 if (state == kUnknown) {
[email protected]86c6b9e32011-10-25 17:09:10122 if (install_apps) {
[email protected]937cf9d2012-08-30 03:51:55123 profile_->GetPrefs()->SetInteger(
[email protected]910f72ce2012-08-24 01:38:35124 prefs::kDefaultAppsInstallState,
[email protected]937cf9d2012-08-30 03:51:55125 kAlreadyInstalledDefaultApps);
[email protected]86c6b9e32011-10-25 17:09:10126 } else {
[email protected]937cf9d2012-08-30 03:51:55127 profile_->GetPrefs()->SetInteger(prefs::kDefaultAppsInstallState,
128 kNeverInstallDefaultApps);
[email protected]86c6b9e32011-10-25 17:09:10129 }
[email protected]86c6b9e32011-10-25 17:09:10130 }
131
132 return install_apps;
133}
134
[email protected]d190cef2011-11-09 02:09:24135Provider::Provider(Profile* profile,
136 VisitorInterface* service,
[email protected]5df038b2012-07-16 19:03:27137 extensions::ExternalLoader* loader,
[email protected]1c321ee52012-05-21 03:02:34138 extensions::Extension::Location crx_location,
139 extensions::Extension::Location download_location,
[email protected]d190cef2011-11-09 02:09:24140 int creation_flags)
[email protected]5df038b2012-07-16 19:03:27141 : extensions::ExternalProviderImpl(service, loader, crx_location,
142 download_location, creation_flags),
[email protected]d190cef2011-11-09 02:09:24143 profile_(profile) {
144 DCHECK(profile);
[email protected]47fc70c2011-12-06 07:29:51145 set_auto_acknowledge(true);
[email protected]d190cef2011-11-09 02:09:24146}
147
148void Provider::VisitRegisteredExtension() {
[email protected]937cf9d2012-08-30 03:51:55149 if (!profile_ || !ShouldInstallInProfile()) {
[email protected]d190cef2011-11-09 02:09:24150 base::DictionaryValue* prefs = new base::DictionaryValue;
151 SetPrefs(prefs);
152 return;
153 }
154
[email protected]5df038b2012-07-16 19:03:27155 extensions::ExternalProviderImpl::VisitRegisteredExtension();
[email protected]d190cef2011-11-09 02:09:24156}
157
[email protected]937cf9d2012-08-30 03:51:55158void Provider::SetPrefs(base::DictionaryValue* prefs) {
159 if (is_migration_) {
160 std::set<std::string> new_default_apps;
161 for (base::DictionaryValue::key_iterator i = prefs->begin_keys();
162 i != prefs->end_keys(); ++i) {
163 if (!IsOldDefaultApp(*i)) {
164 new_default_apps.insert(*i);
165 }
166 }
167 // Filter out the new default apps for migrating users.
168 for (std::set<std::string>::iterator it = new_default_apps.begin();
169 it != new_default_apps.end(); ++it) {
170 prefs->Remove(*it, NULL);
[email protected]910f72ce2012-08-24 01:38:35171 }
172 }
[email protected]937cf9d2012-08-30 03:51:55173
174 ExternalProviderImpl::SetPrefs(prefs);
[email protected]910f72ce2012-08-24 01:38:35175}
176
[email protected]86c6b9e32011-10-25 17:09:10177} // namespace default_apps