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/memory/ref_counted.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/extensions/extension_service.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/custodian_profile_downloader_service.h"
20 #include "chrome/browser/supervised_user/custodian_profile_downloader_service_factory.h"
21 #include "chrome/browser/supervised_user/permission_request_creator_apiary.h"
22 #include "chrome/browser/supervised_user/permission_request_creator_sync.h"
23 #include "chrome/browser/supervised_user/supervised_user_constants.h"
24 #include "chrome/browser/supervised_user/supervised_user_pref_mapping_service.h"
25 #include "chrome/browser/supervised_user/supervised_user_pref_mapping_service_factory.h"
26 #include "chrome/browser/supervised_user/supervised_user_registration_utility.h"
27 #include "chrome/browser/supervised_user/supervised_user_settings_service.h"
28 #include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h"
29 #include "chrome/browser/supervised_user/supervised_user_shared_settings_service_factory.h"
30 #include "chrome/browser/supervised_user/supervised_user_site_list.h"
31 #include "chrome/browser/supervised_user/supervised_user_sync_service.h"
32 #include "chrome/browser/supervised_user/supervised_user_sync_service_factory.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/extensions/api/managed_mode_private/managed_mode_handler.h"
39 #include "chrome/common/pref_names.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 "extensions/browser/extension_registry.h"
47 #include "extensions/browser/extension_system.h"
48 #include "extensions/common/extension_set.h"
49 #include "google_apis/gaia/google_service_auth_error.h"
50 #include "grit/generated_resources.h"
51 #include "net/base/escape.h"
52 #include "ui/base/l10n/l10n_util.h"
54 #if defined(OS_CHROMEOS)
55 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
56 #include "chrome/browser/chromeos/login/users/user_manager.h"
59 #if defined(ENABLE_THEMES)
60 #include "chrome/browser/themes/theme_service.h"
61 #include "chrome/browser/themes/theme_service_factory.h"
64 using base::DictionaryValue;
65 using base::UserMetricsAction;
66 using content::BrowserThread;
68 SupervisedUserService::URLFilterContext::URLFilterContext()
69 : ui_url_filter_(new SupervisedUserURLFilter),
70 io_url_filter_(new SupervisedUserURLFilter) {}
71 SupervisedUserService::URLFilterContext::~URLFilterContext() {}
73 SupervisedUserURLFilter*
74 SupervisedUserService::URLFilterContext::ui_url_filter() const {
75 return ui_url_filter_.get();
78 SupervisedUserURLFilter*
79 SupervisedUserService::URLFilterContext::io_url_filter() const {
80 return io_url_filter_.get();
83 void SupervisedUserService::URLFilterContext::SetDefaultFilteringBehavior(
84 SupervisedUserURLFilter::FilteringBehavior behavior) {
85 ui_url_filter_->SetDefaultFilteringBehavior(behavior);
86 BrowserThread::PostTask(
89 base::Bind(&SupervisedUserURLFilter::SetDefaultFilteringBehavior,
90 io_url_filter_.get(), behavior));
93 void SupervisedUserService::URLFilterContext::LoadWhitelists(
94 ScopedVector<SupervisedUserSiteList> site_lists) {
95 // SupervisedUserURLFilter::LoadWhitelists takes ownership of |site_lists|,
96 // so we make an additional copy of it.
97 /// TODO(bauerb): This is kinda ugly.
98 ScopedVector<SupervisedUserSiteList> site_lists_copy;
99 for (ScopedVector<SupervisedUserSiteList>::iterator it = site_lists.begin();
100 it != site_lists.end(); ++it) {
101 site_lists_copy.push_back((*it)->Clone());
103 ui_url_filter_->LoadWhitelists(site_lists.Pass());
104 BrowserThread::PostTask(
107 base::Bind(&SupervisedUserURLFilter::LoadWhitelists,
108 io_url_filter_, base::Passed(&site_lists_copy)));
111 void SupervisedUserService::URLFilterContext::SetManualHosts(
112 scoped_ptr<std::map<std::string, bool> > host_map) {
113 ui_url_filter_->SetManualHosts(host_map.get());
114 BrowserThread::PostTask(
117 base::Bind(&SupervisedUserURLFilter::SetManualHosts,
118 io_url_filter_, base::Owned(host_map.release())));
121 void SupervisedUserService::URLFilterContext::SetManualURLs(
122 scoped_ptr<std::map<GURL, bool> > url_map) {
123 ui_url_filter_->SetManualURLs(url_map.get());
124 BrowserThread::PostTask(
127 base::Bind(&SupervisedUserURLFilter::SetManualURLs,
128 io_url_filter_, base::Owned(url_map.release())));
131 SupervisedUserService::SupervisedUserService(Profile* profile)
135 extension_registry_observer_(this),
136 waiting_for_sync_initialization_(false),
137 is_profile_active_(false),
138 elevated_for_testing_(false),
139 did_shutdown_(false),
140 waiting_for_permissions_(false),
141 weak_ptr_factory_(this) {
144 SupervisedUserService::~SupervisedUserService() {
145 DCHECK(did_shutdown_);
148 void SupervisedUserService::Shutdown() {
149 did_shutdown_ = true;
150 if (ProfileIsSupervised()) {
151 content::RecordAction(UserMetricsAction("ManagedUsers_QuitBrowser"));
156 bool SupervisedUserService::ProfileIsSupervised() const {
157 return profile_->IsSupervised();
161 void SupervisedUserService::RegisterProfilePrefs(
162 user_prefs::PrefRegistrySyncable* registry) {
163 registry->RegisterDictionaryPref(
164 prefs::kSupervisedUserManualHosts,
165 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
166 registry->RegisterDictionaryPref(
167 prefs::kSupervisedUserManualURLs,
168 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
169 registry->RegisterIntegerPref(
170 prefs::kDefaultSupervisedUserFilteringBehavior,
171 SupervisedUserURLFilter::ALLOW,
172 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
173 registry->RegisterStringPref(
174 prefs::kSupervisedUserCustodianEmail, std::string(),
175 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
176 registry->RegisterStringPref(
177 prefs::kSupervisedUserCustodianName, std::string(),
178 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
179 registry->RegisterBooleanPref(prefs::kSupervisedUserCreationAllowed, true,
180 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
184 void SupervisedUserService::MigrateUserPrefs(PrefService* prefs) {
185 if (!prefs->HasPrefPath(prefs::kProfileIsSupervised))
188 bool is_supervised = prefs->GetBoolean(prefs::kProfileIsSupervised);
189 prefs->ClearPref(prefs::kProfileIsSupervised);
194 std::string supervised_user_id = prefs->GetString(prefs::kSupervisedUserId);
195 if (!supervised_user_id.empty())
198 prefs->SetString(prefs::kSupervisedUserId, "Dummy ID");
201 void SupervisedUserService::SetDelegate(Delegate* delegate) {
202 if (delegate_ == delegate)
204 // If the delegate changed, deactivate first to give the old delegate a chance
207 delegate_ = delegate;
210 scoped_refptr<const SupervisedUserURLFilter>
211 SupervisedUserService::GetURLFilterForIOThread() {
212 return url_filter_context_.io_url_filter();
215 SupervisedUserURLFilter* SupervisedUserService::GetURLFilterForUIThread() {
216 return url_filter_context_.ui_url_filter();
219 // Items not on any list must return -1 (CATEGORY_NOT_ON_LIST in history.js).
220 // Items on a list, but with no category, must return 0 (CATEGORY_OTHER).
221 #define CATEGORY_NOT_ON_LIST -1;
222 #define CATEGORY_OTHER 0;
224 int SupervisedUserService::GetCategory(const GURL& url) {
225 std::vector<SupervisedUserSiteList::Site*> sites;
226 GetURLFilterForUIThread()->GetSites(url, &sites);
228 return CATEGORY_NOT_ON_LIST;
230 return (*sites.begin())->category_id;
234 void SupervisedUserService::GetCategoryNames(CategoryList* list) {
235 SupervisedUserSiteList::GetCategoryNames(list);
238 std::string SupervisedUserService::GetCustodianEmailAddress() const {
239 #if defined(OS_CHROMEOS)
240 return chromeos::UserManager::Get()->GetSupervisedUserManager()->
241 GetManagerDisplayEmail(
242 chromeos::UserManager::Get()->GetActiveUser()->email());
244 return profile_->GetPrefs()->GetString(prefs::kSupervisedUserCustodianEmail);
248 std::string SupervisedUserService::GetCustodianName() const {
249 #if defined(OS_CHROMEOS)
250 return base::UTF16ToUTF8(chromeos::UserManager::Get()->
251 GetSupervisedUserManager()->GetManagerDisplayName(
252 chromeos::UserManager::Get()->GetActiveUser()->email()));
254 std::string name = profile_->GetPrefs()->GetString(
255 prefs::kSupervisedUserCustodianName);
256 return name.empty() ? GetCustodianEmailAddress() : name;
260 void SupervisedUserService::AddNavigationBlockedCallback(
261 const NavigationBlockedCallback& callback) {
262 navigation_blocked_callbacks_.push_back(callback);
265 void SupervisedUserService::DidBlockNavigation(
266 content::WebContents* web_contents) {
267 for (std::vector<NavigationBlockedCallback>::iterator it =
268 navigation_blocked_callbacks_.begin();
269 it != navigation_blocked_callbacks_.end(); ++it) {
270 it->Run(web_contents);
274 std::string SupervisedUserService::GetDebugPolicyProviderName() const {
275 // Save the string space in official builds.
278 return std::string();
280 return "Supervised User Service";
284 bool SupervisedUserService::UserMayLoad(const extensions::Extension* extension,
285 base::string16* error) const {
286 base::string16 tmp_error;
287 if (ExtensionManagementPolicyImpl(extension, &tmp_error))
290 // If the extension is already loaded, we allow it, otherwise we'd unload
291 // all existing extensions.
292 ExtensionService* extension_service =
293 extensions::ExtensionSystem::Get(profile_)->extension_service();
295 // |extension_service| can be NULL in a unit test.
296 if (extension_service &&
297 extension_service->GetInstalledExtension(extension->id()))
300 bool was_installed_by_default = extension->was_installed_by_default();
301 #if defined(OS_CHROMEOS)
302 // On Chrome OS all external sources are controlled by us so it means that
303 // they are "default". Method was_installed_by_default returns false because
304 // extensions creation flags are ignored in case of default extensions with
305 // update URL(the flags aren't passed to OnExternalExtensionUpdateUrlFound).
306 // TODO(dpolukhin): remove this Chrome OS specific code as soon as creation
307 // flags are not ignored.
308 was_installed_by_default =
309 extensions::Manifest::IsExternalLocation(extension->location());
311 if (extension->location() == extensions::Manifest::COMPONENT ||
312 was_installed_by_default) {
321 bool SupervisedUserService::UserMayModifySettings(
322 const extensions::Extension* extension,
323 base::string16* error) const {
324 return ExtensionManagementPolicyImpl(extension, error);
327 void SupervisedUserService::OnStateChanged() {
328 ProfileSyncService* service =
329 ProfileSyncServiceFactory::GetForProfile(profile_);
330 if (waiting_for_sync_initialization_ && service->sync_initialized()) {
331 waiting_for_sync_initialization_ = false;
332 service->RemoveObserver(this);
337 DLOG_IF(ERROR, service->GetAuthError().state() ==
338 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)
339 << "Credentials rejected";
342 void SupervisedUserService::OnExtensionLoaded(
343 content::BrowserContext* browser_context,
344 const extensions::Extension* extension) {
345 if (!extensions::ManagedModeInfo::GetContentPackSiteList(extension).empty()) {
349 void SupervisedUserService::OnExtensionUnloaded(
350 content::BrowserContext* browser_context,
351 const extensions::Extension* extension,
352 extensions::UnloadedExtensionInfo::Reason reason) {
353 if (!extensions::ManagedModeInfo::GetContentPackSiteList(extension).empty()) {
358 void SupervisedUserService::SetupSync() {
359 ProfileSyncService* service =
360 ProfileSyncServiceFactory::GetForProfile(profile_);
361 DCHECK(service->sync_initialized());
363 bool sync_everything = false;
364 syncer::ModelTypeSet synced_datatypes;
365 synced_datatypes.Put(syncer::SUPERVISED_USER_SETTINGS);
366 service->OnUserChoseDatatypes(sync_everything, synced_datatypes);
368 // Notify ProfileSyncService that we are done with configuration.
369 service->SetSetupInProgress(false);
370 service->SetSyncSetupCompleted();
373 bool SupervisedUserService::ExtensionManagementPolicyImpl(
374 const extensions::Extension* extension,
375 base::string16* error) const {
376 // |extension| can be NULL in unit_tests.
377 if (!ProfileIsSupervised() || (extension && extension->is_theme()))
380 if (elevated_for_testing_)
384 *error = l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_MANAGED_USER);
388 ScopedVector<SupervisedUserSiteList>
389 SupervisedUserService::GetActiveSiteLists() {
390 ScopedVector<SupervisedUserSiteList> site_lists;
391 ExtensionService* extension_service =
392 extensions::ExtensionSystem::Get(profile_)->extension_service();
393 // Can be NULL in unit tests.
394 if (!extension_service)
395 return site_lists.Pass();
397 const extensions::ExtensionSet* extensions = extension_service->extensions();
398 for (extensions::ExtensionSet::const_iterator it = extensions->begin();
399 it != extensions->end(); ++it) {
400 const extensions::Extension* extension = it->get();
401 if (!extension_service->IsExtensionEnabled(extension->id()))
404 extensions::ExtensionResource site_list =
405 extensions::ManagedModeInfo::GetContentPackSiteList(extension);
406 if (!site_list.empty()) {
407 site_lists.push_back(new SupervisedUserSiteList(extension->id(),
408 site_list.GetFilePath()));
412 return site_lists.Pass();
415 SupervisedUserSettingsService* SupervisedUserService::GetSettingsService() {
416 return SupervisedUserSettingsServiceFactory::GetForProfile(profile_);
419 void SupervisedUserService::OnSupervisedUserIdChanged() {
420 std::string supervised_user_id =
421 profile_->GetPrefs()->GetString(prefs::kSupervisedUserId);
422 SetActive(!supervised_user_id.empty());
425 void SupervisedUserService::OnDefaultFilteringBehaviorChanged() {
426 DCHECK(ProfileIsSupervised());
428 int behavior_value = profile_->GetPrefs()->GetInteger(
429 prefs::kDefaultSupervisedUserFilteringBehavior);
430 SupervisedUserURLFilter::FilteringBehavior behavior =
431 SupervisedUserURLFilter::BehaviorFromInt(behavior_value);
432 url_filter_context_.SetDefaultFilteringBehavior(behavior);
435 void SupervisedUserService::UpdateSiteLists() {
436 url_filter_context_.LoadWhitelists(GetActiveSiteLists());
439 bool SupervisedUserService::AccessRequestsEnabled() {
440 if (waiting_for_permissions_)
443 ProfileSyncService* service =
444 ProfileSyncServiceFactory::GetForProfile(profile_);
445 GoogleServiceAuthError::State state = service->GetAuthError().state();
446 // We allow requesting access if Sync is working or has a transient error.
447 return (state == GoogleServiceAuthError::NONE ||
448 state == GoogleServiceAuthError::CONNECTION_FAILED ||
449 state == GoogleServiceAuthError::SERVICE_UNAVAILABLE);
452 void SupervisedUserService::OnPermissionRequestIssued() {
453 waiting_for_permissions_ = false;
454 // TODO(akuegel): Figure out how to show the result of issuing the permission
455 // request in the UI. Currently, we assume the permission request was created
459 void SupervisedUserService::AddAccessRequest(const GURL& url) {
460 // Normalize the URL.
461 GURL normalized_url = SupervisedUserURLFilter::Normalize(url);
464 std::string output(net::EscapeQueryParamValue(normalized_url.spec(), true));
466 waiting_for_permissions_ = true;
467 permissions_creator_->CreatePermissionRequest(
469 base::Bind(&SupervisedUserService::OnPermissionRequestIssued,
470 weak_ptr_factory_.GetWeakPtr()));
473 SupervisedUserService::ManualBehavior
474 SupervisedUserService::GetManualBehaviorForHost(
475 const std::string& hostname) {
476 const base::DictionaryValue* dict =
477 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualHosts);
479 if (!dict->GetBooleanWithoutPathExpansion(hostname, &allow))
482 return allow ? MANUAL_ALLOW : MANUAL_BLOCK;
485 SupervisedUserService::ManualBehavior
486 SupervisedUserService::GetManualBehaviorForURL(
488 const base::DictionaryValue* dict =
489 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs);
490 GURL normalized_url = SupervisedUserURLFilter::Normalize(url);
492 if (!dict->GetBooleanWithoutPathExpansion(normalized_url.spec(), &allow))
495 return allow ? MANUAL_ALLOW : MANUAL_BLOCK;
498 void SupervisedUserService::GetManualExceptionsForHost(
499 const std::string& host,
500 std::vector<GURL>* urls) {
501 const base::DictionaryValue* dict =
502 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs);
503 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
505 if (url.host() == host)
506 urls->push_back(url);
510 void SupervisedUserService::InitSync(const std::string& refresh_token) {
511 ProfileSyncService* service =
512 ProfileSyncServiceFactory::GetForProfile(profile_);
513 // Tell the sync service that setup is in progress so we don't start syncing
514 // until we've finished configuration.
515 service->SetSetupInProgress(true);
517 ProfileOAuth2TokenService* token_service =
518 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
519 token_service->UpdateCredentials(supervised_users::kSupervisedUserPseudoEmail,
522 // Continue in SetupSync() once the Sync backend has been initialized.
523 if (service->sync_initialized()) {
526 ProfileSyncServiceFactory::GetForProfile(profile_)->AddObserver(this);
527 waiting_for_sync_initialization_ = true;
531 void SupervisedUserService::Init() {
532 DCHECK(GetSettingsService()->IsReady());
534 pref_change_registrar_.Init(profile_->GetPrefs());
535 pref_change_registrar_.Add(
536 prefs::kSupervisedUserId,
537 base::Bind(&SupervisedUserService::OnSupervisedUserIdChanged,
538 base::Unretained(this)));
540 SetActive(ProfileIsSupervised());
543 void SupervisedUserService::SetActive(bool active) {
544 if (active_ == active)
548 if (!delegate_ || !delegate_->SetActive(active_)) {
550 SupervisedUserPrefMappingServiceFactory::GetForBrowserContext(profile_)
553 CommandLine* command_line = CommandLine::ForCurrentProcess();
554 if (command_line->HasSwitch(switches::kSupervisedUserSyncToken)) {
556 command_line->GetSwitchValueASCII(
557 switches::kSupervisedUserSyncToken));
560 ProfileOAuth2TokenService* token_service =
561 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
562 token_service->LoadCredentials(
563 supervised_users::kSupervisedUserPseudoEmail);
567 // Now activate/deactivate anything not handled by the delegate yet.
569 #if defined(ENABLE_THEMES)
570 // Re-set the default theme to turn the SU theme on/off.
571 ThemeService* theme_service = ThemeServiceFactory::GetForProfile(profile_);
572 if (theme_service->UsingDefaultTheme() || theme_service->UsingSystemTheme()) {
573 ThemeServiceFactory::GetForProfile(profile_)->UseDefaultTheme();
577 SupervisedUserSettingsService* settings_service = GetSettingsService();
578 settings_service->SetActive(active_);
580 extensions::ExtensionSystem* extension_system =
581 extensions::ExtensionSystem::Get(profile_);
582 extensions::ManagementPolicy* management_policy =
583 extension_system->management_policy();
586 if (CommandLine::ForCurrentProcess()->HasSwitch(
587 switches::kPermissionRequestApiUrl)) {
588 permissions_creator_ =
589 PermissionRequestCreatorApiary::CreateWithProfile(profile_);
591 PrefService* pref_service = profile_->GetPrefs();
592 permissions_creator_.reset(new PermissionRequestCreatorSync(
594 SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext(
596 GetSupervisedUserName(),
597 pref_service->GetString(prefs::kSupervisedUserId)));
600 if (management_policy)
601 management_policy->RegisterProvider(this);
603 extension_registry_observer_.Add(
604 extensions::ExtensionRegistry::Get(profile_));
606 pref_change_registrar_.Add(
607 prefs::kDefaultSupervisedUserFilteringBehavior,
608 base::Bind(&SupervisedUserService::OnDefaultFilteringBehaviorChanged,
609 base::Unretained(this)));
610 pref_change_registrar_.Add(prefs::kSupervisedUserManualHosts,
611 base::Bind(&SupervisedUserService::UpdateManualHosts,
612 base::Unretained(this)));
613 pref_change_registrar_.Add(prefs::kSupervisedUserManualURLs,
614 base::Bind(&SupervisedUserService::UpdateManualURLs,
615 base::Unretained(this)));
617 // Initialize the filter.
618 OnDefaultFilteringBehaviorChanged();
623 #if !defined(OS_ANDROID)
624 // TODO(bauerb): Get rid of the platform-specific #ifdef here.
625 // http://crbug.com/313377
626 BrowserList::AddObserver(this);
629 permissions_creator_.reset();
631 if (management_policy)
632 management_policy->UnregisterProvider(this);
634 extension_registry_observer_.RemoveAll();
636 pref_change_registrar_.Remove(
637 prefs::kDefaultSupervisedUserFilteringBehavior);
638 pref_change_registrar_.Remove(prefs::kSupervisedUserManualHosts);
639 pref_change_registrar_.Remove(prefs::kSupervisedUserManualURLs);
641 if (waiting_for_sync_initialization_) {
642 ProfileSyncService* sync_service =
643 ProfileSyncServiceFactory::GetForProfile(profile_);
644 sync_service->RemoveObserver(this);
647 #if !defined(OS_ANDROID)
648 // TODO(bauerb): Get rid of the platform-specific #ifdef here.
649 // http://crbug.com/313377
650 BrowserList::RemoveObserver(this);
655 void SupervisedUserService::RegisterAndInitSync(
656 SupervisedUserRegistrationUtility* registration_utility,
657 Profile* custodian_profile,
658 const std::string& supervised_user_id,
659 const AuthErrorCallback& callback) {
660 DCHECK(ProfileIsSupervised());
661 DCHECK(!custodian_profile->IsSupervised());
663 base::string16 name = base::UTF8ToUTF16(
664 profile_->GetPrefs()->GetString(prefs::kProfileName));
665 int avatar_index = profile_->GetPrefs()->GetInteger(
666 prefs::kProfileAvatarIndex);
667 SupervisedUserRegistrationInfo info(name, avatar_index);
668 registration_utility->Register(
671 base::Bind(&SupervisedUserService::OnSupervisedUserRegistered,
672 weak_ptr_factory_.GetWeakPtr(), callback, custodian_profile));
674 // Fetch the custodian's profile information, to store the name.
675 // TODO(pamg): If --google-profile-info (flag: switches::kGoogleProfileInfo)
676 // is ever enabled, take the name from the ProfileInfoCache instead.
677 CustodianProfileDownloaderService* profile_downloader_service =
678 CustodianProfileDownloaderServiceFactory::GetForProfile(
680 profile_downloader_service->DownloadProfile(
681 base::Bind(&SupervisedUserService::OnCustodianProfileDownloaded,
682 weak_ptr_factory_.GetWeakPtr()));
685 void SupervisedUserService::OnCustodianProfileDownloaded(
686 const base::string16& full_name) {
687 profile_->GetPrefs()->SetString(prefs::kSupervisedUserCustodianName,
688 base::UTF16ToUTF8(full_name));
691 void SupervisedUserService::OnSupervisedUserRegistered(
692 const AuthErrorCallback& callback,
693 Profile* custodian_profile,
694 const GoogleServiceAuthError& auth_error,
695 const std::string& token) {
696 if (auth_error.state() == GoogleServiceAuthError::NONE) {
698 SigninManagerBase* signin =
699 SigninManagerFactory::GetForProfile(custodian_profile);
700 profile_->GetPrefs()->SetString(prefs::kSupervisedUserCustodianEmail,
701 signin->GetAuthenticatedUsername());
703 // The supervised user profile is now ready for use.
704 ProfileManager* profile_manager = g_browser_process->profile_manager();
705 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
706 size_t index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
707 cache.SetIsOmittedProfileAtIndex(index, false);
709 DCHECK_EQ(std::string(), token);
712 callback.Run(auth_error);
715 void SupervisedUserService::UpdateManualHosts() {
716 const base::DictionaryValue* dict =
717 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualHosts);
718 scoped_ptr<std::map<std::string, bool> > host_map(
719 new std::map<std::string, bool>());
720 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
722 bool result = it.value().GetAsBoolean(&allow);
724 (*host_map)[it.key()] = allow;
726 url_filter_context_.SetManualHosts(host_map.Pass());
729 void SupervisedUserService::UpdateManualURLs() {
730 const base::DictionaryValue* dict =
731 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs);
732 scoped_ptr<std::map<GURL, bool> > url_map(new std::map<GURL, bool>());
733 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
735 bool result = it.value().GetAsBoolean(&allow);
737 (*url_map)[GURL(it.key())] = allow;
739 url_filter_context_.SetManualURLs(url_map.Pass());
742 void SupervisedUserService::OnBrowserSetLastActive(Browser* browser) {
743 bool profile_became_active = profile_->IsSameProfile(browser->profile());
744 if (!is_profile_active_ && profile_became_active)
745 content::RecordAction(UserMetricsAction("ManagedUsers_OpenProfile"));
746 else if (is_profile_active_ && !profile_became_active)
747 content::RecordAction(UserMetricsAction("ManagedUsers_SwitchProfile"));
749 is_profile_active_ = profile_became_active;
752 std::string SupervisedUserService::GetSupervisedUserName() const {
753 #if defined(OS_CHROMEOS)
754 // The active user can be NULL in unit tests.
755 if (chromeos::UserManager::Get()->GetActiveUser()) {
756 return UTF16ToUTF8(chromeos::UserManager::Get()->GetUserDisplayName(
757 chromeos::UserManager::Get()->GetActiveUser()->GetUserID()));
759 return std::string();
761 return profile_->GetPrefs()->GetString(prefs::kProfileName);