blob: e08ac1c2a4cd03acc437147741842b152d4b0d14 [file] [log] [blame]
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.site_settings;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridge.SITE_WILDCARD;
import static java.util.Map.entry;
import android.util.Pair;
import androidx.test.filters.SmallTest;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.chromium.base.Callback;
import org.chromium.base.test.params.ParameterAnnotations.UseMethodParameter;
import org.chromium.base.test.params.ParameterAnnotations.UseRunnerDelegate;
import org.chromium.base.test.params.ParameterProvider;
import org.chromium.base.test.params.ParameterSet;
import org.chromium.base.test.params.ParameterizedRunner;
import org.chromium.base.test.util.Batch;
import org.chromium.base.test.util.CallbackHelper;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.DisabledTest;
import org.chromium.chrome.browser.browsing_data.BrowsingDataBridge;
import org.chromium.chrome.browser.browsing_data.BrowsingDataType;
import org.chromium.chrome.browser.browsing_data.TimePeriod;
import org.chromium.chrome.browser.flags.ChromeSwitches;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.profiles.ProfileManager;
import org.chromium.chrome.test.ChromeBrowserTestRule;
import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
import org.chromium.components.browser_ui.site_settings.ChosenObjectInfo;
import org.chromium.components.browser_ui.site_settings.ContentSettingException;
import org.chromium.components.browser_ui.site_settings.CookiesInfo;
import org.chromium.components.browser_ui.site_settings.LocalStorageInfo;
import org.chromium.components.browser_ui.site_settings.PermissionInfo;
import org.chromium.components.browser_ui.site_settings.SharedDictionaryInfo;
import org.chromium.components.browser_ui.site_settings.SiteSettingsCategory;
import org.chromium.components.browser_ui.site_settings.SiteSettingsDelegate;
import org.chromium.components.browser_ui.site_settings.StorageInfo;
import org.chromium.components.browser_ui.site_settings.Website;
import org.chromium.components.browser_ui.site_settings.WebsiteAddress;
import org.chromium.components.browser_ui.site_settings.WebsitePermissionsFetcher;
import org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridge;
import org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridgeJni;
import org.chromium.components.browsing_data.content.BrowsingDataInfo;
import org.chromium.components.browsing_data.content.BrowsingDataModel;
import org.chromium.components.content_settings.ContentSettingValues;
import org.chromium.components.content_settings.ContentSettingsType;
import org.chromium.components.content_settings.ProviderType;
import org.chromium.components.content_settings.SessionModel;
import org.chromium.content_public.browser.BrowserContextHandle;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import org.chromium.url.GURL;
import org.chromium.url.Origin;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/** Tests for WebsitePermissionsFetcher. */
@RunWith(ParameterizedRunner.class)
@UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class)
@CommandLineFlags.Add({
ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
WebsitePermissionsFetcherTest.ENABLE_EXPERIMENTAL_WEB_PLATFORM_FEATURES,
WebsitePermissionsFetcherTest.ENABLE_WEB_BLUETOOTH_NEW_PERMISSIONS_BACKEND
})
@Batch(Batch.PER_CLASS)
public class WebsitePermissionsFetcherTest {
@Rule public final ChromeBrowserTestRule mBrowserTestRule = new ChromeBrowserTestRule();
@Mock private SiteSettingsDelegate mSiteSettingsDelegate;
@Mock private BrowsingDataModel mBrowsingDataModel;
/** Command line flag to enable experimental web platform features in tests. */
public static final String ENABLE_EXPERIMENTAL_WEB_PLATFORM_FEATURES =
"enable-experimental-web-platform-features";
/** Command line flag to enable the new Web Bluetooth permissions backend in tests. */
public static final String ENABLE_WEB_BLUETOOTH_NEW_PERMISSIONS_BACKEND =
"enable-features=WebBluetoothNewPermissionsBackend";
private static final BrowserContextHandle UNUSED_BROWSER_CONTEXT_HANDLE = null;
private static final String[] PERMISSION_URLS = {
"http://www.google.com/",
"http://www.youtube.com/",
"http://www.facebook.com/",
"http://www.baidu.com/",
"http://www.wikipedia.org/",
"http://www.yahoo.com/",
"http://www.google.co.in/",
"http://www.reddit.com/",
"http://www.qq.com/",
"http://www.taobao.com/",
"http://www.google.co.jp/",
"http://www.amazon.com/",
"http://www.twitter.com/",
"http://www.live.com/",
"http://www.instagram.com/",
"http://www.weibo.com/",
"http://www.google.de/",
"http://www.google.co.uk/",
"http://www.google.com.br/",
"http://www.google.fr/",
"http://www.google.ru/",
"http://www.linkedin.com/",
"http://www.google.com.hk/",
"http://www.yandex.ru/",
"http://www.google.it/",
"http://www.netflix.com/",
"http://www.yahoo.co.jp/",
"http://www.google.es/",
"http://www.t.co/",
"http://www.google.com.mx/",
"http://www.google.ca/",
"http://www.ebay.com/",
"http://www.alipay.com/",
"http://www.bing.com/",
"http://www.imgur.com/",
"http://www.twitch.tv/",
"http://www.msn.com/",
"http://www.apple.com/",
"http://www.aliexpress.com/",
"http://www.microsoft.com/",
"http://www.wordpress.com/",
"http://www.office.com/",
"http://www.mail.ru/",
"http://www.tumblr.com/",
"http://www.stackoverflow.com/",
"http://www.microsoftonline.com/",
"http://www.imdb.com/",
"http://www.github.com/",
"http://www.blogspot.com/",
"http://www.amazon.co.jp/",
"http://www.google.com.au/",
"http://www.google.com.tw/",
"http://www.google.com.tr/",
"http://www.paypal.com/",
"http://www.google.pl/",
"http://www.wikia.com/",
"http://www.pinterest.com/",
"http://www.whatsapp.com/",
"http://www.google.co.id/",
"http://www.espn.com/",
"http://www.adobe.com/",
"http://www.google.com.ar/",
"http://www.googleusercontent.com/",
"http://www.amazon.in/",
"http://www.dropbox.com/",
"http://www.amazon.de/",
"http://www.google.com.ua/",
"http://www.so.com/",
"http://www.google.com.pk/",
"http://www.cnn.com/",
"http://www.amazon.co.uk/",
"http://www.bbc.co.uk/",
"http://www.google.com.sa/",
"http://www.craigslist.org/",
"http://www.bbc.com/",
"http://www.google.co.th/",
"http://www.google.com.eg/",
"http://www.google.nl/",
"http://www.amazonaws.com/",
"http://www.soundcloud.com/",
"http://www.ask.com/",
"http://www.google.co.za/",
"http://www.booking.com/",
"http://www.nytimes.com/",
"http://www.google.co.ve/",
"http://www.google.co.kr/",
"http://www.quora.com/",
"http://www.mozilla.org/",
"http://www.dailymotion.com/",
"http://www.stackexchange.com/",
"http://www.salesforce.com/",
"http://www.detik.com/",
"http://www.blogger.com/",
"http://www.ebay.de/",
"http://www.vimeo.com/",
"http://www.theguardian.com/",
"http://www.tribunnews.com/",
"http://www.google.com.sg/",
"http://www.google.gr/",
"http://www.flipkart.com/",
"http://www.spotify.com/",
"http://www.slideshare.net/",
"http://www.chase.com/",
"http://www.google.com.ph/",
"http://www.ebay.co.uk/",
"http://www.google.se/",
"http://www.cnet.com/",
"http://www.google.be/",
"http://www.nih.gov/",
"http://www.google.cn/",
"http://www.steamcommunity.com/",
"http://www.mediafire.com/",
"http://www.xinhuanet.com/",
"http://www.google.az/",
"http://www.vice.com/",
"http://www.alibaba.com/",
"http://www.dailymail.co.uk/",
"http://www.google.com.co/",
"http://www.buzzfeed.com/",
"http://www.doubleclick.net/",
"http://www.google.com.ng/",
"http://www.google.co.ao/",
"http://www.google.at/",
"http://www.uol.com.br/",
"http://www.redd.it/",
"http://www.deviantart.com/",
"http://www.washingtonpost.com/",
"http://www.twimg.com/",
"http://www.w3schools.com/",
"http://www.godaddy.com/",
"http://www.wikihow.com/",
"http://www.etsy.com/",
"http://www.slack.com/",
"http://www.google.cz/",
"http://www.google.ch/",
"http://www.amazon.it/",
"http://www.steampowered.com/",
"http://www.google.com.vn/",
"http://www.walmart.com/",
"http://www.messenger.com/",
"http://www.discordapp.com/",
"http://www.google.cl/",
"http://www.amazon.fr/",
"http://www.yelp.com/",
"http://www.google.no/",
"http://www.google.pt/",
"http://www.google.ae/",
"http://www.weather.com/",
"http://www.mercadolivre.com.br/",
"http://www.google.ro/",
"http://www.bankofamerica.com/",
"http://www.blogspot.co.id/",
"http://www.trello.com/",
"http://www.gfycat.com/",
"http://www.ikea.com/",
"http://www.scribd.com/",
"http://www.china.com.cn/",
"http://www.forbes.com/",
"http://www.wellsfargo.com/",
"http://www.indiatimes.com/",
"http://www.cnblogs.com/",
"http://www.gamepedia.com/",
"http://www.outbrain.com/",
"http://www.9gag.com/",
"http://www.google.ie/",
"http://www.gearbest.com/",
"http://www.files.wordpress.com/",
"http://www.huffingtonpost.com/",
"http://www.speedtest.net/",
"http://www.google.dk/",
"http://www.google.fi/",
"http://www.wikimedia.org/",
"http://www.thesaurus.com/",
"http://www.livejournal.com/",
"http://www.nfl.com/",
"http://www.zillow.com/",
"http://www.foxnews.com/",
"http://www.researchgate.net/",
"http://www.amazon.cn/",
"http://www.google.hu/",
"http://www.google.co.il/",
"http://www.amazon.es/",
"http://www.wordreference.com/",
"http://www.blackboard.com/",
"http://www.google.dz/",
"http://www.tripadvisor.com/",
"http://www.shutterstock.com/",
"http://www.cloudfront.net/",
"http://www.aol.com/",
"http://www.weebly.com/",
"http://www.battle.net/",
"http://www.archive.org/",
};
private static final Map<String, String> FPS_MEMBER_TO_OWNER_MAP =
Map.ofEntries(
entry("https://google.de", "google.com"),
entry("https://youtube.com", "google.com"),
entry("https://google.ch", "google.com"),
entry("https://google.it", "google.com"),
entry("https://wikipedia.org", "wikipedia.org"),
entry("https://chromium.org", "chromium.org"),
entry("https://googlesource.org", "chromium.org"),
entry("https://verizon.com", "verizon.com"),
entry("https://verizonconnect.com", "verizon.com"),
entry("https://aol.com", "verizon.com"),
entry("https://vodafone.de", "vodafone.com"));
private static final List<Integer> EMBEDDED_CONTENT_SETTINGS =
Arrays.asList(ContentSettingsType.STORAGE_ACCESS);
private static final String ORIGIN = "https://google.com:443";
private static final String EMBEDDER = "https://embedder.com";
private static final int EXPIRATION_IN_DAYS = 30;
public static class EmbargoedParams implements ParameterProvider {
@Override
public List<ParameterSet> getParameters() {
return Arrays.asList(
new ParameterSet().value(true).name("Embargoed"),
new ParameterSet().value(false).name("Normal"));
}
}
public static class EmbargoedAndOneTimeSessionParameters implements ParameterProvider {
@Override
public List<ParameterSet> getParameters() {
return Arrays.asList(
new ParameterSet().value(false, false).name("NormalDurable"),
new ParameterSet().value(true, false).name("EmbargoedDurable"),
new ParameterSet().value(false, true).name("NormalOneTime"),
new ParameterSet().value(true, true).name("EmbargoedOneTime"));
}
}
public static class BrowsingDataModelEnabled implements ParameterProvider {
@Override
public List<ParameterSet> getParameters() {
return Arrays.asList(
new ParameterSet().value(true).name("BDMEnabled"),
new ParameterSet().value(false).name("BDMDisabled"));
}
}
private static class WebsitePermissionsWaiter extends CallbackHelper
implements WebsitePermissionsFetcher.WebsitePermissionsCallback {
private Collection<Website> mSites;
@Override
public void onWebsitePermissionsAvailable(Collection<Website> sites) {
mSites = sites;
notifyCalled();
}
public Collection<Website> getSites() {
return mSites;
}
}
@Before
public void setUp() {
MockitoAnnotations.openMocks(this);
}
@After
public void tearDown() throws TimeoutException {
// Clean up permissions.
CallbackHelper helper = new CallbackHelper();
TestThreadUtils.runOnUiThreadBlocking(
() -> {
BrowsingDataBridge.getForProfile(ProfileManager.getLastUsedRegularProfile())
.clearBrowsingData(
helper::notifyCalled,
new int[] {BrowsingDataType.SITE_SETTINGS},
TimePeriod.ALL_TIME);
});
helper.waitForCallback(0);
}
@Test
@SmallTest
public void testNullsCanBeHandled() {
// This is a smoke test to ensure that nulls do not cause crashes.
WebsitePermissionsFetcher.OriginAndEmbedder nullBoth =
new WebsitePermissionsFetcher.OriginAndEmbedder(null, null);
WebsitePermissionsFetcher.OriginAndEmbedder nullOrigin =
new WebsitePermissionsFetcher.OriginAndEmbedder(
WebsiteAddress.create("https://www.google.com"), null);
WebsitePermissionsFetcher.OriginAndEmbedder nullEmbedder =
new WebsitePermissionsFetcher.OriginAndEmbedder(
null, WebsiteAddress.create("https://www.google.com"));
HashMap<WebsitePermissionsFetcher.OriginAndEmbedder, String> map = new HashMap<>();
map.put(nullBoth, "nullBoth");
map.put(nullOrigin, "nullOrigin");
map.put(nullEmbedder, "nullEmbedder");
Assert.assertTrue(map.containsKey(nullBoth));
Assert.assertTrue(map.containsKey(nullOrigin));
Assert.assertTrue(map.containsKey(nullEmbedder));
assertEquals("nullBoth", map.get(nullBoth));
assertEquals("nullOrigin", map.get(nullOrigin));
assertEquals("nullEmbedder", map.get(nullEmbedder));
}
@Test
@SmallTest
@DisabledTest(message = "https://crbug.com/1085592")
public void testFetcherDoesNotTimeOutWithManyUrls() throws Exception {
final WebsitePermissionsWaiter waiter = new WebsitePermissionsWaiter();
// Set lots of permissions values.
TestThreadUtils.runOnUiThreadBlocking(
() -> {
Profile profile = ProfileManager.getLastUsedRegularProfile();
for (String url : PERMISSION_URLS) {
WebsitePreferenceBridgeJni.get()
.setPermissionSettingForOrigin(
profile,
ContentSettingsType.GEOLOCATION,
url,
url,
ContentSettingValues.BLOCK);
WebsitePreferenceBridgeJni.get()
.setPermissionSettingForOrigin(
profile,
ContentSettingsType.MIDI_SYSEX,
url,
url,
ContentSettingValues.ALLOW);
WebsitePreferenceBridgeJni.get()
.setPermissionSettingForOrigin(
profile,
ContentSettingsType.PROTECTED_MEDIA_IDENTIFIER,
url,
url,
ContentSettingValues.BLOCK);
WebsitePreferenceBridgeJni.get()
.setPermissionSettingForOrigin(
profile,
ContentSettingsType.NOTIFICATIONS,
url,
url,
ContentSettingValues.ALLOW);
WebsitePreferenceBridgeJni.get()
.setPermissionSettingForOrigin(
profile,
ContentSettingsType.MEDIASTREAM_MIC,
url,
url,
ContentSettingValues.ALLOW);
WebsitePreferenceBridgeJni.get()
.setPermissionSettingForOrigin(
profile,
ContentSettingsType.MEDIASTREAM_CAMERA,
url,
url,
ContentSettingValues.BLOCK);
}
// This should not time out. See crbug.com/732907.
WebsitePermissionsFetcher fetcher =
new WebsitePermissionsFetcher(mSiteSettingsDelegate);
fetcher.fetchAllPreferences(waiter);
});
waiter.waitForCallback(0, 1, 1000L, TimeUnit.MILLISECONDS);
}
class FakeWebsitePreferenceBridge extends WebsitePreferenceBridge {
public List<PermissionInfo> mPermissionInfos;
public List<ContentSettingException> mContentSettingExceptions;
public List<ChosenObjectInfo> mChosenObjectInfos;
public HashMap<String, LocalStorageInfo> mLocalStorageInfoMap;
public HashMap<String, LocalStorageInfo> mImportantLocalStorageInfoMap;
public ArrayList<StorageInfo> mStorageInfos;
public ArrayList<SharedDictionaryInfo> mSharedDictionaryInfos;
FakeWebsitePreferenceBridge() {
mPermissionInfos = new ArrayList<>();
mContentSettingExceptions = new ArrayList<>();
mChosenObjectInfos = new ArrayList<>();
mLocalStorageInfoMap = new HashMap<>();
mImportantLocalStorageInfoMap = new HashMap<>();
mStorageInfos = new ArrayList<>();
mSharedDictionaryInfos = new ArrayList<>();
}
@Override
public List<PermissionInfo> getPermissionInfo(
BrowserContextHandle browserContextHandle, @ContentSettingsType.EnumType int type) {
List<PermissionInfo> result = new ArrayList<>();
for (PermissionInfo info : mPermissionInfos) {
if (info.getContentSettingsType() == type) {
result.add(info);
}
}
return result;
}
@Override
public List<ContentSettingException> getContentSettingsExceptions(
BrowserContextHandle browserContextHandle,
@ContentSettingsType.EnumType int contentSettingsType) {
List<ContentSettingException> result = new ArrayList<>();
for (ContentSettingException exception : mContentSettingExceptions) {
if (exception.getContentSettingType() == contentSettingsType) {
result.add(exception);
}
}
return result;
}
@Override
public void fetchLocalStorageInfo(
BrowserContextHandle browserContextHandle,
Callback<HashMap> callback,
boolean fetchImportant) {
if (fetchImportant) {
callback.onResult(mImportantLocalStorageInfoMap);
return;
}
callback.onResult(mLocalStorageInfoMap);
}
@Override
public void fetchCookiesInfo(
BrowserContextHandle browserContextHandle,
Callback<Map<String, CookiesInfo>> callback) {
callback.onResult(new HashMap<>());
}
@Override
public void fetchStorageInfo(
BrowserContextHandle browserContextHandle, Callback<ArrayList> callback) {
callback.onResult(mStorageInfos);
}
@Override
public void fetchSharedDictionaryInfo(
BrowserContextHandle browserContextHandle, Callback<ArrayList> callback) {
callback.onResult(mSharedDictionaryInfos);
}
@Override
public List<ChosenObjectInfo> getChosenObjectInfo(
BrowserContextHandle browserContextHandle, int contentSettingsType) {
List<ChosenObjectInfo> result = new ArrayList<>();
for (ChosenObjectInfo info : mChosenObjectInfos) {
if (info.getContentSettingsType() == contentSettingsType) {
result.add(info);
}
}
return result;
}
public void addPermissionInfo(PermissionInfo info) {
mPermissionInfos.add(info);
}
public void addContentSettingException(ContentSettingException exception) {
mContentSettingExceptions.add(exception);
}
public void resetContentSettingExceptions() {
mContentSettingExceptions.clear();
}
public void addLocalStorageInfoMapEntry(LocalStorageInfo info) {
if (info.isDomainImportant()) {
mImportantLocalStorageInfoMap.put(info.getOrigin(), info);
return;
}
mLocalStorageInfoMap.put(info.getOrigin(), info);
}
public void addStorageInfo(StorageInfo info) {
mStorageInfos.add(info);
}
public void addSharedDictionaryInfo(SharedDictionaryInfo info) {
mSharedDictionaryInfos.add(info);
}
public void addChosenObjectInfo(ChosenObjectInfo info) {
mChosenObjectInfos.add(info);
}
}
@Test
@SmallTest
@UseMethodParameter(BrowsingDataModelEnabled.class)
public void testFetchAllPreferencesForSingleOrigin(boolean isBDMEnabled) {
Mockito.doReturn(isBDMEnabled)
.when(mSiteSettingsDelegate)
.isBrowsingDataModelFeatureEnabled();
WebsitePermissionsFetcher fetcher = new WebsitePermissionsFetcher(mSiteSettingsDelegate);
FakeWebsitePreferenceBridge websitePreferenceBridge = new FakeWebsitePreferenceBridge();
fetcher.setWebsitePreferenceBridgeForTesting(websitePreferenceBridge);
websitePreferenceBridge.addPermissionInfo(
new PermissionInfo(
ContentSettingsType.AR,
ORIGIN,
SITE_WILDCARD,
/* isEmbargoed= */ false,
SessionModel.DURABLE));
websitePreferenceBridge.addPermissionInfo(
new PermissionInfo(
ContentSettingsType.IDLE_DETECTION,
ORIGIN,
SITE_WILDCARD,
/* isEmbargoed= */ false,
SessionModel.DURABLE));
websitePreferenceBridge.addPermissionInfo(
new PermissionInfo(
ContentSettingsType.GEOLOCATION,
ORIGIN,
SITE_WILDCARD,
/* isEmbargoed= */ false,
SessionModel.DURABLE));
websitePreferenceBridge.addPermissionInfo(
new PermissionInfo(
ContentSettingsType.MIDI_SYSEX,
ORIGIN,
SITE_WILDCARD,
/* isEmbargoed= */ false,
SessionModel.DURABLE));
websitePreferenceBridge.addPermissionInfo(
new PermissionInfo(
ContentSettingsType.PROTECTED_MEDIA_IDENTIFIER,
ORIGIN,
SITE_WILDCARD,
/* isEmbargoed= */ false,
SessionModel.DURABLE));
websitePreferenceBridge.addPermissionInfo(
new PermissionInfo(
ContentSettingsType.NFC,
ORIGIN,
SITE_WILDCARD,
/* isEmbargoed= */ false,
SessionModel.DURABLE));
websitePreferenceBridge.addPermissionInfo(
new PermissionInfo(
ContentSettingsType.NOTIFICATIONS,
ORIGIN,
SITE_WILDCARD,
/* isEmbargoed= */ false,
SessionModel.DURABLE));
websitePreferenceBridge.addPermissionInfo(
new PermissionInfo(
ContentSettingsType.MEDIASTREAM_CAMERA,
ORIGIN,
SITE_WILDCARD,
/* isEmbargoed= */ false,
SessionModel.DURABLE));
websitePreferenceBridge.addPermissionInfo(
new PermissionInfo(
ContentSettingsType.MEDIASTREAM_MIC,
ORIGIN,
SITE_WILDCARD,
/* isEmbargoed= */ false,
SessionModel.DURABLE));
websitePreferenceBridge.addPermissionInfo(
new PermissionInfo(
ContentSettingsType.CLIPBOARD_READ_WRITE,
ORIGIN,
SITE_WILDCARD,
/* isEmbargoed= */ false,
SessionModel.DURABLE));
websitePreferenceBridge.addPermissionInfo(
new PermissionInfo(
ContentSettingsType.SENSORS,
ORIGIN,
SITE_WILDCARD,
/* isEmbargoed= */ false,
SessionModel.DURABLE));
websitePreferenceBridge.addPermissionInfo(
new PermissionInfo(
ContentSettingsType.VR,
ORIGIN,
SITE_WILDCARD,
/* isEmbargoed= */ false,
SessionModel.DURABLE));
// Add content setting exception types.
// If the ContentSettingsType.MAX_VALUE value changes *and* a new value has been exposed on
// Android, then please update this code block to include a test for your new type.
// Otherwise, just update count in the assert.
// TODO(https://b/332704817): Add test for Tracking Protection content setting after Android
// integration.
assertEquals(108, ContentSettingsType.MAX_VALUE);
websitePreferenceBridge.addContentSettingException(
new ContentSettingException(
ContentSettingsType.COOKIES,
ORIGIN,
ContentSettingValues.DEFAULT,
ProviderType.PREF_PROVIDER,
/* isEmbargoed= */ false));
websitePreferenceBridge.addContentSettingException(
new ContentSettingException(
ContentSettingsType.POPUPS,
ORIGIN,
ContentSettingValues.DEFAULT,
ProviderType.PREF_PROVIDER,
/* isEmbargoed= */ false));
websitePreferenceBridge.addContentSettingException(
new ContentSettingException(
ContentSettingsType.ADS,
ORIGIN,
ContentSettingValues.DEFAULT,
ProviderType.PREF_PROVIDER,
/* isEmbargoed= */ false));
websitePreferenceBridge.addContentSettingException(
new ContentSettingException(
ContentSettingsType.JAVASCRIPT,
ORIGIN,
ContentSettingValues.DEFAULT,
ProviderType.PREF_PROVIDER,
/* isEmbargoed= */ false));
websitePreferenceBridge.addContentSettingException(
new ContentSettingException(
ContentSettingsType.SOUND,
ORIGIN,
ContentSettingValues.DEFAULT,
ProviderType.PREF_PROVIDER,
/* isEmbargoed= */ false));
websitePreferenceBridge.addContentSettingException(
new ContentSettingException(
ContentSettingsType.BACKGROUND_SYNC,
ORIGIN,
ContentSettingValues.DEFAULT,
ProviderType.PREF_PROVIDER,
/* isEmbargoed= */ false));
websitePreferenceBridge.addContentSettingException(
new ContentSettingException(
ContentSettingsType.AUTOMATIC_DOWNLOADS,
ORIGIN,
ContentSettingValues.DEFAULT,
ProviderType.PREF_PROVIDER,
/* isEmbargoed= */ false));
websitePreferenceBridge.addContentSettingException(
new ContentSettingException(
ContentSettingsType.INSECURE_PRIVATE_NETWORK,
ORIGIN,
ContentSettingValues.DEFAULT,
ProviderType.PREF_PROVIDER,
/* isEmbargoed= */ false));
websitePreferenceBridge.addContentSettingException(
new ContentSettingException(
ContentSettingsType.JAVASCRIPT_JIT,
ORIGIN,
ContentSettingValues.DEFAULT,
ProviderType.PREF_PROVIDER,
/* isEmbargoed= */ false));
websitePreferenceBridge.addContentSettingException(
new ContentSettingException(
ContentSettingsType.AUTO_DARK_WEB_CONTENT,
ORIGIN,
ContentSettingValues.DEFAULT,
ProviderType.PREF_PROVIDER,
/* isEmbargoed= */ false));
websitePreferenceBridge.addContentSettingException(
new ContentSettingException(
ContentSettingsType.REQUEST_DESKTOP_SITE,
ORIGIN,
ContentSettingValues.DEFAULT,
ProviderType.PREF_PROVIDER,
/* isEmbargoed= */ false));
websitePreferenceBridge.addContentSettingException(
new ContentSettingException(
ContentSettingsType.FEDERATED_IDENTITY_API,
ORIGIN,
ContentSettingValues.DEFAULT,
ProviderType.PREF_PROVIDER,
/* isEmbargoed= */ false));
websitePreferenceBridge.addContentSettingException(
new ContentSettingException(
ContentSettingsType.FEDERATED_IDENTITY_AUTO_REAUTHN_PERMISSION,
ORIGIN,
ContentSettingValues.DEFAULT,
ProviderType.PREF_PROVIDER,
/* isEmbargoed= */ false));
websitePreferenceBridge.addContentSettingException(
new ContentSettingException(
ContentSettingsType.ANTI_ABUSE,
ORIGIN,
ContentSettingValues.DEFAULT,
ProviderType.PREF_PROVIDER,
/* isEmbargoed= */ false));
int storageSize = 256;
int sharedDictionarySize = 12345;
if (isBDMEnabled) {
var map = new HashMap<Origin, BrowsingDataInfo>();
var origin = Origin.create(new GURL(ORIGIN));
map.put(origin, new BrowsingDataInfo(origin, 0, storageSize + sharedDictionarySize));
Mockito.doReturn(map).when(mBrowsingDataModel).getBrowsingDataInfo();
doAnswer(this::mockBDMCallback)
.when(mSiteSettingsDelegate)
.getBrowsingDataModel(any(Callback.class));
} else {
// Add storage info.
websitePreferenceBridge.addStorageInfo(new StorageInfo(ORIGIN, 0, storageSize));
// Add local storage info.
websitePreferenceBridge.addLocalStorageInfoMapEntry(
new LocalStorageInfo(ORIGIN, storageSize, false));
// Add shared dictionary info.
websitePreferenceBridge.addSharedDictionaryInfo(
new SharedDictionaryInfo(ORIGIN, ORIGIN, sharedDictionarySize));
}
// Add chooser info types.
websitePreferenceBridge.addChosenObjectInfo(
new ChosenObjectInfo(
ContentSettingsType.USB_CHOOSER_DATA, ORIGIN, "Gadget", "Object", false));
websitePreferenceBridge.addChosenObjectInfo(
new ChosenObjectInfo(
ContentSettingsType.BLUETOOTH_CHOOSER_DATA,
ORIGIN,
"Wireless",
"Object",
false));
fetcher.fetchAllPreferences(
(sites) -> {
assertEquals(1, sites.size());
Website site = sites.iterator().next();
Assert.assertTrue(site.getAddress().matches(ORIGIN));
// Check permission info types for |site|.
Assert.assertNotNull(site.getPermissionInfo(ContentSettingsType.GEOLOCATION));
Assert.assertNotNull(
site.getPermissionInfo(ContentSettingsType.IDLE_DETECTION));
Assert.assertNotNull(site.getPermissionInfo(ContentSettingsType.MIDI_SYSEX));
Assert.assertNotNull(
site.getPermissionInfo(ContentSettingsType.PROTECTED_MEDIA_IDENTIFIER));
Assert.assertNotNull(site.getPermissionInfo(ContentSettingsType.NOTIFICATIONS));
Assert.assertNotNull(
site.getPermissionInfo(ContentSettingsType.MEDIASTREAM_CAMERA));
Assert.assertNotNull(
site.getPermissionInfo(ContentSettingsType.MEDIASTREAM_MIC));
Assert.assertNotNull(
site.getPermissionInfo(ContentSettingsType.CLIPBOARD_READ_WRITE));
Assert.assertNotNull(site.getPermissionInfo(ContentSettingsType.SENSORS));
Assert.assertNotNull(site.getPermissionInfo(ContentSettingsType.VR));
Assert.assertNotNull(site.getPermissionInfo(ContentSettingsType.AR));
// Check content setting exception types.
assertEquals(
Integer.valueOf(ContentSettingValues.DEFAULT),
site.getContentSetting(
UNUSED_BROWSER_CONTEXT_HANDLE, ContentSettingsType.COOKIES));
assertEquals(
Integer.valueOf(ContentSettingValues.DEFAULT),
site.getContentSetting(
UNUSED_BROWSER_CONTEXT_HANDLE, ContentSettingsType.POPUPS));
assertEquals(
Integer.valueOf(ContentSettingValues.DEFAULT),
site.getContentSetting(
UNUSED_BROWSER_CONTEXT_HANDLE, ContentSettingsType.ADS));
assertEquals(
Integer.valueOf(ContentSettingValues.DEFAULT),
site.getContentSetting(
UNUSED_BROWSER_CONTEXT_HANDLE, ContentSettingsType.JAVASCRIPT));
assertEquals(
Integer.valueOf(ContentSettingValues.DEFAULT),
site.getContentSetting(
UNUSED_BROWSER_CONTEXT_HANDLE, ContentSettingsType.SOUND));
assertEquals(
Integer.valueOf(ContentSettingValues.DEFAULT),
site.getContentSetting(
UNUSED_BROWSER_CONTEXT_HANDLE,
ContentSettingsType.BACKGROUND_SYNC));
assertEquals(
Integer.valueOf(ContentSettingValues.DEFAULT),
site.getContentSetting(
UNUSED_BROWSER_CONTEXT_HANDLE,
ContentSettingsType.AUTOMATIC_DOWNLOADS));
assertEquals(
Integer.valueOf(ContentSettingValues.DEFAULT),
site.getContentSetting(
UNUSED_BROWSER_CONTEXT_HANDLE,
ContentSettingsType.JAVASCRIPT_JIT));
assertEquals(
Integer.valueOf(ContentSettingValues.DEFAULT),
site.getContentSetting(
UNUSED_BROWSER_CONTEXT_HANDLE,
ContentSettingsType.AUTO_DARK_WEB_CONTENT));
assertEquals(
Integer.valueOf(ContentSettingValues.DEFAULT),
site.getContentSetting(
UNUSED_BROWSER_CONTEXT_HANDLE,
ContentSettingsType.REQUEST_DESKTOP_SITE));
assertEquals(
Integer.valueOf(ContentSettingValues.DEFAULT),
site.getContentSetting(
UNUSED_BROWSER_CONTEXT_HANDLE,
ContentSettingsType.FEDERATED_IDENTITY_API));
assertEquals(
Integer.valueOf(ContentSettingValues.DEFAULT),
site.getContentSetting(
UNUSED_BROWSER_CONTEXT_HANDLE, ContentSettingsType.ANTI_ABUSE));
if (isBDMEnabled) {
assertEquals(storageSize + sharedDictionarySize, site.getTotalUsage());
} else {
// Check storage info.
var storageInfos = new ArrayList<>(site.getStorageInfo());
assertEquals(1, storageInfos.size());
StorageInfo storageInfo = storageInfos.get(0);
assertEquals(ORIGIN, storageInfo.getHost());
assertEquals(storageSize, storageInfo.getSize());
// Check local storage info.
var localStorageInfo = site.getLocalStorageInfo();
assertEquals(ORIGIN, localStorageInfo.getOrigin());
assertEquals(storageSize, localStorageInfo.getSize());
Assert.assertFalse(localStorageInfo.isDomainImportant());
// Check shared dictionary info.
var sharedDictionaryInfos = new ArrayList<>(site.getSharedDictionaryInfo());
assertEquals(1, sharedDictionaryInfos.size());
SharedDictionaryInfo sharedDictionaryInfo = sharedDictionaryInfos.get(0);
assertEquals(ORIGIN, sharedDictionaryInfo.getOrigin());
assertEquals(sharedDictionarySize, sharedDictionaryInfo.getSize());
}
// Check chooser info types.
ArrayList<ChosenObjectInfo> chosenObjectInfos =
new ArrayList<>(site.getChosenObjectInfo());
assertEquals(2, chosenObjectInfos.size());
assertEquals(
ContentSettingsType.BLUETOOTH_CHOOSER_DATA,
chosenObjectInfos.get(0).getContentSettingsType());
assertEquals(
ContentSettingsType.USB_CHOOSER_DATA,
chosenObjectInfos.get(1).getContentSettingsType());
});
}
private Object mockBDMCallback(InvocationOnMock invocation) {
var callback = (Callback<BrowsingDataModel>) invocation.getArguments()[0];
callback.onResult(mBrowsingDataModel);
return null;
}
@Test
@SmallTest
public void testFetchAllPreferencesForMultipleOrigins() {
WebsitePermissionsFetcher fetcher = new WebsitePermissionsFetcher(mSiteSettingsDelegate);
FakeWebsitePreferenceBridge websitePreferenceBridge = new FakeWebsitePreferenceBridge();
fetcher.setWebsitePreferenceBridgeForTesting(websitePreferenceBridge);
String chromiumOrigin = "https://chromium.org";
String exampleOrigin = "https://example.com";
websitePreferenceBridge.addPermissionInfo(
new PermissionInfo(
ContentSettingsType.GEOLOCATION,
ORIGIN,
SITE_WILDCARD,
/* isEmbargoed= */ false,
SessionModel.DURABLE));
websitePreferenceBridge.addPermissionInfo(
new PermissionInfo(
ContentSettingsType.GEOLOCATION,
chromiumOrigin,
SITE_WILDCARD,
/* isEmbargoed= */ false,
SessionModel.DURABLE));
Website expectedGoogleWebsite =
new Website(WebsiteAddress.create(ORIGIN), WebsiteAddress.create(null));
Website expectedChromiumWebsite =
new Website(WebsiteAddress.create(chromiumOrigin), WebsiteAddress.create(null));
fetcher.fetchAllPreferences(
(sites) -> {
assertEquals(2, sites.size());
// The order of |sites| is unknown, so check if the array contains a geolocation
// permission for each of the sites.
ArrayList<Website> siteArray = new ArrayList<>(sites);
boolean containsOriginPermission = false;
boolean containsChromiumOriginPermission = false;
for (Website site : siteArray) {
if (site.compareByAddressTo(expectedGoogleWebsite) == 0) {
containsOriginPermission = true;
} else if (site.compareByAddressTo(expectedChromiumWebsite) == 0) {
containsChromiumOriginPermission = true;
}
Assert.assertNotNull(
site.getPermissionInfo(ContentSettingsType.GEOLOCATION));
}
Assert.assertTrue(containsOriginPermission);
Assert.assertTrue(containsChromiumOriginPermission);
});
websitePreferenceBridge.addPermissionInfo(
new PermissionInfo(
ContentSettingsType.GEOLOCATION,
exampleOrigin,
SITE_WILDCARD,
/* isEmbargoed= */ false,
SessionModel.DURABLE));
Website expectedExampleWebsite =
new Website(WebsiteAddress.create(exampleOrigin), WebsiteAddress.create(null));
fetcher.fetchAllPreferences(
(sites) -> {
assertEquals(3, sites.size());
ArrayList<Website> siteArray = new ArrayList<>(sites);
boolean containsOriginPermission = false;
boolean containsChromiumOriginPermission = false;
boolean containsExampleOriginPermission = false;
for (Website site : siteArray) {
if (site.compareByAddressTo(expectedGoogleWebsite) == 0) {
containsOriginPermission = true;
} else if (site.compareByAddressTo(expectedChromiumWebsite) == 0) {
containsChromiumOriginPermission = true;
} else if (site.compareByAddressTo(expectedExampleWebsite) == 0) {
containsExampleOriginPermission = true;
}
Assert.assertNotNull(
site.getPermissionInfo(ContentSettingsType.GEOLOCATION));
}
Assert.assertTrue(containsOriginPermission);
Assert.assertTrue(containsChromiumOriginPermission);
Assert.assertTrue(containsExampleOriginPermission);
});
}
public void assertContentSettingExceptionEquals(
ContentSettingException expected, ContentSettingException actual) {
assertEquals(expected.getSource(), actual.getSource());
assertEquals(expected.isEmbargoed(), actual.isEmbargoed());
assertEquals(expected.getPrimaryPattern(), actual.getPrimaryPattern());
assertEquals(expected.getSecondaryPattern(), actual.getSecondaryPattern());
assertEquals(expected.getContentSetting(), actual.getContentSetting());
assertEquals(expected.getExpirationInDays(), actual.getExpirationInDays());
assertEquals(expected.hasExpiration(), actual.hasExpiration());
}
@Test
@SmallTest
@UseMethodParameter(EmbargoedAndOneTimeSessionParameters.class)
public void testFetchPreferencesForCategoryPermissionInfoTypes(
boolean isEmbargoed, boolean isOneTime) {
WebsitePermissionsFetcher fetcher = new WebsitePermissionsFetcher(mSiteSettingsDelegate);
FakeWebsitePreferenceBridge websitePreferenceBridge = new FakeWebsitePreferenceBridge();
fetcher.setWebsitePreferenceBridgeForTesting(websitePreferenceBridge);
// MIDI is excluded from this list because it does not have a top level category.
ArrayList<Integer> permissionInfoTypes =
new ArrayList<>(
Arrays.asList(
ContentSettingsType.AR,
ContentSettingsType.MEDIASTREAM_CAMERA,
ContentSettingsType.CLIPBOARD_READ_WRITE,
ContentSettingsType.GEOLOCATION,
ContentSettingsType.IDLE_DETECTION,
ContentSettingsType.MEDIASTREAM_MIC,
ContentSettingsType.NFC,
ContentSettingsType.NOTIFICATIONS,
ContentSettingsType.PROTECTED_MEDIA_IDENTIFIER,
ContentSettingsType.SENSORS,
ContentSettingsType.VR));
@SessionModel.EnumType
int sessionModel = isOneTime ? SessionModel.ONE_TIME : SessionModel.DURABLE;
for (@ContentSettingsType.EnumType int type : permissionInfoTypes) {
PermissionInfo fakePermissionInfo =
new PermissionInfo(type, ORIGIN, SITE_WILDCARD, isEmbargoed, sessionModel);
websitePreferenceBridge.addPermissionInfo(fakePermissionInfo);
fetcher.fetchPreferencesForCategory(
SiteSettingsCategory.createFromContentSettingsType(
UNUSED_BROWSER_CONTEXT_HANDLE, type),
(sites) -> {
assertEquals(1, sites.size());
Website site = sites.iterator().next();
Assert.assertNotNull(site.getPermissionInfo(type));
Assert.assertEquals(
sessionModel, site.getPermissionInfo(type).getSessionModel());
});
}
}
@Test
@SmallTest
@UseMethodParameter(EmbargoedParams.class)
public void testFetchPreferencesForCategoryContentSettingExceptionTypes(boolean isEmbargoed) {
WebsitePermissionsFetcher fetcher = new WebsitePermissionsFetcher(mSiteSettingsDelegate);
FakeWebsitePreferenceBridge websitePreferenceBridge = new FakeWebsitePreferenceBridge();
fetcher.setWebsitePreferenceBridgeForTesting(websitePreferenceBridge);
ArrayList<Integer> contentSettingExceptionTypes =
new ArrayList<>(
Arrays.asList(
ContentSettingsType.ADS,
ContentSettingsType.AUTOMATIC_DOWNLOADS,
ContentSettingsType.BACKGROUND_SYNC,
ContentSettingsType.BLUETOOTH_SCANNING,
ContentSettingsType.COOKIES,
ContentSettingsType.FEDERATED_IDENTITY_API,
ContentSettingsType.JAVASCRIPT,
ContentSettingsType.POPUPS,
ContentSettingsType.SOUND));
for (@ContentSettingsType.EnumType int type : contentSettingExceptionTypes) {
{
ContentSettingException fakeContentSettingException =
new ContentSettingException(
type,
ORIGIN,
ContentSettingValues.DEFAULT,
ProviderType.PREF_PROVIDER,
isEmbargoed);
websitePreferenceBridge.addContentSettingException(fakeContentSettingException);
fetcher.fetchPreferencesForCategory(
SiteSettingsCategory.createFromContentSettingsType(
UNUSED_BROWSER_CONTEXT_HANDLE, type),
(sites) -> {
assertEquals(1, sites.size());
Website site = sites.iterator().next();
assertContentSettingExceptionEquals(
fakeContentSettingException,
site.getContentSettingException(type));
});
}
// Make sure that the content setting value is updated.
{
ContentSettingException fakeContentSettingException =
new ContentSettingException(
type,
ORIGIN,
ContentSettingValues.BLOCK,
ProviderType.PREF_PROVIDER,
isEmbargoed);
websitePreferenceBridge.addContentSettingException(fakeContentSettingException);
fetcher.fetchPreferencesForCategory(
SiteSettingsCategory.createFromContentSettingsType(
UNUSED_BROWSER_CONTEXT_HANDLE, type),
(sites) -> {
assertEquals(1, sites.size());
Website site = sites.iterator().next();
assertContentSettingExceptionEquals(
fakeContentSettingException,
site.getContentSettingException(type));
});
}
}
}
@Test
@SmallTest
@UseMethodParameter(EmbargoedParams.class)
public void testFetchPreferencesForAdvancedCookieSettings(boolean isEmbargoed) {
WebsitePermissionsFetcher fetcher = new WebsitePermissionsFetcher(mSiteSettingsDelegate);
FakeWebsitePreferenceBridge websitePreferenceBridge = new FakeWebsitePreferenceBridge();
fetcher.setWebsitePreferenceBridgeForTesting(websitePreferenceBridge);
String mainSite = "https://a.com";
String thirdPartySite = "https://b.com";
@ContentSettingsType.EnumType int contentSettingsType = ContentSettingsType.COOKIES;
// Test the advanced exception combinations of:
// b.com on a.com
// a.com on a.com
// * on a.com
ArrayList<Pair<String, String>> exceptions =
new ArrayList<>(
Arrays.asList(
new Pair<>(thirdPartySite, mainSite),
new Pair<>(mainSite, mainSite),
new Pair<>(SITE_WILDCARD, mainSite)));
for (Pair<String, String> pair : exceptions) {
websitePreferenceBridge.resetContentSettingExceptions();
{
ContentSettingException fakeContentSettingException =
new ContentSettingException(
contentSettingsType,
pair.first,
pair.second,
ContentSettingValues.DEFAULT,
ProviderType.PREF_PROVIDER,
EXPIRATION_IN_DAYS,
isEmbargoed);
websitePreferenceBridge.addContentSettingException(fakeContentSettingException);
fetcher.fetchPreferencesForCategory(
SiteSettingsCategory.createFromContentSettingsType(
UNUSED_BROWSER_CONTEXT_HANDLE, contentSettingsType),
(sites) -> {
assertEquals(1, sites.size());
Website site = sites.iterator().next();
assertContentSettingExceptionEquals(
fakeContentSettingException,
site.getContentSettingException(contentSettingsType));
});
}
// Make sure that the content setting value is updated.
{
ContentSettingException fakeContentSettingException =
new ContentSettingException(
contentSettingsType,
pair.first,
pair.second,
ContentSettingValues.BLOCK,
ProviderType.PREF_PROVIDER,
EXPIRATION_IN_DAYS,
isEmbargoed);
websitePreferenceBridge.addContentSettingException(fakeContentSettingException);
fetcher.fetchPreferencesForCategory(
SiteSettingsCategory.createFromContentSettingsType(
UNUSED_BROWSER_CONTEXT_HANDLE, contentSettingsType),
(sites) -> {
assertEquals(1, sites.size());
Website site = sites.iterator().next();
assertContentSettingExceptionEquals(
fakeContentSettingException,
site.getContentSettingException(contentSettingsType));
});
}
}
}
@Test
@SmallTest
public void testFetchPreferencesForCategoryStorageInfo() {
WebsitePermissionsFetcher fetcher = new WebsitePermissionsFetcher(mSiteSettingsDelegate);
FakeWebsitePreferenceBridge websitePreferenceBridge = new FakeWebsitePreferenceBridge();
fetcher.setWebsitePreferenceBridgeForTesting(websitePreferenceBridge);
String chromiumOrigin = "https://chromium.org";
int storageSize = 256;
int sharedDictionarySize = 512;
StorageInfo fakeStorageInfo = new StorageInfo(ORIGIN, 0, storageSize);
LocalStorageInfo fakeLocalStorageInfo = new LocalStorageInfo(ORIGIN, storageSize, false);
LocalStorageInfo fakeImportantLocalStorageInfo =
new LocalStorageInfo(chromiumOrigin, storageSize, true);
SharedDictionaryInfo fakeSharedDictionaryInfo =
new SharedDictionaryInfo(ORIGIN, ORIGIN, sharedDictionarySize);
websitePreferenceBridge.addStorageInfo(fakeStorageInfo);
websitePreferenceBridge.addLocalStorageInfoMapEntry(fakeLocalStorageInfo);
websitePreferenceBridge.addLocalStorageInfoMapEntry(fakeImportantLocalStorageInfo);
websitePreferenceBridge.addSharedDictionaryInfo(fakeSharedDictionaryInfo);
fetcher.fetchPreferencesForCategory(
SiteSettingsCategory.createFromType(
UNUSED_BROWSER_CONTEXT_HANDLE, SiteSettingsCategory.Type.USE_STORAGE),
(sites) -> {
assertEquals(1, sites.size());
Website site = sites.iterator().next();
List<StorageInfo> storageInfos = site.getStorageInfo();
assertEquals(1, storageInfos.size());
StorageInfo storageInfo = storageInfos.get(0);
assertEquals(fakeStorageInfo.getSize(), storageInfo.getSize());
assertEquals(fakeStorageInfo.getHost(), storageInfo.getHost());
LocalStorageInfo localStorageInfo = site.getLocalStorageInfo();
Assert.assertFalse(localStorageInfo.isDomainImportant());
assertEquals(fakeLocalStorageInfo.getSize(), localStorageInfo.getSize());
assertEquals(fakeLocalStorageInfo.getOrigin(), localStorageInfo.getOrigin());
List<SharedDictionaryInfo> sharedDictionaryInfos =
site.getSharedDictionaryInfo();
assertEquals(1, sharedDictionaryInfos.size());
SharedDictionaryInfo sharedDictionaryInfo = sharedDictionaryInfos.get(0);
assertEquals(
fakeSharedDictionaryInfo.getOrigin(), sharedDictionaryInfo.getOrigin());
assertEquals(
fakeSharedDictionaryInfo.getSize(), sharedDictionaryInfo.getSize());
});
// Test that the fetcher gets local storage info for important domains.
fetcher = new WebsitePermissionsFetcher(mSiteSettingsDelegate, true);
fetcher.setWebsitePreferenceBridgeForTesting(websitePreferenceBridge);
fetcher.fetchPreferencesForCategory(
SiteSettingsCategory.createFromType(
UNUSED_BROWSER_CONTEXT_HANDLE, SiteSettingsCategory.Type.USE_STORAGE),
(sites) -> {
assertEquals(2, sites.size());
for (Website site : sites) {
if (site.getAddress().matches(ORIGIN)) {
List<StorageInfo> storageInfos = site.getStorageInfo();
assertEquals(1, storageInfos.size());
StorageInfo storageInfo = storageInfos.get(0);
assertEquals(fakeStorageInfo.getSize(), storageInfo.getSize());
assertEquals(fakeStorageInfo.getHost(), storageInfo.getHost());
Assert.assertNull(site.getLocalStorageInfo());
List<SharedDictionaryInfo> sharedDictionaryInfos =
site.getSharedDictionaryInfo();
assertEquals(1, sharedDictionaryInfos.size());
SharedDictionaryInfo sharedDictionaryInfo =
sharedDictionaryInfos.get(0);
assertEquals(
fakeSharedDictionaryInfo.getOrigin(),
sharedDictionaryInfo.getOrigin());
assertEquals(
fakeSharedDictionaryInfo.getSize(),
sharedDictionaryInfo.getSize());
} else if (site.getAddress().matches(chromiumOrigin)) {
List<StorageInfo> storageInfos = site.getStorageInfo();
assertEquals(0, storageInfos.size());
LocalStorageInfo localStorageInfo = site.getLocalStorageInfo();
Assert.assertTrue(localStorageInfo.isDomainImportant());
assertEquals(
fakeImportantLocalStorageInfo.getSize(),
localStorageInfo.getSize());
assertEquals(
fakeImportantLocalStorageInfo.getOrigin(),
localStorageInfo.getOrigin());
List<SharedDictionaryInfo> sharedDictionaryInfos =
site.getSharedDictionaryInfo();
assertEquals(0, sharedDictionaryInfos.size());
} else {
Assert.fail(
"The WebsitePermissionsFetcher should only return "
+ "Website objects for the granted origins.");
}
}
});
}
@Test
@SmallTest
public void testFetchPreferencesForCategoryChooserDataTypes() {
ArrayList<Integer> chooserDataTypes =
new ArrayList<>(
Arrays.asList(
SiteSettingsCategory.Type.USB,
SiteSettingsCategory.Type.BLUETOOTH));
for (@SiteSettingsCategory.Type int type : chooserDataTypes) {
WebsitePermissionsFetcher fetcher =
new WebsitePermissionsFetcher(mSiteSettingsDelegate);
FakeWebsitePreferenceBridge websitePreferenceBridge = new FakeWebsitePreferenceBridge();
fetcher.setWebsitePreferenceBridgeForTesting(websitePreferenceBridge);
@ContentSettingsType.EnumType
int chooserDataType =
SiteSettingsCategory.objectChooserDataTypeFromGuard(
SiteSettingsCategory.contentSettingsType(type));
Assert.assertNotEquals(-1, chooserDataType);
ChosenObjectInfo fakeObjectInfo =
new ChosenObjectInfo(
chooserDataType,
ORIGIN,
"Chosen Object",
"SerializedObjectData",
false);
websitePreferenceBridge.addChosenObjectInfo(fakeObjectInfo);
fetcher.fetchPreferencesForCategory(
SiteSettingsCategory.createFromType(UNUSED_BROWSER_CONTEXT_HANDLE, type),
(sites) -> {
assertEquals(1, sites.size());
List<ChosenObjectInfo> objectInfos =
new ArrayList<>(sites.iterator().next().getChosenObjectInfo());
assertEquals(1, objectInfos.size());
assertEquals(fakeObjectInfo, objectInfos.get(0));
});
}
}
@Test
@SmallTest
public void testGetFirstPartySetsOwnersAndMergeInfoIntoWebsites() {
for (var entry : FPS_MEMBER_TO_OWNER_MAP.entrySet()) {
Mockito.doReturn(entry.getValue())
.when(mSiteSettingsDelegate)
.getFirstPartySetOwner(entry.getKey());
}
Mockito.doReturn(true).when(mSiteSettingsDelegate).isFirstPartySetsDataAccessEnabled();
Mockito.doReturn(true)
.when(mSiteSettingsDelegate)
.isPrivacySandboxFirstPartySetsUIFeatureEnabled();
var fetcher =
new WebsitePermissionsFetcher(
mSiteSettingsDelegate, /* fetchSiteImportantInfo= */ false);
FakeWebsitePreferenceBridge websitePreferenceBridge = new FakeWebsitePreferenceBridge();
fetcher.setWebsitePreferenceBridgeForTesting(websitePreferenceBridge);
String googleDEOrigin = "https://google.de";
String googleITOrigin = "https://google.it";
String googleCHOrigin = "https://google.ch";
String youtubeOrigin = "https://youtube.com";
String verizonConnectOrigin = "https://verizonconnect.com";
String aolOrigin = "https://aol.com";
String noInFPSOrigin = "https://unknow.ch";
Website expectedYoutubeWebsite =
new Website(WebsiteAddress.create(youtubeOrigin), WebsiteAddress.create(null));
Website expectedVerizonConnectWebsite =
new Website(
WebsiteAddress.create(verizonConnectOrigin), WebsiteAddress.create(null));
Website expectedNoInFPSWebsite =
new Website(WebsiteAddress.create(noInFPSOrigin), WebsiteAddress.create(null));
// Use a list of origins and create content settings exceptions.
List<String> origins =
Arrays.asList(
googleDEOrigin,
googleITOrigin,
googleCHOrigin,
youtubeOrigin,
verizonConnectOrigin,
aolOrigin,
noInFPSOrigin);
// Adding content exceptions will generate websites data.
for (String origin : origins) {
websitePreferenceBridge.addContentSettingException(
new ContentSettingException(
ContentSettingsType.COOKIES,
origin,
ContentSettingValues.ALLOW,
ProviderType.PREF_PROVIDER,
/* isEmbargoed= */ false));
}
TestThreadUtils.runOnUiThreadBlocking(
() -> {
fetcher.fetchPreferencesForCategoryAndPopulateFpsInfo(
SiteSettingsCategory.createFromType(
UNUSED_BROWSER_CONTEXT_HANDLE,
SiteSettingsCategory.Type.ALL_SITES),
(sites) -> {
// Verify the number of sites is the same of the origins with
// exceptions.
assertEquals(origins.size(), sites.size());
ArrayList<Website> siteArray = new ArrayList<>(sites);
for (Website site : siteArray) {
// Verify youtube.com has google.com as FPS owner which has 4
// members within the group of sites with data.
if (site.compareByAddressTo(expectedYoutubeWebsite) == 0) {
Assert.assertNotNull(site.getFPSCookieInfo());
assertEquals(
"google.com", site.getFPSCookieInfo().getOwner());
assertEquals(4, site.getFPSCookieInfo().getMembersCount());
}
// Verify verizonconnect.com has verizon.com as FPS owner which
// has 2 members within the group of sites with data.
if (site.compareByAddressTo(expectedVerizonConnectWebsite)
== 0) {
Assert.assertNotNull(site.getFPSCookieInfo());
assertEquals(
"verizon.com", site.getFPSCookieInfo().getOwner());
assertEquals(2, site.getFPSCookieInfo().getMembersCount());
}
// Verify a website with data which is not in a FPS has no FPS
// data set.
if (site.compareByAddressTo(expectedNoInFPSWebsite) == 0) {
assertEquals(null, site.getFPSCookieInfo());
}
}
});
});
}
@Test
@SmallTest
public void testIncognitoFetching() throws TimeoutException {
WebsitePermissionsFetcher fetcher = new WebsitePermissionsFetcher(mSiteSettingsDelegate);
FakeWebsitePreferenceBridge websitePreferenceBridge = new FakeWebsitePreferenceBridge();
fetcher.setWebsitePreferenceBridgeForTesting(websitePreferenceBridge);
String origin = "https://example.com";
final WebsitePermissionsWaiter waiter = new WebsitePermissionsWaiter();
// Add a ALLOW exception and a ASK exception for the same pattern to simulate a permission
// from regular mode that was inherited as ASK and a permission from incognito mode.
websitePreferenceBridge.addContentSettingException(
new ContentSettingException(
ContentSettingsType.STORAGE_ACCESS,
origin,
origin,
ContentSettingValues.ALLOW,
ProviderType.NONE,
null,
false));
websitePreferenceBridge.addContentSettingException(
new ContentSettingException(
ContentSettingsType.STORAGE_ACCESS,
origin,
origin,
ContentSettingValues.ASK,
ProviderType.NONE,
null,
false));
fetcher.fetchAllPreferences(waiter);
waiter.waitForFirst();
// Check that only the ALLOW exception is fetched.
assertEquals(1, waiter.getSites().size());
var site = waiter.getSites().iterator().next();
var permission = site.getEmbeddedPermissions().get(ContentSettingsType.STORAGE_ACCESS);
assertEquals(1, permission.size());
assertEquals(ContentSettingValues.ALLOW, (int) permission.get(0).getContentSetting());
}
@Test
@SmallTest
public void testFetchAllSites() {
WebsitePermissionsFetcher fetcher = new WebsitePermissionsFetcher(mSiteSettingsDelegate);
FakeWebsitePreferenceBridge websitePreferenceBridge = new FakeWebsitePreferenceBridge();
fetcher.setWebsitePreferenceBridgeForTesting(websitePreferenceBridge);
websitePreferenceBridge.addPermissionInfo(
new PermissionInfo(
ContentSettingsType.GEOLOCATION,
ORIGIN,
SITE_WILDCARD,
/* isEmbargoed= */ false,
SessionModel.DURABLE));
websitePreferenceBridge.addPermissionInfo(
new PermissionInfo(
ContentSettingsType.GEOLOCATION,
EMBEDDER,
SITE_WILDCARD,
/* isEmbargoed= */ false,
SessionModel.DURABLE));
websitePreferenceBridge.addContentSettingException(
new ContentSettingException(
ContentSettingsType.STORAGE_ACCESS,
ORIGIN,
EMBEDDER,
ContentSettingValues.DEFAULT,
ProviderType.PREF_PROVIDER,
EXPIRATION_IN_DAYS,
/* isEmbargoed= */ false));
websitePreferenceBridge.addContentSettingException(
new ContentSettingException(
ContentSettingsType.STORAGE_ACCESS,
ORIGIN,
null,
ContentSettingValues.DEFAULT,
ProviderType.PREF_PROVIDER,
EXPIRATION_IN_DAYS,
/* isEmbargoed= */ true));
Website expectedWebsite =
new Website(WebsiteAddress.create(ORIGIN), WebsiteAddress.create(null));
Website expectedEmbedderWebsite =
new Website(WebsiteAddress.create(EMBEDDER), WebsiteAddress.create(null));
fetcher.fetchPreferencesForCategory(
SiteSettingsCategory.createFromType(
UNUSED_BROWSER_CONTEXT_HANDLE, SiteSettingsCategory.Type.ALL_SITES),
(sites) -> {
Assert.assertEquals(2, sites.size());
// The order of |sites| is unknown, so check if the array contains a geolocation
// permission for each of the sites.
ArrayList<Website> siteArray = new ArrayList<>(sites);
boolean containsOriginPermission = false;
boolean containsEmbedderOriginPermission = false;
for (Website site : siteArray) {
if (site.compareByAddressTo(expectedWebsite) == 0) {
containsOriginPermission = true;
// Check that embargoed Storage Access is grouped by the origin.
Assert.assertEquals(
Integer.valueOf(ContentSettingValues.DEFAULT),
site.getContentSetting(
UNUSED_BROWSER_CONTEXT_HANDLE,
ContentSettingsType.STORAGE_ACCESS));
Assert.assertTrue(
site.getEmbeddedPermissions()
.get(ContentSettingsType.STORAGE_ACCESS)
.get(0)
.isEmbargoed());
} else if (site.compareByAddressTo(expectedEmbedderWebsite) == 0) {
containsEmbedderOriginPermission = true;
// Check that a normal Storage Access is grouped by the embedder.
Assert.assertEquals(
Integer.valueOf(ContentSettingValues.DEFAULT),
site.getContentSetting(
UNUSED_BROWSER_CONTEXT_HANDLE,
ContentSettingsType.STORAGE_ACCESS));
Assert.assertFalse(
site.getEmbeddedPermissions()
.get(ContentSettingsType.STORAGE_ACCESS)
.get(0)
.isEmbargoed());
}
Assert.assertNotNull(
site.getPermissionInfo(ContentSettingsType.GEOLOCATION));
}
Assert.assertTrue(containsOriginPermission);
Assert.assertTrue(containsEmbedderOriginPermission);
});
}
@Test
@SmallTest
@UseMethodParameter(EmbargoedParams.class)
public void testFetchPreferencesForCategoryEmbeddedPermissionTypes(boolean isEmbargoed) {
WebsitePermissionsFetcher fetcher = new WebsitePermissionsFetcher(mSiteSettingsDelegate);
FakeWebsitePreferenceBridge websitePreferenceBridge = new FakeWebsitePreferenceBridge();
fetcher.setWebsitePreferenceBridgeForTesting(websitePreferenceBridge);
String embedder = isEmbargoed ? null : EMBEDDER;
for (@ContentSettingsType.EnumType int type : EMBEDDED_CONTENT_SETTINGS) {
ContentSettingException fakeContentSetting =
new ContentSettingException(
type,
ORIGIN,
embedder,
ContentSettingValues.DEFAULT,
ProviderType.PREF_PROVIDER,
EXPIRATION_IN_DAYS,
isEmbargoed);
websitePreferenceBridge.addContentSettingException(fakeContentSetting);
fetcher.fetchPreferencesForCategory(
SiteSettingsCategory.createFromContentSettingsType(
UNUSED_BROWSER_CONTEXT_HANDLE, type),
(sites) -> {
Assert.assertEquals(1, sites.size());
Website site = sites.iterator().next();
List<ContentSettingException> exceptions =
site.getEmbeddedPermissions().get(type);
Assert.assertEquals(1, exceptions.size());
assertContentSettingExceptionEquals(fakeContentSetting, exceptions.get(0));
});
}
}
}