Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1380)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleWebsitePreferences.java

Issue 927763003: Move website settings fetching from WebsitePreferences to new WebsitePermissionFetcher. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase on tot. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleWebsitePreferences.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleWebsitePreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleWebsitePreferences.java
index d337bfa5cfa160abd38b16dbc86a7d8ce70e987a..0361e8e01bcb905d36edd7d92f303dce35334e11 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleWebsitePreferences.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleWebsitePreferences.java
@@ -19,6 +19,13 @@
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ContentSettingsType;
+import org.chromium.chrome.browser.UrlUtilities;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
/**
* Shows a list of HTML5 settings for a single website.
@@ -26,7 +33,13 @@
public class SingleWebsitePreferences extends PreferenceFragment
implements DialogInterface.OnClickListener, OnPreferenceChangeListener,
OnPreferenceClickListener {
+ // SingleWebsitePreferences expects either EXTRA_SITE (a Website) or
+ // EXTRA_ADDRESS (a WebsiteAddress) to be present (but not both). If
+ // EXTRA_SITE is present, the fragment will display the permissions in that
+ // Website object. If EXTRA_ADDRESS is present, the fragment will find all
+ // permissions for that website address and display those.
public static final String EXTRA_SITE = "org.chromium.chrome.preferences.site";
+ public static final String EXTRA_ADDRESS = "org.chromium.chrome.preferences.address";
// Preference keys, see single_website_preferences.xml
// Headings:
@@ -51,13 +64,145 @@
// The website this page is displaying details about.
private Website mSite;
+
+ // The address of the site we want to display. Used only if EXTRA_ADDRESS is provided.
+ private WebsiteAddress mSiteAddress;
+
// A list of possible options for each list preference summary.
private String[] mListPreferenceSummaries;
+ private class SingleWebsitePermissionsPopulator
+ implements WebsitePermissionsFetcher.WebsitePermissionsCallback {
+ @Override
+ public void onWebsitePermissionsAvailable(
+ Map<String, Set<Website>> sitesByOrigin, Map<String, Set<Website>> sitesByHost) {
+ // This method may be called after the activity has been destroyed.
+ // In that case, bail out.
+ if (getActivity() == null) return;
+
+ // TODO(mvanouwerkerk): Do this merge at data retrieval time in C++, instead of now.
+ List<Set<Website>> allSites = new ArrayList<>();
+ allSites.addAll(sitesByOrigin.values());
+ allSites.addAll(sitesByHost.values());
+ // TODO(mvanouwerkerk): Avoid modifying the outer class from this inner class.
+ mSite = mergePermissionInfoForTopLevelOrigin(mSiteAddress, allSites);
+ displaySitePermissions();
+ }
+ }
+
+ /**
+ * Creates a Bundle with the correct arguments for opening this fragment for
+ * the website with the given url.
+ *
+ * @param url The URL to open the fragment with. This is a complete url including scheme,
+ * domain, port, path, etc.
+ * @return The bundle to attach to the preferences intent.
+ */
+ public static Bundle createFragmentArgsForSite(String url) {
+ Bundle fragmentArgs = new Bundle();
+ // TODO(mvanouwerkerk): Define a pure getOrigin method in UrlUtilities that is the
+ // equivalent of the call below, because this is perfectly fine for non-display purposes.
+ String origin = UrlUtilities.getOriginForDisplay(URI.create(url), true /* schowScheme */);
+ fragmentArgs.putSerializable(
+ SingleWebsitePreferences.EXTRA_ADDRESS, WebsiteAddress.create(origin));
+ return fragmentArgs;
+ }
+
@Override
public void onActivityCreated(Bundle savedInstanceState) {
getActivity().setTitle(R.string.prefs_content_settings);
- mSite = (Website) getArguments().getSerializable(EXTRA_SITE);
+ Object extraSite = getArguments().getSerializable(EXTRA_SITE);
+ Object extraAddress = getArguments().getSerializable(EXTRA_ADDRESS);
+
+ if (extraSite != null && extraAddress == null) {
+ mSite = (Website) extraSite;
+ displaySitePermissions();
+ } else if (extraAddress != null && extraSite == null) {
+ mSiteAddress = (WebsiteAddress) extraAddress;
+ WebsitePermissionsFetcher fetcher =
+ new WebsitePermissionsFetcher(new SingleWebsitePermissionsPopulator());
+ fetcher.fetchAllPreferences();
+ } else {
+ assert false : "Exactly one of EXTRA_SITE or EXTRA_SITE_ADDRESS must be provided.";
+ }
+
+ super.onActivityCreated(savedInstanceState);
+ }
+
+ /**
+ * Given an address and a list of sets of websites, returns a new site with the same origin
+ * as |address| which has merged into it the permissions of the matching input sites. If a
+ * permission is found more than once, the one found first is used and the latter are ignored.
+ * This should not drop any relevant data as this method already aggressively filters on an
+ * exact match of origin and embedder.
+ *
+ * @param address The address to search for.
+ * @param websiteSets The websites to search in.
+ * @return The merged website.
+ */
+ private static Website mergePermissionInfoForTopLevelOrigin(
+ WebsiteAddress address, List<Set<Website>> websiteSets) {
+ String origin = address.getOrigin();
+ Website merged = new Website(address);
+ // This nested loop looks expensive, but the amount of data is likely to be relatively
+ // small because most sites have very few permissions.
+ for (Set<Website> websiteSet : websiteSets) {
+ for (Website other : websiteSet) {
+ if (merged.getCookieInfo() == null && other.getCookieInfo() != null
+ && permissionInfoIsForTopLevelOrigin(other.getCookieInfo(), origin)) {
+ merged.setCookieInfo(other.getCookieInfo());
+ }
+ if (merged.getGeolocationInfo() == null && other.getGeolocationInfo() != null
+ && permissionInfoIsForTopLevelOrigin(other.getGeolocationInfo(), origin)) {
+ merged.setGeolocationInfo(other.getGeolocationInfo());
+ }
+ if (merged.getMidiInfo() == null && other.getMidiInfo() != null
+ && permissionInfoIsForTopLevelOrigin(other.getMidiInfo(), origin)) {
+ merged.setMidiInfo(other.getMidiInfo());
+ }
+ if (merged.getProtectedMediaIdentifierInfo() == null
+ && other.getProtectedMediaIdentifierInfo() != null
+ && permissionInfoIsForTopLevelOrigin(
+ other.getProtectedMediaIdentifierInfo(), origin)) {
+ merged.setProtectedMediaIdentifierInfo(other.getProtectedMediaIdentifierInfo());
+ }
+ if (merged.getPushNotificationInfo() == null
+ && other.getPushNotificationInfo() != null
+ && permissionInfoIsForTopLevelOrigin(
+ other.getPushNotificationInfo(), origin)) {
+ merged.setPushNotificationInfo(other.getPushNotificationInfo());
+ }
+ if (merged.getVoiceAndVideoCaptureInfo() == null
+ && other.getVoiceAndVideoCaptureInfo() != null) {
+ if (origin.equals(other.getVoiceAndVideoCaptureInfo().getOrigin())
+ && (origin.equals(other.getVoiceAndVideoCaptureInfo().getEmbedderSafe())
+ || "*".equals(other.getVoiceAndVideoCaptureInfo()
+ .getEmbedderSafe()))) {
+ merged.setVoiceAndVideoCaptureInfo(other.getVoiceAndVideoCaptureInfo());
+ }
+ }
+ // TODO(mvanouwerkerk): Can VoiceAndVideoCaptureInfo share a base type with the
+ // others?
+ // TODO(mvanouwerkerk): Merge in PopupExceptionInfo? It is not a PermissionInfo.
+ // TODO(mvanouwerkerk): Merge in LocalStorageInfo? It is not a PermissionInfo.
+ // TODO(mvanouwerkerk): Merge in all instances of StorageInfo? It is not a
+ // PermissionInfo.
+ }
+ }
+ return merged;
+ }
+
+ private static boolean permissionInfoIsForTopLevelOrigin(PermissionInfo info, String origin) {
+ // TODO(mvanouwerkerk): Find a more generic place for this method.
+ return origin.equals(info.getOrigin())
+ && (origin.equals(info.getEmbedderSafe()) || "*".equals(info.getEmbedderSafe()));
+ }
+
+ /**
+ * Updates the permissions displayed in the UI by fetching them from mSite.
+ * Must only be called once mSite is set.
+ */
+ private void displaySitePermissions() {
addPreferencesFromResource(R.xml.single_website_preferences);
mListPreferenceSummaries = getActivity().getResources().getStringArray(
R.array.website_settings_permission_options);
@@ -91,11 +236,7 @@ public void onActivityCreated(Bundle savedInstanceState) {
} else if (PREF_PROTECTED_MEDIA_IDENTIFIER_PERMISSION.equals(preference.getKey())) {
setUpListPreference(preference, mSite.getProtectedMediaIdentifierPermission());
} else if (PREF_PUSH_NOTIFICATIONS_PERMISSION.equals(preference.getKey())) {
- if (ContentPreferences.pushNotificationsSupported()) {
- setUpListPreference(preference, mSite.getPushNotificationPermission());
- } else {
- getPreferenceScreen().removePreference(preference);
- }
+ setUpListPreference(preference, mSite.getPushNotificationPermission());
} else if (PREF_VOICE_AND_VIDEO_CAPTURE_PERMISSION.equals(preference.getKey())) {
configureVoiceAndVideoPreference(preference);
}
@@ -111,8 +252,6 @@ public void onActivityCreated(Bundle savedInstanceState) {
Preference heading = preferenceScreen.findPreference(PREF_PERMISSIONS);
preferenceScreen.removePreference(heading);
}
-
- super.onActivityCreated(savedInstanceState);
}
private boolean hasUsagePreferences() {

Powered by Google App Engine
This is Rietveld 408576698