blob: 4d01de3d87dee243bd387cf76c9436ef1dcd1ac9 [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]3853a4c2013-02-11 17:15:5711#include "base/prefs/pref_service.h"
[email protected]e4452d32013-11-15 23:07:4112#include "chrome/browser/browser_process.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]b0af4792013-10-23 09:12:1316#include "chrome/common/extensions/extension_constants.h"
[email protected]86c6b9e32011-10-25 17:09:1017#include "chrome/common/pref_names.h"
[email protected]e4452d32013-11-15 23:07:4118#include "components/user_prefs/pref_registry_syncable.h"
19#include "extensions/common/extension.h"
[email protected]86c6b9e32011-10-25 17:09:1020#include "ui/base/l10n/l10n_util.h"
21
[email protected]443e9312013-05-06 06:17:3422#if !defined(OS_ANDROID)
23#include "chrome/browser/first_run/first_run.h"
24#endif
25
[email protected]937cf9d2012-08-30 03:51:5526namespace {
27
[email protected]937cf9d2012-08-30 03:51:5528// Returns true if the app was a default app in Chrome 22
29bool IsOldDefaultApp(const std::string& extension_id) {
[email protected]b8096552013-05-04 15:48:1130 return extension_id == extension_misc::kGmailAppId ||
31 extension_id == extension_misc::kGoogleSearchAppId ||
32 extension_id == extension_misc::kYoutubeAppId;
[email protected]937cf9d2012-08-30 03:51:5533}
34
35bool IsLocaleSupported() {
36 // Don't bother installing default apps in locales where it is known that
37 // they don't work.
38 // TODO(rogerta): Do this check dynamically once the webstore can expose
39 // an API. See http://crbug.com/101357
40 const std::string& locale = g_browser_process->GetApplicationLocale();
41 static const char* unsupported_locales[] = {"CN", "TR", "IR"};
42 for (size_t i = 0; i < arraysize(unsupported_locales); ++i) {
43 if (EndsWith(locale, unsupported_locales[i], false)) {
44 return false;
45 }
46 }
47 return true;
48}
49
[email protected]b8096552013-05-04 15:48:1150} // namespace
[email protected]937cf9d2012-08-30 03:51:5551
[email protected]910f72ce2012-08-24 01:38:3552namespace default_apps {
53
[email protected]37ca3fe02013-07-05 15:32:4454void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
[email protected]443e9312013-05-06 06:17:3455 registry->RegisterIntegerPref(
56 prefs::kDefaultAppsInstallState,
57 kUnknown,
58 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
[email protected]937cf9d2012-08-30 03:51:5559}
60
61bool Provider::ShouldInstallInProfile() {
[email protected]86c6b9e32011-10-25 17:09:1062 // We decide to install or not install default apps based on the following
63 // criteria, from highest priority to lowest priority:
64 //
[email protected]86c6b9e32011-10-25 17:09:1065 // - The command line option. Tests use this option to disable installation
66 // of default apps in some cases.
67 // - If the locale is not compatible with the defaults, don't install them.
[email protected]86c6b9e32011-10-25 17:09:1068 // - The kDefaultApps preferences value in the profile. This value is
69 // usually set in the master_preferences file.
70 bool install_apps =
[email protected]937cf9d2012-08-30 03:51:5571 profile_->GetPrefs()->GetString(prefs::kDefaultApps) == "install";
[email protected]86c6b9e32011-10-25 17:09:1072
[email protected]937cf9d2012-08-30 03:51:5573 InstallState state =
74 static_cast<InstallState>(profile_->GetPrefs()->GetInteger(
[email protected]d190cef2011-11-09 02:09:2475 prefs::kDefaultAppsInstallState));
[email protected]910f72ce2012-08-24 01:38:3576
[email protected]937cf9d2012-08-30 03:51:5577 is_migration_ = (state == kProvideLegacyDefaultApps);
78
[email protected]86c6b9e32011-10-25 17:09:1079 switch (state) {
[email protected]937cf9d2012-08-30 03:51:5580 case kUnknown: {
[email protected]2eef64f2012-08-31 23:09:1281 // Only new installations and profiles get default apps. In theory the
82 // new profile checks should catch new installations, but that is not
83 // always the case (http:/crbug.com/145351).
[email protected]73285952012-05-25 20:46:4084 chrome::VersionInfo version_info;
[email protected]2eef64f2012-08-31 23:09:1285 bool is_new_profile =
86 profile_->WasCreatedByVersionOrLater(version_info.Version().c_str());
87 // Android excludes most of the first run code, so it can't determine
88 // if this is a first run. That's OK though, because Android doesn't
89 // use default apps in general.
90#if defined(OS_ANDROID)
91 bool is_first_run = false;
92#else
93 bool is_first_run = first_run::IsChromeFirstRun();
94#endif
95 if (!is_first_run && !is_new_profile)
[email protected]86c6b9e32011-10-25 17:09:1096 install_apps = false;
97 break;
98 }
[email protected]910f72ce2012-08-24 01:38:3599
100 // The old default apps were provided as external extensions and were
101 // installed everytime Chrome was run. Thus, changing the list of default
102 // apps affected all users. Migrate old default apps to new mechanism where
103 // they are installed only once as INTERNAL.
104 // TODO(grv) : remove after Q1-2013.
[email protected]937cf9d2012-08-30 03:51:55105 case kProvideLegacyDefaultApps:
106 profile_->GetPrefs()->SetInteger(
[email protected]910f72ce2012-08-24 01:38:35107 prefs::kDefaultAppsInstallState,
[email protected]937cf9d2012-08-30 03:51:55108 kAlreadyInstalledDefaultApps);
[email protected]86c6b9e32011-10-25 17:09:10109 break;
[email protected]910f72ce2012-08-24 01:38:35110
[email protected]937cf9d2012-08-30 03:51:55111 case kAlreadyInstalledDefaultApps:
112 case kNeverInstallDefaultApps:
[email protected]86c6b9e32011-10-25 17:09:10113 install_apps = false;
114 break;
115 default:
116 NOTREACHED();
117 }
118
[email protected]9bf21b92012-10-04 21:01:39119 if (install_apps && !IsLocaleSupported())
[email protected]910f72ce2012-08-24 01:38:35120 install_apps = false;
[email protected]86c6b9e32011-10-25 17:09:10121
[email protected]910f72ce2012-08-24 01:38:35122 // Default apps are only installed on profile creation or a new chrome
123 // download.
[email protected]937cf9d2012-08-30 03:51:55124 if (state == kUnknown) {
[email protected]86c6b9e32011-10-25 17:09:10125 if (install_apps) {
[email protected]9bf21b92012-10-04 21:01:39126 profile_->GetPrefs()->SetInteger(prefs::kDefaultAppsInstallState,
127 kAlreadyInstalledDefaultApps);
[email protected]86c6b9e32011-10-25 17:09:10128 } else {
[email protected]937cf9d2012-08-30 03:51:55129 profile_->GetPrefs()->SetInteger(prefs::kDefaultAppsInstallState,
130 kNeverInstallDefaultApps);
[email protected]86c6b9e32011-10-25 17:09:10131 }
[email protected]86c6b9e32011-10-25 17:09:10132 }
133
134 return install_apps;
135}
136
[email protected]d190cef2011-11-09 02:09:24137Provider::Provider(Profile* profile,
138 VisitorInterface* service,
[email protected]5df038b2012-07-16 19:03:27139 extensions::ExternalLoader* loader,
[email protected]1d5e58b2013-01-31 08:41:40140 extensions::Manifest::Location crx_location,
141 extensions::Manifest::Location download_location,
[email protected]d190cef2011-11-09 02:09:24142 int creation_flags)
[email protected]19eac6d2013-05-30 06:51:03143 : extensions::ExternalProviderImpl(service, loader, profile, crx_location,
[email protected]5df038b2012-07-16 19:03:27144 download_location, creation_flags),
[email protected]e9a30af2012-10-04 01:56:25145 profile_(profile),
146 is_migration_(false) {
[email protected]d190cef2011-11-09 02:09:24147 DCHECK(profile);
[email protected]47fc70c2011-12-06 07:29:51148 set_auto_acknowledge(true);
[email protected]d190cef2011-11-09 02:09:24149}
150
151void Provider::VisitRegisteredExtension() {
[email protected]937cf9d2012-08-30 03:51:55152 if (!profile_ || !ShouldInstallInProfile()) {
[email protected]d190cef2011-11-09 02:09:24153 base::DictionaryValue* prefs = new base::DictionaryValue;
154 SetPrefs(prefs);
155 return;
156 }
157
[email protected]5df038b2012-07-16 19:03:27158 extensions::ExternalProviderImpl::VisitRegisteredExtension();
[email protected]d190cef2011-11-09 02:09:24159}
160
[email protected]937cf9d2012-08-30 03:51:55161void Provider::SetPrefs(base::DictionaryValue* prefs) {
162 if (is_migration_) {
163 std::set<std::string> new_default_apps;
[email protected]02d9b272013-03-06 12:54:56164 for (DictionaryValue::Iterator i(*prefs); !i.IsAtEnd(); i.Advance()) {
165 if (!IsOldDefaultApp(i.key()))
166 new_default_apps.insert(i.key());
[email protected]937cf9d2012-08-30 03:51:55167 }
168 // Filter out the new default apps for migrating users.
169 for (std::set<std::string>::iterator it = new_default_apps.begin();
170 it != new_default_apps.end(); ++it) {
171 prefs->Remove(*it, NULL);
[email protected]910f72ce2012-08-24 01:38:35172 }
173 }
[email protected]937cf9d2012-08-30 03:51:55174
175 ExternalProviderImpl::SetPrefs(prefs);
[email protected]910f72ce2012-08-24 01:38:35176}
177
[email protected]86c6b9e32011-10-25 17:09:10178} // namespace default_apps