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..8fbc39a4c301063635e27ee5577a142d26fb80a7 |
--- /dev/null |
+++ b/chrome/browser/managed_mode/managed_user_service.cc |
@@ -0,0 +1,353 @@ |
+// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
+// 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); |
+ 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; |
+ 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()); |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, |
+ FROM_HERE, |
+ base::Bind(&ManagedModeURLFilter::LoadWhitelists, |
+ io_url_filter_, |
+ base::Passed(&site_lists_copy))); |
+} |
+ |
+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), |
+ is_elevated_(false) { |
+ Init(); |
+} |
+ |
+ManagedUserService::~ManagedUserService() { |
+} |
+ |
+bool ManagedUserService::ProfileIsManaged() const { |
+ return profile_->GetPrefs()->GetBoolean(prefs::kProfileIsManaged); |
+} |
+ |
+// static |
+void ManagedUserService::RegisterUserPrefs(PrefServiceSyncable* prefs) { |
+ prefs->RegisterListPref(prefs::kManagedModeWhitelist, |
+ PrefServiceSyncable::UNSYNCABLE_PREF); |
+ prefs->RegisterListPref(prefs::kManagedModeBlacklist, |
+ PrefServiceSyncable::UNSYNCABLE_PREF); |
+ prefs->RegisterIntegerPref(prefs::kDefaultManagedModeFilteringBehavior, |
+ ManagedModeURLFilter::BLOCK, |
+ PrefServiceSyncable::UNSYNCABLE_PREF); |
+} |
+ |
+scoped_refptr<const ManagedModeURLFilter> |
+ManagedUserService::GetURLFilterForIOThread() { |
+ return url_filter_context_.io_url_filter(); |
+} |
+ |
+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) { |
+ 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 User Service"; |
+#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: { |
+ const extensions::Extension* extension = |
+ content::Details<extensions::Extension>(details).ptr(); |
+ if (!extension->GetContentPackSiteList().empty()) |
+ UpdateSiteLists(); |
+ |
+ break; |
+ } |
+ case chrome::NOTIFICATION_EXTENSION_UNLOADED: { |
+ const extensions::UnloadedExtensionInfo* extension_info = |
+ content::Details<extensions::UnloadedExtensionInfo>(details).ptr(); |
+ if (!extension_info->extension->GetContentPackSiteList().empty()) |
+ UpdateSiteLists(); |
+ |
+ break; |
+ } |
+ default: |
+ NOTREACHED(); |
+ } |
+} |
+ |
+bool ManagedUserService::ExtensionManagementPolicyImpl(string16* error) const { |
+ if (!ProfileIsManaged()) |
+ return true; |
+ |
+ if (is_elevated_) |
+ return true; |
+ |
+ if (error) |
+ *error = l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_MANAGED_MODE); |
+ return false; |
+} |
+ |
+ScopedVector<ManagedModeSiteList> ManagedUserService::GetActiveSiteLists() { |
+ ScopedVector<ManagedModeSiteList> site_lists; |
+ ExtensionService* extension_service = |
+ extensions::ExtensionSystem::Get(profile_)->extension_service(); |
+ // Can be NULL in unit tests. |
+ if (!extension_service) |
+ return site_lists.Pass(); |
+ |
+ const ExtensionSet* extensions = extension_service->extensions(); |
+ 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()); |
+} |
+ |
+void ManagedUserService::SetElevatedForTesting(bool is_elevated) { |
+ is_elevated_ = is_elevated; |
+} |
+ |
+void ManagedUserService::Init() { |
+ 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))); |
+ |
+ // Initialize the filter. |
+ OnDefaultFilteringBehaviorChanged(); |
+ UpdateSiteLists(); |
+ UpdateManualLists(); |
+} |
+ |
+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); |
+} |