base::Time multiplicative operator overloading
[chromium-blink-merge.git] / chrome / browser / supervised_user / supervised_user_service.cc
blob316af32ac82554b2ed19d0640ba9730f00f905ab
1 // Copyright 2014 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/supervised_user/supervised_user_service.h"
7 #include "base/command_line.h"
8 #include "base/files/file_path.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/component_updater/supervised_user_whitelist_installer.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/profiles/profile_info_cache.h"
16 #include "chrome/browser/profiles/profile_manager.h"
17 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
18 #include "chrome/browser/signin/signin_manager_factory.h"
19 #include "chrome/browser/supervised_user/experimental/supervised_user_blacklist_downloader.h"
20 #include "chrome/browser/supervised_user/legacy/custodian_profile_downloader_service.h"
21 #include "chrome/browser/supervised_user/legacy/custodian_profile_downloader_service_factory.h"
22 #include "chrome/browser/supervised_user/legacy/permission_request_creator_sync.h"
23 #include "chrome/browser/supervised_user/legacy/supervised_user_pref_mapping_service.h"
24 #include "chrome/browser/supervised_user/legacy/supervised_user_pref_mapping_service_factory.h"
25 #include "chrome/browser/supervised_user/legacy/supervised_user_registration_utility.h"
26 #include "chrome/browser/supervised_user/legacy/supervised_user_shared_settings_service_factory.h"
27 #include "chrome/browser/supervised_user/supervised_user_constants.h"
28 #include "chrome/browser/supervised_user/supervised_user_service_observer.h"
29 #include "chrome/browser/supervised_user/supervised_user_settings_service.h"
30 #include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h"
31 #include "chrome/browser/supervised_user/supervised_user_site_list.h"
32 #include "chrome/browser/supervised_user/supervised_user_whitelist_service.h"
33 #include "chrome/browser/sync/profile_sync_service.h"
34 #include "chrome/browser/sync/profile_sync_service_factory.h"
35 #include "chrome/browser/ui/browser.h"
36 #include "chrome/browser/ui/browser_list.h"
37 #include "chrome/common/chrome_switches.h"
38 #include "chrome/common/pref_names.h"
39 #include "chrome/grit/generated_resources.h"
40 #include "components/pref_registry/pref_registry_syncable.h"
41 #include "components/signin/core/browser/profile_oauth2_token_service.h"
42 #include "components/signin/core/browser/signin_manager.h"
43 #include "components/signin/core/browser/signin_manager_base.h"
44 #include "content/public/browser/browser_thread.h"
45 #include "content/public/browser/user_metrics.h"
46 #include "ui/base/l10n/l10n_util.h"
48 #if defined(OS_CHROMEOS)
49 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
50 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
51 #include "components/user_manager/user_manager.h"
52 #endif
54 #if defined(ENABLE_EXTENSIONS)
55 #include "extensions/browser/extension_registry.h"
56 #include "extensions/browser/extension_system.h"
57 #endif
59 #if defined(ENABLE_THEMES)
60 #include "chrome/browser/themes/theme_service.h"
61 #include "chrome/browser/themes/theme_service_factory.h"
62 #endif
64 using base::DictionaryValue;
65 using base::UserMetricsAction;
66 using content::BrowserThread;
68 namespace {
70 const char* const kCustodianInfoPrefs[] = {
71 prefs::kSupervisedUserCustodianName,
72 prefs::kSupervisedUserCustodianEmail,
73 prefs::kSupervisedUserCustodianProfileImageURL,
74 prefs::kSupervisedUserCustodianProfileURL,
75 prefs::kSupervisedUserSecondCustodianName,
76 prefs::kSupervisedUserSecondCustodianEmail,
77 prefs::kSupervisedUserSecondCustodianProfileImageURL,
78 prefs::kSupervisedUserSecondCustodianProfileURL,
81 } // namespace
83 base::FilePath SupervisedUserService::Delegate::GetBlacklistPath() const {
84 return base::FilePath();
87 GURL SupervisedUserService::Delegate::GetBlacklistURL() const {
88 return GURL();
91 std::string SupervisedUserService::Delegate::GetSafeSitesCx() const {
92 return std::string();
95 SupervisedUserService::URLFilterContext::URLFilterContext()
96 : ui_url_filter_(new SupervisedUserURLFilter),
97 io_url_filter_(new SupervisedUserURLFilter) {}
98 SupervisedUserService::URLFilterContext::~URLFilterContext() {}
100 SupervisedUserURLFilter*
101 SupervisedUserService::URLFilterContext::ui_url_filter() const {
102 return ui_url_filter_.get();
105 SupervisedUserURLFilter*
106 SupervisedUserService::URLFilterContext::io_url_filter() const {
107 return io_url_filter_.get();
110 void SupervisedUserService::URLFilterContext::SetDefaultFilteringBehavior(
111 SupervisedUserURLFilter::FilteringBehavior behavior) {
112 ui_url_filter_->SetDefaultFilteringBehavior(behavior);
113 BrowserThread::PostTask(
114 BrowserThread::IO,
115 FROM_HERE,
116 base::Bind(&SupervisedUserURLFilter::SetDefaultFilteringBehavior,
117 io_url_filter_.get(), behavior));
120 void SupervisedUserService::URLFilterContext::LoadWhitelists(
121 const std::vector<scoped_refptr<SupervisedUserSiteList> >& site_lists) {
122 ui_url_filter_->LoadWhitelists(site_lists);
123 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
124 base::Bind(&SupervisedUserURLFilter::LoadWhitelists,
125 io_url_filter_, site_lists));
128 void SupervisedUserService::URLFilterContext::LoadBlacklist(
129 const base::FilePath& path,
130 const base::Closure& callback) {
131 // For now, support loading only once. If we want to support re-load, we'll
132 // have to clear the blacklist pointer in the url filters first.
133 DCHECK_EQ(0u, blacklist_.GetEntryCount());
134 blacklist_.ReadFromFile(
135 path,
136 base::Bind(&SupervisedUserService::URLFilterContext::OnBlacklistLoaded,
137 base::Unretained(this), callback));
140 void SupervisedUserService::URLFilterContext::SetManualHosts(
141 scoped_ptr<std::map<std::string, bool> > host_map) {
142 ui_url_filter_->SetManualHosts(host_map.get());
143 BrowserThread::PostTask(
144 BrowserThread::IO,
145 FROM_HERE,
146 base::Bind(&SupervisedUserURLFilter::SetManualHosts,
147 io_url_filter_, base::Owned(host_map.release())));
150 void SupervisedUserService::URLFilterContext::SetManualURLs(
151 scoped_ptr<std::map<GURL, bool> > url_map) {
152 ui_url_filter_->SetManualURLs(url_map.get());
153 BrowserThread::PostTask(
154 BrowserThread::IO,
155 FROM_HERE,
156 base::Bind(&SupervisedUserURLFilter::SetManualURLs,
157 io_url_filter_, base::Owned(url_map.release())));
160 void SupervisedUserService::URLFilterContext::Clear() {
161 ui_url_filter_->Clear();
162 BrowserThread::PostTask(
163 BrowserThread::IO,
164 FROM_HERE,
165 base::Bind(&SupervisedUserURLFilter::Clear,
166 io_url_filter_));
169 void SupervisedUserService::URLFilterContext::OnBlacklistLoaded(
170 const base::Closure& callback) {
171 ui_url_filter_->SetBlacklist(&blacklist_);
172 BrowserThread::PostTask(
173 BrowserThread::IO,
174 FROM_HERE,
175 base::Bind(&SupervisedUserURLFilter::SetBlacklist,
176 io_url_filter_,
177 &blacklist_));
178 callback.Run();
181 void SupervisedUserService::URLFilterContext::InitAsyncURLChecker(
182 const scoped_refptr<net::URLRequestContextGetter>& context,
183 const std::string& cx) {
184 ui_url_filter_->InitAsyncURLChecker(context.get(), cx);
185 BrowserThread::PostTask(
186 BrowserThread::IO,
187 FROM_HERE,
188 base::Bind(&SupervisedUserURLFilter::InitAsyncURLChecker,
189 io_url_filter_, context, cx));
192 SupervisedUserService::SupervisedUserService(Profile* profile)
193 : includes_sync_sessions_type_(true),
194 profile_(profile),
195 active_(false),
196 delegate_(NULL),
197 waiting_for_sync_initialization_(false),
198 is_profile_active_(false),
199 did_init_(false),
200 did_shutdown_(false),
201 weak_ptr_factory_(this) {
202 url_filter_context_.ui_url_filter()->AddObserver(this);
205 SupervisedUserService::~SupervisedUserService() {
206 DCHECK(!did_init_ || did_shutdown_);
207 url_filter_context_.ui_url_filter()->RemoveObserver(this);
210 void SupervisedUserService::Shutdown() {
211 if (!did_init_)
212 return;
213 DCHECK(!did_shutdown_);
214 did_shutdown_ = true;
215 if (ProfileIsSupervised()) {
216 content::RecordAction(UserMetricsAction("ManagedUsers_QuitBrowser"));
218 SetActive(false);
220 ProfileSyncService* sync_service =
221 ProfileSyncServiceFactory::GetForProfile(profile_);
222 // Can be null in tests.
223 if (sync_service)
224 sync_service->RemovePreferenceProvider(this);
227 bool SupervisedUserService::ProfileIsSupervised() const {
228 return profile_->IsSupervised();
231 void SupervisedUserService::OnCustodianInfoChanged() {
232 FOR_EACH_OBSERVER(
233 SupervisedUserServiceObserver, observer_list_, OnCustodianInfoChanged());
236 // static
237 void SupervisedUserService::RegisterProfilePrefs(
238 user_prefs::PrefRegistrySyncable* registry) {
239 registry->RegisterDictionaryPref(
240 prefs::kSupervisedUserManualHosts,
241 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
242 registry->RegisterDictionaryPref(
243 prefs::kSupervisedUserManualURLs,
244 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
245 registry->RegisterIntegerPref(
246 prefs::kDefaultSupervisedUserFilteringBehavior,
247 SupervisedUserURLFilter::ALLOW,
248 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
249 registry->RegisterBooleanPref(prefs::kSupervisedUserCreationAllowed, true,
250 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
251 for (const char* pref : kCustodianInfoPrefs) {
252 registry->RegisterStringPref(pref, std::string(),
253 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
257 void SupervisedUserService::SetDelegate(Delegate* delegate) {
258 if (delegate) {
259 // Changing delegates isn't allowed.
260 DCHECK(!delegate_);
261 } else {
262 // If the delegate is removed, deactivate first to give the old delegate a
263 // chance to clean up.
264 SetActive(false);
266 delegate_ = delegate;
269 scoped_refptr<const SupervisedUserURLFilter>
270 SupervisedUserService::GetURLFilterForIOThread() {
271 return url_filter_context_.io_url_filter();
274 SupervisedUserURLFilter* SupervisedUserService::GetURLFilterForUIThread() {
275 return url_filter_context_.ui_url_filter();
278 SupervisedUserWhitelistService* SupervisedUserService::GetWhitelistService() {
279 return whitelist_service_.get();
282 std::string SupervisedUserService::GetCustodianEmailAddress() const {
283 std::string custodian_email = profile_->GetPrefs()->GetString(
284 prefs::kSupervisedUserCustodianEmail);
285 #if defined(OS_CHROMEOS)
286 if (custodian_email.empty()) {
287 custodian_email = chromeos::ChromeUserManager::Get()
288 ->GetSupervisedUserManager()
289 ->GetManagerDisplayEmail(
290 user_manager::UserManager::Get()->GetActiveUser()->email());
292 #endif
293 return custodian_email;
296 std::string SupervisedUserService::GetCustodianName() const {
297 std::string name = profile_->GetPrefs()->GetString(
298 prefs::kSupervisedUserCustodianName);
299 #if defined(OS_CHROMEOS)
300 if (name.empty()) {
301 name = base::UTF16ToUTF8(chromeos::ChromeUserManager::Get()
302 ->GetSupervisedUserManager()
303 ->GetManagerDisplayName(
304 user_manager::UserManager::Get()->GetActiveUser()->email()));
306 #endif
307 return name.empty() ? GetCustodianEmailAddress() : name;
310 std::string SupervisedUserService::GetSecondCustodianEmailAddress() const {
311 return profile_->GetPrefs()->GetString(
312 prefs::kSupervisedUserSecondCustodianEmail);
315 std::string SupervisedUserService::GetSecondCustodianName() const {
316 std::string name = profile_->GetPrefs()->GetString(
317 prefs::kSupervisedUserSecondCustodianName);
318 return name.empty() ? GetSecondCustodianEmailAddress() : name;
321 void SupervisedUserService::AddNavigationBlockedCallback(
322 const NavigationBlockedCallback& callback) {
323 navigation_blocked_callbacks_.push_back(callback);
326 void SupervisedUserService::DidBlockNavigation(
327 content::WebContents* web_contents) {
328 for (const auto& callback : navigation_blocked_callbacks_)
329 callback.Run(web_contents);
332 void SupervisedUserService::AddObserver(
333 SupervisedUserServiceObserver* observer) {
334 observer_list_.AddObserver(observer);
337 void SupervisedUserService::RemoveObserver(
338 SupervisedUserServiceObserver* observer) {
339 observer_list_.RemoveObserver(observer);
342 void SupervisedUserService::AddPermissionRequestCreator(
343 scoped_ptr<PermissionRequestCreator> creator) {
344 permissions_creators_.push_back(creator.release());
347 #if defined(ENABLE_EXTENSIONS)
348 std::string SupervisedUserService::GetDebugPolicyProviderName() const {
349 // Save the string space in official builds.
350 #ifdef NDEBUG
351 NOTREACHED();
352 return std::string();
353 #else
354 return "Supervised User Service";
355 #endif
358 bool SupervisedUserService::UserMayLoad(const extensions::Extension* extension,
359 base::string16* error) const {
360 base::string16 tmp_error;
361 if (ExtensionManagementPolicyImpl(extension, &tmp_error))
362 return true;
364 bool was_installed_by_default = extension->was_installed_by_default();
365 bool was_installed_by_custodian = extension->was_installed_by_custodian();
366 #if defined(OS_CHROMEOS)
367 // On Chrome OS all external sources are controlled by us so it means that
368 // they are "default". Method was_installed_by_default returns false because
369 // extensions creation flags are ignored in case of default extensions with
370 // update URL(the flags aren't passed to OnExternalExtensionUpdateUrlFound).
371 // TODO(dpolukhin): remove this Chrome OS specific code as soon as creation
372 // flags are not ignored.
373 was_installed_by_default =
374 extensions::Manifest::IsExternalLocation(extension->location());
375 #endif
376 if (extensions::Manifest::IsComponentLocation(extension->location()) ||
377 was_installed_by_default ||
378 was_installed_by_custodian) {
379 return true;
382 if (error)
383 *error = tmp_error;
384 return false;
387 bool SupervisedUserService::UserMayModifySettings(
388 const extensions::Extension* extension,
389 base::string16* error) const {
390 return ExtensionManagementPolicyImpl(extension, error);
393 #endif // defined(ENABLE_EXTENSIONS)
395 syncer::ModelTypeSet SupervisedUserService::GetPreferredDataTypes() const {
396 if (!ProfileIsSupervised())
397 return syncer::ModelTypeSet();
399 syncer::ModelTypeSet result;
400 if (IncludesSyncSessionsType())
401 result.Put(syncer::SESSIONS);
402 result.Put(syncer::EXTENSIONS);
403 result.Put(syncer::EXTENSION_SETTINGS);
404 result.Put(syncer::APPS);
405 result.Put(syncer::APP_SETTINGS);
406 result.Put(syncer::APP_NOTIFICATIONS);
407 result.Put(syncer::APP_LIST);
408 return result;
411 void SupervisedUserService::OnHistoryRecordingStateChanged() {
412 bool record_history =
413 profile_->GetPrefs()->GetBoolean(prefs::kRecordHistory);
414 includes_sync_sessions_type_ = record_history;
415 ProfileSyncServiceFactory::GetForProfile(profile_)
416 ->ReconfigureDatatypeManager();
419 bool SupervisedUserService::IncludesSyncSessionsType() const {
420 return includes_sync_sessions_type_;
423 void SupervisedUserService::OnStateChanged() {
424 ProfileSyncService* service =
425 ProfileSyncServiceFactory::GetForProfile(profile_);
426 if (waiting_for_sync_initialization_ && service->backend_initialized() &&
427 service->backend_mode() == ProfileSyncService::SYNC) {
428 waiting_for_sync_initialization_ = false;
429 service->RemoveObserver(this);
430 FinishSetupSync();
431 return;
434 DLOG_IF(ERROR, service->GetAuthError().state() ==
435 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)
436 << "Credentials rejected";
439 void SupervisedUserService::SetupSync() {
440 StartSetupSync();
441 FinishSetupSyncWhenReady();
444 void SupervisedUserService::StartSetupSync() {
445 // Tell the sync service that setup is in progress so we don't start syncing
446 // until we've finished configuration.
447 ProfileSyncServiceFactory::GetForProfile(profile_)->SetSetupInProgress(true);
450 void SupervisedUserService::FinishSetupSyncWhenReady() {
451 // If we're already waiting for the Sync backend, there's nothing to do here.
452 if (waiting_for_sync_initialization_)
453 return;
455 // Continue in FinishSetupSync() once the Sync backend has been initialized.
456 ProfileSyncService* service =
457 ProfileSyncServiceFactory::GetForProfile(profile_);
458 if (service->backend_initialized() &&
459 service->backend_mode() == ProfileSyncService::SYNC) {
460 FinishSetupSync();
461 } else {
462 service->AddObserver(this);
463 waiting_for_sync_initialization_ = true;
467 void SupervisedUserService::FinishSetupSync() {
468 ProfileSyncService* service =
469 ProfileSyncServiceFactory::GetForProfile(profile_);
470 DCHECK(service->backend_initialized());
471 DCHECK(service->backend_mode() == ProfileSyncService::SYNC);
473 // Sync nothing (except types which are set via GetPreferredDataTypes).
474 bool sync_everything = false;
475 syncer::ModelTypeSet synced_datatypes;
476 service->OnUserChoseDatatypes(sync_everything, synced_datatypes);
478 // Notify ProfileSyncService that we are done with configuration.
479 service->SetSetupInProgress(false);
480 service->SetSyncSetupCompleted();
483 #if defined(ENABLE_EXTENSIONS)
484 bool SupervisedUserService::ExtensionManagementPolicyImpl(
485 const extensions::Extension* extension,
486 base::string16* error) const {
487 // |extension| can be NULL in unit_tests.
488 if (!ProfileIsSupervised() || (extension && extension->is_theme()))
489 return true;
491 if (error)
492 *error = l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_SUPERVISED_USER);
493 return false;
496 void SupervisedUserService::SetExtensionsActive() {
497 extensions::ExtensionSystem* extension_system =
498 extensions::ExtensionSystem::Get(profile_);
499 extensions::ManagementPolicy* management_policy =
500 extension_system->management_policy();
502 if (management_policy) {
503 if (active_)
504 management_policy->RegisterProvider(this);
505 else
506 management_policy->UnregisterProvider(this);
509 #endif // defined(ENABLE_EXTENSIONS)
511 SupervisedUserSettingsService* SupervisedUserService::GetSettingsService() {
512 return SupervisedUserSettingsServiceFactory::GetForProfile(profile_);
515 size_t SupervisedUserService::FindEnabledPermissionRequestCreator(
516 size_t start) {
517 for (size_t i = start; i < permissions_creators_.size(); ++i) {
518 if (permissions_creators_[i]->IsEnabled())
519 return i;
521 return permissions_creators_.size();
524 void SupervisedUserService::AddAccessRequestInternal(
525 const GURL& url,
526 const SuccessCallback& callback,
527 size_t index) {
528 // Find a permission request creator that is enabled.
529 size_t next_index = FindEnabledPermissionRequestCreator(index);
530 if (next_index >= permissions_creators_.size()) {
531 callback.Run(false);
532 return;
535 permissions_creators_[next_index]->CreatePermissionRequest(
536 url,
537 base::Bind(&SupervisedUserService::OnPermissionRequestIssued,
538 weak_ptr_factory_.GetWeakPtr(), url, callback, next_index));
541 void SupervisedUserService::OnPermissionRequestIssued(
542 const GURL& url,
543 const SuccessCallback& callback,
544 size_t index,
545 bool success) {
546 if (success) {
547 callback.Run(true);
548 return;
551 AddAccessRequestInternal(url, callback, index + 1);
554 void SupervisedUserService::OnSupervisedUserIdChanged() {
555 SetActive(ProfileIsSupervised());
558 void SupervisedUserService::OnDefaultFilteringBehaviorChanged() {
559 DCHECK(ProfileIsSupervised());
561 int behavior_value = profile_->GetPrefs()->GetInteger(
562 prefs::kDefaultSupervisedUserFilteringBehavior);
563 SupervisedUserURLFilter::FilteringBehavior behavior =
564 SupervisedUserURLFilter::BehaviorFromInt(behavior_value);
565 url_filter_context_.SetDefaultFilteringBehavior(behavior);
567 FOR_EACH_OBSERVER(
568 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
571 void SupervisedUserService::OnSiteListsChanged(
572 const std::vector<scoped_refptr<SupervisedUserSiteList> >& site_lists) {
573 url_filter_context_.LoadWhitelists(site_lists);
576 void SupervisedUserService::OnSiteListUpdated() {
577 FOR_EACH_OBSERVER(
578 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
581 void SupervisedUserService::LoadBlacklist(const base::FilePath& path,
582 const GURL& url) {
583 if (!url.is_valid()) {
584 LoadBlacklistFromFile(path);
585 return;
588 DCHECK(!blacklist_downloader_);
589 blacklist_downloader_.reset(new SupervisedUserBlacklistDownloader(
590 url,
591 path,
592 profile_->GetRequestContext(),
593 base::Bind(&SupervisedUserService::OnBlacklistDownloadDone,
594 base::Unretained(this), path)));
597 void SupervisedUserService::LoadBlacklistFromFile(const base::FilePath& path) {
598 // This object is guaranteed to outlive the URLFilterContext, so we can bind a
599 // raw pointer to it in the callback.
600 url_filter_context_.LoadBlacklist(
601 path, base::Bind(&SupervisedUserService::OnBlacklistLoaded,
602 base::Unretained(this)));
605 void SupervisedUserService::OnBlacklistDownloadDone(const base::FilePath& path,
606 bool success) {
607 if (success) {
608 LoadBlacklistFromFile(path);
609 } else {
610 LOG(WARNING) << "Blacklist download failed";
612 blacklist_downloader_.reset();
615 void SupervisedUserService::OnBlacklistLoaded() {
616 FOR_EACH_OBSERVER(
617 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
620 bool SupervisedUserService::AccessRequestsEnabled() {
621 return FindEnabledPermissionRequestCreator(0) < permissions_creators_.size();
624 void SupervisedUserService::AddAccessRequest(const GURL& url,
625 const SuccessCallback& callback) {
626 AddAccessRequestInternal(SupervisedUserURLFilter::Normalize(url), callback,
630 void SupervisedUserService::InitSync(const std::string& refresh_token) {
631 StartSetupSync();
633 ProfileOAuth2TokenService* token_service =
634 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
635 token_service->UpdateCredentials(supervised_users::kSupervisedUserPseudoEmail,
636 refresh_token);
638 FinishSetupSyncWhenReady();
641 void SupervisedUserService::Init() {
642 DCHECK(!did_init_);
643 did_init_ = true;
644 DCHECK(GetSettingsService()->IsReady());
646 pref_change_registrar_.Init(profile_->GetPrefs());
647 pref_change_registrar_.Add(
648 prefs::kSupervisedUserId,
649 base::Bind(&SupervisedUserService::OnSupervisedUserIdChanged,
650 base::Unretained(this)));
651 pref_change_registrar_.Add(
652 prefs::kRecordHistory,
653 base::Bind(&SupervisedUserService::OnHistoryRecordingStateChanged,
654 base::Unretained(this)));
656 ProfileSyncService* sync_service =
657 ProfileSyncServiceFactory::GetForProfile(profile_);
658 // Can be null in tests.
659 if (sync_service)
660 sync_service->AddPreferenceProvider(this);
662 std::string client_id = component_updater::SupervisedUserWhitelistInstaller::
663 ClientIdForProfilePath(profile_->GetPath());
664 whitelist_service_.reset(new SupervisedUserWhitelistService(
665 profile_->GetPrefs(),
666 g_browser_process->supervised_user_whitelist_installer(), client_id));
667 whitelist_service_->AddSiteListsChangedCallback(
668 base::Bind(&SupervisedUserService::OnSiteListsChanged,
669 weak_ptr_factory_.GetWeakPtr()));
671 SetActive(ProfileIsSupervised());
674 void SupervisedUserService::SetActive(bool active) {
675 if (active_ == active)
676 return;
677 active_ = active;
679 if (!delegate_ || !delegate_->SetActive(active_)) {
680 if (active_) {
681 SupervisedUserPrefMappingServiceFactory::GetForBrowserContext(profile_)
682 ->Init();
684 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
685 if (command_line->HasSwitch(switches::kSupervisedUserSyncToken)) {
686 InitSync(
687 command_line->GetSwitchValueASCII(
688 switches::kSupervisedUserSyncToken));
691 ProfileOAuth2TokenService* token_service =
692 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
693 token_service->LoadCredentials(
694 supervised_users::kSupervisedUserPseudoEmail);
696 permissions_creators_.push_back(new PermissionRequestCreatorSync(
697 GetSettingsService(),
698 SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext(
699 profile_),
700 ProfileSyncServiceFactory::GetForProfile(profile_),
701 GetSupervisedUserName(),
702 profile_->GetPrefs()->GetString(prefs::kSupervisedUserId)));
704 SetupSync();
708 // Now activate/deactivate anything not handled by the delegate yet.
710 #if defined(ENABLE_THEMES)
711 // Re-set the default theme to turn the SU theme on/off.
712 ThemeService* theme_service = ThemeServiceFactory::GetForProfile(profile_);
713 if (theme_service->UsingDefaultTheme() || theme_service->UsingSystemTheme()) {
714 ThemeServiceFactory::GetForProfile(profile_)->UseDefaultTheme();
716 #endif
718 ProfileSyncService* sync_service =
719 ProfileSyncServiceFactory::GetForProfile(profile_);
720 sync_service->SetEncryptEverythingAllowed(!active_);
722 GetSettingsService()->SetActive(active_);
724 #if defined(ENABLE_EXTENSIONS)
725 SetExtensionsActive();
726 #endif
728 if (active_) {
729 pref_change_registrar_.Add(
730 prefs::kDefaultSupervisedUserFilteringBehavior,
731 base::Bind(&SupervisedUserService::OnDefaultFilteringBehaviorChanged,
732 base::Unretained(this)));
733 pref_change_registrar_.Add(prefs::kSupervisedUserManualHosts,
734 base::Bind(&SupervisedUserService::UpdateManualHosts,
735 base::Unretained(this)));
736 pref_change_registrar_.Add(prefs::kSupervisedUserManualURLs,
737 base::Bind(&SupervisedUserService::UpdateManualURLs,
738 base::Unretained(this)));
739 for (const char* pref : kCustodianInfoPrefs) {
740 pref_change_registrar_.Add(pref,
741 base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
742 base::Unretained(this)));
745 // Initialize the filter.
746 OnDefaultFilteringBehaviorChanged();
747 whitelist_service_->Init();
748 UpdateManualHosts();
749 UpdateManualURLs();
750 bool use_blacklist = base::CommandLine::ForCurrentProcess()->HasSwitch(
751 switches::kEnableSupervisedUserBlacklist);
752 if (delegate_ && use_blacklist) {
753 base::FilePath blacklist_path = delegate_->GetBlacklistPath();
754 if (!blacklist_path.empty())
755 LoadBlacklist(blacklist_path, delegate_->GetBlacklistURL());
757 bool use_safesites = base::CommandLine::ForCurrentProcess()->HasSwitch(
758 switches::kEnableSupervisedUserSafeSites);
759 if (delegate_ && use_safesites) {
760 const std::string& cx = delegate_->GetSafeSitesCx();
761 if (!cx.empty()) {
762 url_filter_context_.InitAsyncURLChecker(
763 profile_->GetRequestContext(), cx);
767 #if !defined(OS_ANDROID)
768 // TODO(bauerb): Get rid of the platform-specific #ifdef here.
769 // http://crbug.com/313377
770 BrowserList::AddObserver(this);
771 #endif
772 } else {
773 permissions_creators_.clear();
775 pref_change_registrar_.Remove(
776 prefs::kDefaultSupervisedUserFilteringBehavior);
777 pref_change_registrar_.Remove(prefs::kSupervisedUserManualHosts);
778 pref_change_registrar_.Remove(prefs::kSupervisedUserManualURLs);
779 for (const char* pref : kCustodianInfoPrefs) {
780 pref_change_registrar_.Remove(pref);
783 url_filter_context_.Clear();
784 FOR_EACH_OBSERVER(
785 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
787 if (waiting_for_sync_initialization_)
788 ProfileSyncServiceFactory::GetForProfile(profile_)->RemoveObserver(this);
790 #if !defined(OS_ANDROID)
791 // TODO(bauerb): Get rid of the platform-specific #ifdef here.
792 // http://crbug.com/313377
793 BrowserList::RemoveObserver(this);
794 #endif
798 void SupervisedUserService::RegisterAndInitSync(
799 SupervisedUserRegistrationUtility* registration_utility,
800 Profile* custodian_profile,
801 const std::string& supervised_user_id,
802 const AuthErrorCallback& callback) {
803 DCHECK(ProfileIsSupervised());
804 DCHECK(!custodian_profile->IsSupervised());
806 base::string16 name = base::UTF8ToUTF16(
807 profile_->GetPrefs()->GetString(prefs::kProfileName));
808 int avatar_index = profile_->GetPrefs()->GetInteger(
809 prefs::kProfileAvatarIndex);
810 SupervisedUserRegistrationInfo info(name, avatar_index);
811 registration_utility->Register(
812 supervised_user_id,
813 info,
814 base::Bind(&SupervisedUserService::OnSupervisedUserRegistered,
815 weak_ptr_factory_.GetWeakPtr(), callback, custodian_profile));
817 // Fetch the custodian's profile information, to store the name.
818 // TODO(pamg): If --google-profile-info (flag: switches::kGoogleProfileInfo)
819 // is ever enabled, take the name from the ProfileInfoCache instead.
820 CustodianProfileDownloaderService* profile_downloader_service =
821 CustodianProfileDownloaderServiceFactory::GetForProfile(
822 custodian_profile);
823 profile_downloader_service->DownloadProfile(
824 base::Bind(&SupervisedUserService::OnCustodianProfileDownloaded,
825 weak_ptr_factory_.GetWeakPtr()));
828 void SupervisedUserService::OnCustodianProfileDownloaded(
829 const base::string16& full_name) {
830 profile_->GetPrefs()->SetString(prefs::kSupervisedUserCustodianName,
831 base::UTF16ToUTF8(full_name));
834 void SupervisedUserService::OnSupervisedUserRegistered(
835 const AuthErrorCallback& callback,
836 Profile* custodian_profile,
837 const GoogleServiceAuthError& auth_error,
838 const std::string& token) {
839 if (auth_error.state() == GoogleServiceAuthError::NONE) {
840 InitSync(token);
841 SigninManagerBase* signin =
842 SigninManagerFactory::GetForProfile(custodian_profile);
843 profile_->GetPrefs()->SetString(prefs::kSupervisedUserCustodianEmail,
844 signin->GetAuthenticatedUsername());
846 // The supervised user profile is now ready for use.
847 ProfileManager* profile_manager = g_browser_process->profile_manager();
848 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
849 size_t index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
850 cache.SetIsOmittedProfileAtIndex(index, false);
851 } else {
852 DCHECK_EQ(std::string(), token);
855 callback.Run(auth_error);
858 void SupervisedUserService::UpdateManualHosts() {
859 const base::DictionaryValue* dict =
860 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualHosts);
861 scoped_ptr<std::map<std::string, bool> > host_map(
862 new std::map<std::string, bool>());
863 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
864 bool allow = false;
865 bool result = it.value().GetAsBoolean(&allow);
866 DCHECK(result);
867 (*host_map)[it.key()] = allow;
869 url_filter_context_.SetManualHosts(host_map.Pass());
871 FOR_EACH_OBSERVER(
872 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
875 void SupervisedUserService::UpdateManualURLs() {
876 const base::DictionaryValue* dict =
877 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs);
878 scoped_ptr<std::map<GURL, bool> > url_map(new std::map<GURL, bool>());
879 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
880 bool allow = false;
881 bool result = it.value().GetAsBoolean(&allow);
882 DCHECK(result);
883 (*url_map)[GURL(it.key())] = allow;
885 url_filter_context_.SetManualURLs(url_map.Pass());
887 FOR_EACH_OBSERVER(
888 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
891 void SupervisedUserService::OnBrowserSetLastActive(Browser* browser) {
892 bool profile_became_active = profile_->IsSameProfile(browser->profile());
893 if (!is_profile_active_ && profile_became_active)
894 content::RecordAction(UserMetricsAction("ManagedUsers_OpenProfile"));
895 else if (is_profile_active_ && !profile_became_active)
896 content::RecordAction(UserMetricsAction("ManagedUsers_SwitchProfile"));
898 is_profile_active_ = profile_became_active;
901 std::string SupervisedUserService::GetSupervisedUserName() const {
902 #if defined(OS_CHROMEOS)
903 // The active user can be NULL in unit tests.
904 if (user_manager::UserManager::Get()->GetActiveUser()) {
905 return UTF16ToUTF8(user_manager::UserManager::Get()->GetUserDisplayName(
906 user_manager::UserManager::Get()->GetActiveUser()->GetUserID()));
908 return std::string();
909 #else
910 return profile_->GetPrefs()->GetString(prefs::kProfileName);
911 #endif