blob: 9633d12e78c64fb453391af1f10011f0c648d24a [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
[email protected]b8096552013-05-04 15:48:117#include <set>
8#include <string>
9
[email protected]86c6b9e32011-10-25 17:09:1010#include "base/command_line.h"
[email protected]86c6b9e32011-10-25 17:09:1011#include "chrome/browser/browser_process.h"
[email protected]75fee372013-03-06 00:42:4412#include "components/user_prefs/pref_registry_syncable.h"
[email protected]2eef64f2012-08-31 23:09:1213#if !defined(OS_ANDROID)
[email protected]22768322011-12-21 22:28:2314#include "chrome/browser/first_run/first_run.h"
[email protected]2eef64f2012-08-31 23:09:1215#endif
[email protected]3853a4c2013-02-11 17:15:5716#include "base/prefs/pref_service.h"
[email protected]86c6b9e32011-10-25 17:09:1017#include "chrome/browser/profiles/profile.h"
18#include "chrome/common/chrome_switches.h"
[email protected]73285952012-05-25 20:46:4019#include "chrome/common/chrome_version_info.h"
[email protected]1c321ee52012-05-21 03:02:3420#include "chrome/common/extensions/extension.h"
[email protected]86c6b9e32011-10-25 17:09:1021#include "chrome/common/pref_names.h"
22#include "ui/base/l10n/l10n_util.h"
23
[email protected]937cf9d2012-08-30 03:51:5524namespace {
25
[email protected]937cf9d2012-08-30 03:51:5526// Returns true if the app was a default app in Chrome 22
27bool IsOldDefaultApp(const std::string& extension_id) {
[email protected]b8096552013-05-04 15:48:1128 return extension_id == extension_misc::kGmailAppId ||
29 extension_id == extension_misc::kGoogleSearchAppId ||
30 extension_id == extension_misc::kYoutubeAppId;
[email protected]937cf9d2012-08-30 03:51:5531}
32
33bool IsLocaleSupported() {
34 // Don't bother installing default apps in locales where it is known that
35 // they don't work.
36 // TODO(rogerta): Do this check dynamically once the webstore can expose
37 // an API. See http://crbug.com/101357
38 const std::string& locale = g_browser_process->GetApplicationLocale();
39 static const char* unsupported_locales[] = {"CN", "TR", "IR"};
40 for (size_t i = 0; i < arraysize(unsupported_locales); ++i) {
41 if (EndsWith(locale, unsupported_locales[i], false)) {
42 return false;
43 }
44 }
45 return true;
46}
47
[email protected]b8096552013-05-04 15:48:1148} // namespace
[email protected]937cf9d2012-08-30 03:51:5549
[email protected]910f72ce2012-08-24 01:38:3550namespace default_apps {
51
[email protected]c753f142013-02-10 13:14:0452void RegisterUserPrefs(PrefRegistrySyncable* registry) {
53 registry->RegisterIntegerPref(prefs::kDefaultAppsInstallState, kUnknown,
54 PrefRegistrySyncable::UNSYNCABLE_PREF);
[email protected]937cf9d2012-08-30 03:51:5555}
56
57bool Provider::ShouldInstallInProfile() {
[email protected]86c6b9e32011-10-25 17:09:1058 // We decide to install or not install default apps based on the following
59 // criteria, from highest priority to lowest priority:
60 //
[email protected]86c6b9e32011-10-25 17:09:1061 // - The command line option. Tests use this option to disable installation
62 // of default apps in some cases.
63 // - If the locale is not compatible with the defaults, don't install them.
[email protected]86c6b9e32011-10-25 17:09:1064 // - The kDefaultApps preferences value in the profile. This value is
65 // usually set in the master_preferences file.
66 bool install_apps =
[email protected]937cf9d2012-08-30 03:51:5567 profile_->GetPrefs()->GetString(prefs::kDefaultApps) == "install";
[email protected]86c6b9e32011-10-25 17:09:1068
[email protected]937cf9d2012-08-30 03:51:5569 InstallState state =
70 static_cast<InstallState>(profile_->GetPrefs()->GetInteger(
[email protected]d190cef2011-11-09 02:09:2471 prefs::kDefaultAppsInstallState));
[email protected]910f72ce2012-08-24 01:38:3572
[email protected]937cf9d2012-08-30 03:51:5573 is_migration_ = (state == kProvideLegacyDefaultApps);
74
[email protected]86c6b9e32011-10-25 17:09:1075 switch (state) {
[email protected]937cf9d2012-08-30 03:51:5576 case kUnknown: {
[email protected]2eef64f2012-08-31 23:09:1277 // Only new installations and profiles get default apps. In theory the
78 // new profile checks should catch new installations, but that is not
79 // always the case (http:/crbug.com/145351).
[email protected]73285952012-05-25 20:46:4080 chrome::VersionInfo version_info;
[email protected]2eef64f2012-08-31 23:09:1281 bool is_new_profile =
82 profile_->WasCreatedByVersionOrLater(version_info.Version().c_str());
83 // Android excludes most of the first run code, so it can't determine
84 // if this is a first run. That's OK though, because Android doesn't
85 // use default apps in general.
86#if defined(OS_ANDROID)
87 bool is_first_run = false;
88#else
89 bool is_first_run = first_run::IsChromeFirstRun();
90#endif
91 if (!is_first_run && !is_new_profile)
[email protected]86c6b9e32011-10-25 17:09:1092 install_apps = false;
93 break;
94 }
[email protected]910f72ce2012-08-24 01:38:3595
96 // The old default apps were provided as external extensions and were
97 // installed everytime Chrome was run. Thus, changing the list of default
98 // apps affected all users. Migrate old default apps to new mechanism where
99 // they are installed only once as INTERNAL.
100 // TODO(grv) : remove after Q1-2013.
[email protected]937cf9d2012-08-30 03:51:55101 case kProvideLegacyDefaultApps:
102 profile_->GetPrefs()->SetInteger(
[email protected]910f72ce2012-08-24 01:38:35103 prefs::kDefaultAppsInstallState,
[email protected]937cf9d2012-08-30 03:51:55104 kAlreadyInstalledDefaultApps);
[email protected]86c6b9e32011-10-25 17:09:10105 break;
[email protected]910f72ce2012-08-24 01:38:35106
[email protected]937cf9d2012-08-30 03:51:55107 case kAlreadyInstalledDefaultApps:
108 case kNeverInstallDefaultApps:
[email protected]86c6b9e32011-10-25 17:09:10109 install_apps = false;
110 break;
111 default:
112 NOTREACHED();
113 }
114
[email protected]9bf21b92012-10-04 21:01:39115 if (install_apps && !IsLocaleSupported())
[email protected]910f72ce2012-08-24 01:38:35116 install_apps = false;
[email protected]86c6b9e32011-10-25 17:09:10117
[email protected]910f72ce2012-08-24 01:38:35118 // Default apps are only installed on profile creation or a new chrome
119 // download.
[email protected]937cf9d2012-08-30 03:51:55120 if (state == kUnknown) {
[email protected]86c6b9e32011-10-25 17:09:10121 if (install_apps) {
[email protected]9bf21b92012-10-04 21:01:39122 profile_->GetPrefs()->SetInteger(prefs::kDefaultAppsInstallState,
123 kAlreadyInstalledDefaultApps);
[email protected]86c6b9e32011-10-25 17:09:10124 } else {
[email protected]937cf9d2012-08-30 03:51:55125 profile_->GetPrefs()->SetInteger(prefs::kDefaultAppsInstallState,
126 kNeverInstallDefaultApps);
[email protected]86c6b9e32011-10-25 17:09:10127 }
[email protected]86c6b9e32011-10-25 17:09:10128 }
129
130 return install_apps;
131}
132
[email protected]d190cef2011-11-09 02:09:24133Provider::Provider(Profile* profile,
134 VisitorInterface* service,
[email protected]5df038b2012-07-16 19:03:27135 extensions::ExternalLoader* loader,
[email protected]1d5e58b2013-01-31 08:41:40136 extensions::Manifest::Location crx_location,
137 extensions::Manifest::Location download_location,
[email protected]d190cef2011-11-09 02:09:24138 int creation_flags)
[email protected]5df038b2012-07-16 19:03:27139 : extensions::ExternalProviderImpl(service, loader, crx_location,
140 download_location, creation_flags),
[email protected]e9a30af2012-10-04 01:56:25141 profile_(profile),
142 is_migration_(false) {
[email protected]d190cef2011-11-09 02:09:24143 DCHECK(profile);
[email protected]47fc70c2011-12-06 07:29:51144 set_auto_acknowledge(true);
[email protected]d190cef2011-11-09 02:09:24145}
146
147void Provider::VisitRegisteredExtension() {
[email protected]937cf9d2012-08-30 03:51:55148 if (!profile_ || !ShouldInstallInProfile()) {
[email protected]d190cef2011-11-09 02:09:24149 base::DictionaryValue* prefs = new base::DictionaryValue;
150 SetPrefs(prefs);
151 return;
152 }
153
[email protected]5df038b2012-07-16 19:03:27154 extensions::ExternalProviderImpl::VisitRegisteredExtension();
[email protected]d190cef2011-11-09 02:09:24155}
156
[email protected]937cf9d2012-08-30 03:51:55157void Provider::SetPrefs(base::DictionaryValue* prefs) {
158 if (is_migration_) {
159 std::set<std::string> new_default_apps;
[email protected]02d9b272013-03-06 12:54:56160 for (DictionaryValue::Iterator i(*prefs); !i.IsAtEnd(); i.Advance()) {
161 if (!IsOldDefaultApp(i.key()))
162 new_default_apps.insert(i.key());
[email protected]937cf9d2012-08-30 03:51:55163 }
164 // Filter out the new default apps for migrating users.
165 for (std::set<std::string>::iterator it = new_default_apps.begin();
166 it != new_default_apps.end(); ++it) {
167 prefs->Remove(*it, NULL);
[email protected]910f72ce2012-08-24 01:38:35168 }
169 }
[email protected]937cf9d2012-08-30 03:51:55170
171 ExternalProviderImpl::SetPrefs(prefs);
[email protected]910f72ce2012-08-24 01:38:35172}
173
[email protected]86c6b9e32011-10-25 17:09:10174} // namespace default_apps