Adding instrumentation to locate the source of jankiness
[chromium-blink-merge.git] / chrome / browser / supervised_user / supervised_user_service.cc
blob50325162b78785890d10bfb01bd034652c145161
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/supervised_user/supervised_user_service.h"
7 #include "base/command_line.h"
8 #include "base/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 "ui/base/l10n/l10n_util.h"
50 #if defined(OS_CHROMEOS)
51 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
52 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
53 #include "components/user_manager/user_manager.h"
54 #endif
56 #if defined(ENABLE_EXTENSIONS)
57 #include "chrome/browser/extensions/extension_service.h"
58 #include "chrome/common/extensions/api/supervised_user_private/supervised_user_handler.h"
59 #include "extensions/browser/extension_registry.h"
60 #include "extensions/browser/extension_system.h"
61 #include "extensions/common/extension_set.h"
62 #endif
64 #if defined(ENABLE_THEMES)
65 #include "chrome/browser/themes/theme_service.h"
66 #include "chrome/browser/themes/theme_service_factory.h"
67 #endif
69 using base::DictionaryValue;
70 using base::UserMetricsAction;
71 using content::BrowserThread;
73 SupervisedUserService::URLFilterContext::URLFilterContext()
74 : ui_url_filter_(new SupervisedUserURLFilter),
75 io_url_filter_(new SupervisedUserURLFilter) {}
76 SupervisedUserService::URLFilterContext::~URLFilterContext() {}
78 SupervisedUserURLFilter*
79 SupervisedUserService::URLFilterContext::ui_url_filter() const {
80 return ui_url_filter_.get();
83 SupervisedUserURLFilter*
84 SupervisedUserService::URLFilterContext::io_url_filter() const {
85 return io_url_filter_.get();
88 void SupervisedUserService::URLFilterContext::SetDefaultFilteringBehavior(
89 SupervisedUserURLFilter::FilteringBehavior behavior) {
90 ui_url_filter_->SetDefaultFilteringBehavior(behavior);
91 BrowserThread::PostTask(
92 BrowserThread::IO,
93 FROM_HERE,
94 base::Bind(&SupervisedUserURLFilter::SetDefaultFilteringBehavior,
95 io_url_filter_.get(), behavior));
98 void SupervisedUserService::URLFilterContext::LoadWhitelists(
99 ScopedVector<SupervisedUserSiteList> site_lists) {
100 // SupervisedUserURLFilter::LoadWhitelists takes ownership of |site_lists|,
101 // so we make an additional copy of it.
102 // TODO(bauerb): This is kinda ugly.
103 ScopedVector<SupervisedUserSiteList> site_lists_copy;
104 for (const SupervisedUserSiteList* site_list : site_lists)
105 site_lists_copy.push_back(site_list->Clone());
107 ui_url_filter_->LoadWhitelists(site_lists.Pass());
108 BrowserThread::PostTask(
109 BrowserThread::IO,
110 FROM_HERE,
111 base::Bind(&SupervisedUserURLFilter::LoadWhitelists,
112 io_url_filter_, base::Passed(&site_lists_copy)));
115 void SupervisedUserService::URLFilterContext::LoadBlacklist(
116 const base::FilePath& path) {
117 // For now, support loading only once. If we want to support re-load, we'll
118 // have to clear the blacklist pointer in the url filters first.
119 DCHECK_EQ(0u, blacklist_.GetEntryCount());
120 blacklist_.ReadFromFile(
121 path,
122 base::Bind(&SupervisedUserService::URLFilterContext::OnBlacklistLoaded,
123 base::Unretained(this)));
126 void SupervisedUserService::URLFilterContext::SetManualHosts(
127 scoped_ptr<std::map<std::string, bool> > host_map) {
128 ui_url_filter_->SetManualHosts(host_map.get());
129 BrowserThread::PostTask(
130 BrowserThread::IO,
131 FROM_HERE,
132 base::Bind(&SupervisedUserURLFilter::SetManualHosts,
133 io_url_filter_, base::Owned(host_map.release())));
136 void SupervisedUserService::URLFilterContext::SetManualURLs(
137 scoped_ptr<std::map<GURL, bool> > url_map) {
138 ui_url_filter_->SetManualURLs(url_map.get());
139 BrowserThread::PostTask(
140 BrowserThread::IO,
141 FROM_HERE,
142 base::Bind(&SupervisedUserURLFilter::SetManualURLs,
143 io_url_filter_, base::Owned(url_map.release())));
146 void SupervisedUserService::URLFilterContext::OnBlacklistLoaded() {
147 ui_url_filter_->SetBlacklist(&blacklist_);
148 BrowserThread::PostTask(
149 BrowserThread::IO,
150 FROM_HERE,
151 base::Bind(&SupervisedUserURLFilter::SetBlacklist,
152 io_url_filter_,
153 &blacklist_));
156 SupervisedUserService::SupervisedUserService(Profile* profile)
157 : includes_sync_sessions_type_(true),
158 profile_(profile),
159 active_(false),
160 delegate_(NULL),
161 #if defined(ENABLE_EXTENSIONS)
162 extension_registry_observer_(this),
163 #endif
164 waiting_for_sync_initialization_(false),
165 is_profile_active_(false),
166 elevated_for_testing_(false),
167 did_init_(false),
168 did_shutdown_(false),
169 weak_ptr_factory_(this) {
172 SupervisedUserService::~SupervisedUserService() {
173 DCHECK(!did_init_ || did_shutdown_);
176 void SupervisedUserService::Shutdown() {
177 if (!did_init_)
178 return;
179 DCHECK(!did_shutdown_);
180 did_shutdown_ = true;
181 if (ProfileIsSupervised()) {
182 content::RecordAction(UserMetricsAction("ManagedUsers_QuitBrowser"));
184 SetActive(false);
186 ProfileSyncService* sync_service =
187 ProfileSyncServiceFactory::GetForProfile(profile_);
188 // Can be null in tests.
189 if (sync_service)
190 sync_service->RemovePreferenceProvider(this);
193 bool SupervisedUserService::ProfileIsSupervised() const {
194 return profile_->IsSupervised();
197 void SupervisedUserService::OnCustodianInfoChanged() {
198 FOR_EACH_OBSERVER(
199 SupervisedUserServiceObserver, observer_list_, OnCustodianInfoChanged());
202 // static
203 void SupervisedUserService::RegisterProfilePrefs(
204 user_prefs::PrefRegistrySyncable* registry) {
205 registry->RegisterDictionaryPref(
206 prefs::kSupervisedUserManualHosts,
207 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
208 registry->RegisterDictionaryPref(
209 prefs::kSupervisedUserManualURLs,
210 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
211 registry->RegisterIntegerPref(
212 prefs::kDefaultSupervisedUserFilteringBehavior,
213 SupervisedUserURLFilter::ALLOW,
214 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
215 registry->RegisterStringPref(
216 prefs::kSupervisedUserCustodianEmail, std::string(),
217 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
218 registry->RegisterStringPref(
219 prefs::kSupervisedUserCustodianName, std::string(),
220 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
221 registry->RegisterStringPref(
222 prefs::kSupervisedUserCustodianProfileImageURL, std::string(),
223 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
224 registry->RegisterStringPref(
225 prefs::kSupervisedUserCustodianProfileURL, std::string(),
226 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
227 registry->RegisterStringPref(
228 prefs::kSupervisedUserSecondCustodianEmail, std::string(),
229 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
230 registry->RegisterStringPref(
231 prefs::kSupervisedUserSecondCustodianName, std::string(),
232 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
233 registry->RegisterStringPref(
234 prefs::kSupervisedUserSecondCustodianProfileImageURL, std::string(),
235 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
236 registry->RegisterStringPref(
237 prefs::kSupervisedUserSecondCustodianProfileURL, std::string(),
238 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
239 registry->RegisterBooleanPref(prefs::kSupervisedUserCreationAllowed, true,
240 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
243 void SupervisedUserService::SetDelegate(Delegate* delegate) {
244 if (delegate) {
245 // Changing delegates isn't allowed.
246 DCHECK(!delegate_);
247 } else {
248 // If the delegate is removed, deactivate first to give the old delegate a
249 // chance to clean up.
250 SetActive(false);
252 delegate_ = delegate;
255 scoped_refptr<const SupervisedUserURLFilter>
256 SupervisedUserService::GetURLFilterForIOThread() {
257 return url_filter_context_.io_url_filter();
260 SupervisedUserURLFilter* SupervisedUserService::GetURLFilterForUIThread() {
261 return url_filter_context_.ui_url_filter();
264 // Items not on any list must return -1 (CATEGORY_NOT_ON_LIST in history.js).
265 // Items on a list, but with no category, must return 0 (CATEGORY_OTHER).
266 #define CATEGORY_NOT_ON_LIST -1;
267 #define CATEGORY_OTHER 0;
269 int SupervisedUserService::GetCategory(const GURL& url) {
270 std::vector<SupervisedUserSiteList::Site*> sites;
271 GetURLFilterForUIThread()->GetSites(url, &sites);
272 if (sites.empty())
273 return CATEGORY_NOT_ON_LIST;
275 return (*sites.begin())->category_id;
278 // static
279 void SupervisedUserService::GetCategoryNames(CategoryList* list) {
280 SupervisedUserSiteList::GetCategoryNames(list);
283 std::string SupervisedUserService::GetCustodianEmailAddress() const {
284 std::string custodian_email = profile_->GetPrefs()->GetString(
285 prefs::kSupervisedUserCustodianEmail);
286 #if defined(OS_CHROMEOS)
287 if (custodian_email.empty()) {
288 custodian_email = chromeos::ChromeUserManager::Get()
289 ->GetSupervisedUserManager()
290 ->GetManagerDisplayEmail(
291 user_manager::UserManager::Get()->GetActiveUser()->email());
293 #endif
294 return custodian_email;
297 std::string SupervisedUserService::GetCustodianName() const {
298 std::string name = profile_->GetPrefs()->GetString(
299 prefs::kSupervisedUserCustodianName);
300 #if defined(OS_CHROMEOS)
301 if (name.empty()) {
302 name = base::UTF16ToUTF8(chromeos::ChromeUserManager::Get()
303 ->GetSupervisedUserManager()
304 ->GetManagerDisplayName(
305 user_manager::UserManager::Get()->GetActiveUser()->email()));
307 #endif
308 return name.empty() ? GetCustodianEmailAddress() : name;
311 void SupervisedUserService::AddNavigationBlockedCallback(
312 const NavigationBlockedCallback& callback) {
313 navigation_blocked_callbacks_.push_back(callback);
316 void SupervisedUserService::DidBlockNavigation(
317 content::WebContents* web_contents) {
318 for (const auto& callback : navigation_blocked_callbacks_)
319 callback.Run(web_contents);
322 void SupervisedUserService::AddObserver(
323 SupervisedUserServiceObserver* observer) {
324 observer_list_.AddObserver(observer);
327 void SupervisedUserService::RemoveObserver(
328 SupervisedUserServiceObserver* observer) {
329 observer_list_.RemoveObserver(observer);
332 void SupervisedUserService::AddPermissionRequestCreatorForTesting(
333 PermissionRequestCreator* creator) {
334 permissions_creators_.push_back(creator);
337 #if defined(ENABLE_EXTENSIONS)
338 std::string SupervisedUserService::GetDebugPolicyProviderName() const {
339 // Save the string space in official builds.
340 #ifdef NDEBUG
341 NOTREACHED();
342 return std::string();
343 #else
344 return "Supervised User Service";
345 #endif
348 bool SupervisedUserService::UserMayLoad(const extensions::Extension* extension,
349 base::string16* error) const {
350 base::string16 tmp_error;
351 if (ExtensionManagementPolicyImpl(extension, &tmp_error))
352 return true;
354 bool was_installed_by_default = extension->was_installed_by_default();
355 bool was_installed_by_custodian = extension->was_installed_by_custodian();
356 #if defined(OS_CHROMEOS)
357 // On Chrome OS all external sources are controlled by us so it means that
358 // they are "default". Method was_installed_by_default returns false because
359 // extensions creation flags are ignored in case of default extensions with
360 // update URL(the flags aren't passed to OnExternalExtensionUpdateUrlFound).
361 // TODO(dpolukhin): remove this Chrome OS specific code as soon as creation
362 // flags are not ignored.
363 was_installed_by_default =
364 extensions::Manifest::IsExternalLocation(extension->location());
365 #endif
366 if (extensions::Manifest::IsComponentLocation(extension->location()) ||
367 was_installed_by_default ||
368 was_installed_by_custodian) {
369 return true;
372 if (error)
373 *error = tmp_error;
374 return false;
377 bool SupervisedUserService::UserMayModifySettings(
378 const extensions::Extension* extension,
379 base::string16* error) const {
380 return ExtensionManagementPolicyImpl(extension, error);
383 void SupervisedUserService::OnExtensionLoaded(
384 content::BrowserContext* browser_context,
385 const extensions::Extension* extension) {
386 if (!extensions::SupervisedUserInfo::GetContentPackSiteList(extension)
387 .empty()) {
388 UpdateSiteLists();
391 void SupervisedUserService::OnExtensionUnloaded(
392 content::BrowserContext* browser_context,
393 const extensions::Extension* extension,
394 extensions::UnloadedExtensionInfo::Reason reason) {
395 if (!extensions::SupervisedUserInfo::GetContentPackSiteList(extension)
396 .empty()) {
397 UpdateSiteLists();
400 #endif // defined(ENABLE_EXTENSIONS)
402 syncer::ModelTypeSet SupervisedUserService::GetPreferredDataTypes() const {
403 if (!ProfileIsSupervised())
404 return syncer::ModelTypeSet();
406 syncer::ModelTypeSet result;
407 if (IncludesSyncSessionsType())
408 result.Put(syncer::SESSIONS);
409 result.Put(syncer::EXTENSIONS);
410 result.Put(syncer::EXTENSION_SETTINGS);
411 result.Put(syncer::APPS);
412 result.Put(syncer::APP_SETTINGS);
413 result.Put(syncer::APP_NOTIFICATIONS);
414 result.Put(syncer::APP_LIST);
415 return result;
418 void SupervisedUserService::OnHistoryRecordingStateChanged() {
419 includes_sync_sessions_type_ =
420 profile_->GetPrefs()->GetBoolean(prefs::kRecordHistory);
421 ProfileSyncServiceFactory::GetForProfile(profile_)
422 ->ReconfigureDatatypeManager();
425 bool SupervisedUserService::IncludesSyncSessionsType() const {
426 return includes_sync_sessions_type_;
429 void SupervisedUserService::OnStateChanged() {
430 ProfileSyncService* service =
431 ProfileSyncServiceFactory::GetForProfile(profile_);
432 if (waiting_for_sync_initialization_ && service->backend_initialized() &&
433 service->backend_mode() == ProfileSyncService::SYNC) {
434 waiting_for_sync_initialization_ = false;
435 service->RemoveObserver(this);
436 FinishSetupSync();
437 return;
440 DLOG_IF(ERROR, service->GetAuthError().state() ==
441 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)
442 << "Credentials rejected";
445 void SupervisedUserService::SetupSync() {
446 StartSetupSync();
447 FinishSetupSyncWhenReady();
450 void SupervisedUserService::StartSetupSync() {
451 // Tell the sync service that setup is in progress so we don't start syncing
452 // until we've finished configuration.
453 ProfileSyncServiceFactory::GetForProfile(profile_)->SetSetupInProgress(true);
456 void SupervisedUserService::FinishSetupSyncWhenReady() {
457 // If we're already waiting for the Sync backend, there's nothing to do here.
458 if (waiting_for_sync_initialization_)
459 return;
461 // Continue in FinishSetupSync() once the Sync backend has been initialized.
462 ProfileSyncService* service =
463 ProfileSyncServiceFactory::GetForProfile(profile_);
464 if (service->backend_initialized() &&
465 service->backend_mode() == ProfileSyncService::SYNC) {
466 FinishSetupSync();
467 } else {
468 service->AddObserver(this);
469 waiting_for_sync_initialization_ = true;
473 void SupervisedUserService::FinishSetupSync() {
474 ProfileSyncService* service =
475 ProfileSyncServiceFactory::GetForProfile(profile_);
476 DCHECK(service->backend_initialized());
477 DCHECK(service->backend_mode() == ProfileSyncService::SYNC);
479 // Sync nothing (except types which are set via GetPreferredDataTypes).
480 bool sync_everything = false;
481 syncer::ModelTypeSet synced_datatypes;
482 service->OnUserChoseDatatypes(sync_everything, synced_datatypes);
484 // Notify ProfileSyncService that we are done with configuration.
485 service->SetSetupInProgress(false);
486 service->SetSyncSetupCompleted();
489 #if defined(ENABLE_EXTENSIONS)
490 bool SupervisedUserService::ExtensionManagementPolicyImpl(
491 const extensions::Extension* extension,
492 base::string16* error) const {
493 // |extension| can be NULL in unit_tests.
494 if (!ProfileIsSupervised() || (extension && extension->is_theme()))
495 return true;
497 if (elevated_for_testing_)
498 return true;
500 if (error)
501 *error = l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_SUPERVISED_USER);
502 return false;
505 ScopedVector<SupervisedUserSiteList>
506 SupervisedUserService::GetActiveSiteLists() {
507 ScopedVector<SupervisedUserSiteList> site_lists;
508 ExtensionService* extension_service =
509 extensions::ExtensionSystem::Get(profile_)->extension_service();
510 // Can be NULL in unit tests.
511 if (!extension_service)
512 return site_lists.Pass();
514 for (const scoped_refptr<const extensions::Extension>& extension :
515 *extension_service->extensions()) {
516 if (!extension_service->IsExtensionEnabled(extension->id()))
517 continue;
519 extensions::ExtensionResource site_list =
520 extensions::SupervisedUserInfo::GetContentPackSiteList(extension.get());
521 if (!site_list.empty()) {
522 site_lists.push_back(new SupervisedUserSiteList(extension->id(),
523 site_list.GetFilePath()));
527 return site_lists.Pass();
530 void SupervisedUserService::SetExtensionsActive() {
531 extensions::ExtensionSystem* extension_system =
532 extensions::ExtensionSystem::Get(profile_);
533 extensions::ManagementPolicy* management_policy =
534 extension_system->management_policy();
536 if (active_) {
537 if (management_policy)
538 management_policy->RegisterProvider(this);
540 extension_registry_observer_.Add(
541 extensions::ExtensionRegistry::Get(profile_));
542 } else {
543 if (management_policy)
544 management_policy->UnregisterProvider(this);
546 extension_registry_observer_.RemoveAll();
549 #endif // defined(ENABLE_EXTENSIONS)
551 SupervisedUserSettingsService* SupervisedUserService::GetSettingsService() {
552 return SupervisedUserSettingsServiceFactory::GetForProfile(profile_);
555 size_t SupervisedUserService::FindEnabledPermissionRequestCreator(
556 size_t start) {
557 for (size_t i = start; i < permissions_creators_.size(); ++i) {
558 if (permissions_creators_[i]->IsEnabled())
559 return i;
561 return permissions_creators_.size();
564 void SupervisedUserService::AddAccessRequestInternal(
565 const GURL& url,
566 const SuccessCallback& callback,
567 size_t index) {
568 // Find a permission request creator that is enabled.
569 size_t next_index = FindEnabledPermissionRequestCreator(index);
570 if (next_index >= permissions_creators_.size()) {
571 callback.Run(false);
572 return;
575 permissions_creators_[next_index]->CreatePermissionRequest(
576 url,
577 base::Bind(&SupervisedUserService::OnPermissionRequestIssued,
578 weak_ptr_factory_.GetWeakPtr(), url, callback, next_index));
581 void SupervisedUserService::OnPermissionRequestIssued(
582 const GURL& url,
583 const SuccessCallback& callback,
584 size_t index,
585 bool success) {
586 if (success) {
587 callback.Run(true);
588 return;
591 AddAccessRequestInternal(url, callback, index + 1);
594 void SupervisedUserService::OnSupervisedUserIdChanged() {
595 std::string supervised_user_id =
596 profile_->GetPrefs()->GetString(prefs::kSupervisedUserId);
597 SetActive(!supervised_user_id.empty());
600 void SupervisedUserService::OnDefaultFilteringBehaviorChanged() {
601 DCHECK(ProfileIsSupervised());
603 int behavior_value = profile_->GetPrefs()->GetInteger(
604 prefs::kDefaultSupervisedUserFilteringBehavior);
605 SupervisedUserURLFilter::FilteringBehavior behavior =
606 SupervisedUserURLFilter::BehaviorFromInt(behavior_value);
607 url_filter_context_.SetDefaultFilteringBehavior(behavior);
609 FOR_EACH_OBSERVER(
610 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
613 void SupervisedUserService::UpdateSiteLists() {
614 #if defined(ENABLE_EXTENSIONS)
615 url_filter_context_.LoadWhitelists(GetActiveSiteLists());
617 FOR_EACH_OBSERVER(
618 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
619 #endif
622 void SupervisedUserService::LoadBlacklist(const base::FilePath& path,
623 const GURL& url) {
624 if (!url.is_valid()) {
625 LoadBlacklistFromFile(path);
626 return;
629 DCHECK(!blacklist_downloader_.get());
630 blacklist_downloader_.reset(new SupervisedUserBlacklistDownloader(
631 url,
632 path,
633 profile_->GetRequestContext(),
634 base::Bind(&SupervisedUserService::OnBlacklistDownloadDone,
635 base::Unretained(this), path)));
638 void SupervisedUserService::LoadBlacklistFromFile(const base::FilePath& path) {
639 url_filter_context_.LoadBlacklist(path);
641 FOR_EACH_OBSERVER(
642 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
645 void SupervisedUserService::OnBlacklistDownloadDone(const base::FilePath& path,
646 bool success) {
647 if (success) {
648 LoadBlacklistFromFile(path);
649 } else {
650 LOG(WARNING) << "Blacklist download failed";
652 blacklist_downloader_.reset();
655 bool SupervisedUserService::AccessRequestsEnabled() {
656 return FindEnabledPermissionRequestCreator(0) < permissions_creators_.size();
659 void SupervisedUserService::AddAccessRequest(const GURL& url,
660 const SuccessCallback& callback) {
661 AddAccessRequestInternal(SupervisedUserURLFilter::Normalize(url), callback,
665 SupervisedUserService::ManualBehavior
666 SupervisedUserService::GetManualBehaviorForHost(
667 const std::string& hostname) {
668 const base::DictionaryValue* dict =
669 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualHosts);
670 bool allow = false;
671 if (!dict->GetBooleanWithoutPathExpansion(hostname, &allow))
672 return MANUAL_NONE;
674 return allow ? MANUAL_ALLOW : MANUAL_BLOCK;
677 SupervisedUserService::ManualBehavior
678 SupervisedUserService::GetManualBehaviorForURL(
679 const GURL& url) {
680 const base::DictionaryValue* dict =
681 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs);
682 GURL normalized_url = SupervisedUserURLFilter::Normalize(url);
683 bool allow = false;
684 if (!dict->GetBooleanWithoutPathExpansion(normalized_url.spec(), &allow))
685 return MANUAL_NONE;
687 return allow ? MANUAL_ALLOW : MANUAL_BLOCK;
690 void SupervisedUserService::GetManualExceptionsForHost(
691 const std::string& host,
692 std::vector<GURL>* urls) {
693 const base::DictionaryValue* dict =
694 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs);
695 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
696 GURL url(it.key());
697 if (url.host() == host)
698 urls->push_back(url);
702 void SupervisedUserService::InitSync(const std::string& refresh_token) {
703 StartSetupSync();
705 ProfileOAuth2TokenService* token_service =
706 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
707 token_service->UpdateCredentials(supervised_users::kSupervisedUserPseudoEmail,
708 refresh_token);
710 FinishSetupSyncWhenReady();
713 void SupervisedUserService::Init() {
714 DCHECK(!did_init_);
715 did_init_ = true;
716 DCHECK(GetSettingsService()->IsReady());
718 pref_change_registrar_.Init(profile_->GetPrefs());
719 pref_change_registrar_.Add(
720 prefs::kSupervisedUserId,
721 base::Bind(&SupervisedUserService::OnSupervisedUserIdChanged,
722 base::Unretained(this)));
723 pref_change_registrar_.Add(
724 prefs::kRecordHistory,
725 base::Bind(&SupervisedUserService::OnHistoryRecordingStateChanged,
726 base::Unretained(this)));
728 ProfileSyncService* sync_service =
729 ProfileSyncServiceFactory::GetForProfile(profile_);
730 // Can be null in tests.
731 if (sync_service)
732 sync_service->AddPreferenceProvider(this);
734 SetActive(ProfileIsSupervised());
737 void SupervisedUserService::SetActive(bool active) {
738 if (active_ == active)
739 return;
740 active_ = active;
742 if (!delegate_ || !delegate_->SetActive(active_)) {
743 if (active_) {
744 SupervisedUserPrefMappingServiceFactory::GetForBrowserContext(profile_)
745 ->Init();
747 CommandLine* command_line = CommandLine::ForCurrentProcess();
748 if (command_line->HasSwitch(switches::kSupervisedUserSyncToken)) {
749 InitSync(
750 command_line->GetSwitchValueASCII(
751 switches::kSupervisedUserSyncToken));
754 ProfileOAuth2TokenService* token_service =
755 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
756 token_service->LoadCredentials(
757 supervised_users::kSupervisedUserPseudoEmail);
759 SetupSync();
763 // Now activate/deactivate anything not handled by the delegate yet.
765 #if defined(ENABLE_THEMES)
766 // Re-set the default theme to turn the SU theme on/off.
767 ThemeService* theme_service = ThemeServiceFactory::GetForProfile(profile_);
768 if (theme_service->UsingDefaultTheme() || theme_service->UsingSystemTheme()) {
769 ThemeServiceFactory::GetForProfile(profile_)->UseDefaultTheme();
771 #endif
773 GetSettingsService()->SetActive(active_);
775 #if defined(ENABLE_EXTENSIONS)
776 SetExtensionsActive();
777 #endif
779 if (active_) {
780 if (CommandLine::ForCurrentProcess()->HasSwitch(
781 switches::kPermissionRequestApiUrl)) {
782 GURL url(CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
783 switches::kPermissionRequestApiUrl));
784 if (url.is_valid()) {
785 scoped_ptr<PermissionRequestCreator> creator =
786 PermissionRequestCreatorApiary::CreateWithProfile(profile_, url);
787 permissions_creators_.push_back(creator.release());
788 } else {
789 LOG(WARNING) << "Got invalid URL for "
790 << switches::kPermissionRequestApiUrl;
792 } else {
793 permissions_creators_.push_back(new PermissionRequestCreatorSync(
794 GetSettingsService(),
795 SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext(
796 profile_),
797 ProfileSyncServiceFactory::GetForProfile(profile_),
798 GetSupervisedUserName(),
799 profile_->GetPrefs()->GetString(prefs::kSupervisedUserId)));
802 pref_change_registrar_.Add(
803 prefs::kDefaultSupervisedUserFilteringBehavior,
804 base::Bind(&SupervisedUserService::OnDefaultFilteringBehaviorChanged,
805 base::Unretained(this)));
806 pref_change_registrar_.Add(prefs::kSupervisedUserManualHosts,
807 base::Bind(&SupervisedUserService::UpdateManualHosts,
808 base::Unretained(this)));
809 pref_change_registrar_.Add(prefs::kSupervisedUserManualURLs,
810 base::Bind(&SupervisedUserService::UpdateManualURLs,
811 base::Unretained(this)));
812 pref_change_registrar_.Add(prefs::kSupervisedUserCustodianName,
813 base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
814 base::Unretained(this)));
815 pref_change_registrar_.Add(prefs::kSupervisedUserCustodianEmail,
816 base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
817 base::Unretained(this)));
818 pref_change_registrar_.Add(prefs::kSupervisedUserCustodianProfileImageURL,
819 base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
820 base::Unretained(this)));
821 pref_change_registrar_.Add(prefs::kSupervisedUserCustodianProfileURL,
822 base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
823 base::Unretained(this)));
824 pref_change_registrar_.Add(prefs::kSupervisedUserSecondCustodianName,
825 base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
826 base::Unretained(this)));
827 pref_change_registrar_.Add(prefs::kSupervisedUserSecondCustodianEmail,
828 base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
829 base::Unretained(this)));
830 pref_change_registrar_.Add(
831 prefs::kSupervisedUserSecondCustodianProfileImageURL,
832 base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
833 base::Unretained(this)));
834 pref_change_registrar_.Add(prefs::kSupervisedUserSecondCustodianProfileURL,
835 base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
836 base::Unretained(this)));
838 // Initialize the filter.
839 OnDefaultFilteringBehaviorChanged();
840 UpdateSiteLists();
841 UpdateManualHosts();
842 UpdateManualURLs();
843 bool use_blacklist =
844 CommandLine::ForCurrentProcess()->HasSwitch(
845 switches::kEnableSupervisedUserBlacklist);
846 if (delegate_ && use_blacklist) {
847 base::FilePath blacklist_path = delegate_->GetBlacklistPath();
848 if (!blacklist_path.empty())
849 LoadBlacklist(blacklist_path, delegate_->GetBlacklistURL());
852 #if !defined(OS_ANDROID)
853 // TODO(bauerb): Get rid of the platform-specific #ifdef here.
854 // http://crbug.com/313377
855 BrowserList::AddObserver(this);
856 #endif
857 } else {
858 permissions_creators_.clear();
860 pref_change_registrar_.Remove(
861 prefs::kDefaultSupervisedUserFilteringBehavior);
862 pref_change_registrar_.Remove(prefs::kSupervisedUserManualHosts);
863 pref_change_registrar_.Remove(prefs::kSupervisedUserManualURLs);
865 if (waiting_for_sync_initialization_)
866 ProfileSyncServiceFactory::GetForProfile(profile_)->RemoveObserver(this);
868 #if !defined(OS_ANDROID)
869 // TODO(bauerb): Get rid of the platform-specific #ifdef here.
870 // http://crbug.com/313377
871 BrowserList::RemoveObserver(this);
872 #endif
876 void SupervisedUserService::RegisterAndInitSync(
877 SupervisedUserRegistrationUtility* registration_utility,
878 Profile* custodian_profile,
879 const std::string& supervised_user_id,
880 const AuthErrorCallback& callback) {
881 DCHECK(ProfileIsSupervised());
882 DCHECK(!custodian_profile->IsSupervised());
884 base::string16 name = base::UTF8ToUTF16(
885 profile_->GetPrefs()->GetString(prefs::kProfileName));
886 int avatar_index = profile_->GetPrefs()->GetInteger(
887 prefs::kProfileAvatarIndex);
888 SupervisedUserRegistrationInfo info(name, avatar_index);
889 registration_utility->Register(
890 supervised_user_id,
891 info,
892 base::Bind(&SupervisedUserService::OnSupervisedUserRegistered,
893 weak_ptr_factory_.GetWeakPtr(), callback, custodian_profile));
895 // Fetch the custodian's profile information, to store the name.
896 // TODO(pamg): If --google-profile-info (flag: switches::kGoogleProfileInfo)
897 // is ever enabled, take the name from the ProfileInfoCache instead.
898 CustodianProfileDownloaderService* profile_downloader_service =
899 CustodianProfileDownloaderServiceFactory::GetForProfile(
900 custodian_profile);
901 profile_downloader_service->DownloadProfile(
902 base::Bind(&SupervisedUserService::OnCustodianProfileDownloaded,
903 weak_ptr_factory_.GetWeakPtr()));
906 void SupervisedUserService::OnCustodianProfileDownloaded(
907 const base::string16& full_name) {
908 profile_->GetPrefs()->SetString(prefs::kSupervisedUserCustodianName,
909 base::UTF16ToUTF8(full_name));
912 void SupervisedUserService::OnSupervisedUserRegistered(
913 const AuthErrorCallback& callback,
914 Profile* custodian_profile,
915 const GoogleServiceAuthError& auth_error,
916 const std::string& token) {
917 if (auth_error.state() == GoogleServiceAuthError::NONE) {
918 InitSync(token);
919 SigninManagerBase* signin =
920 SigninManagerFactory::GetForProfile(custodian_profile);
921 profile_->GetPrefs()->SetString(prefs::kSupervisedUserCustodianEmail,
922 signin->GetAuthenticatedUsername());
924 // The supervised user profile is now ready for use.
925 ProfileManager* profile_manager = g_browser_process->profile_manager();
926 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
927 size_t index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
928 cache.SetIsOmittedProfileAtIndex(index, false);
929 } else {
930 DCHECK_EQ(std::string(), token);
933 callback.Run(auth_error);
936 void SupervisedUserService::UpdateManualHosts() {
937 const base::DictionaryValue* dict =
938 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualHosts);
939 scoped_ptr<std::map<std::string, bool> > host_map(
940 new std::map<std::string, bool>());
941 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
942 bool allow = false;
943 bool result = it.value().GetAsBoolean(&allow);
944 DCHECK(result);
945 (*host_map)[it.key()] = allow;
947 url_filter_context_.SetManualHosts(host_map.Pass());
949 FOR_EACH_OBSERVER(
950 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
953 void SupervisedUserService::UpdateManualURLs() {
954 const base::DictionaryValue* dict =
955 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs);
956 scoped_ptr<std::map<GURL, bool> > url_map(new std::map<GURL, bool>());
957 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
958 bool allow = false;
959 bool result = it.value().GetAsBoolean(&allow);
960 DCHECK(result);
961 (*url_map)[GURL(it.key())] = allow;
963 url_filter_context_.SetManualURLs(url_map.Pass());
965 FOR_EACH_OBSERVER(
966 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
969 void SupervisedUserService::OnBrowserSetLastActive(Browser* browser) {
970 bool profile_became_active = profile_->IsSameProfile(browser->profile());
971 if (!is_profile_active_ && profile_became_active)
972 content::RecordAction(UserMetricsAction("ManagedUsers_OpenProfile"));
973 else if (is_profile_active_ && !profile_became_active)
974 content::RecordAction(UserMetricsAction("ManagedUsers_SwitchProfile"));
976 is_profile_active_ = profile_became_active;
979 std::string SupervisedUserService::GetSupervisedUserName() const {
980 #if defined(OS_CHROMEOS)
981 // The active user can be NULL in unit tests.
982 if (user_manager::UserManager::Get()->GetActiveUser()) {
983 return UTF16ToUTF8(user_manager::UserManager::Get()->GetUserDisplayName(
984 user_manager::UserManager::Get()->GetActiveUser()->GetUserID()));
986 return std::string();
987 #else
988 return profile_->GetPrefs()->GetString(prefs::kProfileName);
989 #endif