// 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.browsing_data;
import org.jni_zero.CalledByNative;
import org.jni_zero.NativeMethods;
import org.chromium.base.Callback;
import org.chromium.base.ThreadUtils;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.profiles.ProfileKeyedMap;
import org.chromium.components.browsing_data.content.BrowsingDataModel;
/**
* Communicates between ClearBrowsingData, ImportantSitesUtils (C++) and ClearBrowsingDataFragment
* (Java UI).
*/
public final class BrowsingDataBridge {
private static ProfileKeyedMap<BrowsingDataBridge> sProfileMap;
private final Profile mProfile;
/** Interface for a class that is listening to clear browser data events. */
public interface OnClearBrowsingDataListener {
@CalledByNative("OnClearBrowsingDataListener")
void onBrowsingDataCleared();
}
/** Interface for a class that is fetching important site information. */
public interface ImportantSitesCallback {
/**
* Called when the list of important registerable domains has been fetched from cpp.
* See net/base/registry_controlled_domains/registry_controlled_domain.h for more details on
* registrable domains and the current list of effective eTLDs.
* @param domains Important registerable domains.
* @param exampleOrigins Example origins for each domain. These can be used to retrieve
* favicons.
* @param importantReasons Bitfield of reasons why this domain was selected. Pass this back
* to clearBrowinsgData so we can record metrics.
* @param dialogDisabled If the important dialog has been ignored too many times and should
* not be shown.
*/
@CalledByNative("ImportantSitesCallback")
void onImportantRegisterableDomainsReady(
String[] domains,
String[] exampleOrigins,
int[] importantReasons,
boolean dialogDisabled);
}
/**
* Interface to a class that receives callbacks instructing it to inform the user about other
* forms of browsing history.
*/
public interface OtherFormsOfBrowsingHistoryListener {
/**
* Called by the web history service when it discovers that other forms of browsing history
* exist.
*/
@CalledByNative("OtherFormsOfBrowsingHistoryListener")
void enableDialogAboutOtherFormsOfBrowsingHistory();
}
private BrowsingDataBridge(Profile profile) {
mProfile = profile;
}
/** Return the {@link BrowsingDataBridge} associated with the given {@link Profile}. */
public static BrowsingDataBridge getForProfile(Profile profile) {
ThreadUtils.assertOnUiThread();
if (sProfileMap == null) {
sProfileMap = new ProfileKeyedMap<>(ProfileKeyedMap.NO_REQUIRED_CLEANUP_ACTION);
}
return sProfileMap.getForProfile(profile, BrowsingDataBridge::new);
}
/**
* Clear the specified types of browsing data asynchronously. |listener| is an object to be
* notified when clearing completes. It can be null, but many operations (e.g. navigation) are
* ill-advised while browsing data is being cleared.
*
* @param listener A listener to call back when the clearing is finished.
* @param dataTypes An array of browsing data types to delete, represented as values from the
* shared enum {@link BrowsingDataType}.
* @param timePeriod The time period for which to delete the data.
*/
public void clearBrowsingData(
OnClearBrowsingDataListener listener, int[] dataTypes, @TimePeriod int timePeriod) {
clearBrowsingDataExcludingDomains(
listener,
dataTypes,
timePeriod,
new String[0],
new int[0],
new String[0],
new int[0]);
}
/**
* Same as above, but now we can specify a list of domains to exclude from clearing browsing
* data.
* Do not use this method unless caller knows what they're doing. Not all backends are supported
* yet, and more data than expected could be deleted. See crbug.com/113621.
* @param listener A listener to call back when the clearing is finished.
* @param dataTypes An array of browsing data types to delete, represented as values from
* the shared enum {@link BrowsingDataType}.
* @param timePeriod The time period for which to delete the data.
* @param excludedDomains A list of registerable domains that we don't clear data for.
* @param excludedDomainReasons A list of the reason metadata for the excluded domains.
* @param ignoredDomains A list of ignored domains that the user chose to not exclude. We use
* these to remove important site entries if the user ignores them enough.
* @param ignoredDomainReasons A list of reason metadata for the ignored domains.
*/
public void clearBrowsingDataExcludingDomains(
OnClearBrowsingDataListener listener,
int[] dataTypes,
@TimePeriod int timePeriod,
String[] excludedDomains,
int[] excludedDomainReasons,
String[] ignoredDomains,
int[] ignoredDomainReasons) {
BrowsingDataBridgeJni.get()
.clearBrowsingData(
BrowsingDataBridge.this,
mProfile,
listener,
dataTypes,
timePeriod,
excludedDomains,
excludedDomainReasons,
ignoredDomains,
ignoredDomainReasons);
}
/**
* This method tests clearing of specified types of browsing data for primary Incognito profile.
* @param dataTypes An array of browsing data types to delete, represented as values from
* the shared enum {@link BrowsingDataType}.
* @param timePeriod The time period for which to delete the data.
*/
public void clearBrowsingDataIncognitoForTesting(
OnClearBrowsingDataListener listener, int[] dataTypes, @TimePeriod int timePeriod) {
BrowsingDataBridgeJni.get()
.clearBrowsingData(
BrowsingDataBridge.this,
mProfile.getPrimaryOTRProfile(/* createIfNeeded= */ true),
listener,
dataTypes,
timePeriod,
new String[0],
new int[0],
new String[0],
new int[0]);
}
/**
* This fetches sites (registerable domains) that we consider important. This combines many
* pieces of information, including site engagement and permissions. The callback is called with
* the list of important registerable domains.
*
* <p>See net/base/registry_controlled_domains/registry_controlled_domain.h for more details on
* registrable domains and the current list of effective eTLDs.
*
* @param callback The callback that will be used to set the list of important sites.
*/
public void fetchImportantSites(ImportantSitesCallback callback) {
BrowsingDataBridgeJni.get().fetchImportantSites(mProfile, callback);
}
/**
* @return The maximum number of important sites that will be returned from the call above.
* This is a constant that won't change.
*/
public static int getMaxImportantSites() {
return BrowsingDataBridgeJni.get().getMaxImportantSites();
}
/** This lets us mark an origin as important for testing. */
public void markOriginAsImportantForTesting(String origin) {
BrowsingDataBridgeJni.get().markOriginAsImportantForTesting(mProfile, origin);
}
/**
* Requests that the web history service finds out if we should inform the user about the
* existence of other forms of browsing history. The response will be asynchronous, through
* {@link OtherFormsOfBrowsingHistoryListener}.
*/
public void requestInfoAboutOtherFormsOfBrowsingHistory(
OtherFormsOfBrowsingHistoryListener listener) {
BrowsingDataBridgeJni.get()
.requestInfoAboutOtherFormsOfBrowsingHistory(
BrowsingDataBridge.this, mProfile, listener);
}
/**
* Checks the state of deletion preference for a certain browsing data type.
* @param dataType The requested browsing data type (from the shared enum
* {@link BrowsingDataType}).
* @param clearBrowsingDataTab Indicates if this is a checkbox on the default, basic or advanced
* tab to apply the right preference.
* @return The state of the corresponding deletion preference.
*/
public boolean getBrowsingDataDeletionPreference(int dataType, int clearBrowsingDataTab) {
return BrowsingDataBridgeJni.get()
.getBrowsingDataDeletionPreference(
BrowsingDataBridge.this, mProfile, dataType, clearBrowsingDataTab);
}
/**
* Sets the state of deletion preference for a certain browsing data type.
* @param dataType The requested browsing data type (from the shared enum
* {@link BrowsingDataType}).
* @param clearBrowsingDataTab Indicates if this is a checkbox on the default, basic or advanced
* tab to apply the right preference.
* @param value The state to be set.
*/
public void setBrowsingDataDeletionPreference(
int dataType, int clearBrowsingDataTab, boolean value) {
BrowsingDataBridgeJni.get()
.setBrowsingDataDeletionPreference(
BrowsingDataBridge.this, mProfile, dataType, clearBrowsingDataTab, value);
}
/**
* Gets the time period for which browsing data will be deleted.
* @param clearBrowsingDataTab Indicates if this is a timeperiod on the default, basic or
* advanced tab to apply the right preference.
* @return The currently selected browsing data deletion time period.
*/
public @TimePeriod int getBrowsingDataDeletionTimePeriod(int clearBrowsingDataTab) {
return BrowsingDataBridgeJni.get()
.getBrowsingDataDeletionTimePeriod(
BrowsingDataBridge.this, mProfile, clearBrowsingDataTab);
}
/**
* Sets the time period for which browsing data will be deleted.
* @param clearBrowsingDataTab Indicates if this is a timeperiod on the default, basic or
* advanced tab to apply the right preference.
* @param timePeriod The selected browsing data deletion time period.
*/
public void setBrowsingDataDeletionTimePeriod(
int clearBrowsingDataTab, @TimePeriod int timePeriod) {
BrowsingDataBridgeJni.get()
.setBrowsingDataDeletionTimePeriod(
BrowsingDataBridge.this, mProfile, clearBrowsingDataTab, timePeriod);
}
/**
* @return The index of the tab last visited by the user in the CBD dialog.
* Index 0 is for the basic tab, 1 is the advanced tab.
*/
public int getLastSelectedClearBrowsingDataTab() {
return BrowsingDataBridgeJni.get()
.getLastClearBrowsingDataTab(BrowsingDataBridge.this, mProfile);
}
/**
* Set the index of the tab last visited by the user.
* @param tabIndex The last visited tab index, 0 for basic, 1 for advanced.
*/
public void setLastSelectedClearBrowsingDataTab(int tabIndex) {
BrowsingDataBridgeJni.get()
.setLastClearBrowsingDataTab(BrowsingDataBridge.this, mProfile, tabIndex);
}
/**
* Builds the `BrowsingDataModel` from disk and returns the object async.
*
* @param callback Callback runs with the BrowsingDataModel object when the model is built.
*/
public static void buildBrowsingDataModelFromDisk(
Profile profile, Callback<BrowsingDataModel> callback) {
BrowsingDataBridgeJni.get().buildBrowsingDataModelFromDisk(profile, callback);
}
@CalledByNative
private static void onBrowsingDataModelBuilt(
Callback<BrowsingDataModel> callback, long nativeBrowsingDataModel) {
callback.onResult(new BrowsingDataModel(nativeBrowsingDataModel));
}
@NativeMethods
public interface Natives {
void clearBrowsingData(
BrowsingDataBridge caller,
Profile profile,
OnClearBrowsingDataListener callback,
int[] dataTypes,
int timePeriod,
String[] excludedDomains,
int[] excludedDomainReasons,
String[] ignoredDomains,
int[] ignoredDomainReasons);
void requestInfoAboutOtherFormsOfBrowsingHistory(
BrowsingDataBridge caller,
Profile profile,
OtherFormsOfBrowsingHistoryListener listener);
void fetchImportantSites(Profile profile, ImportantSitesCallback callback);
int getMaxImportantSites();
void markOriginAsImportantForTesting(Profile profile, String origin);
boolean getBrowsingDataDeletionPreference(
BrowsingDataBridge caller, Profile profile, int dataType, int clearBrowsingDataTab);
void setBrowsingDataDeletionPreference(
BrowsingDataBridge caller,
Profile profile,
int dataType,
int clearBrowsingDataTab,
boolean value);
int getBrowsingDataDeletionTimePeriod(
BrowsingDataBridge caller, Profile profile, int clearBrowsingDataTab);
void setBrowsingDataDeletionTimePeriod(
BrowsingDataBridge caller,
Profile profile,
int clearBrowsingDataTab,
int timePeriod);
int getLastClearBrowsingDataTab(BrowsingDataBridge caller, Profile profile);
void setLastClearBrowsingDataTab(BrowsingDataBridge caller, Profile profile, int lastTab);
void buildBrowsingDataModelFromDisk(Profile profile, Callback<BrowsingDataModel> callback);
}
}