Chromium Code Reviews| Index: chrome/browser/managed_mode/managed_user_service.cc |
| diff --git a/chrome/browser/managed_mode/managed_user_service.cc b/chrome/browser/managed_mode/managed_user_service.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..d358d2d1080d34a1b9a94a1a848094fce525bdde |
| --- /dev/null |
| +++ b/chrome/browser/managed_mode/managed_user_service.cc |
| @@ -0,0 +1,326 @@ |
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
|
Pam (message me for reviews)
2013/01/14 14:12:42
2013
Bernhard Bauer
2013/01/15 14:24:44
Done.
|
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "chrome/browser/managed_mode/managed_user_service.h" |
| + |
| +#include "base/memory/ref_counted.h" |
| +#include "base/sequenced_task_runner.h" |
| +#include "chrome/browser/extensions/extension_service.h" |
| +#include "chrome/browser/extensions/extension_system.h" |
| +#include "chrome/browser/managed_mode/managed_mode_site_list.h" |
| +#include "chrome/browser/prefs/pref_service.h" |
| +#include "chrome/browser/prefs/scoped_user_pref_update.h" |
| +#include "chrome/browser/profiles/profile.h" |
| +#include "chrome/common/chrome_notification_types.h" |
| +#include "chrome/common/extensions/extension_set.h" |
| +#include "chrome/common/pref_names.h" |
| +#include "content/public/browser/browser_thread.h" |
| +#include "grit/generated_resources.h" |
| +#include "ui/base/l10n/l10n_util.h" |
| + |
| +using content::BrowserThread; |
| + |
| +ManagedUserService::URLFilterContext::URLFilterContext() |
| + : ui_url_filter_(new ManagedModeURLFilter), |
| + io_url_filter_(new ManagedModeURLFilter) {} |
| +ManagedUserService::URLFilterContext::~URLFilterContext() {} |
| + |
| +ManagedModeURLFilter* |
| +ManagedUserService::URLFilterContext::ui_url_filter() const { |
| + return ui_url_filter_.get(); |
| +} |
| + |
| +ManagedModeURLFilter* |
| +ManagedUserService::URLFilterContext::io_url_filter() const { |
| + return io_url_filter_.get(); |
| +} |
| + |
| +void ManagedUserService::URLFilterContext::SetDefaultFilteringBehavior( |
| + ManagedModeURLFilter::FilteringBehavior behavior) { |
| + ui_url_filter_->SetDefaultFilteringBehavior(behavior); |
|
Pam (message me for reviews)
2013/01/14 14:12:42
Is it worth making sure that we're on the UI threa
Bernhard Bauer
2013/01/15 14:24:44
The filter will check that itself.
|
| + BrowserThread::PostTask( |
| + BrowserThread::IO, |
| + FROM_HERE, |
| + base::Bind(&ManagedModeURLFilter::SetDefaultFilteringBehavior, |
| + io_url_filter_.get(), |
| + behavior)); |
| +} |
| + |
| +void ManagedUserService::URLFilterContext::LoadWhitelists( |
| + ScopedVector<ManagedModeSiteList> site_lists) { |
| + // ManagedModeURLFilter::LoadWhitelists takes ownership of |site_lists|, |
| + // so we make an additional copy of it. |
| + /// TODO(bauerb): This is kinda ugly. |
| + ScopedVector<ManagedModeSiteList> site_lists_copy; |
|
Pam (message me for reviews)
2013/01/14 14:12:42
You make this copy, then don't do anything with it
Bernhard Bauer
2013/01/15 14:24:44
Oops. Fixed.
|
| + for (ScopedVector<ManagedModeSiteList>::iterator it = site_lists.begin(); |
| + it != site_lists.end(); ++it) { |
| + site_lists_copy.push_back((*it)->Clone()); |
| + } |
| + ui_url_filter_->LoadWhitelists(site_lists.Pass(), |
| + base::Bind(&base::DoNothing)); |
| + BrowserThread::PostTask( |
| + BrowserThread::IO, |
| + FROM_HERE, |
| + base::Bind(&ManagedModeURLFilter::LoadWhitelists, |
| + io_url_filter_, |
| + base::Passed(&site_lists), |
| + base::Bind(&base::DoNothing))); |
| +} |
| + |
| +void ManagedUserService::URLFilterContext::SetManualLists( |
| + scoped_ptr<ListValue> whitelist, |
| + scoped_ptr<ListValue> blacklist) { |
| + ui_url_filter_->SetManualLists(whitelist.get(), blacklist.get()); |
| + BrowserThread::PostTask( |
| + BrowserThread::IO, |
| + FROM_HERE, |
| + base::Bind(&ManagedModeURLFilter::SetManualLists, |
| + io_url_filter_, |
| + base::Owned(whitelist.release()), |
| + base::Owned(blacklist.release()))); |
| +} |
| + |
| +void ManagedUserService::URLFilterContext::AddURLPatternToManualList( |
| + const bool is_whitelist, |
| + const std::string& url) { |
| + ui_url_filter_->AddURLPatternToManualList(is_whitelist, url); |
| + BrowserThread::PostTask( |
| + BrowserThread::IO, |
| + FROM_HERE, |
| + base::Bind(&ManagedModeURLFilter::AddURLPatternToManualList, |
| + io_url_filter_, |
| + is_whitelist, |
| + url)); |
| +} |
| + |
| +ManagedUserService::ManagedUserService(Profile* profile) : profile_(profile) { |
| + if (!ProfileIsManaged()) |
| + return; |
| + |
| + extensions::ExtensionSystem* extension_system = |
| + extensions::ExtensionSystem::Get(profile); |
| + extensions::ManagementPolicy* management_policy = |
| + extension_system->management_policy(); |
| + if (management_policy) |
| + extension_system->management_policy()->RegisterProvider(this); |
| + |
| + registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, |
| + content::Source<Profile>(profile_)); |
| + registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, |
| + content::Source<Profile>(profile_)); |
| + pref_change_registrar_.Init(profile_->GetPrefs()); |
| + pref_change_registrar_.Add( |
| + prefs::kDefaultManagedModeFilteringBehavior, |
| + base::Bind( |
| + &ManagedUserService::OnDefaultFilteringBehaviorChanged, |
| + base::Unretained(this))); |
| +} |
| + |
| +ManagedUserService::~ManagedUserService() { |
| +} |
| + |
| +bool ManagedUserService::ProfileIsManaged() const { |
| + return profile_->GetPrefs()->GetBoolean(prefs::kProfileIsManaged); |
|
Pam (message me for reviews)
2013/01/14 14:12:42
What sets kProfileIsManaged? Will it be possible t
Bernhard Bauer
2013/01/15 14:24:44
It's set by the profile creation mechanism when th
Pam (message me for reviews)
2013/01/15 14:47:53
I'm not convinced that kProfileIsManaged is necess
Bernhard Bauer
2013/01/15 14:59:55
* Can install extensions/content packs only after
|
| +} |
| + |
| +// static |
| +void ManagedUserService::RegisterUserPrefs(PrefServiceSyncable* prefs) { |
| + prefs->RegisterIntegerPref(prefs::kDefaultManagedModeFilteringBehavior, |
| + 2, |
|
Pam (message me for reviews)
2013/01/14 14:12:42
Ew. Please at least attach a comment saying what t
Bernhard Bauer
2013/01/15 14:24:44
Done.
|
| + PrefServiceSyncable::UNSYNCABLE_PREF); |
| +} |
| + |
| +scoped_refptr<const ManagedModeURLFilter> |
| +ManagedUserService::GetURLFilterForIOThread() { |
| + return url_filter_context_.io_url_filter(); |
| +} |
| + |
| +const ManagedModeURLFilter* ManagedUserService::GetURLFilterForUIThread() { |
| + return url_filter_context_.ui_url_filter(); |
| +} |
| + |
| +// Items not on any list must return -1 (CATEGORY_NOT_ON_LIST in history.js). |
| +// Items on a list, but with no category, must return 0 (CATEGORY_OTHER). |
| +#define CATEGORY_NOT_ON_LIST -1; |
| +#define CATEGORY_OTHER 0; |
| + |
| +int ManagedUserService::GetCategory(const GURL& url) { |
| + std::vector<ManagedModeSiteList::Site*> sites; |
| + GetURLFilterForUIThread()->GetSites(url, &sites); |
| + if (sites.empty()) |
| + return CATEGORY_NOT_ON_LIST; |
| + |
| + return (*sites.begin())->category_id; |
| +} |
| + |
| +// static |
| +void ManagedUserService::GetCategoryNames(CategoryList* list) { |
| + ManagedModeSiteList::GetCategoryNames(list); |
| +}; |
| + |
| +void ManagedUserService::AddToManualList(bool is_whitelist, |
| + const base::ListValue& list) { |
| + |
|
Pam (message me for reviews)
2013/01/14 14:12:42
Extra blank line
Bernhard Bauer
2013/01/15 14:24:44
Removed.
|
| + ListPrefUpdate pref_update(profile_->GetPrefs(), |
| + is_whitelist ? prefs::kManagedModeWhitelist : |
| + prefs::kManagedModeBlacklist); |
| + ListValue* pref_list = pref_update.Get(); |
| + |
| + for (size_t i = 0; i < list.GetSize(); ++i) { |
| + std::string url_pattern; |
| + list.GetString(i, &url_pattern); |
| + |
| + if (!IsInManualList(is_whitelist, url_pattern)) { |
| + pref_list->AppendString(url_pattern); |
| + AddURLPatternToManualList(is_whitelist, url_pattern); |
| + } |
| + } |
| +} |
| + |
| +void ManagedUserService::RemoveFromManualList(bool is_whitelist, |
| + const base::ListValue& list) { |
| + ListPrefUpdate pref_update(profile_->GetPrefs(), |
| + is_whitelist ? prefs::kManagedModeWhitelist : |
| + prefs::kManagedModeBlacklist); |
| + ListValue* pref_list = pref_update.Get(); |
| + |
| + for (size_t i = 0; i < list.GetSize(); ++i) { |
| + std::string pattern; |
| + size_t out_index; |
| + list.GetString(i, &pattern); |
| + StringValue value_to_remove(pattern); |
| + |
| + pref_list->Remove(value_to_remove, &out_index); |
| + } |
| +} |
| + |
| +bool ManagedUserService::IsInManualList(bool is_whitelist, |
| + const std::string& url_pattern) { |
| + StringValue pattern(url_pattern); |
| + const ListValue* list = profile_->GetPrefs()->GetList( |
| + is_whitelist ? prefs::kManagedModeWhitelist : |
| + prefs::kManagedModeBlacklist); |
| + return list->Find(pattern) != list->end(); |
| +} |
| + |
| +// static |
| +scoped_ptr<base::ListValue> ManagedUserService::GetBlacklist() { |
| + return make_scoped_ptr( |
| + profile_->GetPrefs()->GetList(prefs::kManagedModeBlacklist)->DeepCopy()); |
| +} |
| + |
| +std::string ManagedUserService::GetDebugPolicyProviderName() const { |
| + // Save the string space in official builds. |
| +#ifdef NDEBUG |
| + NOTREACHED(); |
| + return std::string(); |
| +#else |
| + return "Managed Mode"; |
|
Pam (message me for reviews)
2013/01/14 14:12:42
"Managed User Service"
Bernhard Bauer
2013/01/15 14:24:44
Done.
|
| +#endif |
| +} |
| + |
| +bool ManagedUserService::UserMayLoad(const extensions::Extension* extension, |
| + string16* error) const { |
| + string16 tmp_error; |
| + if (ExtensionManagementPolicyImpl(&tmp_error)) |
| + return true; |
| + |
| + // If the extension is already loaded, we allow it, otherwise we'd unload |
| + // all existing extensions. |
| + ExtensionService* extension_service = |
| + extensions::ExtensionSystem::Get(profile_)->extension_service(); |
| + |
| + // |extension_service| can be NULL in a unit test. |
| + if (extension_service && |
| + extension_service->GetInstalledExtension(extension->id())) |
| + return true; |
| + |
| + if (error) |
| + *error = tmp_error; |
| + return false; |
| +} |
| + |
| +bool ManagedUserService::UserMayModifySettings( |
| + const extensions::Extension* extension, |
| + string16* error) const { |
| + return ExtensionManagementPolicyImpl(error); |
| +} |
| + |
| +void ManagedUserService::Observe(int type, |
| + const content::NotificationSource& source, |
| + const content::NotificationDetails& details) { |
| + switch (type) { |
| + case chrome::NOTIFICATION_EXTENSION_LOADED: |
| + case chrome::NOTIFICATION_EXTENSION_UNLOADED: { |
| + if (!profile_) |
| + break; |
| + |
| + const extensions::Extension* extension = |
| + content::Details<const extensions::Extension>(details).ptr(); |
| + if (!extension->GetContentPackSiteList().empty()) |
| + UpdateSiteLists(); |
| + |
| + break; |
| + } |
| + default: |
| + NOTREACHED(); |
| + } |
| +} |
| + |
| +bool ManagedUserService::ExtensionManagementPolicyImpl(string16* error) const { |
| + if (!ProfileIsManaged()) |
| + return true; |
| + |
| + if (error) |
| + *error = l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_MANAGED_MODE); |
| + return false; |
| +} |
| + |
| +ScopedVector<ManagedModeSiteList> ManagedUserService::GetActiveSiteLists() { |
| + ExtensionService* extension_service = |
| + extensions::ExtensionSystem::Get(profile_)->extension_service(); |
| + const ExtensionSet* extensions = extension_service->extensions(); |
| + ScopedVector<ManagedModeSiteList> site_lists; |
| + for (ExtensionSet::const_iterator it = extensions->begin(); |
| + it != extensions->end(); ++it) { |
| + const extensions::Extension* extension = *it; |
| + if (!extension_service->IsExtensionEnabled(extension->id())) |
| + continue; |
| + |
| + ExtensionResource site_list = extension->GetContentPackSiteList(); |
| + if (!site_list.empty()) |
| + site_lists.push_back(new ManagedModeSiteList(extension->id(), site_list)); |
| + } |
| + |
| + return site_lists.Pass(); |
| +} |
| + |
| +void ManagedUserService::OnDefaultFilteringBehaviorChanged() { |
| + DCHECK(ProfileIsManaged()); |
| + |
| + int behavior_value = profile_->GetPrefs()->GetInteger( |
| + prefs::kDefaultManagedModeFilteringBehavior); |
| + ManagedModeURLFilter::FilteringBehavior behavior = |
| + ManagedModeURLFilter::BehaviorFromInt(behavior_value); |
| + url_filter_context_.SetDefaultFilteringBehavior(behavior); |
| +} |
| + |
| +void ManagedUserService::UpdateSiteLists() { |
| + url_filter_context_.LoadWhitelists(GetActiveSiteLists()); |
| +} |
| + |
| +void ManagedUserService::UpdateManualLists() { |
| + url_filter_context_.SetManualLists(GetWhitelist(), GetBlacklist()); |
| +} |
| + |
| +scoped_ptr<base::ListValue> ManagedUserService::GetWhitelist() { |
| + return make_scoped_ptr( |
| + profile_->GetPrefs()->GetList(prefs::kManagedModeWhitelist)->DeepCopy()); |
| +} |
| + |
| +void ManagedUserService::AddURLPatternToManualList( |
| + bool is_whitelist, |
| + const std::string& url_pattern) { |
| + url_filter_context_.AddURLPatternToManualList(true, url_pattern); |
| +} |