1 // Copyright (c) 2013 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/managed_mode/managed_user_service.h"
7 #include "base/command_line.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/metrics/field_trial.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/prefs/scoped_user_pref_update.h"
12 #include "base/sequenced_task_runner.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/extensions/extension_service.h"
17 #include "chrome/browser/extensions/extension_system.h"
18 #include "chrome/browser/managed_mode/custodian_profile_downloader_service.h"
19 #include "chrome/browser/managed_mode/custodian_profile_downloader_service_factory.h"
20 #include "chrome/browser/managed_mode/managed_mode_site_list.h"
21 #include "chrome/browser/managed_mode/managed_user_constants.h"
22 #include "chrome/browser/managed_mode/managed_user_registration_utility.h"
23 #include "chrome/browser/managed_mode/managed_user_settings_service.h"
24 #include "chrome/browser/managed_mode/managed_user_settings_service_factory.h"
25 #include "chrome/browser/managed_mode/managed_user_sync_service.h"
26 #include "chrome/browser/managed_mode/managed_user_sync_service_factory.h"
27 #include "chrome/browser/profiles/profile.h"
28 #include "chrome/browser/signin/signin_manager.h"
29 #include "chrome/browser/signin/signin_manager_base.h"
30 #include "chrome/browser/signin/signin_manager_factory.h"
31 #include "chrome/browser/signin/token_service.h"
32 #include "chrome/browser/signin/token_service_factory.h"
33 #include "chrome/browser/sync/glue/session_model_associator.h"
34 #include "chrome/browser/sync/profile_sync_service.h"
35 #include "chrome/browser/sync/profile_sync_service_factory.h"
36 #include "chrome/browser/ui/browser.h"
37 #include "chrome/browser/ui/browser_list.h"
38 #include "chrome/browser/ui/tabs/tab_strip_model.h"
39 #include "chrome/common/chrome_switches.h"
40 #include "chrome/common/extensions/api/managed_mode_private/managed_mode_handler.h"
41 #include "chrome/common/extensions/extension_set.h"
42 #include "chrome/common/pref_names.h"
43 #include "components/user_prefs/pref_registry_syncable.h"
44 #include "content/public/browser/browser_thread.h"
45 #include "content/public/browser/notification_details.h"
46 #include "content/public/browser/notification_source.h"
47 #include "google_apis/gaia/gaia_constants.h"
48 #include "google_apis/gaia/google_service_auth_error.h"
49 #include "grit/generated_resources.h"
50 #include "net/base/escape.h"
51 #include "ui/base/l10n/l10n_util.h"
53 #if defined(OS_CHROMEOS)
54 #include "chrome/browser/chromeos/login/supervised_user_manager.h"
55 #include "chrome/browser/chromeos/login/user_manager.h"
58 using base::DictionaryValue;
60 using content::BrowserThread;
64 const char kManagedModeFinchActive[] = "Active";
65 const char kManagedModeFinchName[] = "ManagedModeLaunch";
66 const char kManagedUserAccessRequestKeyPrefix[] =
67 "X-ManagedUser-AccessRequests";
68 const char kManagedUserAccessRequestTime[] = "timestamp";
69 const char kManagedUserPseudoEmail[] = "managed_user@localhost";
70 const char kOpenManagedProfileKeyPrefix[] = "X-ManagedUser-Events-OpenProfile";
71 const char kQuitBrowserKeyPrefix[] = "X-ManagedUser-Events-QuitBrowser";
72 const char kSwitchFromManagedProfileKeyPrefix[] =
73 "X-ManagedUser-Events-SwitchProfile";
74 const char kEventTimestamp[] = "timestamp";
76 std::string CanonicalizeHostname(const std::string& hostname) {
77 std::string canonicalized;
78 url_canon::StdStringCanonOutput output(&canonicalized);
79 url_parse::Component in_comp(0, hostname.length());
80 url_parse::Component out_comp;
82 url_canon::CanonicalizeHost(hostname.c_str(), in_comp, &output, &out_comp);
89 ManagedUserService::URLFilterContext::URLFilterContext()
90 : ui_url_filter_(new ManagedModeURLFilter),
91 io_url_filter_(new ManagedModeURLFilter) {}
92 ManagedUserService::URLFilterContext::~URLFilterContext() {}
95 ManagedUserService::URLFilterContext::ui_url_filter() const {
96 return ui_url_filter_.get();
100 ManagedUserService::URLFilterContext::io_url_filter() const {
101 return io_url_filter_.get();
104 void ManagedUserService::URLFilterContext::SetDefaultFilteringBehavior(
105 ManagedModeURLFilter::FilteringBehavior behavior) {
106 ui_url_filter_->SetDefaultFilteringBehavior(behavior);
107 BrowserThread::PostTask(
110 base::Bind(&ManagedModeURLFilter::SetDefaultFilteringBehavior,
111 io_url_filter_.get(), behavior));
114 void ManagedUserService::URLFilterContext::LoadWhitelists(
115 ScopedVector<ManagedModeSiteList> site_lists) {
116 // ManagedModeURLFilter::LoadWhitelists takes ownership of |site_lists|,
117 // so we make an additional copy of it.
118 /// TODO(bauerb): This is kinda ugly.
119 ScopedVector<ManagedModeSiteList> site_lists_copy;
120 for (ScopedVector<ManagedModeSiteList>::iterator it = site_lists.begin();
121 it != site_lists.end(); ++it) {
122 site_lists_copy.push_back((*it)->Clone());
124 ui_url_filter_->LoadWhitelists(site_lists.Pass());
125 BrowserThread::PostTask(
128 base::Bind(&ManagedModeURLFilter::LoadWhitelists,
129 io_url_filter_, base::Passed(&site_lists_copy)));
132 void ManagedUserService::URLFilterContext::SetManualHosts(
133 scoped_ptr<std::map<std::string, bool> > host_map) {
134 ui_url_filter_->SetManualHosts(host_map.get());
135 BrowserThread::PostTask(
138 base::Bind(&ManagedModeURLFilter::SetManualHosts,
139 io_url_filter_, base::Owned(host_map.release())));
142 void ManagedUserService::URLFilterContext::SetManualURLs(
143 scoped_ptr<std::map<GURL, bool> > url_map) {
144 ui_url_filter_->SetManualURLs(url_map.get());
145 BrowserThread::PostTask(
148 base::Bind(&ManagedModeURLFilter::SetManualURLs,
149 io_url_filter_, base::Owned(url_map.release())));
152 ManagedUserService::ManagedUserService(Profile* profile)
153 : weak_ptr_factory_(this),
155 waiting_for_sync_initialization_(false),
156 is_profile_active_(false),
157 elevated_for_testing_(false),
158 did_shutdown_(false) {
161 ManagedUserService::~ManagedUserService() {
162 DCHECK(did_shutdown_);
165 void ManagedUserService::Shutdown() {
166 did_shutdown_ = true;
167 if (ProfileIsManaged()) {
168 RecordProfileAndBrowserEventsHelper(kQuitBrowserKeyPrefix);
169 BrowserList::RemoveObserver(this);
172 if (!waiting_for_sync_initialization_)
175 ProfileSyncService* sync_service =
176 ProfileSyncServiceFactory::GetForProfile(profile_);
177 sync_service->RemoveObserver(this);
180 bool ManagedUserService::ProfileIsManaged() const {
181 return profile_->IsManaged();
185 void ManagedUserService::RegisterProfilePrefs(
186 user_prefs::PrefRegistrySyncable* registry) {
187 registry->RegisterDictionaryPref(
188 prefs::kManagedModeManualHosts,
189 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
190 registry->RegisterDictionaryPref(
191 prefs::kManagedModeManualURLs,
192 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
193 registry->RegisterIntegerPref(
194 prefs::kDefaultManagedModeFilteringBehavior, ManagedModeURLFilter::ALLOW,
195 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
196 registry->RegisterStringPref(
197 prefs::kManagedUserCustodianEmail, std::string(),
198 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
199 registry->RegisterStringPref(
200 prefs::kManagedUserCustodianName, std::string(),
201 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
202 registry->RegisterBooleanPref(prefs::kManagedUserCreationAllowed, true,
203 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
207 bool ManagedUserService::AreManagedUsersEnabled() {
208 // Allow enabling by command line for now for easier development.
209 return base::FieldTrialList::FindFullName(kManagedModeFinchName) ==
210 kManagedModeFinchActive ||
211 CommandLine::ForCurrentProcess()->HasSwitch(
212 switches::kEnableManagedUsers);
216 void ManagedUserService::MigrateUserPrefs(PrefService* prefs) {
217 if (!prefs->HasPrefPath(prefs::kProfileIsManaged))
220 bool is_managed = prefs->GetBoolean(prefs::kProfileIsManaged);
221 prefs->ClearPref(prefs::kProfileIsManaged);
226 std::string managed_user_id = prefs->GetString(prefs::kManagedUserId);
227 if (!managed_user_id.empty())
230 prefs->SetString(prefs::kManagedUserId, "Dummy ID");
233 scoped_refptr<const ManagedModeURLFilter>
234 ManagedUserService::GetURLFilterForIOThread() {
235 return url_filter_context_.io_url_filter();
238 ManagedModeURLFilter* ManagedUserService::GetURLFilterForUIThread() {
239 return url_filter_context_.ui_url_filter();
242 // Items not on any list must return -1 (CATEGORY_NOT_ON_LIST in history.js).
243 // Items on a list, but with no category, must return 0 (CATEGORY_OTHER).
244 #define CATEGORY_NOT_ON_LIST -1;
245 #define CATEGORY_OTHER 0;
247 int ManagedUserService::GetCategory(const GURL& url) {
248 std::vector<ManagedModeSiteList::Site*> sites;
249 GetURLFilterForUIThread()->GetSites(url, &sites);
251 return CATEGORY_NOT_ON_LIST;
253 return (*sites.begin())->category_id;
257 void ManagedUserService::GetCategoryNames(CategoryList* list) {
258 ManagedModeSiteList::GetCategoryNames(list);
261 std::string ManagedUserService::GetCustodianEmailAddress() const {
262 #if defined(OS_CHROMEOS)
263 return chromeos::UserManager::Get()->GetSupervisedUserManager()->
264 GetManagerDisplayEmail(
265 chromeos::UserManager::Get()->GetActiveUser()->email());
267 return profile_->GetPrefs()->GetString(prefs::kManagedUserCustodianEmail);
271 std::string ManagedUserService::GetCustodianName() const {
272 #if defined(OS_CHROMEOS)
273 return UTF16ToUTF8(chromeos::UserManager::Get()->GetSupervisedUserManager()->
274 GetManagerDisplayName(
275 chromeos::UserManager::Get()->GetActiveUser()->email()));
277 std::string name = profile_->GetPrefs()->GetString(
278 prefs::kManagedUserCustodianName);
279 return name.empty() ? GetCustodianEmailAddress() : name;
283 void ManagedUserService::AddNavigationBlockedCallback(
284 const NavigationBlockedCallback& callback) {
285 navigation_blocked_callbacks_.push_back(callback);
288 void ManagedUserService::DidBlockNavigation(
289 content::WebContents* web_contents) {
290 for (std::vector<NavigationBlockedCallback>::iterator it =
291 navigation_blocked_callbacks_.begin();
292 it != navigation_blocked_callbacks_.end(); ++it) {
293 it->Run(web_contents);
297 std::string ManagedUserService::GetDebugPolicyProviderName() const {
298 // Save the string space in official builds.
301 return std::string();
303 return "Managed User Service";
307 bool ManagedUserService::UserMayLoad(const extensions::Extension* extension,
308 string16* error) const {
310 if (ExtensionManagementPolicyImpl(extension, &tmp_error))
313 // If the extension is already loaded, we allow it, otherwise we'd unload
314 // all existing extensions.
315 ExtensionService* extension_service =
316 extensions::ExtensionSystem::Get(profile_)->extension_service();
318 // |extension_service| can be NULL in a unit test.
319 if (extension_service &&
320 extension_service->GetInstalledExtension(extension->id()))
323 bool was_installed_by_default = extension->was_installed_by_default();
324 #if defined(OS_CHROMEOS)
325 // On Chrome OS all external sources are controlled by us so it means that
326 // they are "default". Method was_installed_by_default returns false because
327 // extensions creation flags are ignored in case of default extensions with
328 // update URL(the flags aren't passed to OnExternalExtensionUpdateUrlFound).
329 // TODO(dpolukhin): remove this Chrome OS specific code as soon as creation
330 // flags are not ignored.
331 was_installed_by_default =
332 extensions::Manifest::IsExternalLocation(extension->location());
334 if (extension->location() == extensions::Manifest::COMPONENT ||
335 was_installed_by_default) {
344 bool ManagedUserService::UserMayModifySettings(
345 const extensions::Extension* extension,
346 string16* error) const {
347 return ExtensionManagementPolicyImpl(extension, error);
350 void ManagedUserService::OnStateChanged() {
351 ProfileSyncService* service =
352 ProfileSyncServiceFactory::GetForProfile(profile_);
353 if (waiting_for_sync_initialization_ && service->sync_initialized()) {
354 waiting_for_sync_initialization_ = false;
355 service->RemoveObserver(this);
360 DLOG_IF(ERROR, service->GetAuthError().state() ==
361 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)
362 << "Credentials rejected";
365 void ManagedUserService::Observe(int type,
366 const content::NotificationSource& source,
367 const content::NotificationDetails& details) {
369 case chrome::NOTIFICATION_EXTENSION_LOADED: {
370 const extensions::Extension* extension =
371 content::Details<extensions::Extension>(details).ptr();
372 if (!extensions::ManagedModeInfo::GetContentPackSiteList(
373 extension).empty()) {
378 case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
379 const extensions::UnloadedExtensionInfo* extension_info =
380 content::Details<extensions::UnloadedExtensionInfo>(details).ptr();
381 if (!extensions::ManagedModeInfo::GetContentPackSiteList(
382 extension_info->extension).empty()) {
392 void ManagedUserService::SetupSync() {
393 ProfileSyncService* service =
394 ProfileSyncServiceFactory::GetForProfile(profile_);
395 DCHECK(service->sync_initialized());
397 bool sync_everything = false;
398 syncer::ModelTypeSet synced_datatypes;
399 synced_datatypes.Put(syncer::MANAGED_USER_SETTINGS);
400 service->OnUserChoseDatatypes(sync_everything, synced_datatypes);
402 // Notify ProfileSyncService that we are done with configuration.
403 service->SetSetupInProgress(false);
404 service->SetSyncSetupCompleted();
407 bool ManagedUserService::ExtensionManagementPolicyImpl(
408 const extensions::Extension* extension,
409 string16* error) const {
410 // |extension| can be NULL in unit_tests.
411 if (!ProfileIsManaged() || (extension && extension->is_theme()))
414 if (elevated_for_testing_)
418 *error = l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_MANAGED_USER);
422 ScopedVector<ManagedModeSiteList> ManagedUserService::GetActiveSiteLists() {
423 ScopedVector<ManagedModeSiteList> site_lists;
424 ExtensionService* extension_service =
425 extensions::ExtensionSystem::Get(profile_)->extension_service();
426 // Can be NULL in unit tests.
427 if (!extension_service)
428 return site_lists.Pass();
430 const ExtensionSet* extensions = extension_service->extensions();
431 for (ExtensionSet::const_iterator it = extensions->begin();
432 it != extensions->end(); ++it) {
433 const extensions::Extension* extension = it->get();
434 if (!extension_service->IsExtensionEnabled(extension->id()))
437 extensions::ExtensionResource site_list =
438 extensions::ManagedModeInfo::GetContentPackSiteList(extension);
439 if (!site_list.empty())
440 site_lists.push_back(new ManagedModeSiteList(extension->id(), site_list));
443 return site_lists.Pass();
446 ManagedUserSettingsService* ManagedUserService::GetSettingsService() {
447 return ManagedUserSettingsServiceFactory::GetForProfile(profile_);
450 void ManagedUserService::OnDefaultFilteringBehaviorChanged() {
451 DCHECK(ProfileIsManaged());
453 int behavior_value = profile_->GetPrefs()->GetInteger(
454 prefs::kDefaultManagedModeFilteringBehavior);
455 ManagedModeURLFilter::FilteringBehavior behavior =
456 ManagedModeURLFilter::BehaviorFromInt(behavior_value);
457 url_filter_context_.SetDefaultFilteringBehavior(behavior);
460 void ManagedUserService::UpdateSiteLists() {
461 url_filter_context_.LoadWhitelists(GetActiveSiteLists());
464 bool ManagedUserService::AccessRequestsEnabled() {
465 ProfileSyncService* service =
466 ProfileSyncServiceFactory::GetForProfile(profile_);
467 GoogleServiceAuthError::State state = service->GetAuthError().state();
468 // We allow requesting access if Sync is working or has a transient error.
469 return (state == GoogleServiceAuthError::NONE ||
470 state == GoogleServiceAuthError::CONNECTION_FAILED ||
471 state == GoogleServiceAuthError::SERVICE_UNAVAILABLE);
474 void ManagedUserService::AddAccessRequest(const GURL& url) {
475 // Normalize the URL.
476 GURL normalized_url = ManagedModeURLFilter::Normalize(url);
479 std::string output(net::EscapeQueryParamValue(normalized_url.spec(), true));
482 std::string key = ManagedUserSettingsService::MakeSplitSettingKey(
483 kManagedUserAccessRequestKeyPrefix, output);
485 scoped_ptr<DictionaryValue> dict(new DictionaryValue);
487 // TODO(sergiu): Use sane time here when it's ready.
488 dict->SetDouble(kManagedUserAccessRequestTime, base::Time::Now().ToJsTime());
490 GetSettingsService()->UploadItem(key, dict.PassAs<Value>());
493 ManagedUserService::ManualBehavior ManagedUserService::GetManualBehaviorForHost(
494 const std::string& hostname) {
495 const DictionaryValue* dict =
496 profile_->GetPrefs()->GetDictionary(prefs::kManagedModeManualHosts);
498 if (!dict->GetBooleanWithoutPathExpansion(hostname, &allow))
501 return allow ? MANUAL_ALLOW : MANUAL_BLOCK;
504 ManagedUserService::ManualBehavior ManagedUserService::GetManualBehaviorForURL(
506 const DictionaryValue* dict =
507 profile_->GetPrefs()->GetDictionary(prefs::kManagedModeManualURLs);
508 GURL normalized_url = ManagedModeURLFilter::Normalize(url);
510 if (!dict->GetBooleanWithoutPathExpansion(normalized_url.spec(), &allow))
513 return allow ? MANUAL_ALLOW : MANUAL_BLOCK;
516 void ManagedUserService::GetManualExceptionsForHost(const std::string& host,
517 std::vector<GURL>* urls) {
518 const DictionaryValue* dict =
519 profile_->GetPrefs()->GetDictionary(prefs::kManagedModeManualURLs);
520 for (DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
522 if (url.host() == host)
523 urls->push_back(url);
527 void ManagedUserService::InitSync(const std::string& refresh_token) {
528 ProfileSyncService* service =
529 ProfileSyncServiceFactory::GetForProfile(profile_);
530 // Tell the sync service that setup is in progress so we don't start syncing
531 // until we've finished configuration.
532 service->SetSetupInProgress(true);
534 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
535 token_service->UpdateCredentialsWithOAuth2(
536 GaiaAuthConsumer::ClientOAuthResult(refresh_token, std::string(), 0));
538 // Continue in SetupSync() once the Sync backend has been initialized.
539 if (service->sync_initialized()) {
542 ProfileSyncServiceFactory::GetForProfile(profile_)->AddObserver(this);
543 waiting_for_sync_initialization_ = true;
548 const char* ManagedUserService::GetManagedUserPseudoEmail() {
549 return kManagedUserPseudoEmail;
552 void ManagedUserService::Init() {
553 ManagedUserSettingsService* settings_service = GetSettingsService();
554 DCHECK(settings_service->IsReady());
555 if (!ProfileIsManaged()) {
556 settings_service->Clear();
560 settings_service->Activate();
562 CommandLine* command_line = CommandLine::ForCurrentProcess();
563 if (command_line->HasSwitch(switches::kManagedUserSyncToken)) {
565 command_line->GetSwitchValueASCII(switches::kManagedUserSyncToken));
568 // TokenService only loads tokens automatically if we're signed in, so we have
569 // to nudge it ourselves.
570 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
571 token_service->LoadTokensFromDB();
573 extensions::ExtensionSystem* extension_system =
574 extensions::ExtensionSystem::Get(profile_);
575 extensions::ManagementPolicy* management_policy =
576 extension_system->management_policy();
577 if (management_policy)
578 extension_system->management_policy()->RegisterProvider(this);
580 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
581 content::Source<Profile>(profile_));
582 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
583 content::Source<Profile>(profile_));
585 pref_change_registrar_.Init(profile_->GetPrefs());
586 pref_change_registrar_.Add(
587 prefs::kDefaultManagedModeFilteringBehavior,
588 base::Bind(&ManagedUserService::OnDefaultFilteringBehaviorChanged,
589 base::Unretained(this)));
590 pref_change_registrar_.Add(prefs::kManagedModeManualHosts,
591 base::Bind(&ManagedUserService::UpdateManualHosts,
592 base::Unretained(this)));
593 pref_change_registrar_.Add(prefs::kManagedModeManualURLs,
594 base::Bind(&ManagedUserService::UpdateManualURLs,
595 base::Unretained(this)));
597 BrowserList::AddObserver(this);
599 // Initialize the filter.
600 OnDefaultFilteringBehaviorChanged();
606 void ManagedUserService::RegisterAndInitSync(
607 ManagedUserRegistrationUtility* registration_utility,
608 Profile* custodian_profile,
609 const std::string& managed_user_id,
610 const AuthErrorCallback& callback) {
611 DCHECK(ProfileIsManaged());
612 DCHECK(!custodian_profile->IsManaged());
614 string16 name = UTF8ToUTF16(
615 profile_->GetPrefs()->GetString(prefs::kProfileName));
616 int avatar_index = profile_->GetPrefs()->GetInteger(
617 prefs::kProfileAvatarIndex);
618 ManagedUserRegistrationInfo info(name, avatar_index);
619 registration_utility->Register(
622 base::Bind(&ManagedUserService::OnManagedUserRegistered,
623 weak_ptr_factory_.GetWeakPtr(), callback, custodian_profile));
625 // Fetch the custodian's profile information, to store the name.
626 // TODO(pamg): If --google-profile-info (flag: switches::kGoogleProfileInfo)
627 // is ever enabled, take the name from the ProfileInfoCache instead.
628 CustodianProfileDownloaderService* profile_downloader_service =
629 CustodianProfileDownloaderServiceFactory::GetForProfile(
631 profile_downloader_service->DownloadProfile(
632 base::Bind(&ManagedUserService::OnCustodianProfileDownloaded,
633 weak_ptr_factory_.GetWeakPtr()));
636 void ManagedUserService::OnCustodianProfileDownloaded(
637 const string16& full_name) {
638 profile_->GetPrefs()->SetString(prefs::kManagedUserCustodianName,
639 UTF16ToUTF8(full_name));
642 void ManagedUserService::OnManagedUserRegistered(
643 const AuthErrorCallback& callback,
644 Profile* custodian_profile,
645 const GoogleServiceAuthError& auth_error,
646 const std::string& token) {
647 if (auth_error.state() == GoogleServiceAuthError::NONE) {
649 SigninManagerBase* signin =
650 SigninManagerFactory::GetForProfile(custodian_profile);
651 profile_->GetPrefs()->SetString(prefs::kManagedUserCustodianEmail,
652 signin->GetAuthenticatedUsername());
654 DCHECK_EQ(std::string(), token);
657 callback.Run(auth_error);
660 void ManagedUserService::UpdateManualHosts() {
661 const DictionaryValue* dict =
662 profile_->GetPrefs()->GetDictionary(prefs::kManagedModeManualHosts);
663 scoped_ptr<std::map<std::string, bool> > host_map(
664 new std::map<std::string, bool>());
665 for (DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
667 bool result = it.value().GetAsBoolean(&allow);
669 (*host_map)[it.key()] = allow;
671 url_filter_context_.SetManualHosts(host_map.Pass());
674 void ManagedUserService::UpdateManualURLs() {
675 const DictionaryValue* dict =
676 profile_->GetPrefs()->GetDictionary(prefs::kManagedModeManualURLs);
677 scoped_ptr<std::map<GURL, bool> > url_map(new std::map<GURL, bool>());
678 for (DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
680 bool result = it.value().GetAsBoolean(&allow);
682 (*url_map)[GURL(it.key())] = allow;
684 url_filter_context_.SetManualURLs(url_map.Pass());
687 void ManagedUserService::OnBrowserSetLastActive(Browser* browser) {
688 bool profile_became_active = profile_->IsSameProfile(browser->profile());
689 if (!is_profile_active_ && profile_became_active)
690 RecordProfileAndBrowserEventsHelper(kOpenManagedProfileKeyPrefix);
691 else if (is_profile_active_ && !profile_became_active)
692 RecordProfileAndBrowserEventsHelper(kSwitchFromManagedProfileKeyPrefix);
694 is_profile_active_ = profile_became_active;
697 void ManagedUserService::RecordProfileAndBrowserEventsHelper(
698 const char* key_prefix) {
699 std::string key = ManagedUserSettingsService::MakeSplitSettingKey(
701 base::Int64ToString(base::TimeTicks::Now().ToInternalValue()));
703 scoped_ptr<DictionaryValue> dict(new DictionaryValue);
705 // TODO(bauerb): Use sane time when ready.
706 dict->SetDouble(kEventTimestamp, base::Time::Now().ToJsTime());
708 GetSettingsService()->UploadItem(key, dict.PassAs<Value>());