1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/extensions/default_apps.h"
10 #include "base/command_line.h"
11 #include "chrome/browser/browser_process.h"
12 #include "components/user_prefs/pref_registry_syncable.h"
13 #include "base/prefs/pref_service.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/common/chrome_switches.h"
16 #include "chrome/common/chrome_version_info.h"
17 #include "chrome/common/extensions/extension.h"
18 #include "chrome/common/pref_names.h"
19 #include "ui/base/l10n/l10n_util.h"
21 #if !defined(OS_ANDROID)
22 #include "chrome/browser/first_run/first_run.h"
27 // Returns true if the app was a default app in Chrome 22
28 bool IsOldDefaultApp(const std::string
& extension_id
) {
29 return extension_id
== extension_misc::kGmailAppId
||
30 extension_id
== extension_misc::kGoogleSearchAppId
||
31 extension_id
== extension_misc::kYoutubeAppId
;
34 bool IsLocaleSupported() {
35 // Don't bother installing default apps in locales where it is known that
37 // TODO(rogerta): Do this check dynamically once the webstore can expose
38 // an API. See http://crbug.com/101357
39 const std::string
& locale
= g_browser_process
->GetApplicationLocale();
40 static const char* unsupported_locales
[] = {"CN", "TR", "IR"};
41 for (size_t i
= 0; i
< arraysize(unsupported_locales
); ++i
) {
42 if (EndsWith(locale
, unsupported_locales
[i
], false)) {
51 namespace default_apps
{
53 void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable
* registry
) {
54 registry
->RegisterIntegerPref(
55 prefs::kDefaultAppsInstallState
,
57 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
60 bool Provider::ShouldInstallInProfile() {
61 // We decide to install or not install default apps based on the following
62 // criteria, from highest priority to lowest priority:
64 // - The command line option. Tests use this option to disable installation
65 // of default apps in some cases.
66 // - If the locale is not compatible with the defaults, don't install them.
67 // - The kDefaultApps preferences value in the profile. This value is
68 // usually set in the master_preferences file.
70 profile_
->GetPrefs()->GetString(prefs::kDefaultApps
) == "install";
73 static_cast<InstallState
>(profile_
->GetPrefs()->GetInteger(
74 prefs::kDefaultAppsInstallState
));
76 is_migration_
= (state
== kProvideLegacyDefaultApps
);
80 // Only new installations and profiles get default apps. In theory the
81 // new profile checks should catch new installations, but that is not
82 // always the case (http:/crbug.com/145351).
83 chrome::VersionInfo version_info
;
85 profile_
->WasCreatedByVersionOrLater(version_info
.Version().c_str());
86 // Android excludes most of the first run code, so it can't determine
87 // if this is a first run. That's OK though, because Android doesn't
88 // use default apps in general.
89 #if defined(OS_ANDROID)
90 bool is_first_run
= false;
92 bool is_first_run
= first_run::IsChromeFirstRun();
94 if (!is_first_run
&& !is_new_profile
)
99 // The old default apps were provided as external extensions and were
100 // installed everytime Chrome was run. Thus, changing the list of default
101 // apps affected all users. Migrate old default apps to new mechanism where
102 // they are installed only once as INTERNAL.
103 // TODO(grv) : remove after Q1-2013.
104 case kProvideLegacyDefaultApps
:
105 profile_
->GetPrefs()->SetInteger(
106 prefs::kDefaultAppsInstallState
,
107 kAlreadyInstalledDefaultApps
);
110 case kAlreadyInstalledDefaultApps
:
111 case kNeverInstallDefaultApps
:
112 install_apps
= false;
118 if (install_apps
&& !IsLocaleSupported())
119 install_apps
= false;
121 // Default apps are only installed on profile creation or a new chrome
123 if (state
== kUnknown
) {
125 profile_
->GetPrefs()->SetInteger(prefs::kDefaultAppsInstallState
,
126 kAlreadyInstalledDefaultApps
);
128 profile_
->GetPrefs()->SetInteger(prefs::kDefaultAppsInstallState
,
129 kNeverInstallDefaultApps
);
136 Provider::Provider(Profile
* profile
,
137 VisitorInterface
* service
,
138 extensions::ExternalLoader
* loader
,
139 extensions::Manifest::Location crx_location
,
140 extensions::Manifest::Location download_location
,
142 : extensions::ExternalProviderImpl(service
, loader
, profile
, crx_location
,
143 download_location
, creation_flags
),
145 is_migration_(false) {
147 set_auto_acknowledge(true);
150 void Provider::VisitRegisteredExtension() {
151 if (!profile_
|| !ShouldInstallInProfile()) {
152 base::DictionaryValue
* prefs
= new base::DictionaryValue
;
157 extensions::ExternalProviderImpl::VisitRegisteredExtension();
160 void Provider::SetPrefs(base::DictionaryValue
* prefs
) {
162 std::set
<std::string
> new_default_apps
;
163 for (DictionaryValue::Iterator
i(*prefs
); !i
.IsAtEnd(); i
.Advance()) {
164 if (!IsOldDefaultApp(i
.key()))
165 new_default_apps
.insert(i
.key());
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
);
174 ExternalProviderImpl::SetPrefs(prefs
);
177 } // namespace default_apps