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

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/WebsiteSettingsPopup.java

Issue 620983002: Add Permissions to the PageInfo dialog on Android (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@page_info_dialog_shell_only_v2
Patch Set: Rebase and added arrow next to dropdowns on PageInfo screen Created 6 years, 2 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/WebsiteSettingsPopup.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/WebsiteSettingsPopup.java b/chrome/android/java/src/org/chromium/chrome/browser/WebsiteSettingsPopup.java
index c3d3ab9c3433dea915ec353ab7c48ccffd3380eb..f7d462dd21d78f8053939f562fccd06443f413ac 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/WebsiteSettingsPopup.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/WebsiteSettingsPopup.java
@@ -12,13 +12,20 @@ import android.graphics.drawable.ColorDrawable;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
-import android.text.style.StyleSpan;
import android.view.Gravity;
import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
+import android.widget.Spinner;
import android.widget.TextView;
import org.chromium.base.CalledByNative;
@@ -27,11 +34,37 @@ import org.chromium.chrome.ChromeSwitches;
import org.chromium.chrome.R;
import org.chromium.content.browser.WebContentsObserverAndroid;
import org.chromium.content_public.browser.WebContents;
+import org.chromium.ui.base.Clipboard;
+
+import java.util.Arrays;
+import java.util.List;
/**
* Java side of Android implementation of the website settings UI.
+ * TODO(sashab): Rename this, and all its resources, to PageInfo* and page_info_* instead of
+ * WebsiteSettings* and website_settings_*. Do this on the C++ side as well.
*/
-public class WebsiteSettingsPopup {
+public class WebsiteSettingsPopup implements OnClickListener, OnItemSelectedListener {
+ /**
+ * An entry in the settings dropdown for a given permission. There are two options for each
+ * permission: Allow and Block.
+ */
+ private static final class PageInfoPermissionEntry {
+ public final String name;
+ public final int type;
+ public final int value;
+
+ PageInfoPermissionEntry(String name, int type, int value) {
+ this.name = name;
+ this.type = type;
+ this.value = value;
+ }
+
+ public String toString() {
+ return name;
+ }
+ }
+
private final Context mContext;
private final WebContents mWebContents;
@@ -44,13 +77,21 @@ public class WebsiteSettingsPopup {
// UI elements in the dialog.
private final TextView mUrlTitle;
private final TextView mUrlConnectionMessage;
+ private final LinearLayout mPermissionsList;
+ private final Button mCopyUrlButton;
+ private final Button mSiteSettingsButton;
+ private final Button mDoneButton;
// The dialog the container is placed in.
private final Dialog mDialog;
+ // The full URL from the URL bar, which is copied to the user's clipboard when they select 'Copy
+ // URL'.
+ private String mFullUrl;
+
/**
- * Creates the WebsiteSettingsPopup, but does not display it. Also
- * initializes the corresponding C++ object and saves a pointer to it.
+ * Creates the WebsiteSettingsPopup, but does not display it. Also initializes the corresponding
+ * C++ object and saves a pointer to it.
*/
private WebsiteSettingsPopup(Context context, WebContents webContents) {
mContext = context;
@@ -63,7 +104,22 @@ public class WebsiteSettingsPopup {
mUrlTitle = (TextView) mContainer
.findViewById(R.id.website_settings_url);
mUrlConnectionMessage = (TextView) mContainer
- .findViewById(R.id.website_settings_permission_message);
+ .findViewById(R.id.website_settings_connection_message);
+ mPermissionsList = (LinearLayout) mContainer
+ .findViewById(R.id.website_settings_permissions_list);
+
+ mCopyUrlButton = (Button) mContainer.findViewById(R.id.website_settings_copy_url_button);
+ mCopyUrlButton.setOnClickListener(this);
+
+ mSiteSettingsButton = (Button) mContainer
+ .findViewById(R.id.website_settings_site_settings_button);
+ mSiteSettingsButton.setOnClickListener(this);
+ // Hide the Site Settings button until there's a link to take it to.
+ // TODO(sashab,finnur): Make this button visible once Site Settings is working.
+ mSiteSettingsButton.setVisibility(View.GONE);
+
+ mDoneButton = (Button) mContainer.findViewById(R.id.website_settings_done_button);
+ mDoneButton.setOnClickListener(this);
// Create the dialog.
mDialog = new Dialog(mContext);
@@ -81,8 +137,8 @@ public class WebsiteSettingsPopup {
mWebContents) {
@Override
public void navigationEntryCommitted() {
- // If a navigation is committed (e.g. from in-page redirect), the data we're
- // showing is stale so dismiss the dialog.
+ // If a navigation is committed (e.g. from in-page redirect), the data we're showing
+ // is stale so dismiss the dialog.
mDialog.dismiss();
}
};
@@ -97,72 +153,152 @@ public class WebsiteSettingsPopup {
}
/**
- * Sets the URL in the title to: (scheme)://(domain)(path). Also colors
- * different parts of the URL depending on connectionType.
- * connectionType should be a valid PageInfoConnectionType.
+ * Finds the Image resource of the icon to use for the given permission.
+ *
+ * @param permission A valid ContentSettingsType that can be displayed in the PageInfo dialog to
+ * retrieve the image for.
+ * @return The resource ID of the icon to use for that permission.
+ */
+ private int getImageResourceForPermission(int permission) {
+ switch (permission) {
+ case ContentSettingsType.CONTENT_SETTINGS_TYPE_IMAGES:
+ return R.drawable.page_info_image;
+ case ContentSettingsType.CONTENT_SETTINGS_TYPE_JAVASCRIPT:
+ return R.drawable.page_info_javascript;
+ case ContentSettingsType.CONTENT_SETTINGS_TYPE_GEOLOCATION:
+ return R.drawable.page_info_location;
+ case ContentSettingsType.CONTENT_SETTINGS_TYPE_MEDIASTREAM:
+ return R.drawable.page_info_media;
+ case ContentSettingsType.CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
+ return R.drawable.page_info_notification;
+ case ContentSettingsType.CONTENT_SETTINGS_TYPE_POPUPS:
+ return R.drawable.page_info_popups;
+ default:
+ assert false : "Icon requested for invalid permission: " + permission;
+ return -1;
+ }
+ }
+
+ /**
+ * Sets the URL in the title of the dialog.
+ *
+ * @param url The URL to display, and to copy to the clipboard if the user selects 'copy'.
+ * @param connectionType The type of connection (determines the colours used for the URL); must
+ * be a valid PageInfoConnectionType.
+ * @param schemeEndIndex The index of the last character in the scheme (e.g. the index of the
+ * 's' in https://www.google.com/)
+ * @param domainEndIndex The index of the last character of the domain (e.g. the index of 'm' in
+ * https://www.google.com/foo).
*/
@CalledByNative
- private void setURLTitle(String scheme, String domain, String path, int connectionType) {
- boolean makeDomainBold = false;
+ private void setURL(String url, int connectionType, int schemeEndIndex, int domainEndIndex) {
+ mFullUrl = url;
int schemeColorId = R.color.website_settings_popup_url_scheme_broken;
switch (connectionType) {
case PageInfoConnectionType.CONNECTION_UNKNOWN:
schemeColorId = R.color.website_settings_popup_url_scheme_http;
- makeDomainBold = true;
break;
case PageInfoConnectionType.CONNECTION_ENCRYPTED:
schemeColorId = R.color.website_settings_popup_url_scheme_https;
break;
case PageInfoConnectionType.CONNECTION_MIXED_CONTENT:
schemeColorId = R.color.website_settings_popup_url_scheme_mixed;
- makeDomainBold = true;
break;
case PageInfoConnectionType.CONNECTION_UNENCRYPTED:
schemeColorId = R.color.website_settings_popup_url_scheme_http;
- makeDomainBold = true;
break;
case PageInfoConnectionType.CONNECTION_ENCRYPTED_ERROR:
schemeColorId = R.color.website_settings_popup_url_scheme_broken;
- makeDomainBold = true;
break;
case PageInfoConnectionType.CONNECTION_INTERNAL_PAGE:
schemeColorId = R.color.website_settings_popup_url_scheme_http;
break;
default:
- assert false : "Unexpected connection type: " + connectionType;
+ assert false : "Unknown connection type: " + connectionType;
}
- SpannableStringBuilder sb = new SpannableStringBuilder(scheme + "://" + domain + path);
+ SpannableStringBuilder sb = new SpannableStringBuilder(url);
ForegroundColorSpan schemeColorSpan = new ForegroundColorSpan(
mContext.getResources().getColor(schemeColorId));
- sb.setSpan(schemeColorSpan, 0, scheme.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
+ sb.setSpan(schemeColorSpan, 0, schemeEndIndex, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
- int domainStartIndex = scheme.length() + 3;
ForegroundColorSpan domainColorSpan = new ForegroundColorSpan(
mContext.getResources().getColor(R.color.website_settings_popup_url_domain));
- sb.setSpan(domainColorSpan, domainStartIndex, domainStartIndex + domain.length(),
+ sb.setSpan(domainColorSpan, schemeEndIndex + 1, domainEndIndex,
Spannable.SPAN_INCLUSIVE_INCLUSIVE);
- if (makeDomainBold) {
- StyleSpan boldStyleSpan = new StyleSpan(android.graphics.Typeface.BOLD);
- sb.setSpan(boldStyleSpan, domainStartIndex, domainStartIndex + domain.length(),
- Spannable.SPAN_INCLUSIVE_INCLUSIVE);
- }
-
mUrlTitle.setText(sb);
}
/**
- * Sets the connection message displayed at the top of the dialog to
- * connectionMessage (e.g. "Could not securely connect to this site").
+ * Sets the connection message displayed at the top of the dialog (e.g. "Could not securely
+ * connect to this site").
+ *
+ * @param connectionMessage The connection message to display.
*/
@CalledByNative
private void setConnectionMessage(String connectionMessage) {
mUrlConnectionMessage.setText(connectionMessage);
}
- /** Displays the WebsiteSettingsPopup. */
+ /**
+ * Adds a new row for the given permission.
+ *
+ * @param name The title of the permission to display to the user.
+ * @param type The ContentSettingsType of the permission.
+ * @param currentSetting The ContentSetting of the currently selected setting.
+ */
+ @CalledByNative
+ private void addPermissionSection(String name, int type, int currentSetting) {
+ LinearLayout permissionRow = (LinearLayout) LayoutInflater.from(mContext).inflate(
+ R.layout.website_settings_permission_row, null);
+
+ ImageView permission_icon = (ImageView) permissionRow.findViewById(
+ R.id.website_settings_permission_icon);
+ permission_icon.setImageResource(getImageResourceForPermission(type));
+
+ TextView permission_name = (TextView) permissionRow.findViewById(
+ R.id.website_settings_permission_name);
+ permission_name.setText(name);
+
+ Spinner permission_spinner = (Spinner) permissionRow.findViewById(
+ R.id.website_settings_permission_spinner);
+
+ // Save the permission type in a tag inside the spinner.
+ permission_spinner.setTag(R.id.website_settings_popup_permission_type, type);
+
+ // Work out the index of the currently selected setting.
+ int selectedSettingIndex = -1;
+ switch (currentSetting) {
+ case ContentSetting.ALLOW:
+ selectedSettingIndex = 0;
+ break;
+ case ContentSetting.BLOCK:
+ selectedSettingIndex = 1;
+ break;
+ default:
+ assert false : "Invalid current setting specified: " + currentSetting;
+ }
+
+ List<PageInfoPermissionEntry> settingsChoices = Arrays.asList(
+ new PageInfoPermissionEntry(mContext.getResources().getString(
+ R.string.page_info_permission_allow), type, ContentSetting.ALLOW),
+ new PageInfoPermissionEntry(mContext.getResources().getString(
+ R.string.page_info_permission_block), type, ContentSetting.BLOCK));
+ ArrayAdapter<PageInfoPermissionEntry> adapter = new ArrayAdapter<PageInfoPermissionEntry>(
+ mContext, R.drawable.website_settings_permission_spinner_item, settingsChoices);
+ adapter.setDropDownViewResource(
+ R.drawable.website_settings_permission_spinner_dropdown_item);
+ permission_spinner.setAdapter(adapter);
+ permission_spinner.setSelection(selectedSettingIndex, false);
+ permission_spinner.setOnItemSelectedListener(this);
+ mPermissionsList.addView(permissionRow);
+ }
+
+ /**
+ * Displays the WebsiteSettingsPopup.
+ */
@CalledByNative
private void showDialog() {
// Wrap the dialog in a ScrollView in case the content is too long.
@@ -172,8 +308,8 @@ public class WebsiteSettingsPopup {
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT));
- // Make the dialog fill the width of the screen. This must be called
- // after addContentView, or it won't fully fill to the edge.
+ // Make the dialog fill the width of the screen. This must be called after addContentView,
+ // or it won't fully fill to the edge.
Window window = mDialog.getWindow();
window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
@@ -181,14 +317,51 @@ public class WebsiteSettingsPopup {
mDialog.show();
}
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
+ int settingsType = (Integer) parent.getTag(R.id.website_settings_popup_permission_type);
+
+ int selectedSetting = -1;
+ switch (pos) {
+ case 0:
+ selectedSetting = ContentSetting.ALLOW;
+ break;
+ case 1:
+ selectedSetting = ContentSetting.BLOCK;
+ break;
+ default:
+ assert false : "Invalid permission option selected: " + pos;
+ }
+
Ted C 2014/10/16 00:24:25 In the transition to PageInfoPermissionEntry, we s
sashab 2014/10/16 05:52:02 Nice, thanks :) Done.
+ nativeOnPermissionSettingChanged(mNativeWebsiteSettingsPopup, settingsType,
+ selectedSetting);
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+ // Do nothing intentionally.
+ }
+
+ @Override
+ public void onClick(View view) {
+ if (view == mCopyUrlButton) {
+ new Clipboard(mContext).setText(mFullUrl, mFullUrl);
+ } else if (view == mSiteSettingsButton) {
+ // TODO(sashab,finnur): Make this open the Website Settings dialog.
+ assert false : "No Website Settings here!";
+ mDialog.dismiss();
+ } else if (view == mDoneButton) {
+ mDialog.dismiss();
+ }
+ }
+
/**
- * Shows a WebsiteSettings dialog for the provided WebContents. The popup
- * adds itself to the view hierarchy which owns the reference while it's
- * visible.
+ * Shows a WebsiteSettings dialog for the provided WebContents. The popup adds itself to the
+ * view hierarchy which owns the reference while it's visible.
*
* @param context Context which is used for launching a dialog.
- * @param webContents The WebContents for which to show Website information.
- * This information is retrieved for the visible entry.
+ * @param webContents The WebContents for which to show Website information. This information is
+ * retrieved for the visible entry.
*/
@SuppressWarnings("unused")
public static void show(Context context, WebContents webContents) {
@@ -203,4 +376,7 @@ public class WebsiteSettingsPopup {
WebContents webContents);
private native void nativeDestroy(long nativeWebsiteSettingsPopupAndroid);
+
+ private native void nativeOnPermissionSettingChanged(long nativeWebsiteSettingsPopupAndroid,
+ int type, int setting);
}

Powered by Google App Engine
This is Rietveld 408576698