Commit eee03003 authored by Theodore Olsauskas-Warren's avatar Theodore Olsauskas-Warren Committed by Commit Bot

Add GetRecentSitePermissions handler to SiteSettingsHandler

As part of the privacy settings redesign, the capability to display
recently changed permissions to the user is required. This CL introduces
the a handler to enable querying for this information from JS.

The GetRecentSitePermissions provides the most recent permissions
changes grouped by at most N unique origin/[incognito, normal]
combinations.

Existing functionality which is reused from the GetAllSites handler
is also refactored out.

Bug: 1032584
Change-Id: I885c859d455bc49d8ec9d91bf3101cf337c4ae51
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2002577
Commit-Queue: Theodore Olsauskas-Warren <sauski@google.com>
Reviewed-by: default avatarBalazs Engedy <engedy@chromium.org>
Reviewed-by: default avatarDemetrios Papadopoulos <dpapad@chromium.org>
Cr-Commit-Position: refs/heads/master@{#739027}
parent 6ccb8a6e
......@@ -65,6 +65,7 @@ let SiteGroup;
* incognito: boolean,
* origin: string,
* displayName: string,
* type: string,
* setting: !settings.ContentSetting,
* source: !settings.SiteSettingSource}}
*/
......@@ -85,6 +86,16 @@ let RawSiteException;
*/
let SiteException;
/**
* Represents a list of exceptions recently configured for a site, where recent
* is defined by the maximum number of sources parameter passed to
* GetRecentSiterPermissions.
* @typedef {{origin: string,
* incognito: boolean,
* recentPermissions: Array<RawSiteException>}}
*/
let RecentSitePermissions;
/**
* The chooser exception information passed from the C++ handler.
* See also: ChooserException.
......@@ -157,6 +168,18 @@ cr.define('settings', function() {
*/
getAllSites(contentTypes) {}
/**
* Gets most recently changed permissions grouped by host and limited to
* numSources different origin/profile (inconigto/regular) pairings.
* This includes permissions adjusted by embargo, but excludes any set
* via policy.
* @param {!Array<!settings.ContentSettingsTypes>} contentTypes A list of
* the content types to retrieve sites with recently changed settings.
* @param {!number} numSources Maximum number of different sources to return
* @return {!Promise<!Array<!RecentSitePermissions>>}
*/
getRecentSitePermissions(contentTypes, numSources) {}
/**
* Gets the chooser exceptions for a particular chooser type.
* @param {settings.ChooserType} chooserType The chooser type to grab
......@@ -392,6 +415,12 @@ cr.define('settings', function() {
return cr.sendWithPromise('getAllSites', contentTypes);
}
/** @override */
getRecentSitePermissions(contentTypes, numSources) {
return cr.sendWithPromise(
'getRecentSitePermissions', contentTypes, numSources);
}
/** @override */
getChooserExceptionList(chooserType) {
return cr.sendWithPromise('getChooserExceptionList', chooserType);
......
......@@ -1327,6 +1327,8 @@ jumbo_static_library("ui") {
"webui/policy_indicator_localized_strings_provider.h",
"webui/profile_info_watcher.cc",
"webui/profile_info_watcher.h",
"webui/recent_site_settings_helper.cc",
"webui/recent_site_settings_helper.h",
"webui/settings/about_handler.cc",
"webui/settings/about_handler.h",
"webui/settings/accessibility_main_handler.cc",
......
This diff is collapsed.
// Copyright 2020 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.
#ifndef CHROME_BROWSER_UI_WEBUI_RECENT_SITE_SETTINGS_HELPER_H_
#define CHROME_BROWSER_UI_WEBUI_RECENT_SITE_SETTINGS_HELPER_H_
#include <vector>
#include "base/time/time.h"
#include "chrome/browser/ui/webui/site_settings_helper.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "url/gurl.h"
class Profile;
namespace site_settings {
struct TimestampedSetting {
base::Time timestamp;
ContentSettingsType content_type;
ContentSetting content_setting;
site_settings::SiteSettingSource setting_source;
TimestampedSetting();
TimestampedSetting(const TimestampedSetting& other);
TimestampedSetting& operator=(const TimestampedSetting& other) = default;
TimestampedSetting(TimestampedSetting&& other) = default;
TimestampedSetting(base::Time timestamp,
ContentSettingsType content_type,
ContentSetting content_setting,
site_settings::SiteSettingSource setting_source);
~TimestampedSetting();
};
struct RecentSitePermissions {
GURL origin;
bool incognito;
std::vector<TimestampedSetting> settings;
RecentSitePermissions();
RecentSitePermissions(const RecentSitePermissions& other);
RecentSitePermissions& operator=(const RecentSitePermissions& other) =
default;
RecentSitePermissions(RecentSitePermissions&& other);
RecentSitePermissions(GURL origin,
bool incognito,
std::vector<TimestampedSetting> settings);
~RecentSitePermissions();
};
// Returns a list containing the most recent permission changes for the
// provided content types grouped by origin/profile (incognito, regular)
// combinations. Limited to |max_sources| origin/profile pairings and ordered
// from most recently adjusted site to least recently. Includes permissions
// changed by embargo, but not those changed by enterprise policy.
std::vector<RecentSitePermissions> GetRecentSitePermissions(
Profile* profile,
std::vector<ContentSettingsType> content_types,
size_t max_sources);
} // namespace site_settings
#endif // CHROME_BROWSER_UI_WEBUI_RECENT_SITE_SETTINGS_HELPER_H_
......@@ -34,6 +34,7 @@
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/page_info/page_info_infobar_delegate.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/webui/recent_site_settings_helper.h"
#include "chrome/browser/ui/webui/site_settings_helper.h"
#include "chrome/browser/usb/usb_chooser_context.h"
#include "chrome/browser/usb/usb_chooser_context_factory.h"
......@@ -158,21 +159,6 @@ base::flat_set<web_app::AppId> GetInstalledApps(
return installed;
}
// Whether |pattern| applies to a single origin.
bool PatternAppliesToSingleOrigin(const ContentSettingPatternSource& pattern) {
const GURL url(pattern.primary_pattern.ToString());
// Default settings and other patterns apply to multiple origins.
if (url::Origin::Create(url).opaque())
return false;
// Embedded content settings only when |url| is embedded in another origin, so
// ignore non-wildcard secondary patterns that are different to the primary.
if (pattern.primary_pattern != pattern.secondary_pattern &&
pattern.secondary_pattern != ContentSettingsPattern::Wildcard()) {
return false;
}
return true;
}
// Groups |url| into sets of eTLD+1s in |site_group_map|, assuming |url| is an
// origin.
// There are three cases:
......@@ -367,6 +353,10 @@ void SiteSettingsHandler::RegisterMessages() {
"getAllSites",
base::BindRepeating(&SiteSettingsHandler::HandleGetAllSites,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"getRecentSitePermissions",
base::BindRepeating(&SiteSettingsHandler::HandleGetRecentSitePermissions,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"getFormattedBytes",
base::BindRepeating(&SiteSettingsHandler::HandleGetFormattedBytes,
......@@ -674,22 +664,14 @@ void SiteSettingsHandler::HandleGetDefaultValueForContentType(
void SiteSettingsHandler::HandleGetAllSites(const base::ListValue* args) {
AllowJavascript();
CHECK_EQ(2U, args->GetSize());
const base::Value* callback_id;
CHECK(args->Get(0, &callback_id));
const base::ListValue* types;
CHECK(args->GetList(1, &types));
CHECK_EQ(2U, args->GetList().size());
std::string callback_id = args->GetList()[0].GetString();
auto types = args->GetList()[1].GetList();
all_sites_map_.clear();
origin_permission_set_.clear();
// Convert |types| to a list of ContentSettingsTypes.
std::vector<ContentSettingsType> content_types;
for (size_t i = 0; i < types->GetSize(); ++i) {
std::string type;
types->GetString(i, &type);
content_types.push_back(
site_settings::ContentSettingsTypeFromGroupName(type));
}
auto content_types = site_settings::ContentSettingsTypesFromGroupNames(types);
// Incognito contains incognito content settings plus non-incognito content
// settings. Thus if it exists, just get exceptions for the incognito profile.
......@@ -712,17 +694,14 @@ void SiteSettingsHandler::HandleGetAllSites(const base::ListValue* args) {
origin_permission_set_.insert(url.spec());
}
// Convert |types| to a list of ContentSettingsTypes.
for (ContentSettingsType content_type : content_types) {
ContentSettingsForOneType entries;
map->GetSettingsForOneType(content_type, std::string(), &entries);
for (const ContentSettingPatternSource& e : entries) {
if (PatternAppliesToSingleOrigin(e)) {
CreateOrAppendSiteGroupEntry(&all_sites_map_,
GURL(e.primary_pattern.ToString()));
origin_permission_set_.insert(
GURL(e.primary_pattern.ToString()).spec());
}
// Get permission exceptions which apply to a single site
for (auto content_type : content_types) {
auto exceptions =
site_settings::GetSiteExceptionsForContentType(map, content_type);
for (const auto& e : exceptions) {
GURL url = GURL(e.primary_pattern.ToString());
CreateOrAppendSiteGroupEntry(&all_sites_map_, url);
origin_permission_set_.insert(url.spec());
}
}
......@@ -744,7 +723,54 @@ void SiteSettingsHandler::HandleGetAllSites(const base::ListValue* args) {
send_sites_list_ = true;
ResolveJavascriptCallback(*callback_id, result);
ResolveJavascriptCallback(base::Value(callback_id), result);
}
void SiteSettingsHandler::HandleGetRecentSitePermissions(
const base::ListValue* args) {
AllowJavascript();
CHECK_EQ(3U, args->GetList().size());
std::string callback_id = args->GetList()[0].GetString();
auto types = args->GetList()[1].GetList();
size_t max_sources = base::checked_cast<size_t>(args->GetList()[2].GetInt());
auto content_types = site_settings::ContentSettingsTypesFromGroupNames(types);
auto recent_site_permissions = site_settings::GetRecentSitePermissions(
profile_, content_types, max_sources);
// Convert groups of TimestampedPermissions for consumption by JS
base::Value result(base::Value::Type::LIST);
for (const auto& site_permissions : recent_site_permissions) {
DCHECK(!site_permissions.settings.empty());
base::Value recent_site(base::Value::Type::DICTIONARY);
recent_site.SetKey(site_settings::kOrigin,
base::Value(site_permissions.origin.spec()));
recent_site.SetKey(site_settings::kIncognito,
base::Value(site_permissions.incognito));
base::Value permissions_list(base::Value::Type::LIST);
for (const auto& p : site_permissions.settings) {
base::Value recent_permission(base::Value::Type::DICTIONARY);
recent_permission.SetKey(
site_settings::kType,
base::Value(
site_settings::ContentSettingsTypeToGroupName(p.content_type)));
recent_permission.SetKey(
site_settings::kSetting,
base::Value(
content_settings::ContentSettingToString(p.content_setting)));
recent_permission.SetKey(
site_settings::kSource,
base::Value(
site_settings::SiteSettingSourceToString(p.setting_source)));
permissions_list.Append(std::move(recent_permission));
}
recent_site.SetKey(site_settings::kRecentPermissions,
std::move(permissions_list));
result.Append(std::move(recent_site));
}
ResolveJavascriptCallback(base::Value(callback_id), result);
}
base::Value SiteSettingsHandler::PopulateCookiesAndUsageData(Profile* profile) {
......@@ -774,13 +800,14 @@ base::Value SiteSettingsHandler::PopulateCookiesAndUsageData(Profile* profile) {
const auto& size_info_it = origin_size_map.find(origin);
if (size_info_it != origin_size_map.end())
origin_info.SetKey("usage", base::Value(double(size_info_it->second)));
GURL origin_url(origin);
const auto& origin_cookie_num_it =
origin_cookie_map.find(GURL(origin).host());
origin_cookie_map.find(origin_url.host());
if (origin_cookie_num_it != origin_cookie_map.end()) {
origin_info.SetKey(kNumCookies,
base::Value(origin_cookie_num_it->second));
// Add cookies numbers for origins that isn't an eTLD+1.
if (GURL(origin).host() != etld_plus1)
if (origin_url.host() != etld_plus1)
cookie_num += origin_cookie_num_it->second;
}
}
......
......@@ -110,6 +110,7 @@ class SiteSettingsHandler : public SettingsPageUIHandler,
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, ExceptionHelpers);
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, ExtensionDisplayName);
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, GetAllSites);
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, GetRecentSitePermissions);
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, OnStorageFetched);
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, GetAndSetDefault);
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, GetAndSetForInvalidURLs);
......@@ -163,6 +164,13 @@ class SiteSettingsHandler : public SettingsPageUIHandler,
// the front end when fetching finished.
void HandleGetAllSites(const base::ListValue* args);
// Returns a list containing the most recent permission changes for the
// provided content types grouped by origin/profile (incognito, regular)
// combinations, limited to N origin/profile pairings. This includes
// permission changes made by embargo, but does not include permissions
// enforced via policy.
void HandleGetRecentSitePermissions(const base::ListValue* args);
// Called when the list of origins using storage has been fetched, and sends
// this list back to the front end.
void OnStorageFetched();
......
......@@ -719,6 +719,131 @@ TEST_F(SiteSettingsHandlerTest, MAYBE_GetAllSites) {
run_loop.RunUntilIdle();
}
TEST_F(SiteSettingsHandlerTest, GetRecentSitePermissions) {
// Constants used only in this test.
std::string kAllowed = content_settings::ContentSettingToString(
ContentSetting::CONTENT_SETTING_ALLOW);
std::string kBlocked = content_settings::ContentSettingToString(
ContentSetting::CONTENT_SETTING_BLOCK);
std::string kEmbargo =
SiteSettingSourceToString(site_settings::SiteSettingSource::kEmbargo);
std::string kPreference =
SiteSettingSourceToString(site_settings::SiteSettingSource::kPreference);
base::ListValue get_recent_permissions_args;
get_recent_permissions_args.AppendString(kCallbackId);
base::Value category_list(base::Value::Type::LIST);
category_list.Append(kNotifications);
category_list.Append(kFlash);
get_recent_permissions_args.Append(std::move(category_list));
get_recent_permissions_args.Append(3);
// Configure prefs and auto blocker with a controllable clock.
base::SimpleTestClock clock;
clock.SetNow(base::Time::Now());
HostContentSettingsMap* map =
HostContentSettingsMapFactory::GetForProfile(profile());
map->SetClockForTesting(&clock);
permissions::PermissionDecisionAutoBlocker* auto_blocker =
PermissionDecisionAutoBlockerFactory::GetForProfile(profile());
auto_blocker->SetClockForTesting(&clock);
clock.Advance(base::TimeDelta::FromHours(1));
// Test recent permissions is empty when there are no preferences.
handler()->HandleGetRecentSitePermissions(&get_recent_permissions_args);
EXPECT_EQ(1U, web_ui()->call_data().size());
{
const content::TestWebUI::CallData& data = *web_ui()->call_data().back();
EXPECT_EQ("cr.webUIResponse", data.function_name());
EXPECT_EQ(kCallbackId, data.arg1()->GetString());
ASSERT_TRUE(data.arg2()->GetBool());
base::Value::ConstListView recent_permissions = data.arg3()->GetList();
EXPECT_EQ(0UL, recent_permissions.size());
}
// Add numerous permissions from different sources and confirm that the recent
// permissions are correctly transformed for usage by JS.
const GURL url1("https://example.com");
const GURL url2("http://example.com");
for (int i = 0; i < 3; ++i)
auto_blocker->RecordDismissAndEmbargo(
url1, ContentSettingsType::NOTIFICATIONS, false);
clock.Advance(base::TimeDelta::FromHours(2));
map->SetContentSettingDefaultScope(url2, url2, ContentSettingsType::PLUGINS,
std::string(), CONTENT_SETTING_ALLOW);
clock.Advance(base::TimeDelta::FromHours(1));
CreateIncognitoProfile();
HostContentSettingsMap* incognito_map =
HostContentSettingsMapFactory::GetForProfile(incognito_profile());
incognito_map->SetClockForTesting(&clock);
incognito_map->SetContentSettingDefaultScope(
url1, url1, ContentSettingsType::PLUGINS, std::string(),
CONTENT_SETTING_ALLOW);
clock.Advance(base::TimeDelta::FromHours(1));
permissions::PermissionDecisionAutoBlocker* incognito_auto_blocker =
PermissionDecisionAutoBlockerFactory::GetForProfile(incognito_profile());
incognito_auto_blocker->SetClockForTesting(&clock);
for (int i = 0; i < 3; ++i)
incognito_auto_blocker->RecordDismissAndEmbargo(
url1, ContentSettingsType::NOTIFICATIONS, false);
handler()->HandleGetRecentSitePermissions(&get_recent_permissions_args);
{
const content::TestWebUI::CallData& data = *web_ui()->call_data().back();
EXPECT_EQ("cr.webUIResponse", data.function_name());
EXPECT_EQ(kCallbackId, data.arg1()->GetString());
ASSERT_TRUE(data.arg2()->GetBool());
base::Value::ConstListView recent_permissions = data.arg3()->GetList();
EXPECT_EQ(3UL, recent_permissions.size());
EXPECT_EQ(url1.spec(),
recent_permissions[2].FindKey("origin")->GetString());
EXPECT_EQ(url2.spec(),
recent_permissions[1].FindKey("origin")->GetString());
EXPECT_EQ(url1.spec(),
recent_permissions[0].FindKey("origin")->GetString());
EXPECT_TRUE(recent_permissions[0].FindKey("incognito")->GetBool());
EXPECT_FALSE(recent_permissions[1].FindKey("incognito")->GetBool());
EXPECT_FALSE(recent_permissions[2].FindKey("incognito")->GetBool());
base::Value::ConstListView incognito_url1_permissions =
recent_permissions[0].FindKey("recentPermissions")->GetList();
base::Value::ConstListView url1_permissions =
recent_permissions[2].FindKey("recentPermissions")->GetList();
base::Value::ConstListView url2_permissions =
recent_permissions[1].FindKey("recentPermissions")->GetList();
EXPECT_EQ(2UL, incognito_url1_permissions.size());
EXPECT_EQ(kNotifications,
incognito_url1_permissions[0].FindKey("type")->GetString());
EXPECT_EQ(kBlocked,
incognito_url1_permissions[0].FindKey("setting")->GetString());
EXPECT_EQ(kEmbargo,
incognito_url1_permissions[0].FindKey("source")->GetString());
EXPECT_EQ(kFlash,
incognito_url1_permissions[1].FindKey("type")->GetString());
EXPECT_EQ(kAllowed,
incognito_url1_permissions[1].FindKey("setting")->GetString());
EXPECT_EQ(kPreference,
incognito_url1_permissions[1].FindKey("source")->GetString());
EXPECT_EQ(kNotifications, url1_permissions[0].FindKey("type")->GetString());
EXPECT_EQ(kBlocked, url1_permissions[0].FindKey("setting")->GetString());
EXPECT_EQ(kEmbargo, url1_permissions[0].FindKey("source")->GetString());
EXPECT_EQ(kFlash, url2_permissions[0].FindKey("type")->GetString());
EXPECT_EQ(kAllowed, url2_permissions[0].FindKey("setting")->GetString());
EXPECT_EQ(kPreference, url2_permissions[0].FindKey("source")->GetString());
}
}
TEST_F(SiteSettingsHandlerTest, OnStorageFetched) {
SetUpCookiesTreeModel();
......
......@@ -231,6 +231,21 @@ SiteSettingSource CalculateSiteSettingSource(
return SiteSettingSource::kPreference;
}
// Whether |pattern| applies to a single origin.
bool PatternAppliesToSingleOrigin(const ContentSettingPatternSource& pattern) {
const GURL url(pattern.primary_pattern.ToString());
// Default settings and other patterns apply to multiple origins.
if (url::Origin::Create(url).opaque())
return false;
// Embedded content settings only when |url| is embedded in another origin, so
// ignore non-wildcard secondary patterns that are different to the primary.
if (pattern.primary_pattern != pattern.secondary_pattern &&
pattern.secondary_pattern != ContentSettingsPattern::Wildcard()) {
return false;
}
return true;
}
// Retrieves the source of a chooser exception as a string. This method uses the
// CalculateSiteSettingSource method above to calculate the correct string to
// use.
......@@ -317,6 +332,18 @@ std::string ContentSettingsTypeToGroupName(ContentSettingsType type) {
return std::string();
}
std::vector<ContentSettingsType> ContentSettingsTypesFromGroupNames(
const base::Value::ConstListView types) {
std::vector<ContentSettingsType> content_types;
content_types.reserve(types.size());
for (const auto& value : types) {
const auto& type = value.GetString();
content_types.push_back(
site_settings::ContentSettingsTypeFromGroupName(type));
}
return content_types;
}
std::string SiteSettingSourceToString(const SiteSettingSource source) {
return kSiteSettingSourceStringMapping[static_cast<int>(source)].source_str;
}
......@@ -568,6 +595,19 @@ ContentSetting GetContentSettingForOrigin(
return result.content_setting;
}
std::vector<ContentSettingPatternSource> GetSiteExceptionsForContentType(
HostContentSettingsMap* map,
ContentSettingsType content_type) {
ContentSettingsForOneType entries;
map->GetSettingsForOneType(content_type, std::string(), &entries);
entries.erase(std::remove_if(entries.begin(), entries.end(),
[](const ContentSettingPatternSource& e) {
return !PatternAppliesToSingleOrigin(e);
}),
entries.end());
return entries;
}
void GetPolicyAllowedUrls(
ContentSettingsType type,
std::vector<std::unique_ptr<base::DictionaryValue>>* exceptions,
......
......@@ -12,6 +12,7 @@
#include <utility>
#include <vector>
#include "base/values.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/content_settings/core/common/content_settings_pattern.h"
#include "components/content_settings/core/common/content_settings_types.h"
......@@ -22,12 +23,6 @@ class ChooserContextBase;
class HostContentSettingsMap;
class Profile;
namespace base {
class DictionaryValue;
class ListValue;
class Value;
} // namespace base
namespace extensions {
class ExtensionRegistry;
}
......@@ -63,9 +58,11 @@ constexpr char kIncognito[] = "incognito";
constexpr char kObject[] = "object";
constexpr char kOrigin[] = "origin";
constexpr char kOriginForFavicon[] = "originForFavicon";
constexpr char kRecentPermissions[] = "recentPermissions";
constexpr char kSetting[] = "setting";
constexpr char kSites[] = "sites";
constexpr char kSource[] = "source";
constexpr char kType[] = "type";
enum class SiteSettingSource {
kAdsFilterBlacklist,
......@@ -87,6 +84,10 @@ bool HasRegisteredGroupName(ContentSettingsType type);
ContentSettingsType ContentSettingsTypeFromGroupName(const std::string& name);
std::string ContentSettingsTypeToGroupName(ContentSettingsType type);
// Converts a ListValue of group names to a list of ContentSettingsTypes
std::vector<ContentSettingsType> ContentSettingsTypesFromGroupNames(
const base::Value::ConstListView types);
// Converts a SiteSettingSource to its string identifier.
std::string SiteSettingSourceToString(const SiteSettingSource source);
......@@ -145,6 +146,11 @@ void GetPolicyAllowedUrls(
content::WebUI* web_ui,
bool incognito);
// Returns all site permission exceptions for a given content type
std::vector<ContentSettingPatternSource> GetSiteExceptionsForContentType(
HostContentSettingsMap* map,
ContentSettingsType content_type);
// This struct facilitates lookup of a chooser context factory function by name
// for a given content settings type and is declared early so that it can used
// by functions below.
......
......@@ -4157,6 +4157,7 @@ test("unit_tests") {
"../browser/ui/webui/history/browsing_history_handler_unittest.cc",
"../browser/ui/webui/managed_ui_handler_unittest.cc",
"../browser/ui/webui/management_ui_handler_unittest.cc",
"../browser/ui/webui/recent_site_settings_helper_unittest.cc",
"../browser/ui/webui/settings/downloads_handler_unittest.cc",
"../browser/ui/webui/settings/metrics_reporting_handler_unittest.cc",
"../browser/ui/webui/settings/on_startup_handler_unittest.cc",
......
......@@ -20,8 +20,13 @@ class GURL;
namespace settings {
FORWARD_DECLARE_TEST(SiteSettingsHandlerTest, GetAllSites);
FORWARD_DECLARE_TEST(SiteSettingsHandlerTest, GetRecentSitePermissions);
} // namespace settings
namespace site_settings {
FORWARD_DECLARE_TEST(RecentSiteSettingsHelperTest, CheckRecentSitePermissions);
} // namespace site_settings
namespace permissions {
// The PermissionDecisionAutoBlocker decides whether or not a given origin
......@@ -111,7 +116,11 @@ class PermissionDecisionAutoBlocker : public KeyedService {
private:
friend class PermissionDecisionAutoBlockerUnitTest;
FRIEND_TEST_ALL_PREFIXES(site_settings::RecentSiteSettingsHelperTest,
CheckRecentSitePermissions);
FRIEND_TEST_ALL_PREFIXES(settings::SiteSettingsHandlerTest, GetAllSites);
FRIEND_TEST_ALL_PREFIXES(settings::SiteSettingsHandlerTest,
GetRecentSitePermissions);
void PlaceUnderEmbargo(const GURL& request_origin,
ContentSettingsType permission,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment