dfc1e160f490dcc05b4fc91f79bf348ae2dece35
[platform/framework/web/crosswalk.git] / src / chrome / browser / supervised_user / supervised_user_service.cc
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.
4
5 #include "chrome/browser/supervised_user/supervised_user_service.h"
6
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"
53
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"
57 #endif
58
59 #if defined(ENABLE_THEMES)
60 #include "chrome/browser/themes/theme_service.h"
61 #include "chrome/browser/themes/theme_service_factory.h"
62 #endif
63
64 using base::DictionaryValue;
65 using base::UserMetricsAction;
66 using content::BrowserThread;
67
68 SupervisedUserService::URLFilterContext::URLFilterContext()
69     : ui_url_filter_(new SupervisedUserURLFilter),
70       io_url_filter_(new SupervisedUserURLFilter) {}
71 SupervisedUserService::URLFilterContext::~URLFilterContext() {}
72
73 SupervisedUserURLFilter*
74 SupervisedUserService::URLFilterContext::ui_url_filter() const {
75   return ui_url_filter_.get();
76 }
77
78 SupervisedUserURLFilter*
79 SupervisedUserService::URLFilterContext::io_url_filter() const {
80   return io_url_filter_.get();
81 }
82
83 void SupervisedUserService::URLFilterContext::SetDefaultFilteringBehavior(
84     SupervisedUserURLFilter::FilteringBehavior behavior) {
85   ui_url_filter_->SetDefaultFilteringBehavior(behavior);
86   BrowserThread::PostTask(
87       BrowserThread::IO,
88       FROM_HERE,
89       base::Bind(&SupervisedUserURLFilter::SetDefaultFilteringBehavior,
90                  io_url_filter_.get(), behavior));
91 }
92
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());
102   }
103   ui_url_filter_->LoadWhitelists(site_lists.Pass());
104   BrowserThread::PostTask(
105       BrowserThread::IO,
106       FROM_HERE,
107       base::Bind(&SupervisedUserURLFilter::LoadWhitelists,
108                  io_url_filter_, base::Passed(&site_lists_copy)));
109 }
110
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(
115       BrowserThread::IO,
116       FROM_HERE,
117       base::Bind(&SupervisedUserURLFilter::SetManualHosts,
118                  io_url_filter_, base::Owned(host_map.release())));
119 }
120
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(
125       BrowserThread::IO,
126       FROM_HERE,
127       base::Bind(&SupervisedUserURLFilter::SetManualURLs,
128                  io_url_filter_, base::Owned(url_map.release())));
129 }
130
131 SupervisedUserService::SupervisedUserService(Profile* profile)
132     : profile_(profile),
133       active_(false),
134       delegate_(NULL),
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) {
142 }
143
144 SupervisedUserService::~SupervisedUserService() {
145   DCHECK(did_shutdown_);
146 }
147
148 void SupervisedUserService::Shutdown() {
149   did_shutdown_ = true;
150   if (ProfileIsSupervised()) {
151     content::RecordAction(UserMetricsAction("ManagedUsers_QuitBrowser"));
152   }
153   SetActive(false);
154 }
155
156 bool SupervisedUserService::ProfileIsSupervised() const {
157   return profile_->IsSupervised();
158 }
159
160 // static
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);
181 }
182
183 // static
184 void SupervisedUserService::MigrateUserPrefs(PrefService* prefs) {
185   if (!prefs->HasPrefPath(prefs::kProfileIsSupervised))
186     return;
187
188   bool is_supervised = prefs->GetBoolean(prefs::kProfileIsSupervised);
189   prefs->ClearPref(prefs::kProfileIsSupervised);
190
191   if (!is_supervised)
192     return;
193
194   std::string supervised_user_id = prefs->GetString(prefs::kSupervisedUserId);
195   if (!supervised_user_id.empty())
196     return;
197
198   prefs->SetString(prefs::kSupervisedUserId, "Dummy ID");
199 }
200
201 void SupervisedUserService::SetDelegate(Delegate* delegate) {
202   if (delegate_ == delegate)
203     return;
204   // If the delegate changed, deactivate first to give the old delegate a chance
205   // to clean up.
206   SetActive(false);
207   delegate_ = delegate;
208 }
209
210 scoped_refptr<const SupervisedUserURLFilter>
211 SupervisedUserService::GetURLFilterForIOThread() {
212   return url_filter_context_.io_url_filter();
213 }
214
215 SupervisedUserURLFilter* SupervisedUserService::GetURLFilterForUIThread() {
216   return url_filter_context_.ui_url_filter();
217 }
218
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;
223
224 int SupervisedUserService::GetCategory(const GURL& url) {
225   std::vector<SupervisedUserSiteList::Site*> sites;
226   GetURLFilterForUIThread()->GetSites(url, &sites);
227   if (sites.empty())
228     return CATEGORY_NOT_ON_LIST;
229
230   return (*sites.begin())->category_id;
231 }
232
233 // static
234 void SupervisedUserService::GetCategoryNames(CategoryList* list) {
235   SupervisedUserSiteList::GetCategoryNames(list);
236 }
237
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());
243 #else
244   return profile_->GetPrefs()->GetString(prefs::kSupervisedUserCustodianEmail);
245 #endif
246 }
247
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()));
253 #else
254   std::string name = profile_->GetPrefs()->GetString(
255       prefs::kSupervisedUserCustodianName);
256   return name.empty() ? GetCustodianEmailAddress() : name;
257 #endif
258 }
259
260 void SupervisedUserService::AddNavigationBlockedCallback(
261     const NavigationBlockedCallback& callback) {
262   navigation_blocked_callbacks_.push_back(callback);
263 }
264
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);
271   }
272 }
273
274 std::string SupervisedUserService::GetDebugPolicyProviderName() const {
275   // Save the string space in official builds.
276 #ifdef NDEBUG
277   NOTREACHED();
278   return std::string();
279 #else
280   return "Supervised User Service";
281 #endif
282 }
283
284 bool SupervisedUserService::UserMayLoad(const extensions::Extension* extension,
285                                         base::string16* error) const {
286   base::string16 tmp_error;
287   if (ExtensionManagementPolicyImpl(extension, &tmp_error))
288     return true;
289
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();
294
295   // |extension_service| can be NULL in a unit test.
296   if (extension_service &&
297       extension_service->GetInstalledExtension(extension->id()))
298     return true;
299
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());
310 #endif
311   if (extension->location() == extensions::Manifest::COMPONENT ||
312       was_installed_by_default) {
313     return true;
314   }
315
316   if (error)
317     *error = tmp_error;
318   return false;
319 }
320
321 bool SupervisedUserService::UserMayModifySettings(
322     const extensions::Extension* extension,
323     base::string16* error) const {
324   return ExtensionManagementPolicyImpl(extension, error);
325 }
326
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);
333     SetupSync();
334     return;
335   }
336
337   DLOG_IF(ERROR, service->GetAuthError().state() ==
338                      GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)
339       << "Credentials rejected";
340 }
341
342 void SupervisedUserService::OnExtensionLoaded(
343     content::BrowserContext* browser_context,
344     const extensions::Extension* extension) {
345   if (!extensions::ManagedModeInfo::GetContentPackSiteList(extension).empty()) {
346     UpdateSiteLists();
347   }
348 }
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()) {
354     UpdateSiteLists();
355   }
356 }
357
358 void SupervisedUserService::SetupSync() {
359   ProfileSyncService* service =
360       ProfileSyncServiceFactory::GetForProfile(profile_);
361   DCHECK(service->sync_initialized());
362
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);
367
368   // Notify ProfileSyncService that we are done with configuration.
369   service->SetSetupInProgress(false);
370   service->SetSyncSetupCompleted();
371 }
372
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()))
378     return true;
379
380   if (elevated_for_testing_)
381     return true;
382
383   if (error)
384     *error = l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_MANAGED_USER);
385   return false;
386 }
387
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();
396
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()))
402       continue;
403
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()));
409     }
410   }
411
412   return site_lists.Pass();
413 }
414
415 SupervisedUserSettingsService* SupervisedUserService::GetSettingsService() {
416   return SupervisedUserSettingsServiceFactory::GetForProfile(profile_);
417 }
418
419 void SupervisedUserService::OnSupervisedUserIdChanged() {
420   std::string supervised_user_id =
421       profile_->GetPrefs()->GetString(prefs::kSupervisedUserId);
422   SetActive(!supervised_user_id.empty());
423 }
424
425 void SupervisedUserService::OnDefaultFilteringBehaviorChanged() {
426   DCHECK(ProfileIsSupervised());
427
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);
433 }
434
435 void SupervisedUserService::UpdateSiteLists() {
436   url_filter_context_.LoadWhitelists(GetActiveSiteLists());
437 }
438
439 bool SupervisedUserService::AccessRequestsEnabled() {
440   if (waiting_for_permissions_)
441     return false;
442
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);
450 }
451
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
456   // successfully.
457 }
458
459 void SupervisedUserService::AddAccessRequest(const GURL& url) {
460   // Normalize the URL.
461   GURL normalized_url = SupervisedUserURLFilter::Normalize(url);
462
463   // Escape the URL.
464   std::string output(net::EscapeQueryParamValue(normalized_url.spec(), true));
465
466   waiting_for_permissions_ = true;
467   permissions_creator_->CreatePermissionRequest(
468       output,
469       base::Bind(&SupervisedUserService::OnPermissionRequestIssued,
470                  weak_ptr_factory_.GetWeakPtr()));
471 }
472
473 SupervisedUserService::ManualBehavior
474 SupervisedUserService::GetManualBehaviorForHost(
475     const std::string& hostname) {
476   const base::DictionaryValue* dict =
477       profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualHosts);
478   bool allow = false;
479   if (!dict->GetBooleanWithoutPathExpansion(hostname, &allow))
480     return MANUAL_NONE;
481
482   return allow ? MANUAL_ALLOW : MANUAL_BLOCK;
483 }
484
485 SupervisedUserService::ManualBehavior
486 SupervisedUserService::GetManualBehaviorForURL(
487     const GURL& url) {
488   const base::DictionaryValue* dict =
489       profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs);
490   GURL normalized_url = SupervisedUserURLFilter::Normalize(url);
491   bool allow = false;
492   if (!dict->GetBooleanWithoutPathExpansion(normalized_url.spec(), &allow))
493     return MANUAL_NONE;
494
495   return allow ? MANUAL_ALLOW : MANUAL_BLOCK;
496 }
497
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()) {
504     GURL url(it.key());
505     if (url.host() == host)
506       urls->push_back(url);
507   }
508 }
509
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);
516
517   ProfileOAuth2TokenService* token_service =
518       ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
519   token_service->UpdateCredentials(supervised_users::kSupervisedUserPseudoEmail,
520                                    refresh_token);
521
522   // Continue in SetupSync() once the Sync backend has been initialized.
523   if (service->sync_initialized()) {
524     SetupSync();
525   } else {
526     ProfileSyncServiceFactory::GetForProfile(profile_)->AddObserver(this);
527     waiting_for_sync_initialization_ = true;
528   }
529 }
530
531 void SupervisedUserService::Init() {
532   DCHECK(GetSettingsService()->IsReady());
533
534   pref_change_registrar_.Init(profile_->GetPrefs());
535   pref_change_registrar_.Add(
536       prefs::kSupervisedUserId,
537       base::Bind(&SupervisedUserService::OnSupervisedUserIdChanged,
538           base::Unretained(this)));
539
540   SetActive(ProfileIsSupervised());
541 }
542
543 void SupervisedUserService::SetActive(bool active) {
544   if (active_ == active)
545     return;
546   active_ = active;
547
548   if (!delegate_ || !delegate_->SetActive(active_)) {
549     if (active_) {
550       SupervisedUserPrefMappingServiceFactory::GetForBrowserContext(profile_)
551           ->Init();
552
553       CommandLine* command_line = CommandLine::ForCurrentProcess();
554       if (command_line->HasSwitch(switches::kSupervisedUserSyncToken)) {
555         InitSync(
556             command_line->GetSwitchValueASCII(
557                 switches::kSupervisedUserSyncToken));
558       }
559
560       ProfileOAuth2TokenService* token_service =
561           ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
562       token_service->LoadCredentials(
563           supervised_users::kSupervisedUserPseudoEmail);
564     }
565   }
566
567   // Now activate/deactivate anything not handled by the delegate yet.
568
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();
574   }
575 #endif
576
577   SupervisedUserSettingsService* settings_service = GetSettingsService();
578   settings_service->SetActive(active_);
579
580   extensions::ExtensionSystem* extension_system =
581       extensions::ExtensionSystem::Get(profile_);
582   extensions::ManagementPolicy* management_policy =
583       extension_system->management_policy();
584
585   if (active_) {
586     if (CommandLine::ForCurrentProcess()->HasSwitch(
587             switches::kPermissionRequestApiUrl)) {
588       permissions_creator_ =
589           PermissionRequestCreatorApiary::CreateWithProfile(profile_);
590     } else {
591       PrefService* pref_service = profile_->GetPrefs();
592       permissions_creator_.reset(new PermissionRequestCreatorSync(
593           settings_service,
594           SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext(
595               profile_),
596           GetSupervisedUserName(),
597           pref_service->GetString(prefs::kSupervisedUserId)));
598     }
599
600     if (management_policy)
601       management_policy->RegisterProvider(this);
602
603     extension_registry_observer_.Add(
604         extensions::ExtensionRegistry::Get(profile_));
605
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)));
616
617     // Initialize the filter.
618     OnDefaultFilteringBehaviorChanged();
619     UpdateSiteLists();
620     UpdateManualHosts();
621     UpdateManualURLs();
622
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);
627 #endif
628   } else {
629     permissions_creator_.reset();
630
631     if (management_policy)
632       management_policy->UnregisterProvider(this);
633
634     extension_registry_observer_.RemoveAll();
635
636     pref_change_registrar_.Remove(
637         prefs::kDefaultSupervisedUserFilteringBehavior);
638     pref_change_registrar_.Remove(prefs::kSupervisedUserManualHosts);
639     pref_change_registrar_.Remove(prefs::kSupervisedUserManualURLs);
640
641     if (waiting_for_sync_initialization_) {
642       ProfileSyncService* sync_service =
643           ProfileSyncServiceFactory::GetForProfile(profile_);
644       sync_service->RemoveObserver(this);
645     }
646
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);
651 #endif
652   }
653 }
654
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());
662
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(
669       supervised_user_id,
670       info,
671       base::Bind(&SupervisedUserService::OnSupervisedUserRegistered,
672                  weak_ptr_factory_.GetWeakPtr(), callback, custodian_profile));
673
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(
679           custodian_profile);
680   profile_downloader_service->DownloadProfile(
681       base::Bind(&SupervisedUserService::OnCustodianProfileDownloaded,
682                  weak_ptr_factory_.GetWeakPtr()));
683 }
684
685 void SupervisedUserService::OnCustodianProfileDownloaded(
686     const base::string16& full_name) {
687   profile_->GetPrefs()->SetString(prefs::kSupervisedUserCustodianName,
688                                   base::UTF16ToUTF8(full_name));
689 }
690
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) {
697     InitSync(token);
698     SigninManagerBase* signin =
699         SigninManagerFactory::GetForProfile(custodian_profile);
700     profile_->GetPrefs()->SetString(prefs::kSupervisedUserCustodianEmail,
701                                     signin->GetAuthenticatedUsername());
702
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);
708   } else {
709     DCHECK_EQ(std::string(), token);
710   }
711
712   callback.Run(auth_error);
713 }
714
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()) {
721     bool allow = false;
722     bool result = it.value().GetAsBoolean(&allow);
723     DCHECK(result);
724     (*host_map)[it.key()] = allow;
725   }
726   url_filter_context_.SetManualHosts(host_map.Pass());
727 }
728
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()) {
734     bool allow = false;
735     bool result = it.value().GetAsBoolean(&allow);
736     DCHECK(result);
737     (*url_map)[GURL(it.key())] = allow;
738   }
739   url_filter_context_.SetManualURLs(url_map.Pass());
740 }
741
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"));
748
749   is_profile_active_ = profile_became_active;
750 }
751
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()));
758   }
759   return std::string();
760 #else
761   return profile_->GetPrefs()->GetString(prefs::kProfileName);
762 #endif
763 }