Home | History | Annotate | Download | only in managed_mode
      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.
      4 
      5 #include "chrome/browser/managed_mode/managed_user_service.h"
      6 
      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/sequenced_task_runner.h"
     12 #include "base/strings/string_number_conversions.h"
     13 #include "base/strings/utf_string_conversions.h"
     14 #include "chrome/browser/chrome_notification_types.h"
     15 #include "chrome/browser/extensions/extension_service.h"
     16 #include "chrome/browser/extensions/extension_system.h"
     17 #include "chrome/browser/managed_mode/custodian_profile_downloader_service.h"
     18 #include "chrome/browser/managed_mode/custodian_profile_downloader_service_factory.h"
     19 #include "chrome/browser/managed_mode/managed_mode_site_list.h"
     20 #include "chrome/browser/managed_mode/managed_user_registration_utility.h"
     21 #include "chrome/browser/managed_mode/managed_user_sync_service.h"
     22 #include "chrome/browser/managed_mode/managed_user_sync_service_factory.h"
     23 #include "chrome/browser/policy/managed_mode_policy_provider.h"
     24 #include "chrome/browser/policy/profile_policy_connector.h"
     25 #include "chrome/browser/policy/profile_policy_connector_factory.h"
     26 #include "chrome/browser/prefs/scoped_user_pref_update.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 "policy/policy_constants.h"
     52 #include "ui/base/l10n/l10n_util.h"
     53 
     54 #if defined(OS_CHROMEOS)
     55 #include "chrome/browser/chromeos/login/user_manager.h"
     56 #endif
     57 
     58 using base::DictionaryValue;
     59 using base::Value;
     60 using content::BrowserThread;
     61 using policy::ManagedModePolicyProvider;
     62 
     63 namespace {
     64 
     65 const char kManagedModeFinchActive[] = "Active";
     66 const char kManagedModeFinchName[] = "ManagedModeLaunch";
     67 const char kManagedUserAccessRequestKeyPrefix[] =
     68     "X-ManagedUser-AccessRequests";
     69 const char kManagedUserAccessRequestTime[] = "timestamp";
     70 const char kManagedUserPseudoEmail[] = "managed_user@localhost";
     71 const char kOpenManagedProfileKeyPrefix[] = "X-ManagedUser-Events-OpenProfile";
     72 const char kQuitBrowserKeyPrefix[] = "X-ManagedUser-Events-QuitBrowser";
     73 const char kSwitchFromManagedProfileKeyPrefix[] =
     74     "X-ManagedUser-Events-SwitchProfile";
     75 const char kEventTimestamp[] = "timestamp";
     76 
     77 std::string CanonicalizeHostname(const std::string& hostname) {
     78   std::string canonicalized;
     79   url_canon::StdStringCanonOutput output(&canonicalized);
     80   url_parse::Component in_comp(0, hostname.length());
     81   url_parse::Component out_comp;
     82 
     83   url_canon::CanonicalizeHost(hostname.c_str(), in_comp, &output, &out_comp);
     84   output.Complete();
     85   return canonicalized;
     86 }
     87 
     88 }  // namespace
     89 
     90 ManagedUserService::URLFilterContext::URLFilterContext()
     91     : ui_url_filter_(new ManagedModeURLFilter),
     92       io_url_filter_(new ManagedModeURLFilter) {}
     93 ManagedUserService::URLFilterContext::~URLFilterContext() {}
     94 
     95 ManagedModeURLFilter*
     96 ManagedUserService::URLFilterContext::ui_url_filter() const {
     97   return ui_url_filter_.get();
     98 }
     99 
    100 ManagedModeURLFilter*
    101 ManagedUserService::URLFilterContext::io_url_filter() const {
    102   return io_url_filter_.get();
    103 }
    104 
    105 void ManagedUserService::URLFilterContext::SetDefaultFilteringBehavior(
    106     ManagedModeURLFilter::FilteringBehavior behavior) {
    107   ui_url_filter_->SetDefaultFilteringBehavior(behavior);
    108   BrowserThread::PostTask(
    109       BrowserThread::IO,
    110       FROM_HERE,
    111       base::Bind(&ManagedModeURLFilter::SetDefaultFilteringBehavior,
    112                  io_url_filter_.get(), behavior));
    113 }
    114 
    115 void ManagedUserService::URLFilterContext::LoadWhitelists(
    116     ScopedVector<ManagedModeSiteList> site_lists) {
    117   // ManagedModeURLFilter::LoadWhitelists takes ownership of |site_lists|,
    118   // so we make an additional copy of it.
    119   /// TODO(bauerb): This is kinda ugly.
    120   ScopedVector<ManagedModeSiteList> site_lists_copy;
    121   for (ScopedVector<ManagedModeSiteList>::iterator it = site_lists.begin();
    122        it != site_lists.end(); ++it) {
    123     site_lists_copy.push_back((*it)->Clone());
    124   }
    125   ui_url_filter_->LoadWhitelists(site_lists.Pass());
    126   BrowserThread::PostTask(
    127       BrowserThread::IO,
    128       FROM_HERE,
    129       base::Bind(&ManagedModeURLFilter::LoadWhitelists,
    130                  io_url_filter_, base::Passed(&site_lists_copy)));
    131 }
    132 
    133 void ManagedUserService::URLFilterContext::SetManualHosts(
    134     scoped_ptr<std::map<std::string, bool> > host_map) {
    135   ui_url_filter_->SetManualHosts(host_map.get());
    136   BrowserThread::PostTask(
    137       BrowserThread::IO,
    138       FROM_HERE,
    139       base::Bind(&ManagedModeURLFilter::SetManualHosts,
    140                  io_url_filter_, base::Owned(host_map.release())));
    141 }
    142 
    143 void ManagedUserService::URLFilterContext::SetManualURLs(
    144     scoped_ptr<std::map<GURL, bool> > url_map) {
    145   ui_url_filter_->SetManualURLs(url_map.get());
    146   BrowserThread::PostTask(
    147       BrowserThread::IO,
    148       FROM_HERE,
    149       base::Bind(&ManagedModeURLFilter::SetManualURLs,
    150                  io_url_filter_, base::Owned(url_map.release())));
    151 }
    152 
    153 ManagedUserService::ManagedUserService(Profile* profile)
    154     : weak_ptr_factory_(this),
    155       profile_(profile),
    156       waiting_for_sync_initialization_(false),
    157       is_profile_active_(false),
    158       elevated_for_testing_(false),
    159       did_shutdown_(false) {
    160 }
    161 
    162 ManagedUserService::~ManagedUserService() {
    163   DCHECK(did_shutdown_);
    164 }
    165 
    166 void ManagedUserService::Shutdown() {
    167   did_shutdown_ = true;
    168   if (ProfileIsManaged()) {
    169     RecordProfileAndBrowserEventsHelper(kQuitBrowserKeyPrefix);
    170     BrowserList::RemoveObserver(this);
    171   }
    172 
    173   if (!waiting_for_sync_initialization_)
    174     return;
    175 
    176   ProfileSyncService* sync_service =
    177         ProfileSyncServiceFactory::GetForProfile(profile_);
    178   sync_service->RemoveObserver(this);
    179 }
    180 
    181 bool ManagedUserService::ProfileIsManaged() const {
    182   return profile_->IsManaged();
    183 }
    184 
    185 // static
    186 void ManagedUserService::RegisterProfilePrefs(
    187     user_prefs::PrefRegistrySyncable* registry) {
    188   registry->RegisterDictionaryPref(
    189       prefs::kManagedModeManualHosts,
    190       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    191   registry->RegisterDictionaryPref(
    192       prefs::kManagedModeManualURLs,
    193       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    194   registry->RegisterIntegerPref(
    195       prefs::kDefaultManagedModeFilteringBehavior, ManagedModeURLFilter::ALLOW,
    196       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    197   registry->RegisterStringPref(
    198       prefs::kManagedUserCustodianEmail, std::string(),
    199       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    200   registry->RegisterStringPref(
    201       prefs::kManagedUserCustodianName, std::string(),
    202       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    203   registry->RegisterBooleanPref(prefs::kManagedUserCreationAllowed, true,
    204       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
    205 }
    206 
    207 // static
    208 bool ManagedUserService::AreManagedUsersEnabled() {
    209   // Allow enabling by command line for now for easier development.
    210   return base::FieldTrialList::FindFullName(kManagedModeFinchName) ==
    211              kManagedModeFinchActive ||
    212          CommandLine::ForCurrentProcess()->HasSwitch(
    213              switches::kEnableManagedUsers);
    214 }
    215 
    216 scoped_refptr<const ManagedModeURLFilter>
    217 ManagedUserService::GetURLFilterForIOThread() {
    218   return url_filter_context_.io_url_filter();
    219 }
    220 
    221 ManagedModeURLFilter* ManagedUserService::GetURLFilterForUIThread() {
    222   return url_filter_context_.ui_url_filter();
    223 }
    224 
    225 // Items not on any list must return -1 (CATEGORY_NOT_ON_LIST in history.js).
    226 // Items on a list, but with no category, must return 0 (CATEGORY_OTHER).
    227 #define CATEGORY_NOT_ON_LIST -1;
    228 #define CATEGORY_OTHER 0;
    229 
    230 int ManagedUserService::GetCategory(const GURL& url) {
    231   std::vector<ManagedModeSiteList::Site*> sites;
    232   GetURLFilterForUIThread()->GetSites(url, &sites);
    233   if (sites.empty())
    234     return CATEGORY_NOT_ON_LIST;
    235 
    236   return (*sites.begin())->category_id;
    237 }
    238 
    239 // static
    240 void ManagedUserService::GetCategoryNames(CategoryList* list) {
    241   ManagedModeSiteList::GetCategoryNames(list);
    242 }
    243 
    244 std::string ManagedUserService::GetCustodianEmailAddress() const {
    245 #if defined(OS_CHROMEOS)
    246   return chromeos::UserManager::Get()->
    247       GetManagerDisplayEmailForManagedUser(
    248           chromeos::UserManager::Get()->GetActiveUser()->email());
    249 #else
    250   return profile_->GetPrefs()->GetString(prefs::kManagedUserCustodianEmail);
    251 #endif
    252 }
    253 
    254 std::string ManagedUserService::GetCustodianName() const {
    255 #if defined(OS_CHROMEOS)
    256   return UTF16ToUTF8(chromeos::UserManager::Get()->
    257       GetManagerDisplayNameForManagedUser(
    258           chromeos::UserManager::Get()->GetActiveUser()->email()));
    259 #else
    260   std::string name = profile_->GetPrefs()->GetString(
    261       prefs::kManagedUserCustodianName);
    262   return name.empty() ? GetCustodianEmailAddress() : name;
    263 #endif
    264 }
    265 
    266 void ManagedUserService::AddNavigationBlockedCallback(
    267     const NavigationBlockedCallback& callback) {
    268   navigation_blocked_callbacks_.push_back(callback);
    269 }
    270 
    271 void ManagedUserService::DidBlockNavigation(
    272     content::WebContents* web_contents) {
    273   for (std::vector<NavigationBlockedCallback>::iterator it =
    274            navigation_blocked_callbacks_.begin();
    275        it != navigation_blocked_callbacks_.end(); ++it) {
    276     it->Run(web_contents);
    277   }
    278 }
    279 
    280 void ManagedUserService::AddInitCallback(
    281     const base::Closure& callback) {
    282   init_callbacks_.push_back(callback);
    283 }
    284 
    285 std::string ManagedUserService::GetDebugPolicyProviderName() const {
    286   // Save the string space in official builds.
    287 #ifdef NDEBUG
    288   NOTREACHED();
    289   return std::string();
    290 #else
    291   return "Managed User Service";
    292 #endif
    293 }
    294 
    295 bool ManagedUserService::UserMayLoad(const extensions::Extension* extension,
    296                                      string16* error) const {
    297   string16 tmp_error;
    298   if (ExtensionManagementPolicyImpl(extension, &tmp_error))
    299     return true;
    300 
    301   // If the extension is already loaded, we allow it, otherwise we'd unload
    302   // all existing extensions.
    303   ExtensionService* extension_service =
    304       extensions::ExtensionSystem::Get(profile_)->extension_service();
    305 
    306   // |extension_service| can be NULL in a unit test.
    307   if (extension_service &&
    308       extension_service->GetInstalledExtension(extension->id()))
    309     return true;
    310 
    311   if (extension) {
    312     bool was_installed_by_default = extension->was_installed_by_default();
    313 #if defined(OS_CHROMEOS)
    314     // On Chrome OS all external sources are controlled by us so it means that
    315     // they are "default". Method was_installed_by_default returns false because
    316     // extensions creation flags are ignored in case of default extensions with
    317     // update URL(the flags aren't passed to OnExternalExtensionUpdateUrlFound).
    318     // TODO(dpolukhin): remove this Chrome OS specific code as soon as creation
    319     // flags are not ignored.
    320     was_installed_by_default =
    321         extensions::Manifest::IsExternalLocation(extension->location());
    322 #endif
    323     if (extension->location() == extensions::Manifest::COMPONENT ||
    324         was_installed_by_default) {
    325       return true;
    326     }
    327   }
    328 
    329   if (error)
    330     *error = tmp_error;
    331   return false;
    332 }
    333 
    334 bool ManagedUserService::UserMayModifySettings(
    335     const extensions::Extension* extension,
    336     string16* error) const {
    337   return ExtensionManagementPolicyImpl(extension, error);
    338 }
    339 
    340 void ManagedUserService::OnStateChanged() {
    341   ProfileSyncService* service =
    342       ProfileSyncServiceFactory::GetForProfile(profile_);
    343   if (waiting_for_sync_initialization_ && service->sync_initialized()) {
    344     waiting_for_sync_initialization_ = false;
    345     service->RemoveObserver(this);
    346     SetupSync();
    347     return;
    348   }
    349 
    350   DLOG_IF(ERROR, service->GetAuthError().state() ==
    351                      GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)
    352       << "Credentials rejected";
    353 }
    354 
    355 void ManagedUserService::Observe(int type,
    356                           const content::NotificationSource& source,
    357                           const content::NotificationDetails& details) {
    358   switch (type) {
    359     case chrome::NOTIFICATION_EXTENSION_LOADED: {
    360       const extensions::Extension* extension =
    361           content::Details<extensions::Extension>(details).ptr();
    362       if (!extensions::ManagedModeInfo::GetContentPackSiteList(
    363               extension).empty()) {
    364         UpdateSiteLists();
    365       }
    366       break;
    367     }
    368     case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
    369       const extensions::UnloadedExtensionInfo* extension_info =
    370           content::Details<extensions::UnloadedExtensionInfo>(details).ptr();
    371       if (!extensions::ManagedModeInfo::GetContentPackSiteList(
    372               extension_info->extension).empty()) {
    373         UpdateSiteLists();
    374       }
    375       break;
    376     }
    377     default:
    378       NOTREACHED();
    379   }
    380 }
    381 
    382 void ManagedUserService::SetupSync() {
    383   ProfileSyncService* service =
    384       ProfileSyncServiceFactory::GetForProfile(profile_);
    385   DCHECK(service->sync_initialized());
    386 
    387   bool sync_everything = false;
    388   syncer::ModelTypeSet synced_datatypes;
    389   synced_datatypes.Put(syncer::MANAGED_USER_SETTINGS);
    390   service->OnUserChoseDatatypes(sync_everything, synced_datatypes);
    391 
    392   // Notify ProfileSyncService that we are done with configuration.
    393   service->SetSetupInProgress(false);
    394   service->SetSyncSetupCompleted();
    395 }
    396 
    397 bool ManagedUserService::ExtensionManagementPolicyImpl(
    398     const extensions::Extension* extension,
    399     string16* error) const {
    400   // |extension| can be NULL in unit_tests.
    401   if (!ProfileIsManaged() || (extension && extension->is_theme()))
    402     return true;
    403 
    404   if (elevated_for_testing_)
    405     return true;
    406 
    407   if (error)
    408     *error = l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_MANAGED_USER);
    409   return false;
    410 }
    411 
    412 ScopedVector<ManagedModeSiteList> ManagedUserService::GetActiveSiteLists() {
    413   ScopedVector<ManagedModeSiteList> site_lists;
    414   ExtensionService* extension_service =
    415       extensions::ExtensionSystem::Get(profile_)->extension_service();
    416   // Can be NULL in unit tests.
    417   if (!extension_service)
    418     return site_lists.Pass();
    419 
    420   const ExtensionSet* extensions = extension_service->extensions();
    421   for (ExtensionSet::const_iterator it = extensions->begin();
    422        it != extensions->end(); ++it) {
    423     const extensions::Extension* extension = it->get();
    424     if (!extension_service->IsExtensionEnabled(extension->id()))
    425       continue;
    426 
    427     extensions::ExtensionResource site_list =
    428         extensions::ManagedModeInfo::GetContentPackSiteList(extension);
    429     if (!site_list.empty())
    430       site_lists.push_back(new ManagedModeSiteList(extension->id(), site_list));
    431   }
    432 
    433   return site_lists.Pass();
    434 }
    435 
    436 ManagedModePolicyProvider* ManagedUserService::GetPolicyProvider() {
    437   policy::ProfilePolicyConnector* connector =
    438       policy::ProfilePolicyConnectorFactory::GetForProfile(profile_);
    439   return connector->managed_mode_policy_provider();
    440 }
    441 
    442 void ManagedUserService::OnDefaultFilteringBehaviorChanged() {
    443   DCHECK(ProfileIsManaged());
    444 
    445   int behavior_value = profile_->GetPrefs()->GetInteger(
    446       prefs::kDefaultManagedModeFilteringBehavior);
    447   ManagedModeURLFilter::FilteringBehavior behavior =
    448       ManagedModeURLFilter::BehaviorFromInt(behavior_value);
    449   url_filter_context_.SetDefaultFilteringBehavior(behavior);
    450 }
    451 
    452 void ManagedUserService::UpdateSiteLists() {
    453   url_filter_context_.LoadWhitelists(GetActiveSiteLists());
    454 }
    455 
    456 bool ManagedUserService::AccessRequestsEnabled() {
    457   ProfileSyncService* service =
    458       ProfileSyncServiceFactory::GetForProfile(profile_);
    459   GoogleServiceAuthError::State state = service->GetAuthError().state();
    460   // We allow requesting access if Sync is working or has a transient error.
    461   return (state == GoogleServiceAuthError::NONE ||
    462           state == GoogleServiceAuthError::CONNECTION_FAILED ||
    463           state == GoogleServiceAuthError::SERVICE_UNAVAILABLE);
    464 }
    465 
    466 void ManagedUserService::AddAccessRequest(const GURL& url) {
    467   // Normalize the URL.
    468   GURL normalized_url = ManagedModeURLFilter::Normalize(url);
    469 
    470   // Escape the URL.
    471   std::string output(net::EscapeQueryParamValue(normalized_url.spec(), true));
    472 
    473   // Add the prefix.
    474   std::string key = ManagedModePolicyProvider::MakeSplitSettingKey(
    475       kManagedUserAccessRequestKeyPrefix, output);
    476 
    477   scoped_ptr<DictionaryValue> dict(new DictionaryValue);
    478 
    479   // TODO(sergiu): Use sane time here when it's ready.
    480   dict->SetDouble(kManagedUserAccessRequestTime, base::Time::Now().ToJsTime());
    481 
    482   GetPolicyProvider()->UploadItem(key, dict.PassAs<Value>());
    483 }
    484 
    485 ManagedUserService::ManualBehavior ManagedUserService::GetManualBehaviorForHost(
    486     const std::string& hostname) {
    487   const DictionaryValue* dict =
    488       profile_->GetPrefs()->GetDictionary(prefs::kManagedModeManualHosts);
    489   bool allow = false;
    490   if (!dict->GetBooleanWithoutPathExpansion(hostname, &allow))
    491     return MANUAL_NONE;
    492 
    493   return allow ? MANUAL_ALLOW : MANUAL_BLOCK;
    494 }
    495 
    496 ManagedUserService::ManualBehavior ManagedUserService::GetManualBehaviorForURL(
    497     const GURL& url) {
    498   const DictionaryValue* dict =
    499       profile_->GetPrefs()->GetDictionary(prefs::kManagedModeManualURLs);
    500   GURL normalized_url = ManagedModeURLFilter::Normalize(url);
    501   bool allow = false;
    502   if (!dict->GetBooleanWithoutPathExpansion(normalized_url.spec(), &allow))
    503     return MANUAL_NONE;
    504 
    505   return allow ? MANUAL_ALLOW : MANUAL_BLOCK;
    506 }
    507 
    508 void ManagedUserService::GetManualExceptionsForHost(const std::string& host,
    509                                                     std::vector<GURL>* urls) {
    510   const DictionaryValue* dict =
    511       profile_->GetPrefs()->GetDictionary(prefs::kManagedModeManualURLs);
    512   for (DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
    513     GURL url(it.key());
    514     if (url.host() == host)
    515       urls->push_back(url);
    516   }
    517 }
    518 
    519 void ManagedUserService::InitForTesting() {
    520   DCHECK(!profile_->GetPrefs()->GetBoolean(prefs::kProfileIsManaged));
    521   profile_->GetPrefs()->SetBoolean(prefs::kProfileIsManaged, true);
    522   Init();
    523 }
    524 
    525 void ManagedUserService::InitSync(const std::string& refresh_token) {
    526   ProfileSyncService* service =
    527       ProfileSyncServiceFactory::GetForProfile(profile_);
    528   // Tell the sync service that setup is in progress so we don't start syncing
    529   // until we've finished configuration.
    530   service->SetSetupInProgress(true);
    531 
    532   TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
    533   token_service->UpdateCredentialsWithOAuth2(
    534       GaiaAuthConsumer::ClientOAuthResult(refresh_token, std::string(), 0));
    535 
    536   // Continue in SetupSync() once the Sync backend has been initialized.
    537   if (service->sync_initialized()) {
    538     SetupSync();
    539   } else {
    540     ProfileSyncServiceFactory::GetForProfile(profile_)->AddObserver(this);
    541     waiting_for_sync_initialization_ = true;
    542   }
    543 }
    544 
    545 // static
    546 const char* ManagedUserService::GetManagedUserPseudoEmail() {
    547   return kManagedUserPseudoEmail;
    548 }
    549 
    550 void ManagedUserService::Init() {
    551   ManagedModePolicyProvider* policy_provider = GetPolicyProvider();
    552   if (!ProfileIsManaged()) {
    553     if (policy_provider)
    554       policy_provider->Clear();
    555 
    556     return;
    557   }
    558 
    559   CommandLine* command_line = CommandLine::ForCurrentProcess();
    560   if (command_line->HasSwitch(switches::kManagedUserSyncToken)) {
    561     InitSync(
    562         command_line->GetSwitchValueASCII(switches::kManagedUserSyncToken));
    563   }
    564 
    565   // TokenService only loads tokens automatically if we're signed in, so we have
    566   // to nudge it ourselves.
    567   TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
    568   token_service->LoadTokensFromDB();
    569 
    570   extensions::ExtensionSystem* extension_system =
    571       extensions::ExtensionSystem::Get(profile_);
    572   extensions::ManagementPolicy* management_policy =
    573       extension_system->management_policy();
    574   if (management_policy)
    575     extension_system->management_policy()->RegisterProvider(this);
    576 
    577   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
    578                  content::Source<Profile>(profile_));
    579   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
    580                  content::Source<Profile>(profile_));
    581 
    582   pref_change_registrar_.Init(profile_->GetPrefs());
    583   pref_change_registrar_.Add(
    584       prefs::kDefaultManagedModeFilteringBehavior,
    585       base::Bind(&ManagedUserService::OnDefaultFilteringBehaviorChanged,
    586           base::Unretained(this)));
    587   pref_change_registrar_.Add(prefs::kManagedModeManualHosts,
    588       base::Bind(&ManagedUserService::UpdateManualHosts,
    589                  base::Unretained(this)));
    590   pref_change_registrar_.Add(prefs::kManagedModeManualURLs,
    591       base::Bind(&ManagedUserService::UpdateManualURLs,
    592                  base::Unretained(this)));
    593 
    594   BrowserList::AddObserver(this);
    595 
    596   if (policy_provider)
    597     policy_provider->InitLocalPolicies();
    598 
    599   // Initialize the filter.
    600   OnDefaultFilteringBehaviorChanged();
    601   UpdateSiteLists();
    602   UpdateManualHosts();
    603   UpdateManualURLs();
    604 
    605   // Call the callbacks to notify that the ManagedUserService has been
    606   // initialized.
    607   for (std::vector<base::Closure>::iterator it = init_callbacks_.begin();
    608        it != init_callbacks_.end();
    609        ++it) {
    610     it->Run();
    611   }
    612 }
    613 
    614 void ManagedUserService::RegisterAndInitSync(
    615     ManagedUserRegistrationUtility* registration_utility,
    616     Profile* custodian_profile,
    617     const std::string& managed_user_id,
    618     const ProfileManager::CreateCallback& callback) {
    619   DCHECK(ProfileIsManaged());
    620   DCHECK(!custodian_profile->IsManaged());
    621 
    622   string16 name = UTF8ToUTF16(
    623       profile_->GetPrefs()->GetString(prefs::kProfileName));
    624   ManagedUserRegistrationInfo info(name);
    625   registration_utility->Register(
    626       managed_user_id,
    627       info,
    628       base::Bind(&ManagedUserService::OnManagedUserRegistered,
    629                  weak_ptr_factory_.GetWeakPtr(), callback, custodian_profile));
    630 
    631   // Fetch the custodian's profile information, to store the name.
    632   // TODO(pamg): If --gaia-profile-info (keyword: switches::kGaiaProfileInfo)
    633   // is ever enabled, take the name from the ProfileInfoCache instead.
    634   CustodianProfileDownloaderService* profile_downloader_service =
    635       CustodianProfileDownloaderServiceFactory::GetForProfile(
    636           custodian_profile);
    637   profile_downloader_service->DownloadProfile(
    638       base::Bind(&ManagedUserService::OnCustodianProfileDownloaded,
    639                  weak_ptr_factory_.GetWeakPtr()));
    640 }
    641 
    642 void ManagedUserService::OnCustodianProfileDownloaded(
    643     const string16& full_name) {
    644   profile_->GetPrefs()->SetString(prefs::kManagedUserCustodianName,
    645                                   UTF16ToUTF8(full_name));
    646 }
    647 
    648 void ManagedUserService::OnManagedUserRegistered(
    649     const ProfileManager::CreateCallback& callback,
    650     Profile* custodian_profile,
    651     const GoogleServiceAuthError& auth_error,
    652     const std::string& token) {
    653   if (auth_error.state() != GoogleServiceAuthError::NONE) {
    654     LOG(ERROR) << "Managed user OAuth error: " << auth_error.ToString();
    655     DCHECK_EQ(std::string(), token);
    656     callback.Run(profile_, Profile::CREATE_STATUS_REMOTE_FAIL);
    657     return;
    658   }
    659 
    660   InitSync(token);
    661   SigninManagerBase* signin =
    662       SigninManagerFactory::GetForProfile(custodian_profile);
    663   profile_->GetPrefs()->SetString(prefs::kManagedUserCustodianEmail,
    664                                   signin->GetAuthenticatedUsername());
    665   callback.Run(profile_, Profile::CREATE_STATUS_INITIALIZED);
    666 }
    667 
    668 void ManagedUserService::UpdateManualHosts() {
    669   const DictionaryValue* dict =
    670       profile_->GetPrefs()->GetDictionary(prefs::kManagedModeManualHosts);
    671   scoped_ptr<std::map<std::string, bool> > host_map(
    672       new std::map<std::string, bool>());
    673   for (DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
    674     bool allow = false;
    675     bool result = it.value().GetAsBoolean(&allow);
    676     DCHECK(result);
    677     (*host_map)[it.key()] = allow;
    678   }
    679   url_filter_context_.SetManualHosts(host_map.Pass());
    680 }
    681 
    682 void ManagedUserService::UpdateManualURLs() {
    683   const DictionaryValue* dict =
    684       profile_->GetPrefs()->GetDictionary(prefs::kManagedModeManualURLs);
    685   scoped_ptr<std::map<GURL, bool> > url_map(new std::map<GURL, bool>());
    686   for (DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
    687     bool allow = false;
    688     bool result = it.value().GetAsBoolean(&allow);
    689     DCHECK(result);
    690     (*url_map)[GURL(it.key())] = allow;
    691   }
    692   url_filter_context_.SetManualURLs(url_map.Pass());
    693 }
    694 
    695 void ManagedUserService::OnBrowserSetLastActive(Browser* browser) {
    696   bool profile_became_active = profile_->IsSameProfile(browser->profile());
    697   if (!is_profile_active_ && profile_became_active)
    698     RecordProfileAndBrowserEventsHelper(kOpenManagedProfileKeyPrefix);
    699   else if (is_profile_active_ && !profile_became_active)
    700     RecordProfileAndBrowserEventsHelper(kSwitchFromManagedProfileKeyPrefix);
    701 
    702   is_profile_active_ = profile_became_active;
    703 }
    704 
    705 void ManagedUserService::RecordProfileAndBrowserEventsHelper(
    706     const char* key_prefix) {
    707   std::string key = ManagedModePolicyProvider::MakeSplitSettingKey(key_prefix,
    708       base::Int64ToString(base::TimeTicks::Now().ToInternalValue()));
    709 
    710   scoped_ptr<DictionaryValue> dict(new DictionaryValue);
    711 
    712   // TODO(bauerb): Use sane time when ready.
    713   dict->SetDouble(kEventTimestamp, base::Time::Now().ToJsTime());
    714 
    715   ManagedModePolicyProvider* provider = GetPolicyProvider();
    716   // It is NULL in tests.
    717   if (provider)
    718     provider->UploadItem(key, dict.PassAs<Value>());
    719 }
    720