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.
4
5#include "chrome/browser/profiles/profile.h"
6
7#include <string>
8
9#include "base/prefs/pref_service.h"
10#include "build/build_config.h"
11#include "chrome/browser/chrome_notification_types.h"
12#include "chrome/browser/first_run/first_run.h"
13#include "chrome/browser/profiles/profile_manager.h"
14#include "chrome/browser/sync/profile_sync_service.h"
15#include "chrome/browser/sync/profile_sync_service_factory.h"
16#include "chrome/common/pref_names.h"
17#include "components/data_reduction_proxy/browser/data_reduction_proxy_prefs.h"
18#include "components/pref_registry/pref_registry_syncable.h"
19#include "components/sync_driver/sync_prefs.h"
20#include "content/public/browser/notification_service.h"
21#include "content/public/browser/notification_source.h"
22#include "content/public/browser/web_contents.h"
23#include "content/public/browser/web_ui.h"
24
25#if defined(OS_CHROMEOS)
26#include "base/command_line.h"
27#include "chrome/common/chrome_switches.h"
28#include "chromeos/chromeos_switches.h"
29#endif
30
31#if defined(OS_ANDROID) && defined(FULL_SAFE_BROWSING)
32#include "chrome/browser/safe_browsing/safe_browsing_service.h"
33#endif
34
35#if defined(ENABLE_EXTENSIONS)
36#include "extensions/browser/pref_names.h"
37#endif
38
39Profile::Profile()
40    : restored_last_session_(false),
41      sent_destroyed_notification_(false),
42      accessibility_pause_level_(0) {
43}
44
45Profile::~Profile() {
46}
47
48// static
49Profile* Profile::FromBrowserContext(content::BrowserContext* browser_context) {
50  // This is safe; this is the only implementation of the browser context.
51  return static_cast<Profile*>(browser_context);
52}
53
54// static
55Profile* Profile::FromWebUI(content::WebUI* web_ui) {
56  return FromBrowserContext(web_ui->GetWebContents()->GetBrowserContext());
57}
58
59TestingProfile* Profile::AsTestingProfile() {
60  return NULL;
61}
62
63Profile::Delegate::~Delegate() {
64}
65
66// static
67const char Profile::kProfileKey[] = "__PROFILE__";
68
69// static
70void Profile::RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
71  registry->RegisterBooleanPref(
72      prefs::kSearchSuggestEnabled,
73      true,
74      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
75#if defined(OS_ANDROID)
76  registry->RegisterStringPref(
77      prefs::kContextualSearchEnabled,
78      std::string(),
79      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
80#endif
81  registry->RegisterBooleanPref(
82      prefs::kSessionExitedCleanly,
83      true,
84      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
85  registry->RegisterStringPref(
86      prefs::kSessionExitType,
87      std::string(),
88      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
89#if defined(OS_ANDROID) && defined(FULL_SAFE_BROWSING)
90  // During Finch trail, safe browsing should be turned off
91  // by default, and not sync'ed with desktop.
92  // If we want to enable safe browsing on Android, we will
93  // need to remove this Android-specific code.
94  registry->RegisterBooleanPref(
95      prefs::kSafeBrowsingEnabled,
96      SafeBrowsingService::IsEnabledByFieldTrial(),
97      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
98#else
99  registry->RegisterBooleanPref(
100      prefs::kSafeBrowsingEnabled,
101      true,
102      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
103#endif
104  registry->RegisterBooleanPref(
105      prefs::kSafeBrowsingExtendedReportingEnabled,
106      false,
107      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
108  registry->RegisterBooleanPref(
109      prefs::kSafeBrowsingProceedAnywayDisabled,
110      false,
111      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
112  registry->RegisterBooleanPref(
113      prefs::kSafeBrowsingIncidentReportSent,
114      false,
115      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
116  registry->RegisterDictionaryPref(
117      prefs::kSafeBrowsingIncidentsSent,
118      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
119#if defined(ENABLE_GOOGLE_NOW)
120  registry->RegisterBooleanPref(
121      prefs::kGoogleGeolocationAccessEnabled,
122      false,
123      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
124#endif
125  registry->RegisterBooleanPref(
126      prefs::kDisableExtensions,
127      false,
128      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
129#if defined(ENABLE_EXTENSIONS)
130  registry->RegisterBooleanPref(
131      extensions::pref_names::kAlertsInitialized,
132      false,
133      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
134#endif
135  registry->RegisterStringPref(
136      prefs::kSelectFileLastDirectory,
137      std::string(),
138      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
139  registry->RegisterDoublePref(
140      prefs::kDefaultZoomLevel,
141      0.0,
142      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
143  registry->RegisterDictionaryPref(
144      prefs::kPerHostZoomLevels,
145      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
146  registry->RegisterStringPref(
147      prefs::kDefaultApps,
148      "install",
149      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
150  registry->RegisterBooleanPref(
151      prefs::kSpeechRecognitionFilterProfanities,
152      true,
153      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
154  registry->RegisterIntegerPref(
155      prefs::kProfileIconVersion,
156      0,
157      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
158#if defined(OS_CHROMEOS)
159  // TODO(dilmah): For OS_CHROMEOS we maintain kApplicationLocale in both
160  // local state and user's profile.  For other platforms we maintain
161  // kApplicationLocale only in local state.
162  // In the future we may want to maintain kApplicationLocale
163  // in user's profile for other platforms as well.
164  registry->RegisterStringPref(
165      prefs::kApplicationLocale,
166      std::string(),
167      user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
168  registry->RegisterStringPref(
169      prefs::kApplicationLocaleBackup,
170      std::string(),
171      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
172  registry->RegisterStringPref(
173      prefs::kApplicationLocaleAccepted,
174      std::string(),
175      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
176  registry->RegisterStringPref(
177      prefs::kCurrentWallpaperAppName,
178      std::string(),
179      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
180#endif
181
182#if defined(OS_ANDROID)
183  registry->RegisterBooleanPref(
184      prefs::kDevToolsRemoteEnabled,
185      false,
186      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
187#endif
188
189  data_reduction_proxy::RegisterSyncableProfilePrefs(registry);
190
191#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) && !defined(OS_IOS)
192  // Preferences related to the avatar bubble and user manager tutorials.
193  registry->RegisterIntegerPref(
194      prefs::kProfileAvatarTutorialShown,
195      0,
196      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
197#endif
198}
199
200std::string Profile::GetDebugName() {
201  std::string name = GetPath().BaseName().MaybeAsASCII();
202  if (name.empty()) {
203    name = "UnknownProfile";
204  }
205  return name;
206}
207
208bool Profile::IsGuestSession() const {
209#if defined(OS_CHROMEOS)
210  static bool is_guest_session = CommandLine::ForCurrentProcess()->HasSwitch(
211      chromeos::switches::kGuestSession);
212  return is_guest_session;
213#else
214  return GetPath() == ProfileManager::GetGuestProfilePath();
215#endif
216}
217
218bool Profile::IsNewProfile() {
219  // The profile has been shut down if the prefs were loaded from disk, unless
220  // first-run autoimport wrote them and reloaded the pref service.
221  // TODO(dconnelly): revisit this when crbug.com/22142 (unifying the profile
222  // import code) is fixed.
223  return GetOriginalProfile()->GetPrefs()->GetInitializationStatus() ==
224      PrefService::INITIALIZATION_STATUS_CREATED_NEW_PREF_STORE;
225}
226
227bool Profile::IsSyncAccessible() {
228  if (ProfileSyncServiceFactory::HasProfileSyncService(this))
229    return !ProfileSyncServiceFactory::GetForProfile(this)->IsManaged();
230
231  // No ProfileSyncService created yet - we don't want to create one, so just
232  // infer the accessible state by looking at prefs/command line flags.
233  sync_driver::SyncPrefs prefs(GetPrefs());
234  return ProfileSyncService::IsSyncEnabled() && !prefs.IsManaged();
235}
236
237void Profile::MaybeSendDestroyedNotification() {
238  if (!sent_destroyed_notification_) {
239    sent_destroyed_notification_ = true;
240    content::NotificationService::current()->Notify(
241        chrome::NOTIFICATION_PROFILE_DESTROYED,
242        content::Source<Profile>(this),
243        content::NotificationService::NoDetails());
244  }
245}
246
247bool ProfileCompare::operator()(Profile* a, Profile* b) const {
248  DCHECK(a && b);
249  if (a->IsSameProfile(b))
250    return false;
251  return a->GetOriginalProfile() < b->GetOriginalProfile();
252}
253