blob: b759304fb4092a7a7cc9695a3cb307232d357d7e [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
avia2f4804a2015-12-24 23:11:137#include <stddef.h>
8
Jinho Bangb5216cec2018-01-17 19:43:119#include <memory>
[email protected]b8096552013-05-04 15:48:1110#include <set>
11#include <string>
12
[email protected]86c6b9e32011-10-25 17:09:1013#include "base/command_line.h"
Avi Drissman5f0fb8c2018-12-25 23:20:4914#include "base/stl_util.h"
[email protected]d4f52042014-08-08 22:43:5915#include "base/strings/string_util.h"
[email protected]e4452d32013-11-15 23:07:4116#include "chrome/browser/browser_process.h"
[email protected]86c6b9e32011-10-25 17:09:1017#include "chrome/browser/profiles/profile.h"
18#include "chrome/common/chrome_switches.h"
[email protected]b0af4792013-10-23 09:12:1319#include "chrome/common/extensions/extension_constants.h"
[email protected]86c6b9e32011-10-25 17:09:1020#include "chrome/common/pref_names.h"
[email protected]f0c8c4992014-05-15 17:37:2621#include "components/pref_registry/pref_registry_syncable.h"
brettwb1fc1b82016-02-02 00:19:0822#include "components/prefs/pref_service.h"
sdefresne9fb67692015-08-03 18:48:2223#include "components/version_info/version_info.h"
Michael Giuffridae84fe6de2018-08-30 07:19:5224#include "extensions/common/constants.h"
[email protected]e4452d32013-11-15 23:07:4125#include "extensions/common/extension.h"
[email protected]86c6b9e32011-10-25 17:09:1026
[email protected]937cf9d2012-08-30 03:51:5527namespace {
28
[email protected]937cf9d2012-08-30 03:51:5529// Returns true if the app was a default app in Chrome 22
30bool IsOldDefaultApp(const std::string& extension_id) {
[email protected]b8096552013-05-04 15:48:1131 return extension_id == extension_misc::kGmailAppId ||
[email protected]b8096552013-05-04 15:48:1132 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();
thestig4b36dd32014-10-31 20:30:1941 static const char* const unsupported_locales[] = {"CN", "TR", "IR"};
Avi Drissman5f0fb8c2018-12-25 23:20:4942 for (size_t i = 0; i < base::size(unsupported_locales); ++i) {
brettwa7ff1b292015-07-16 17:49:2943 if (base::EndsWith(locale, unsupported_locales[i],
44 base::CompareCase::INSENSITIVE_ASCII)) {
[email protected]937cf9d2012-08-30 03:51:5545 return false;
46 }
47 }
48 return true;
49}
50
[email protected]b8096552013-05-04 15:48:1151} // namespace
[email protected]937cf9d2012-08-30 03:51:5552
[email protected]910f72ce2012-08-24 01:38:3553namespace default_apps {
54
[email protected]37ca3fe02013-07-05 15:32:4455void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
raymesaa608722015-04-27 03:00:2556 registry->RegisterIntegerPref(prefs::kDefaultAppsInstallState, kUnknown);
[email protected]937cf9d2012-08-30 03:51:5557}
58
59bool Provider::ShouldInstallInProfile() {
[email protected]86c6b9e32011-10-25 17:09:1060 // We decide to install or not install default apps based on the following
61 // criteria, from highest priority to lowest priority:
62 //
[email protected]86c6b9e32011-10-25 17:09:1063 // - The command line option. Tests use this option to disable installation
64 // of default apps in some cases.
65 // - If the locale is not compatible with the defaults, don't install them.
[email protected]86c6b9e32011-10-25 17:09:1066 // - The kDefaultApps preferences value in the profile. This value is
67 // usually set in the master_preferences file.
68 bool install_apps =
[email protected]937cf9d2012-08-30 03:51:5569 profile_->GetPrefs()->GetString(prefs::kDefaultApps) == "install";
[email protected]86c6b9e32011-10-25 17:09:1070
[email protected]937cf9d2012-08-30 03:51:5571 InstallState state =
72 static_cast<InstallState>(profile_->GetPrefs()->GetInteger(
[email protected]d190cef2011-11-09 02:09:2473 prefs::kDefaultAppsInstallState));
[email protected]910f72ce2012-08-24 01:38:3574
[email protected]937cf9d2012-08-30 03:51:5575 is_migration_ = (state == kProvideLegacyDefaultApps);
76
[email protected]86c6b9e32011-10-25 17:09:1077 switch (state) {
[email protected]937cf9d2012-08-30 03:51:5578 case kUnknown: {
sdefresne9fb67692015-08-03 18:48:2279 bool is_new_profile = profile_->WasCreatedByVersionOrLater(
80 version_info::GetVersionNumber());
David Roger8b4b8b562019-05-17 15:59:0481 if (!is_new_profile)
[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]9bf21b92012-10-04 21:01:39105 if (install_apps && !IsLocaleSupported())
[email protected]910f72ce2012-08-24 01:38:35106 install_apps = false;
[email protected]86c6b9e32011-10-25 17:09:10107
[email protected]910f72ce2012-08-24 01:38:35108 // Default apps are only installed on profile creation or a new chrome
109 // download.
[email protected]937cf9d2012-08-30 03:51:55110 if (state == kUnknown) {
[email protected]86c6b9e32011-10-25 17:09:10111 if (install_apps) {
[email protected]9bf21b92012-10-04 21:01:39112 profile_->GetPrefs()->SetInteger(prefs::kDefaultAppsInstallState,
113 kAlreadyInstalledDefaultApps);
[email protected]86c6b9e32011-10-25 17:09:10114 } else {
[email protected]937cf9d2012-08-30 03:51:55115 profile_->GetPrefs()->SetInteger(prefs::kDefaultAppsInstallState,
116 kNeverInstallDefaultApps);
[email protected]86c6b9e32011-10-25 17:09:10117 }
[email protected]86c6b9e32011-10-25 17:09:10118 }
119
120 return install_apps;
121}
122
[email protected]d190cef2011-11-09 02:09:24123Provider::Provider(Profile* profile,
124 VisitorInterface* service,
Matthew Dentonef83a622019-08-30 02:07:00125 scoped_refptr<extensions::ExternalLoader> loader,
[email protected]1d5e58b2013-01-31 08:41:40126 extensions::Manifest::Location crx_location,
127 extensions::Manifest::Location download_location,
[email protected]d190cef2011-11-09 02:09:24128 int creation_flags)
Matthew Dentonef83a622019-08-30 02:07:00129 : extensions::ExternalProviderImpl(service,
130 std::move(loader),
131 profile,
132 crx_location,
133 download_location,
134 creation_flags),
[email protected]e9a30af2012-10-04 01:56:25135 profile_(profile),
136 is_migration_(false) {
[email protected]d190cef2011-11-09 02:09:24137 DCHECK(profile);
[email protected]47fc70c2011-12-06 07:29:51138 set_auto_acknowledge(true);
[email protected]d190cef2011-11-09 02:09:24139}
140
141void Provider::VisitRegisteredExtension() {
[email protected]937cf9d2012-08-30 03:51:55142 if (!profile_ || !ShouldInstallInProfile()) {
Jinho Bangb5216cec2018-01-17 19:43:11143 SetPrefs(std::make_unique<base::DictionaryValue>());
[email protected]d190cef2011-11-09 02:09:24144 return;
145 }
146
[email protected]5df038b2012-07-16 19:03:27147 extensions::ExternalProviderImpl::VisitRegisteredExtension();
[email protected]d190cef2011-11-09 02:09:24148}
149
Istiaque Ahmeda7431b32017-08-20 18:33:37150void Provider::SetPrefs(std::unique_ptr<base::DictionaryValue> prefs) {
[email protected]937cf9d2012-08-30 03:51:55151 if (is_migration_) {
152 std::set<std::string> new_default_apps;
[email protected]023b3d12013-12-23 18:46:49153 for (base::DictionaryValue::Iterator i(*prefs); !i.IsAtEnd(); i.Advance()) {
[email protected]02d9b272013-03-06 12:54:56154 if (!IsOldDefaultApp(i.key()))
155 new_default_apps.insert(i.key());
[email protected]937cf9d2012-08-30 03:51:55156 }
157 // Filter out the new default apps for migrating users.
jdoerrie13cd648c82018-10-02 21:21:02158 for (auto it = new_default_apps.begin(); it != new_default_apps.end();
159 ++it) {
[email protected]937cf9d2012-08-30 03:51:55160 prefs->Remove(*it, NULL);
[email protected]910f72ce2012-08-24 01:38:35161 }
162 }
[email protected]937cf9d2012-08-30 03:51:55163
Istiaque Ahmeda7431b32017-08-20 18:33:37164 ExternalProviderImpl::SetPrefs(std::move(prefs));
[email protected]910f72ce2012-08-24 01:38:35165}
166
[email protected]86c6b9e32011-10-25 17:09:10167} // namespace default_apps