Home | History | Annotate | Download | only in supervised_user
      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/files/file_path.h"
      9 #include "base/memory/ref_counted.h"
     10 #include "base/prefs/pref_service.h"
     11 #include "base/strings/string_number_conversions.h"
     12 #include "base/strings/utf_string_conversions.h"
     13 #include "chrome/browser/browser_process.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/experimental/supervised_user_blacklist_downloader.h"
     22 #include "chrome/browser/supervised_user/permission_request_creator_apiary.h"
     23 #include "chrome/browser/supervised_user/permission_request_creator_sync.h"
     24 #include "chrome/browser/supervised_user/supervised_user_constants.h"
     25 #include "chrome/browser/supervised_user/supervised_user_pref_mapping_service.h"
     26 #include "chrome/browser/supervised_user/supervised_user_pref_mapping_service_factory.h"
     27 #include "chrome/browser/supervised_user/supervised_user_registration_utility.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_shared_settings_service_factory.h"
     32 #include "chrome/browser/supervised_user/supervised_user_site_list.h"
     33 #include "chrome/browser/supervised_user/supervised_user_sync_service.h"
     34 #include "chrome/browser/supervised_user/supervised_user_sync_service_factory.h"
     35 #include "chrome/browser/sync/profile_sync_service.h"
     36 #include "chrome/browser/sync/profile_sync_service_factory.h"
     37 #include "chrome/browser/ui/browser.h"
     38 #include "chrome/browser/ui/browser_list.h"
     39 #include "chrome/common/chrome_switches.h"
     40 #include "chrome/common/pref_names.h"
     41 #include "chrome/grit/generated_resources.h"
     42 #include "components/pref_registry/pref_registry_syncable.h"
     43 #include "components/signin/core/browser/profile_oauth2_token_service.h"
     44 #include "components/signin/core/browser/signin_manager.h"
     45 #include "components/signin/core/browser/signin_manager_base.h"
     46 #include "content/public/browser/browser_thread.h"
     47 #include "content/public/browser/user_metrics.h"
     48 #include "google_apis/gaia/google_service_auth_error.h"
     49 #include "ui/base/l10n/l10n_util.h"
     50 
     51 #if defined(OS_CHROMEOS)
     52 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
     53 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
     54 #include "components/user_manager/user_manager.h"
     55 #endif
     56 
     57 #if defined(ENABLE_EXTENSIONS)
     58 #include "chrome/browser/extensions/extension_service.h"
     59 #include "chrome/common/extensions/api/supervised_user_private/supervised_user_handler.h"
     60 #include "extensions/browser/extension_registry.h"
     61 #include "extensions/browser/extension_system.h"
     62 #include "extensions/common/extension_set.h"
     63 #endif
     64 
     65 #if defined(ENABLE_THEMES)
     66 #include "chrome/browser/themes/theme_service.h"
     67 #include "chrome/browser/themes/theme_service_factory.h"
     68 #endif
     69 
     70 using base::DictionaryValue;
     71 using base::UserMetricsAction;
     72 using content::BrowserThread;
     73 
     74 SupervisedUserService::URLFilterContext::URLFilterContext()
     75     : ui_url_filter_(new SupervisedUserURLFilter),
     76       io_url_filter_(new SupervisedUserURLFilter) {}
     77 SupervisedUserService::URLFilterContext::~URLFilterContext() {}
     78 
     79 SupervisedUserURLFilter*
     80 SupervisedUserService::URLFilterContext::ui_url_filter() const {
     81   return ui_url_filter_.get();
     82 }
     83 
     84 SupervisedUserURLFilter*
     85 SupervisedUserService::URLFilterContext::io_url_filter() const {
     86   return io_url_filter_.get();
     87 }
     88 
     89 void SupervisedUserService::URLFilterContext::SetDefaultFilteringBehavior(
     90     SupervisedUserURLFilter::FilteringBehavior behavior) {
     91   ui_url_filter_->SetDefaultFilteringBehavior(behavior);
     92   BrowserThread::PostTask(
     93       BrowserThread::IO,
     94       FROM_HERE,
     95       base::Bind(&SupervisedUserURLFilter::SetDefaultFilteringBehavior,
     96                  io_url_filter_.get(), behavior));
     97 }
     98 
     99 void SupervisedUserService::URLFilterContext::LoadWhitelists(
    100     ScopedVector<SupervisedUserSiteList> site_lists) {
    101   // SupervisedUserURLFilter::LoadWhitelists takes ownership of |site_lists|,
    102   // so we make an additional copy of it.
    103   /// TODO(bauerb): This is kinda ugly.
    104   ScopedVector<SupervisedUserSiteList> site_lists_copy;
    105   for (ScopedVector<SupervisedUserSiteList>::iterator it = site_lists.begin();
    106        it != site_lists.end(); ++it) {
    107     site_lists_copy.push_back((*it)->Clone());
    108   }
    109   ui_url_filter_->LoadWhitelists(site_lists.Pass());
    110   BrowserThread::PostTask(
    111       BrowserThread::IO,
    112       FROM_HERE,
    113       base::Bind(&SupervisedUserURLFilter::LoadWhitelists,
    114                  io_url_filter_, base::Passed(&site_lists_copy)));
    115 }
    116 
    117 void SupervisedUserService::URLFilterContext::LoadBlacklist(
    118     const base::FilePath& path) {
    119   // For now, support loading only once. If we want to support re-load, we'll
    120   // have to clear the blacklist pointer in the url filters first.
    121   DCHECK_EQ(0u, blacklist_.GetEntryCount());
    122   blacklist_.ReadFromFile(
    123       path,
    124       base::Bind(&SupervisedUserService::URLFilterContext::OnBlacklistLoaded,
    125                  base::Unretained(this)));
    126 }
    127 
    128 void SupervisedUserService::URLFilterContext::SetManualHosts(
    129     scoped_ptr<std::map<std::string, bool> > host_map) {
    130   ui_url_filter_->SetManualHosts(host_map.get());
    131   BrowserThread::PostTask(
    132       BrowserThread::IO,
    133       FROM_HERE,
    134       base::Bind(&SupervisedUserURLFilter::SetManualHosts,
    135                  io_url_filter_, base::Owned(host_map.release())));
    136 }
    137 
    138 void SupervisedUserService::URLFilterContext::SetManualURLs(
    139     scoped_ptr<std::map<GURL, bool> > url_map) {
    140   ui_url_filter_->SetManualURLs(url_map.get());
    141   BrowserThread::PostTask(
    142       BrowserThread::IO,
    143       FROM_HERE,
    144       base::Bind(&SupervisedUserURLFilter::SetManualURLs,
    145                  io_url_filter_, base::Owned(url_map.release())));
    146 }
    147 
    148 void SupervisedUserService::URLFilterContext::OnBlacklistLoaded() {
    149   ui_url_filter_->SetBlacklist(&blacklist_);
    150   BrowserThread::PostTask(
    151       BrowserThread::IO,
    152       FROM_HERE,
    153       base::Bind(&SupervisedUserURLFilter::SetBlacklist,
    154                  io_url_filter_,
    155                  &blacklist_));
    156 }
    157 
    158 SupervisedUserService::SupervisedUserService(Profile* profile)
    159     : profile_(profile),
    160       active_(false),
    161       delegate_(NULL),
    162 #if defined(ENABLE_EXTENSIONS)
    163       extension_registry_observer_(this),
    164 #endif
    165       waiting_for_sync_initialization_(false),
    166       is_profile_active_(false),
    167       elevated_for_testing_(false),
    168       did_init_(false),
    169       did_shutdown_(false),
    170       weak_ptr_factory_(this) {
    171 }
    172 
    173 SupervisedUserService::~SupervisedUserService() {
    174   DCHECK(!did_init_ || did_shutdown_);
    175 }
    176 
    177 void SupervisedUserService::Shutdown() {
    178   if (!did_init_)
    179     return;
    180   DCHECK(!did_shutdown_);
    181   did_shutdown_ = true;
    182   if (ProfileIsSupervised()) {
    183     content::RecordAction(UserMetricsAction("ManagedUsers_QuitBrowser"));
    184   }
    185   SetActive(false);
    186 
    187   ProfileSyncService* sync_service =
    188       ProfileSyncServiceFactory::GetForProfile(profile_);
    189   // Can be null in tests.
    190   if (sync_service)
    191     sync_service->RemovePreferenceProvider(this);
    192 }
    193 
    194 bool SupervisedUserService::ProfileIsSupervised() const {
    195   return profile_->IsSupervised();
    196 }
    197 
    198 void SupervisedUserService::OnCustodianInfoChanged() {
    199   FOR_EACH_OBSERVER(
    200       SupervisedUserServiceObserver, observer_list_, OnCustodianInfoChanged());
    201 }
    202 
    203 // static
    204 void SupervisedUserService::RegisterProfilePrefs(
    205     user_prefs::PrefRegistrySyncable* registry) {
    206   registry->RegisterDictionaryPref(
    207       prefs::kSupervisedUserManualHosts,
    208       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    209   registry->RegisterDictionaryPref(
    210       prefs::kSupervisedUserManualURLs,
    211       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    212   registry->RegisterIntegerPref(
    213       prefs::kDefaultSupervisedUserFilteringBehavior,
    214       SupervisedUserURLFilter::ALLOW,
    215       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    216   registry->RegisterStringPref(
    217       prefs::kSupervisedUserCustodianEmail, std::string(),
    218       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    219   registry->RegisterStringPref(
    220       prefs::kSupervisedUserCustodianName, std::string(),
    221       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    222   registry->RegisterStringPref(
    223       prefs::kSupervisedUserCustodianProfileImageURL, std::string(),
    224       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    225   registry->RegisterStringPref(
    226       prefs::kSupervisedUserCustodianProfileURL, std::string(),
    227       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    228   registry->RegisterStringPref(
    229       prefs::kSupervisedUserSecondCustodianEmail, std::string(),
    230       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    231   registry->RegisterStringPref(
    232       prefs::kSupervisedUserSecondCustodianName, std::string(),
    233       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    234   registry->RegisterStringPref(
    235       prefs::kSupervisedUserSecondCustodianProfileImageURL, std::string(),
    236       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    237   registry->RegisterStringPref(
    238       prefs::kSupervisedUserSecondCustodianProfileURL, std::string(),
    239       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    240   registry->RegisterBooleanPref(prefs::kSupervisedUserCreationAllowed, true,
    241       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    242 }
    243 
    244 void SupervisedUserService::SetDelegate(Delegate* delegate) {
    245   if (delegate) {
    246     // Changing delegates isn't allowed.
    247     DCHECK(!delegate_);
    248   } else {
    249     // If the delegate is removed, deactivate first to give the old delegate a
    250     // chance to clean up.
    251     SetActive(false);
    252   }
    253   delegate_ = delegate;
    254 }
    255 
    256 scoped_refptr<const SupervisedUserURLFilter>
    257 SupervisedUserService::GetURLFilterForIOThread() {
    258   return url_filter_context_.io_url_filter();
    259 }
    260 
    261 SupervisedUserURLFilter* SupervisedUserService::GetURLFilterForUIThread() {
    262   return url_filter_context_.ui_url_filter();
    263 }
    264 
    265 // Items not on any list must return -1 (CATEGORY_NOT_ON_LIST in history.js).
    266 // Items on a list, but with no category, must return 0 (CATEGORY_OTHER).
    267 #define CATEGORY_NOT_ON_LIST -1;
    268 #define CATEGORY_OTHER 0;
    269 
    270 int SupervisedUserService::GetCategory(const GURL& url) {
    271   std::vector<SupervisedUserSiteList::Site*> sites;
    272   GetURLFilterForUIThread()->GetSites(url, &sites);
    273   if (sites.empty())
    274     return CATEGORY_NOT_ON_LIST;
    275 
    276   return (*sites.begin())->category_id;
    277 }
    278 
    279 // static
    280 void SupervisedUserService::GetCategoryNames(CategoryList* list) {
    281   SupervisedUserSiteList::GetCategoryNames(list);
    282 }
    283 
    284 std::string SupervisedUserService::GetCustodianEmailAddress() const {
    285 #if defined(OS_CHROMEOS)
    286   return chromeos::ChromeUserManager::Get()
    287       ->GetSupervisedUserManager()
    288       ->GetManagerDisplayEmail(
    289           user_manager::UserManager::Get()->GetActiveUser()->email());
    290 #else
    291   return profile_->GetPrefs()->GetString(prefs::kSupervisedUserCustodianEmail);
    292 #endif
    293 }
    294 
    295 std::string SupervisedUserService::GetCustodianName() const {
    296 #if defined(OS_CHROMEOS)
    297   return base::UTF16ToUTF8(
    298       chromeos::ChromeUserManager::Get()
    299           ->GetSupervisedUserManager()
    300           ->GetManagerDisplayName(
    301               user_manager::UserManager::Get()->GetActiveUser()->email()));
    302 #else
    303   std::string name = profile_->GetPrefs()->GetString(
    304       prefs::kSupervisedUserCustodianName);
    305   return name.empty() ? GetCustodianEmailAddress() : name;
    306 #endif
    307 }
    308 
    309 void SupervisedUserService::AddNavigationBlockedCallback(
    310     const NavigationBlockedCallback& callback) {
    311   navigation_blocked_callbacks_.push_back(callback);
    312 }
    313 
    314 void SupervisedUserService::DidBlockNavigation(
    315     content::WebContents* web_contents) {
    316   for (std::vector<NavigationBlockedCallback>::iterator it =
    317            navigation_blocked_callbacks_.begin();
    318        it != navigation_blocked_callbacks_.end(); ++it) {
    319     it->Run(web_contents);
    320   }
    321 }
    322 
    323 void SupervisedUserService::AddObserver(
    324     SupervisedUserServiceObserver* observer) {
    325   observer_list_.AddObserver(observer);
    326 }
    327 
    328 void SupervisedUserService::RemoveObserver(
    329     SupervisedUserServiceObserver* observer) {
    330   observer_list_.RemoveObserver(observer);
    331 }
    332 
    333 #if defined(ENABLE_EXTENSIONS)
    334 std::string SupervisedUserService::GetDebugPolicyProviderName() const {
    335   // Save the string space in official builds.
    336 #ifdef NDEBUG
    337   NOTREACHED();
    338   return std::string();
    339 #else
    340   return "Supervised User Service";
    341 #endif
    342 }
    343 
    344 bool SupervisedUserService::UserMayLoad(const extensions::Extension* extension,
    345                                         base::string16* error) const {
    346   base::string16 tmp_error;
    347   if (ExtensionManagementPolicyImpl(extension, &tmp_error))
    348     return true;
    349 
    350   bool was_installed_by_default = extension->was_installed_by_default();
    351   bool was_installed_by_custodian = extension->was_installed_by_custodian();
    352 #if defined(OS_CHROMEOS)
    353   // On Chrome OS all external sources are controlled by us so it means that
    354   // they are "default". Method was_installed_by_default returns false because
    355   // extensions creation flags are ignored in case of default extensions with
    356   // update URL(the flags aren't passed to OnExternalExtensionUpdateUrlFound).
    357   // TODO(dpolukhin): remove this Chrome OS specific code as soon as creation
    358   // flags are not ignored.
    359   was_installed_by_default =
    360       extensions::Manifest::IsExternalLocation(extension->location());
    361 #endif
    362   if (extensions::Manifest::IsComponentLocation(extension->location()) ||
    363       was_installed_by_default ||
    364       was_installed_by_custodian) {
    365     return true;
    366   }
    367 
    368   if (error)
    369     *error = tmp_error;
    370   return false;
    371 }
    372 
    373 bool SupervisedUserService::UserMayModifySettings(
    374     const extensions::Extension* extension,
    375     base::string16* error) const {
    376   return ExtensionManagementPolicyImpl(extension, error);
    377 }
    378 
    379 void SupervisedUserService::OnExtensionLoaded(
    380     content::BrowserContext* browser_context,
    381     const extensions::Extension* extension) {
    382   if (!extensions::SupervisedUserInfo::GetContentPackSiteList(extension)
    383            .empty()) {
    384     UpdateSiteLists();
    385   }
    386 }
    387 void SupervisedUserService::OnExtensionUnloaded(
    388     content::BrowserContext* browser_context,
    389     const extensions::Extension* extension,
    390     extensions::UnloadedExtensionInfo::Reason reason) {
    391   if (!extensions::SupervisedUserInfo::GetContentPackSiteList(extension)
    392            .empty()) {
    393     UpdateSiteLists();
    394   }
    395 }
    396 #endif  // defined(ENABLE_EXTENSIONS)
    397 
    398 syncer::ModelTypeSet SupervisedUserService::GetPreferredDataTypes() const {
    399   if (!ProfileIsSupervised())
    400     return syncer::ModelTypeSet();
    401 
    402   syncer::ModelTypeSet result;
    403   result.Put(syncer::SESSIONS);
    404   result.Put(syncer::EXTENSIONS);
    405   result.Put(syncer::EXTENSION_SETTINGS);
    406   result.Put(syncer::APPS);
    407   result.Put(syncer::APP_SETTINGS);
    408   result.Put(syncer::APP_NOTIFICATIONS);
    409   result.Put(syncer::APP_LIST);
    410   return result;
    411 }
    412 
    413 void SupervisedUserService::OnStateChanged() {
    414   ProfileSyncService* service =
    415       ProfileSyncServiceFactory::GetForProfile(profile_);
    416   if (waiting_for_sync_initialization_ && service->sync_initialized() &&
    417       service->backend_mode() == ProfileSyncService::SYNC) {
    418     waiting_for_sync_initialization_ = false;
    419     service->RemoveObserver(this);
    420     FinishSetupSync();
    421     return;
    422   }
    423 
    424   DLOG_IF(ERROR, service->GetAuthError().state() ==
    425                      GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)
    426       << "Credentials rejected";
    427 }
    428 
    429 void SupervisedUserService::SetupSync() {
    430   StartSetupSync();
    431   FinishSetupSyncWhenReady();
    432 }
    433 
    434 void SupervisedUserService::StartSetupSync() {
    435   // Tell the sync service that setup is in progress so we don't start syncing
    436   // until we've finished configuration.
    437   ProfileSyncServiceFactory::GetForProfile(profile_)->SetSetupInProgress(true);
    438 }
    439 
    440 void SupervisedUserService::FinishSetupSyncWhenReady() {
    441   // If we're already waiting for the Sync backend, there's nothing to do here.
    442   if (waiting_for_sync_initialization_)
    443     return;
    444 
    445   // Continue in FinishSetupSync() once the Sync backend has been initialized.
    446   ProfileSyncService* service =
    447       ProfileSyncServiceFactory::GetForProfile(profile_);
    448   if (service->sync_initialized() &&
    449       service->backend_mode() == ProfileSyncService::SYNC) {
    450     FinishSetupSync();
    451   } else {
    452     service->AddObserver(this);
    453     waiting_for_sync_initialization_ = true;
    454   }
    455 }
    456 
    457 void SupervisedUserService::FinishSetupSync() {
    458   ProfileSyncService* service =
    459       ProfileSyncServiceFactory::GetForProfile(profile_);
    460   DCHECK(service->sync_initialized() &&
    461          service->backend_mode() == ProfileSyncService::SYNC);
    462 
    463   // Sync nothing (except types which are set via GetPreferredDataTypes).
    464   bool sync_everything = false;
    465   syncer::ModelTypeSet synced_datatypes;
    466   service->OnUserChoseDatatypes(sync_everything, synced_datatypes);
    467 
    468   // Notify ProfileSyncService that we are done with configuration.
    469   service->SetSetupInProgress(false);
    470   service->SetSyncSetupCompleted();
    471 }
    472 
    473 #if defined(ENABLE_EXTENSIONS)
    474 bool SupervisedUserService::ExtensionManagementPolicyImpl(
    475     const extensions::Extension* extension,
    476     base::string16* error) const {
    477   // |extension| can be NULL in unit_tests.
    478   if (!ProfileIsSupervised() || (extension && extension->is_theme()))
    479     return true;
    480 
    481   if (elevated_for_testing_)
    482     return true;
    483 
    484   if (error)
    485     *error = l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_SUPERVISED_USER);
    486   return false;
    487 }
    488 
    489 ScopedVector<SupervisedUserSiteList>
    490 SupervisedUserService::GetActiveSiteLists() {
    491   ScopedVector<SupervisedUserSiteList> site_lists;
    492   ExtensionService* extension_service =
    493       extensions::ExtensionSystem::Get(profile_)->extension_service();
    494   // Can be NULL in unit tests.
    495   if (!extension_service)
    496     return site_lists.Pass();
    497 
    498   const extensions::ExtensionSet* extensions = extension_service->extensions();
    499   for (extensions::ExtensionSet::const_iterator it = extensions->begin();
    500        it != extensions->end(); ++it) {
    501     const extensions::Extension* extension = it->get();
    502     if (!extension_service->IsExtensionEnabled(extension->id()))
    503       continue;
    504 
    505     extensions::ExtensionResource site_list =
    506         extensions::SupervisedUserInfo::GetContentPackSiteList(extension);
    507     if (!site_list.empty()) {
    508       site_lists.push_back(new SupervisedUserSiteList(extension->id(),
    509                                                       site_list.GetFilePath()));
    510     }
    511   }
    512 
    513   return site_lists.Pass();
    514 }
    515 
    516 void SupervisedUserService::SetExtensionsActive() {
    517   extensions::ExtensionSystem* extension_system =
    518       extensions::ExtensionSystem::Get(profile_);
    519   extensions::ManagementPolicy* management_policy =
    520       extension_system->management_policy();
    521 
    522   if (active_) {
    523     if (management_policy)
    524       management_policy->RegisterProvider(this);
    525 
    526     extension_registry_observer_.Add(
    527         extensions::ExtensionRegistry::Get(profile_));
    528   } else {
    529     if (management_policy)
    530       management_policy->UnregisterProvider(this);
    531 
    532     extension_registry_observer_.RemoveAll();
    533   }
    534 }
    535 #endif  // defined(ENABLE_EXTENSIONS)
    536 
    537 SupervisedUserSettingsService* SupervisedUserService::GetSettingsService() {
    538   return SupervisedUserSettingsServiceFactory::GetForProfile(profile_);
    539 }
    540 
    541 void SupervisedUserService::OnSupervisedUserIdChanged() {
    542   std::string supervised_user_id =
    543       profile_->GetPrefs()->GetString(prefs::kSupervisedUserId);
    544   SetActive(!supervised_user_id.empty());
    545 }
    546 
    547 void SupervisedUserService::OnDefaultFilteringBehaviorChanged() {
    548   DCHECK(ProfileIsSupervised());
    549 
    550   int behavior_value = profile_->GetPrefs()->GetInteger(
    551       prefs::kDefaultSupervisedUserFilteringBehavior);
    552   SupervisedUserURLFilter::FilteringBehavior behavior =
    553       SupervisedUserURLFilter::BehaviorFromInt(behavior_value);
    554   url_filter_context_.SetDefaultFilteringBehavior(behavior);
    555 
    556   FOR_EACH_OBSERVER(
    557       SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
    558 }
    559 
    560 void SupervisedUserService::UpdateSiteLists() {
    561 #if defined(ENABLE_EXTENSIONS)
    562   url_filter_context_.LoadWhitelists(GetActiveSiteLists());
    563 
    564   FOR_EACH_OBSERVER(
    565       SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
    566 #endif
    567 }
    568 
    569 void SupervisedUserService::LoadBlacklist(const base::FilePath& path,
    570                                           const GURL& url) {
    571   if (!url.is_valid()) {
    572     LoadBlacklistFromFile(path);
    573     return;
    574   }
    575 
    576   DCHECK(!blacklist_downloader_.get());
    577   blacklist_downloader_.reset(new SupervisedUserBlacklistDownloader(
    578       url,
    579       path,
    580       profile_->GetRequestContext(),
    581       base::Bind(&SupervisedUserService::OnBlacklistDownloadDone,
    582                  base::Unretained(this), path)));
    583 }
    584 
    585 void SupervisedUserService::LoadBlacklistFromFile(const base::FilePath& path) {
    586   url_filter_context_.LoadBlacklist(path);
    587 
    588   FOR_EACH_OBSERVER(
    589       SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
    590 }
    591 
    592 void SupervisedUserService::OnBlacklistDownloadDone(const base::FilePath& path,
    593                                                     bool success) {
    594   if (success) {
    595     LoadBlacklistFromFile(path);
    596   } else {
    597     LOG(WARNING) << "Blacklist download failed";
    598   }
    599   blacklist_downloader_.reset();
    600 }
    601 
    602 bool SupervisedUserService::AccessRequestsEnabled() {
    603   ProfileSyncService* service =
    604       ProfileSyncServiceFactory::GetForProfile(profile_);
    605   GoogleServiceAuthError::State state = service->GetAuthError().state();
    606   // We allow requesting access if Sync is working or has a transient error.
    607   return (state == GoogleServiceAuthError::NONE ||
    608           state == GoogleServiceAuthError::CONNECTION_FAILED ||
    609           state == GoogleServiceAuthError::SERVICE_UNAVAILABLE);
    610 }
    611 
    612 void SupervisedUserService::OnPermissionRequestIssued() {
    613   // TODO(akuegel): Figure out how to show the result of issuing the permission
    614   // request in the UI. Currently, we assume the permission request was created
    615   // successfully.
    616 }
    617 
    618 void SupervisedUserService::AddAccessRequest(const GURL& url) {
    619   permissions_creator_->CreatePermissionRequest(
    620       SupervisedUserURLFilter::Normalize(url),
    621       base::Bind(&SupervisedUserService::OnPermissionRequestIssued,
    622                  weak_ptr_factory_.GetWeakPtr()));
    623 }
    624 
    625 SupervisedUserService::ManualBehavior
    626 SupervisedUserService::GetManualBehaviorForHost(
    627     const std::string& hostname) {
    628   const base::DictionaryValue* dict =
    629       profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualHosts);
    630   bool allow = false;
    631   if (!dict->GetBooleanWithoutPathExpansion(hostname, &allow))
    632     return MANUAL_NONE;
    633 
    634   return allow ? MANUAL_ALLOW : MANUAL_BLOCK;
    635 }
    636 
    637 SupervisedUserService::ManualBehavior
    638 SupervisedUserService::GetManualBehaviorForURL(
    639     const GURL& url) {
    640   const base::DictionaryValue* dict =
    641       profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs);
    642   GURL normalized_url = SupervisedUserURLFilter::Normalize(url);
    643   bool allow = false;
    644   if (!dict->GetBooleanWithoutPathExpansion(normalized_url.spec(), &allow))
    645     return MANUAL_NONE;
    646 
    647   return allow ? MANUAL_ALLOW : MANUAL_BLOCK;
    648 }
    649 
    650 void SupervisedUserService::GetManualExceptionsForHost(
    651     const std::string& host,
    652     std::vector<GURL>* urls) {
    653   const base::DictionaryValue* dict =
    654       profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs);
    655   for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
    656     GURL url(it.key());
    657     if (url.host() == host)
    658       urls->push_back(url);
    659   }
    660 }
    661 
    662 void SupervisedUserService::InitSync(const std::string& refresh_token) {
    663   StartSetupSync();
    664 
    665   ProfileOAuth2TokenService* token_service =
    666       ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
    667   token_service->UpdateCredentials(supervised_users::kSupervisedUserPseudoEmail,
    668                                    refresh_token);
    669 
    670   FinishSetupSyncWhenReady();
    671 }
    672 
    673 void SupervisedUserService::Init() {
    674   DCHECK(!did_init_);
    675   did_init_ = true;
    676   DCHECK(GetSettingsService()->IsReady());
    677 
    678   pref_change_registrar_.Init(profile_->GetPrefs());
    679   pref_change_registrar_.Add(
    680       prefs::kSupervisedUserId,
    681       base::Bind(&SupervisedUserService::OnSupervisedUserIdChanged,
    682           base::Unretained(this)));
    683 
    684   ProfileSyncService* sync_service =
    685       ProfileSyncServiceFactory::GetForProfile(profile_);
    686   // Can be null in tests.
    687   if (sync_service)
    688     sync_service->AddPreferenceProvider(this);
    689 
    690   SetActive(ProfileIsSupervised());
    691 }
    692 
    693 void SupervisedUserService::SetActive(bool active) {
    694   if (active_ == active)
    695     return;
    696   active_ = active;
    697 
    698   if (!delegate_ || !delegate_->SetActive(active_)) {
    699     if (active_) {
    700       SupervisedUserPrefMappingServiceFactory::GetForBrowserContext(profile_)
    701           ->Init();
    702 
    703       CommandLine* command_line = CommandLine::ForCurrentProcess();
    704       if (command_line->HasSwitch(switches::kSupervisedUserSyncToken)) {
    705         InitSync(
    706             command_line->GetSwitchValueASCII(
    707                 switches::kSupervisedUserSyncToken));
    708       }
    709 
    710       ProfileOAuth2TokenService* token_service =
    711           ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
    712       token_service->LoadCredentials(
    713           supervised_users::kSupervisedUserPseudoEmail);
    714 
    715       SetupSync();
    716     }
    717   }
    718 
    719   // Now activate/deactivate anything not handled by the delegate yet.
    720 
    721 #if defined(ENABLE_THEMES)
    722   // Re-set the default theme to turn the SU theme on/off.
    723   ThemeService* theme_service = ThemeServiceFactory::GetForProfile(profile_);
    724   if (theme_service->UsingDefaultTheme() || theme_service->UsingSystemTheme()) {
    725     ThemeServiceFactory::GetForProfile(profile_)->UseDefaultTheme();
    726   }
    727 #endif
    728 
    729   ProfileSyncService* sync_service =
    730       ProfileSyncServiceFactory::GetForProfile(profile_);
    731   sync_service->SetEncryptEverythingAllowed(!active_);
    732 
    733   SupervisedUserSettingsService* settings_service = GetSettingsService();
    734   settings_service->SetActive(active_);
    735 
    736 #if defined(ENABLE_EXTENSIONS)
    737   SetExtensionsActive();
    738 #endif
    739 
    740   if (active_) {
    741     if (CommandLine::ForCurrentProcess()->HasSwitch(
    742             switches::kPermissionRequestApiUrl)) {
    743       permissions_creator_ =
    744           PermissionRequestCreatorApiary::CreateWithProfile(profile_);
    745     } else {
    746       PrefService* pref_service = profile_->GetPrefs();
    747       permissions_creator_.reset(new PermissionRequestCreatorSync(
    748           settings_service,
    749           SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext(
    750               profile_),
    751           GetSupervisedUserName(),
    752           pref_service->GetString(prefs::kSupervisedUserId)));
    753     }
    754 
    755     pref_change_registrar_.Add(
    756         prefs::kDefaultSupervisedUserFilteringBehavior,
    757         base::Bind(&SupervisedUserService::OnDefaultFilteringBehaviorChanged,
    758             base::Unretained(this)));
    759     pref_change_registrar_.Add(prefs::kSupervisedUserManualHosts,
    760         base::Bind(&SupervisedUserService::UpdateManualHosts,
    761                    base::Unretained(this)));
    762     pref_change_registrar_.Add(prefs::kSupervisedUserManualURLs,
    763         base::Bind(&SupervisedUserService::UpdateManualURLs,
    764                    base::Unretained(this)));
    765     pref_change_registrar_.Add(prefs::kSupervisedUserCustodianName,
    766         base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
    767                    base::Unretained(this)));
    768     pref_change_registrar_.Add(prefs::kSupervisedUserCustodianEmail,
    769         base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
    770                    base::Unretained(this)));
    771     pref_change_registrar_.Add(prefs::kSupervisedUserCustodianProfileImageURL,
    772         base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
    773                    base::Unretained(this)));
    774     pref_change_registrar_.Add(prefs::kSupervisedUserCustodianProfileURL,
    775         base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
    776                    base::Unretained(this)));
    777     pref_change_registrar_.Add(prefs::kSupervisedUserSecondCustodianName,
    778         base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
    779                    base::Unretained(this)));
    780     pref_change_registrar_.Add(prefs::kSupervisedUserSecondCustodianEmail,
    781         base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
    782                    base::Unretained(this)));
    783     pref_change_registrar_.Add(
    784         prefs::kSupervisedUserSecondCustodianProfileImageURL,
    785         base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
    786                    base::Unretained(this)));
    787     pref_change_registrar_.Add(prefs::kSupervisedUserSecondCustodianProfileURL,
    788         base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
    789                    base::Unretained(this)));
    790 
    791     // Initialize the filter.
    792     OnDefaultFilteringBehaviorChanged();
    793     UpdateSiteLists();
    794     UpdateManualHosts();
    795     UpdateManualURLs();
    796     bool use_blacklist =
    797         CommandLine::ForCurrentProcess()->HasSwitch(
    798             switches::kEnableSupervisedUserBlacklist);
    799     if (delegate_ && use_blacklist) {
    800       base::FilePath blacklist_path = delegate_->GetBlacklistPath();
    801       if (!blacklist_path.empty())
    802         LoadBlacklist(blacklist_path, delegate_->GetBlacklistURL());
    803     }
    804 
    805 #if !defined(OS_ANDROID)
    806     // TODO(bauerb): Get rid of the platform-specific #ifdef here.
    807     // http://crbug.com/313377
    808     BrowserList::AddObserver(this);
    809 #endif
    810   } else {
    811     permissions_creator_.reset();
    812 
    813     pref_change_registrar_.Remove(
    814         prefs::kDefaultSupervisedUserFilteringBehavior);
    815     pref_change_registrar_.Remove(prefs::kSupervisedUserManualHosts);
    816     pref_change_registrar_.Remove(prefs::kSupervisedUserManualURLs);
    817 
    818     if (waiting_for_sync_initialization_)
    819       ProfileSyncServiceFactory::GetForProfile(profile_)->RemoveObserver(this);
    820 
    821 #if !defined(OS_ANDROID)
    822     // TODO(bauerb): Get rid of the platform-specific #ifdef here.
    823     // http://crbug.com/313377
    824     BrowserList::RemoveObserver(this);
    825 #endif
    826   }
    827 }
    828 
    829 void SupervisedUserService::RegisterAndInitSync(
    830     SupervisedUserRegistrationUtility* registration_utility,
    831     Profile* custodian_profile,
    832     const std::string& supervised_user_id,
    833     const AuthErrorCallback& callback) {
    834   DCHECK(ProfileIsSupervised());
    835   DCHECK(!custodian_profile->IsSupervised());
    836 
    837   base::string16 name = base::UTF8ToUTF16(
    838       profile_->GetPrefs()->GetString(prefs::kProfileName));
    839   int avatar_index = profile_->GetPrefs()->GetInteger(
    840       prefs::kProfileAvatarIndex);
    841   SupervisedUserRegistrationInfo info(name, avatar_index);
    842   registration_utility->Register(
    843       supervised_user_id,
    844       info,
    845       base::Bind(&SupervisedUserService::OnSupervisedUserRegistered,
    846                  weak_ptr_factory_.GetWeakPtr(), callback, custodian_profile));
    847 
    848   // Fetch the custodian's profile information, to store the name.
    849   // TODO(pamg): If --google-profile-info (flag: switches::kGoogleProfileInfo)
    850   // is ever enabled, take the name from the ProfileInfoCache instead.
    851   CustodianProfileDownloaderService* profile_downloader_service =
    852       CustodianProfileDownloaderServiceFactory::GetForProfile(
    853           custodian_profile);
    854   profile_downloader_service->DownloadProfile(
    855       base::Bind(&SupervisedUserService::OnCustodianProfileDownloaded,
    856                  weak_ptr_factory_.GetWeakPtr()));
    857 }
    858 
    859 void SupervisedUserService::OnCustodianProfileDownloaded(
    860     const base::string16& full_name) {
    861   profile_->GetPrefs()->SetString(prefs::kSupervisedUserCustodianName,
    862                                   base::UTF16ToUTF8(full_name));
    863 }
    864 
    865 void SupervisedUserService::OnSupervisedUserRegistered(
    866     const AuthErrorCallback& callback,
    867     Profile* custodian_profile,
    868     const GoogleServiceAuthError& auth_error,
    869     const std::string& token) {
    870   if (auth_error.state() == GoogleServiceAuthError::NONE) {
    871     InitSync(token);
    872     SigninManagerBase* signin =
    873         SigninManagerFactory::GetForProfile(custodian_profile);
    874     profile_->GetPrefs()->SetString(prefs::kSupervisedUserCustodianEmail,
    875                                     signin->GetAuthenticatedUsername());
    876 
    877     // The supervised user profile is now ready for use.
    878     ProfileManager* profile_manager = g_browser_process->profile_manager();
    879     ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
    880     size_t index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
    881     cache.SetIsOmittedProfileAtIndex(index, false);
    882   } else {
    883     DCHECK_EQ(std::string(), token);
    884   }
    885 
    886   callback.Run(auth_error);
    887 }
    888 
    889 void SupervisedUserService::UpdateManualHosts() {
    890   const base::DictionaryValue* dict =
    891       profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualHosts);
    892   scoped_ptr<std::map<std::string, bool> > host_map(
    893       new std::map<std::string, bool>());
    894   for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
    895     bool allow = false;
    896     bool result = it.value().GetAsBoolean(&allow);
    897     DCHECK(result);
    898     (*host_map)[it.key()] = allow;
    899   }
    900   url_filter_context_.SetManualHosts(host_map.Pass());
    901 
    902   FOR_EACH_OBSERVER(
    903       SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
    904 }
    905 
    906 void SupervisedUserService::UpdateManualURLs() {
    907   const base::DictionaryValue* dict =
    908       profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs);
    909   scoped_ptr<std::map<GURL, bool> > url_map(new std::map<GURL, bool>());
    910   for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
    911     bool allow = false;
    912     bool result = it.value().GetAsBoolean(&allow);
    913     DCHECK(result);
    914     (*url_map)[GURL(it.key())] = allow;
    915   }
    916   url_filter_context_.SetManualURLs(url_map.Pass());
    917 
    918   FOR_EACH_OBSERVER(
    919       SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
    920 }
    921 
    922 void SupervisedUserService::OnBrowserSetLastActive(Browser* browser) {
    923   bool profile_became_active = profile_->IsSameProfile(browser->profile());
    924   if (!is_profile_active_ && profile_became_active)
    925     content::RecordAction(UserMetricsAction("ManagedUsers_OpenProfile"));
    926   else if (is_profile_active_ && !profile_became_active)
    927     content::RecordAction(UserMetricsAction("ManagedUsers_SwitchProfile"));
    928 
    929   is_profile_active_ = profile_became_active;
    930 }
    931 
    932 std::string SupervisedUserService::GetSupervisedUserName() const {
    933 #if defined(OS_CHROMEOS)
    934   // The active user can be NULL in unit tests.
    935   if (user_manager::UserManager::Get()->GetActiveUser()) {
    936     return UTF16ToUTF8(user_manager::UserManager::Get()->GetUserDisplayName(
    937         user_manager::UserManager::Get()->GetActiveUser()->GetUserID()));
    938   }
    939   return std::string();
    940 #else
    941   return profile_->GetPrefs()->GetString(prefs::kProfileName);
    942 #endif
    943 }
    944