1f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/supervised_user/supervised_user_service.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/command_line.h"
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_path.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/ref_counted.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/strings/string_number_conversions.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/browser_process.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/profiles/profile.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/profiles/profile_info_cache.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/signin/signin_manager_factory.h"
19f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/supervised_user/custodian_profile_downloader_service.h"
20f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/supervised_user/custodian_profile_downloader_service_factory.h"
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/supervised_user/experimental/supervised_user_blacklist_downloader.h"
22f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/supervised_user/permission_request_creator_apiary.h"
23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/supervised_user/permission_request_creator_sync.h"
24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/supervised_user/supervised_user_constants.h"
25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/supervised_user/supervised_user_pref_mapping_service.h"
26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/supervised_user/supervised_user_pref_mapping_service_factory.h"
27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/supervised_user/supervised_user_registration_utility.h"
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/supervised_user/supervised_user_service_observer.h"
29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/supervised_user/supervised_user_settings_service.h"
30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h"
31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/supervised_user/supervised_user_shared_settings_service_factory.h"
32f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/supervised_user/supervised_user_site_list.h"
33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/supervised_user/supervised_user_sync_service.h"
34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/supervised_user/supervised_user_sync_service_factory.h"
3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/sync/profile_sync_service.h"
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/sync/profile_sync_service_factory.h"
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser.h"
387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/ui/browser_list.h"
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/common/chrome_switches.h"
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/pref_names.h"
4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/grit/generated_resources.h"
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/pref_registry/pref_registry_syncable.h"
43effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "components/signin/core/browser/profile_oauth2_token_service.h"
44e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "components/signin/core/browser/signin_manager.h"
45effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "components/signin/core/browser/signin_manager_base.h"
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/public/browser/user_metrics.h"
48a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "google_apis/gaia/google_service_auth_error.h"
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
51ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#if defined(OS_CHROMEOS)
526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/user_manager/user_manager.h"
55ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#endif
56ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(ENABLE_EXTENSIONS)
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/extensions/extension_service.h"
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/common/extensions/api/supervised_user_private/supervised_user_handler.h"
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/browser/extension_registry.h"
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/browser/extension_system.h"
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/common/extension_set.h"
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
65f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(ENABLE_THEMES)
66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/themes/theme_service.h"
67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/themes/theme_service_factory.h"
68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif
69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using base::DictionaryValue;
71c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochusing base::UserMetricsAction;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::BrowserThread;
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)SupervisedUserService::URLFilterContext::URLFilterContext()
75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    : ui_url_filter_(new SupervisedUserURLFilter),
76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      io_url_filter_(new SupervisedUserURLFilter) {}
77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)SupervisedUserService::URLFilterContext::~URLFilterContext() {}
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)SupervisedUserURLFilter*
80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)SupervisedUserService::URLFilterContext::ui_url_filter() const {
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ui_url_filter_.get();
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)SupervisedUserURLFilter*
85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)SupervisedUserService::URLFilterContext::io_url_filter() const {
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return io_url_filter_.get();
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::URLFilterContext::SetDefaultFilteringBehavior(
90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    SupervisedUserURLFilter::FilteringBehavior behavior) {
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui_url_filter_->SetDefaultFilteringBehavior(behavior);
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserThread::PostTask(
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BrowserThread::IO,
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      base::Bind(&SupervisedUserURLFilter::SetDefaultFilteringBehavior,
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 io_url_filter_.get(), behavior));
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::URLFilterContext::LoadWhitelists(
100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ScopedVector<SupervisedUserSiteList> site_lists) {
101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // SupervisedUserURLFilter::LoadWhitelists takes ownership of |site_lists|,
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // so we make an additional copy of it.
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  /// TODO(bauerb): This is kinda ugly.
104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ScopedVector<SupervisedUserSiteList> site_lists_copy;
105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  for (ScopedVector<SupervisedUserSiteList>::iterator it = site_lists.begin();
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != site_lists.end(); ++it) {
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    site_lists_copy.push_back((*it)->Clone());
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui_url_filter_->LoadWhitelists(site_lists.Pass());
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserThread::PostTask(
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BrowserThread::IO,
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      base::Bind(&SupervisedUserURLFilter::LoadWhitelists,
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 io_url_filter_, base::Passed(&site_lists_copy)));
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid SupervisedUserService::URLFilterContext::LoadBlacklist(
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const base::FilePath& path) {
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // For now, support loading only once. If we want to support re-load, we'll
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // have to clear the blacklist pointer in the url filters first.
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK_EQ(0u, blacklist_.GetEntryCount());
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blacklist_.ReadFromFile(
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      path,
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&SupervisedUserService::URLFilterContext::OnBlacklistLoaded,
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 base::Unretained(this)));
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::URLFilterContext::SetManualHosts(
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<std::map<std::string, bool> > host_map) {
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui_url_filter_->SetManualHosts(host_map.get());
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserThread::PostTask(
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BrowserThread::IO,
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
134f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      base::Bind(&SupervisedUserURLFilter::SetManualHosts,
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 io_url_filter_, base::Owned(host_map.release())));
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
138f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::URLFilterContext::SetManualURLs(
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<std::map<GURL, bool> > url_map) {
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui_url_filter_->SetManualURLs(url_map.get());
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserThread::PostTask(
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BrowserThread::IO,
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
144f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      base::Bind(&SupervisedUserURLFilter::SetManualURLs,
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 io_url_filter_, base::Owned(url_map.release())));
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid SupervisedUserService::URLFilterContext::OnBlacklistLoaded() {
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ui_url_filter_->SetBlacklist(&blacklist_);
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  BrowserThread::PostTask(
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      BrowserThread::IO,
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      FROM_HERE,
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&SupervisedUserURLFilter::SetBlacklist,
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 io_url_filter_,
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 &blacklist_));
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
158f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)SupervisedUserService::SupervisedUserService(Profile* profile)
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    : profile_(profile),
160f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      active_(false),
161f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      delegate_(NULL),
162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(ENABLE_EXTENSIONS)
163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      extension_registry_observer_(this),
164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif
165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      waiting_for_sync_initialization_(false),
1667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      is_profile_active_(false),
1677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      elevated_for_testing_(false),
1686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      did_init_(false),
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      did_shutdown_(false),
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      weak_ptr_factory_(this) {
171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
173f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)SupervisedUserService::~SupervisedUserService() {
1746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(!did_init_ || did_shutdown_);
1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
177f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::Shutdown() {
1786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!did_init_)
1796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return;
1806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(!did_shutdown_);
1817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  did_shutdown_ = true;
182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (ProfileIsSupervised()) {
183c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    content::RecordAction(UserMetricsAction("ManagedUsers_QuitBrowser"));
1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
185f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  SetActive(false);
1866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ProfileSyncService* sync_service =
1886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      ProfileSyncServiceFactory::GetForProfile(profile_);
1896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Can be null in tests.
1906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (sync_service)
1916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    sync_service->RemovePreferenceProvider(this);
192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
194f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool SupervisedUserService::ProfileIsSupervised() const {
195f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return profile_->IsSupervised();
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid SupervisedUserService::OnCustodianInfoChanged() {
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  FOR_EACH_OBSERVER(
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SupervisedUserServiceObserver, observer_list_, OnCustodianInfoChanged());
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
204f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::RegisterProfilePrefs(
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    user_prefs::PrefRegistrySyncable* registry) {
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  registry->RegisterDictionaryPref(
207f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      prefs::kSupervisedUserManualHosts,
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  registry->RegisterDictionaryPref(
210f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      prefs::kSupervisedUserManualURLs,
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  registry->RegisterIntegerPref(
213f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      prefs::kDefaultSupervisedUserFilteringBehavior,
214f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      SupervisedUserURLFilter::ALLOW,
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  registry->RegisterStringPref(
217f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      prefs::kSupervisedUserCustodianEmail, std::string(),
218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  registry->RegisterStringPref(
220f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      prefs::kSupervisedUserCustodianName, std::string(),
221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  registry->RegisterStringPref(
2236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      prefs::kSupervisedUserCustodianProfileImageURL, std::string(),
2246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  registry->RegisterStringPref(
2266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      prefs::kSupervisedUserCustodianProfileURL, std::string(),
2276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  registry->RegisterStringPref(
2296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      prefs::kSupervisedUserSecondCustodianEmail, std::string(),
2306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  registry->RegisterStringPref(
2326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      prefs::kSupervisedUserSecondCustodianName, std::string(),
2336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  registry->RegisterStringPref(
2356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      prefs::kSupervisedUserSecondCustodianProfileImageURL, std::string(),
2366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  registry->RegisterStringPref(
2386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      prefs::kSupervisedUserSecondCustodianProfileURL, std::string(),
2396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
240f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  registry->RegisterBooleanPref(prefs::kSupervisedUserCreationAllowed, true,
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
244f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::SetDelegate(Delegate* delegate) {
2456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (delegate) {
2466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // Changing delegates isn't allowed.
2476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    DCHECK(!delegate_);
2486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  } else {
2496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // If the delegate is removed, deactivate first to give the old delegate a
2506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // chance to clean up.
2516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    SetActive(false);
2526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  delegate_ = delegate;
2543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)scoped_refptr<const SupervisedUserURLFilter>
257f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)SupervisedUserService::GetURLFilterForIOThread() {
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return url_filter_context_.io_url_filter();
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
261f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)SupervisedUserURLFilter* SupervisedUserService::GetURLFilterForUIThread() {
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return url_filter_context_.ui_url_filter();
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Items not on any list must return -1 (CATEGORY_NOT_ON_LIST in history.js).
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Items on a list, but with no category, must return 0 (CATEGORY_OTHER).
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define CATEGORY_NOT_ON_LIST -1;
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define CATEGORY_OTHER 0;
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)int SupervisedUserService::GetCategory(const GURL& url) {
271f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::vector<SupervisedUserSiteList::Site*> sites;
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetURLFilterForUIThread()->GetSites(url, &sites);
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (sites.empty())
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return CATEGORY_NOT_ON_LIST;
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (*sites.begin())->category_id;
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::GetCategoryNames(CategoryList* list) {
281f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  SupervisedUserSiteList::GetCategoryNames(list);
28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
284f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)std::string SupervisedUserService::GetCustodianEmailAddress() const {
285ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#if defined(OS_CHROMEOS)
2866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return chromeos::ChromeUserManager::Get()
2876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      ->GetSupervisedUserManager()
2886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      ->GetManagerDisplayEmail(
2896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          user_manager::UserManager::Get()->GetActiveUser()->email());
290ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#else
291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return profile_->GetPrefs()->GetString(prefs::kSupervisedUserCustodianEmail);
292ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#endif
293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
295f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)std::string SupervisedUserService::GetCustodianName() const {
296ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#if defined(OS_CHROMEOS)
2976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return base::UTF16ToUTF8(
2986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      chromeos::ChromeUserManager::Get()
2996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          ->GetSupervisedUserManager()
3006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          ->GetManagerDisplayName(
3016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)              user_manager::UserManager::Get()->GetActiveUser()->email()));
302ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#else
303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string name = profile_->GetPrefs()->GetString(
304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      prefs::kSupervisedUserCustodianName);
305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return name.empty() ? GetCustodianEmailAddress() : name;
306ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#endif
307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::AddNavigationBlockedCallback(
3103240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const NavigationBlockedCallback& callback) {
3113240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  navigation_blocked_callbacks_.push_back(callback);
3123240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
3133240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
314f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::DidBlockNavigation(
3153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    content::WebContents* web_contents) {
3163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  for (std::vector<NavigationBlockedCallback>::iterator it =
3173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch           navigation_blocked_callbacks_.begin();
3183240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch       it != navigation_blocked_callbacks_.end(); ++it) {
3193240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    it->Run(web_contents);
3203240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  }
3213240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
3223240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid SupervisedUserService::AddObserver(
3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SupervisedUserServiceObserver* observer) {
3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  observer_list_.AddObserver(observer);
3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid SupervisedUserService::RemoveObserver(
3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SupervisedUserServiceObserver* observer) {
3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  observer_list_.RemoveObserver(observer);
3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
333116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(ENABLE_EXTENSIONS)
334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)std::string SupervisedUserService::GetDebugPolicyProviderName() const {
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Save the string space in official builds.
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef NDEBUG
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NOTREACHED();
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return std::string();
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
340f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return "Supervised User Service";
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
344f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool SupervisedUserService::UserMayLoad(const extensions::Extension* extension,
345f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                        base::string16* error) const {
346a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 tmp_error;
347558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (ExtensionManagementPolicyImpl(extension, &tmp_error))
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
350424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool was_installed_by_default = extension->was_installed_by_default();
351116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool was_installed_by_custodian = extension->was_installed_by_custodian();
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_CHROMEOS)
353424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // On Chrome OS all external sources are controlled by us so it means that
354424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // they are "default". Method was_installed_by_default returns false because
355424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // extensions creation flags are ignored in case of default extensions with
356424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // update URL(the flags aren't passed to OnExternalExtensionUpdateUrlFound).
357424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // TODO(dpolukhin): remove this Chrome OS specific code as soon as creation
358424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // flags are not ignored.
359424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  was_installed_by_default =
360424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      extensions::Manifest::IsExternalLocation(extension->location());
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (extensions::Manifest::IsComponentLocation(extension->location()) ||
363116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      was_installed_by_default ||
364116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      was_installed_by_custodian) {
365424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return true;
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (error)
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *error = tmp_error;
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
373f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool SupervisedUserService::UserMayModifySettings(
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const extensions::Extension* extension,
375a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::string16* error) const {
376558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return ExtensionManagementPolicyImpl(extension, error);
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
379116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid SupervisedUserService::OnExtensionLoaded(
380116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    content::BrowserContext* browser_context,
381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const extensions::Extension* extension) {
382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!extensions::SupervisedUserInfo::GetContentPackSiteList(extension)
383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch           .empty()) {
384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    UpdateSiteLists();
385116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
386116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
387116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid SupervisedUserService::OnExtensionUnloaded(
388116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    content::BrowserContext* browser_context,
389116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const extensions::Extension* extension,
390116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    extensions::UnloadedExtensionInfo::Reason reason) {
391116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!extensions::SupervisedUserInfo::GetContentPackSiteList(extension)
392116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch           .empty()) {
393116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    UpdateSiteLists();
394116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
395116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
396116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif  // defined(ENABLE_EXTENSIONS)
397116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)syncer::ModelTypeSet SupervisedUserService::GetPreferredDataTypes() const {
3996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!ProfileIsSupervised())
4006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return syncer::ModelTypeSet();
4016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  syncer::ModelTypeSet result;
4036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  result.Put(syncer::SESSIONS);
4046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  result.Put(syncer::EXTENSIONS);
4056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  result.Put(syncer::EXTENSION_SETTINGS);
4066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  result.Put(syncer::APPS);
4076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  result.Put(syncer::APP_SETTINGS);
4086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  result.Put(syncer::APP_NOTIFICATIONS);
4096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  result.Put(syncer::APP_LIST);
4106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return result;
4116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
4126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
413f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::OnStateChanged() {
414eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ProfileSyncService* service =
415eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      ProfileSyncServiceFactory::GetForProfile(profile_);
4161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (waiting_for_sync_initialization_ && service->sync_initialized() &&
4171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      service->backend_mode() == ProfileSyncService::SYNC) {
418eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    waiting_for_sync_initialization_ = false;
4199ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    service->RemoveObserver(this);
420116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    FinishSetupSync();
421eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
422eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
423eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
424eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DLOG_IF(ERROR, service->GetAuthError().state() ==
425eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)
426eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      << "Credentials rejected";
427eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
428eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
429116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid SupervisedUserService::SetupSync() {
430116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  StartSetupSync();
431116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  FinishSetupSyncWhenReady();
432cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
433116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
434116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid SupervisedUserService::StartSetupSync() {
435116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Tell the sync service that setup is in progress so we don't start syncing
436116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // until we've finished configuration.
437116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ProfileSyncServiceFactory::GetForProfile(profile_)->SetSetupInProgress(true);
438116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
439116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
440116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid SupervisedUserService::FinishSetupSyncWhenReady() {
441116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // If we're already waiting for the Sync backend, there's nothing to do here.
442116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (waiting_for_sync_initialization_)
443116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
444116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
445116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Continue in FinishSetupSync() once the Sync backend has been initialized.
446116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ProfileSyncService* service =
447116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ProfileSyncServiceFactory::GetForProfile(profile_);
4481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (service->sync_initialized() &&
4491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      service->backend_mode() == ProfileSyncService::SYNC) {
450116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    FinishSetupSync();
451116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else {
452116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    service->AddObserver(this);
453116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    waiting_for_sync_initialization_ = true;
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
457116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid SupervisedUserService::FinishSetupSync() {
458eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ProfileSyncService* service =
459eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      ProfileSyncServiceFactory::GetForProfile(profile_);
4601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(service->sync_initialized() &&
4611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         service->backend_mode() == ProfileSyncService::SYNC);
462eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
4636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Sync nothing (except types which are set via GetPreferredDataTypes).
464eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bool sync_everything = false;
465eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  syncer::ModelTypeSet synced_datatypes;
466eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  service->OnUserChoseDatatypes(sync_everything, synced_datatypes);
467eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
468eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Notify ProfileSyncService that we are done with configuration.
469eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  service->SetSetupInProgress(false);
470eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  service->SetSyncSetupCompleted();
471eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
472eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
473116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(ENABLE_EXTENSIONS)
474f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool SupervisedUserService::ExtensionManagementPolicyImpl(
475558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    const extensions::Extension* extension,
476a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::string16* error) const {
477558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // |extension| can be NULL in unit_tests.
478f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!ProfileIsSupervised() || (extension && extension->is_theme()))
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
48190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (elevated_for_testing_)
48290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return true;
48390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (error)
485116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    *error = l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_SUPERVISED_USER);
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
489f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)ScopedVector<SupervisedUserSiteList>
490f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)SupervisedUserService::GetActiveSiteLists() {
491f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ScopedVector<SupervisedUserSiteList> site_lists;
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExtensionService* extension_service =
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions::ExtensionSystem::Get(profile_)->extension_service();
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Can be NULL in unit tests.
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!extension_service)
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return site_lists.Pass();
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const extensions::ExtensionSet* extensions = extension_service->extensions();
4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (extensions::ExtensionSet::const_iterator it = extensions->begin();
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != extensions->end(); ++it) {
5017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const extensions::Extension* extension = it->get();
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!extension_service->IsExtensionEnabled(extension->id()))
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    extensions::ExtensionResource site_list =
506116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        extensions::SupervisedUserInfo::GetContentPackSiteList(extension);
507f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!site_list.empty()) {
508f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      site_lists.push_back(new SupervisedUserSiteList(extension->id(),
509f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                                      site_list.GetFilePath()));
510f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return site_lists.Pass();
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
516116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid SupervisedUserService::SetExtensionsActive() {
517116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  extensions::ExtensionSystem* extension_system =
518116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      extensions::ExtensionSystem::Get(profile_);
519116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  extensions::ManagementPolicy* management_policy =
520116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      extension_system->management_policy();
521116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
522116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (active_) {
523116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (management_policy)
524116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      management_policy->RegisterProvider(this);
525116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
526116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    extension_registry_observer_.Add(
527116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        extensions::ExtensionRegistry::Get(profile_));
528116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else {
529116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (management_policy)
530116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      management_policy->UnregisterProvider(this);
531116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
532116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    extension_registry_observer_.RemoveAll();
533116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
534116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
535116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif  // defined(ENABLE_EXTENSIONS)
536116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
537f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)SupervisedUserSettingsService* SupervisedUserService::GetSettingsService() {
538f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return SupervisedUserSettingsServiceFactory::GetForProfile(profile_);
539f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
540f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
541f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::OnSupervisedUserIdChanged() {
542f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::string supervised_user_id =
543f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      profile_->GetPrefs()->GetString(prefs::kSupervisedUserId);
544f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  SetActive(!supervised_user_id.empty());
5457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
5467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
547f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::OnDefaultFilteringBehaviorChanged() {
548f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(ProfileIsSupervised());
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int behavior_value = profile_->GetPrefs()->GetInteger(
551f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      prefs::kDefaultSupervisedUserFilteringBehavior);
552f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  SupervisedUserURLFilter::FilteringBehavior behavior =
553f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      SupervisedUserURLFilter::BehaviorFromInt(behavior_value);
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_filter_context_.SetDefaultFilteringBehavior(behavior);
5551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  FOR_EACH_OBSERVER(
5571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
560f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::UpdateSiteLists() {
561116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(ENABLE_EXTENSIONS)
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_filter_context_.LoadWhitelists(GetActiveSiteLists());
5631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  FOR_EACH_OBSERVER(
5651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
566116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid SupervisedUserService::LoadBlacklist(const base::FilePath& path,
5701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                          const GURL& url) {
5711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!url.is_valid()) {
5721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    LoadBlacklistFromFile(path);
5731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
5741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
5751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(!blacklist_downloader_.get());
5771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blacklist_downloader_.reset(new SupervisedUserBlacklistDownloader(
5781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url,
5791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      path,
5801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      profile_->GetRequestContext(),
5811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&SupervisedUserService::OnBlacklistDownloadDone,
5821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 base::Unretained(this), path)));
5831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
584cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
5851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid SupervisedUserService::LoadBlacklistFromFile(const base::FilePath& path) {
5861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  url_filter_context_.LoadBlacklist(path);
5871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  FOR_EACH_OBSERVER(
5891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
5901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
5911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid SupervisedUserService::OnBlacklistDownloadDone(const base::FilePath& path,
5931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                    bool success) {
5941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (success) {
5951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    LoadBlacklistFromFile(path);
5961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else {
5971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    LOG(WARNING) << "Blacklist download failed";
5981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
5991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blacklist_downloader_.reset();
6001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
6011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool SupervisedUserService::AccessRequestsEnabled() {
603ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ProfileSyncService* service =
604ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      ProfileSyncServiceFactory::GetForProfile(profile_);
605ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  GoogleServiceAuthError::State state = service->GetAuthError().state();
606ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // We allow requesting access if Sync is working or has a transient error.
607ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  return (state == GoogleServiceAuthError::NONE ||
608ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          state == GoogleServiceAuthError::CONNECTION_FAILED ||
609ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          state == GoogleServiceAuthError::SERVICE_UNAVAILABLE);
610ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
611ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
612f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::OnPermissionRequestIssued() {
613cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO(akuegel): Figure out how to show the result of issuing the permission
614cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // request in the UI. Currently, we assume the permission request was created
615cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // successfully.
616cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
617cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
618f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::AddAccessRequest(const GURL& url) {
619cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  permissions_creator_->CreatePermissionRequest(
6201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SupervisedUserURLFilter::Normalize(url),
621f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      base::Bind(&SupervisedUserService::OnPermissionRequestIssued,
622cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
6237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
6247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
625f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)SupervisedUserService::ManualBehavior
626f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)SupervisedUserService::GetManualBehaviorForHost(
6277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::string& hostname) {
6285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::DictionaryValue* dict =
629f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualHosts);
6307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool allow = false;
6317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!dict->GetBooleanWithoutPathExpansion(hostname, &allow))
6327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return MANUAL_NONE;
6337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return allow ? MANUAL_ALLOW : MANUAL_BLOCK;
635868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
636868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
637f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)SupervisedUserService::ManualBehavior
638f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)SupervisedUserService::GetManualBehaviorForURL(
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& url) {
6405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::DictionaryValue* dict =
641f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs);
642f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  GURL normalized_url = SupervisedUserURLFilter::Normalize(url);
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool allow = false;
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!dict->GetBooleanWithoutPathExpansion(normalized_url.spec(), &allow))
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return MANUAL_NONE;
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return allow ? MANUAL_ALLOW : MANUAL_BLOCK;
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
650f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::GetManualExceptionsForHost(
651f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const std::string& host,
652f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    std::vector<GURL>* urls) {
6535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::DictionaryValue* dict =
654f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs);
6555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GURL url(it.key());
657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (url.host() == host)
658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      urls->push_back(url);
659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
662f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::InitSync(const std::string& refresh_token) {
663116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  StartSetupSync();
66490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
665f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ProfileOAuth2TokenService* token_service =
666f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
667f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  token_service->UpdateCredentials(supervised_users::kSupervisedUserPseudoEmail,
668f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                   refresh_token);
669eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
670116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  FinishSetupSyncWhenReady();
67190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
67290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
673f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::Init() {
6746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(!did_init_);
6756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  did_init_ = true;
676f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(GetSettingsService()->IsReady());
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
678f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  pref_change_registrar_.Init(profile_->GetPrefs());
679f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  pref_change_registrar_.Add(
680f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      prefs::kSupervisedUserId,
681f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      base::Bind(&SupervisedUserService::OnSupervisedUserIdChanged,
682f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          base::Unretained(this)));
68358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ProfileSyncService* sync_service =
6856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      ProfileSyncServiceFactory::GetForProfile(profile_);
6866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Can be null in tests.
6876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (sync_service)
6886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    sync_service->AddPreferenceProvider(this);
6896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
690f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  SetActive(ProfileIsSupervised());
691f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
6925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
693f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::SetActive(bool active) {
694f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (active_ == active)
695f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
696f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  active_ = active;
697f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
698f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!delegate_ || !delegate_->SetActive(active_)) {
699f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (active_) {
700f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      SupervisedUserPrefMappingServiceFactory::GetForBrowserContext(profile_)
701f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          ->Init();
702f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
703f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      CommandLine* command_line = CommandLine::ForCurrentProcess();
704f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      if (command_line->HasSwitch(switches::kSupervisedUserSyncToken)) {
705f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        InitSync(
706f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            command_line->GetSwitchValueASCII(
707f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                switches::kSupervisedUserSyncToken));
708f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      }
709f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
710f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ProfileOAuth2TokenService* token_service =
711f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
712f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      token_service->LoadCredentials(
713f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          supervised_users::kSupervisedUserPseudoEmail);
714116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
715116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      SetupSync();
716f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
71790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
71890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
719f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Now activate/deactivate anything not handled by the delegate yet.
720f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
721f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(ENABLE_THEMES)
722f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Re-set the default theme to turn the SU theme on/off.
723f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ThemeService* theme_service = ThemeServiceFactory::GetForProfile(profile_);
724f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (theme_service->UsingDefaultTheme() || theme_service->UsingSystemTheme()) {
725f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ThemeServiceFactory::GetForProfile(profile_)->UseDefaultTheme();
726cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
727f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif
728f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
729ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch  ProfileSyncService* sync_service =
730ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch      ProfileSyncServiceFactory::GetForProfile(profile_);
731ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch  sync_service->SetEncryptEverythingAllowed(!active_);
732ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch
733f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  SupervisedUserSettingsService* settings_service = GetSettingsService();
734f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  settings_service->SetActive(active_);
735eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
736116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(ENABLE_EXTENSIONS)
737116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SetExtensionsActive();
738116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
740f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (active_) {
741f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (CommandLine::ForCurrentProcess()->HasSwitch(
742f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            switches::kPermissionRequestApiUrl)) {
743f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      permissions_creator_ =
744f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          PermissionRequestCreatorApiary::CreateWithProfile(profile_);
745f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    } else {
746f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      PrefService* pref_service = profile_->GetPrefs();
747f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      permissions_creator_.reset(new PermissionRequestCreatorSync(
748f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          settings_service,
749f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext(
750f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              profile_),
7515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          GetSupervisedUserName(),
752f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          pref_service->GetString(prefs::kSupervisedUserId)));
753f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
755f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    pref_change_registrar_.Add(
756f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        prefs::kDefaultSupervisedUserFilteringBehavior,
757f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        base::Bind(&SupervisedUserService::OnDefaultFilteringBehaviorChanged,
758f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            base::Unretained(this)));
759f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    pref_change_registrar_.Add(prefs::kSupervisedUserManualHosts,
760f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        base::Bind(&SupervisedUserService::UpdateManualHosts,
761f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                   base::Unretained(this)));
762f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    pref_change_registrar_.Add(prefs::kSupervisedUserManualURLs,
763f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        base::Bind(&SupervisedUserService::UpdateManualURLs,
764f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                   base::Unretained(this)));
7651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    pref_change_registrar_.Add(prefs::kSupervisedUserCustodianName,
7661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
7671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   base::Unretained(this)));
7681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    pref_change_registrar_.Add(prefs::kSupervisedUserCustodianEmail,
7691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
7701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   base::Unretained(this)));
7711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    pref_change_registrar_.Add(prefs::kSupervisedUserCustodianProfileImageURL,
7721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
7731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   base::Unretained(this)));
7741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    pref_change_registrar_.Add(prefs::kSupervisedUserCustodianProfileURL,
7751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
7761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   base::Unretained(this)));
7771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    pref_change_registrar_.Add(prefs::kSupervisedUserSecondCustodianName,
7781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
7791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   base::Unretained(this)));
7801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    pref_change_registrar_.Add(prefs::kSupervisedUserSecondCustodianEmail,
7811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
7821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   base::Unretained(this)));
7831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    pref_change_registrar_.Add(
7841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        prefs::kSupervisedUserSecondCustodianProfileImageURL,
7851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
7861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   base::Unretained(this)));
7871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    pref_change_registrar_.Add(prefs::kSupervisedUserSecondCustodianProfileURL,
7881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
7891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   base::Unretained(this)));
790f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
791f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // Initialize the filter.
792f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    OnDefaultFilteringBehaviorChanged();
793f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    UpdateSiteLists();
794f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    UpdateManualHosts();
795f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    UpdateManualURLs();
7961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool use_blacklist =
7971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        CommandLine::ForCurrentProcess()->HasSwitch(
7981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            switches::kEnableSupervisedUserBlacklist);
7991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (delegate_ && use_blacklist) {
8001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::FilePath blacklist_path = delegate_->GetBlacklistPath();
8011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (!blacklist_path.empty())
8021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        LoadBlacklist(blacklist_path, delegate_->GetBlacklistURL());
8031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
805f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if !defined(OS_ANDROID)
806f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // TODO(bauerb): Get rid of the platform-specific #ifdef here.
807f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // http://crbug.com/313377
808f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    BrowserList::AddObserver(this);
809f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
810f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  } else {
811f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    permissions_creator_.reset();
812f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
813f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    pref_change_registrar_.Remove(
814f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        prefs::kDefaultSupervisedUserFilteringBehavior);
815f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    pref_change_registrar_.Remove(prefs::kSupervisedUserManualHosts);
816f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    pref_change_registrar_.Remove(prefs::kSupervisedUserManualURLs);
817f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
8186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (waiting_for_sync_initialization_)
8196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      ProfileSyncServiceFactory::GetForProfile(profile_)->RemoveObserver(this);
8207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
821f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if !defined(OS_ANDROID)
822f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // TODO(bauerb): Get rid of the platform-specific #ifdef here.
823f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // http://crbug.com/313377
824f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    BrowserList::RemoveObserver(this);
825f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif
826f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
829f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::RegisterAndInitSync(
830f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    SupervisedUserRegistrationUtility* registration_utility,
831868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Profile* custodian_profile,
832f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const std::string& supervised_user_id,
8333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const AuthErrorCallback& callback) {
834f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(ProfileIsSupervised());
835f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(!custodian_profile->IsSupervised());
836eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
8375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::string16 name = base::UTF8ToUTF16(
838868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      profile_->GetPrefs()->GetString(prefs::kProfileName));
83958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int avatar_index = profile_->GetPrefs()->GetInteger(
84058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      prefs::kProfileAvatarIndex);
841f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  SupervisedUserRegistrationInfo info(name, avatar_index);
842a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  registration_utility->Register(
843f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      supervised_user_id,
8447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      info,
845f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      base::Bind(&SupervisedUserService::OnSupervisedUserRegistered,
846868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(), callback, custodian_profile));
847eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
848eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Fetch the custodian's profile information, to store the name.
8491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // TODO(pamg): If --google-profile-info (flag: switches::kGoogleProfileInfo)
850eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // is ever enabled, take the name from the ProfileInfoCache instead.
851a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CustodianProfileDownloaderService* profile_downloader_service =
852a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      CustodianProfileDownloaderServiceFactory::GetForProfile(
853a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          custodian_profile);
854a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  profile_downloader_service->DownloadProfile(
855f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      base::Bind(&SupervisedUserService::OnCustodianProfileDownloaded,
856a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
857eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
858eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
859f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::OnCustodianProfileDownloaded(
860a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& full_name) {
861f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  profile_->GetPrefs()->SetString(prefs::kSupervisedUserCustodianName,
8625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  base::UTF16ToUTF8(full_name));
863a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
864a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
865f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::OnSupervisedUserRegistered(
8663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const AuthErrorCallback& callback,
867868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Profile* custodian_profile,
868a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const GoogleServiceAuthError& auth_error,
869a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const std::string& token) {
8703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (auth_error.state() == GoogleServiceAuthError::NONE) {
8713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    InitSync(token);
8723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    SigninManagerBase* signin =
8733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        SigninManagerFactory::GetForProfile(custodian_profile);
874f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    profile_->GetPrefs()->SetString(prefs::kSupervisedUserCustodianEmail,
8753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                    signin->GetAuthenticatedUsername());
8765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
877f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // The supervised user profile is now ready for use.
8785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ProfileManager* profile_manager = g_browser_process->profile_manager();
8795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
8805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    size_t index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
8815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    cache.SetIsOmittedProfileAtIndex(index, false);
8823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  } else {
883a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    DCHECK_EQ(std::string(), token);
884a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
885a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
8863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  callback.Run(auth_error);
887a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
888a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
889f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::UpdateManualHosts() {
8905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::DictionaryValue* dict =
891f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualHosts);
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<std::map<std::string, bool> > host_map(
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new std::map<std::string, bool>());
8945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool allow = false;
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool result = it.value().GetAsBoolean(&allow);
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(result);
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*host_map)[it.key()] = allow;
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_filter_context_.SetManualHosts(host_map.Pass());
9011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
9021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  FOR_EACH_OBSERVER(
9031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
906f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::UpdateManualURLs() {
9075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::DictionaryValue* dict =
908f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs);
9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<std::map<GURL, bool> > url_map(new std::map<GURL, bool>());
9105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool allow = false;
9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool result = it.value().GetAsBoolean(&allow);
9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(result);
9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*url_map)[GURL(it.key())] = allow;
9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_filter_context_.SetManualURLs(url_map.Pass());
9171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
9181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  FOR_EACH_OBSERVER(
9191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
922f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SupervisedUserService::OnBrowserSetLastActive(Browser* browser) {
9237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bool profile_became_active = profile_->IsSameProfile(browser->profile());
9247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!is_profile_active_ && profile_became_active)
925c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    content::RecordAction(UserMetricsAction("ManagedUsers_OpenProfile"));
9267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  else if (is_profile_active_ && !profile_became_active)
927c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    content::RecordAction(UserMetricsAction("ManagedUsers_SwitchProfile"));
9287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
9297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  is_profile_active_ = profile_became_active;
9307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
9315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)std::string SupervisedUserService::GetSupervisedUserName() const {
9335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_CHROMEOS)
9345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // The active user can be NULL in unit tests.
9356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (user_manager::UserManager::Get()->GetActiveUser()) {
9366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return UTF16ToUTF8(user_manager::UserManager::Get()->GetUserDisplayName(
9376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        user_manager::UserManager::Get()->GetActiveUser()->GetUserID()));
9385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
9395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return std::string();
9405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#else
9415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return profile_->GetPrefs()->GetString(prefs::kProfileName);
9425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif
9435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
944