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

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

Issue 2765733002: Rename Android Java pageinfo folder to page_info (matching other platforms). (Closed)
Patch Set: Rename Android Java pageinfo folder to page_info (matching other platforms). Created 3 years, 9 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/pageinfo/WebsiteSettingsPopup.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/pageinfo/WebsiteSettingsPopup.java b/chrome/android/java/src/org/chromium/chrome/browser/pageinfo/WebsiteSettingsPopup.java
deleted file mode 100644
index 7685ecdb4b3fdd11d35c6461e3d9d99e0ea69637..0000000000000000000000000000000000000000
--- a/chrome/android/java/src/org/chromium/chrome/browser/pageinfo/WebsiteSettingsPopup.java
+++ /dev/null
@@ -1,980 +0,0 @@
-// Copyright 2013 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.
-
-package org.chromium.chrome.browser.pageinfo;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.app.Activity;
-import android.app.Dialog;
-import android.content.ActivityNotFoundException;
-import android.content.ClipData;
-import android.content.ClipboardManager;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.graphics.Color;
-import android.graphics.drawable.ColorDrawable;
-import android.net.Uri;
-import android.os.Bundle;
-import android.provider.Settings;
-import android.support.annotation.IntDef;
-import android.support.v7.widget.AppCompatTextView;
-import android.text.Layout;
-import android.text.Spannable;
-import android.text.SpannableString;
-import android.text.SpannableStringBuilder;
-import android.text.TextUtils;
-import android.text.style.ForegroundColorSpan;
-import android.text.style.StyleSpan;
-import android.util.AttributeSet;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.View.OnLongClickListener;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.widget.Button;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.ScrollView;
-import android.widget.TextView;
-
-import org.chromium.base.ApiCompatibilityUtils;
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.metrics.RecordHistogram;
-import org.chromium.base.metrics.RecordUserAction;
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.ContentSettingsType;
-import org.chromium.chrome.browser.UrlConstants;
-import org.chromium.chrome.browser.instantapps.InstantAppsHandler;
-import org.chromium.chrome.browser.offlinepages.OfflinePageItem;
-import org.chromium.chrome.browser.offlinepages.OfflinePageUtils;
-import org.chromium.chrome.browser.omnibox.OmniboxUrlEmphasizer;
-import org.chromium.chrome.browser.preferences.PrefServiceBridge;
-import org.chromium.chrome.browser.preferences.Preferences;
-import org.chromium.chrome.browser.preferences.PreferencesLauncher;
-import org.chromium.chrome.browser.preferences.website.ContentSetting;
-import org.chromium.chrome.browser.preferences.website.ContentSettingsResources;
-import org.chromium.chrome.browser.preferences.website.SingleWebsitePreferences;
-import org.chromium.chrome.browser.preferences.website.WebsitePreferenceBridge;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.browser.ssl.SecurityStateModel;
-import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.browser.util.UrlUtilities;
-import org.chromium.components.location.LocationUtils;
-import org.chromium.content_public.browser.WebContents;
-import org.chromium.content_public.browser.WebContentsObserver;
-import org.chromium.ui.base.DeviceFormFactor;
-import org.chromium.ui.base.WindowAndroid;
-import org.chromium.ui.base.WindowAndroid.PermissionCallback;
-import org.chromium.ui.interpolators.BakedBezierInterpolator;
-import org.chromium.ui.widget.Toast;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.text.DateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-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 implements OnClickListener {
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({OPENED_FROM_MENU, OPENED_FROM_TOOLBAR})
- private @interface OpenedFromSource {}
-
- public static final int OPENED_FROM_MENU = 1;
- public static final int OPENED_FROM_TOOLBAR = 2;
-
- /**
- * 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 ContentSetting setting;
-
- PageInfoPermissionEntry(String name, int type, ContentSetting setting) {
- this.name = name;
- this.type = type;
- this.setting = setting;
- }
-
- @Override
- public String toString() {
- return name;
- }
- }
-
- /**
- * A TextView which truncates and displays a URL such that the origin is always visible.
- * The URL can be expanded by clicking on the it.
- */
- public static class ElidedUrlTextView extends AppCompatTextView {
- // The number of lines to display when the URL is truncated. This number
- // should still allow the origin to be displayed. NULL before
- // setUrlAfterLayout() is called.
- private Integer mTruncatedUrlLinesToDisplay;
-
- // The number of lines to display when the URL is expanded. This should be enough to display
- // at most two lines of the fragment if there is one in the URL.
- private Integer mFullLinesToDisplay;
-
- // If true, the text view will show the truncated text. If false, it
- // will show the full, expanded text.
- private boolean mIsShowingTruncatedText = true;
-
- // The profile to use when getting the end index for the origin.
- private Profile mProfile;
-
- // The maximum number of lines currently shown in the view
- private int mCurrentMaxLines = Integer.MAX_VALUE;
-
- /** Constructor for inflating from XML. */
- public ElidedUrlTextView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- public void setMaxLines(int maxlines) {
- super.setMaxLines(maxlines);
- mCurrentMaxLines = maxlines;
- }
-
- /**
- * Find the number of lines of text which must be shown in order to display the character at
- * a given index.
- */
- private int getLineForIndex(int index) {
- Layout layout = getLayout();
- int endLine = 0;
- while (endLine < layout.getLineCount() && layout.getLineEnd(endLine) < index) {
- endLine++;
- }
- // Since endLine is an index, add 1 to get the number of lines.
- return endLine + 1;
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- setMaxLines(Integer.MAX_VALUE);
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- assert mProfile != null : "setProfile() must be called before layout.";
- String urlText = getText().toString();
-
- // Lay out the URL in a StaticLayout that is the same size as our final
- // container.
- int originEndIndex = OmniboxUrlEmphasizer.getOriginEndIndex(urlText, mProfile);
-
- // Find the range of lines containing the origin.
- int originEndLine = getLineForIndex(originEndIndex);
-
- // Display an extra line so we don't accidentally hide the origin with
- // ellipses
- mTruncatedUrlLinesToDisplay = originEndLine + 1;
-
- // Find the line where the fragment starts. Since # is a reserved character, it is safe
- // to just search for the first # to appear in the url.
- int fragmentStartIndex = urlText.indexOf('#');
- if (fragmentStartIndex == -1) fragmentStartIndex = urlText.length();
-
- int fragmentStartLine = getLineForIndex(fragmentStartIndex);
- mFullLinesToDisplay = fragmentStartLine + 1;
-
- // If there is no origin (according to OmniboxUrlEmphasizer), make sure the fragment is
- // still hidden correctly.
- if (mFullLinesToDisplay < mTruncatedUrlLinesToDisplay) {
- mTruncatedUrlLinesToDisplay = mFullLinesToDisplay;
- }
-
- if (updateMaxLines()) super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- }
-
- /**
- * Sets the profile to use when calculating the end index of the origin.
- * Must be called before layout.
- *
- * @param profile The profile to use when coloring the URL.
- */
- public void setProfile(Profile profile) {
- mProfile = profile;
- }
-
- /**
- * Toggles truncating/expanding the URL text. If the URL text is not
- * truncated, has no effect.
- */
- public void toggleTruncation() {
- mIsShowingTruncatedText = !mIsShowingTruncatedText;
- updateMaxLines();
- }
-
- private boolean updateMaxLines() {
- int maxLines = mFullLinesToDisplay;
- if (mIsShowingTruncatedText) maxLines = mTruncatedUrlLinesToDisplay;
- if (maxLines != mCurrentMaxLines) {
- setMaxLines(maxLines);
- return true;
- }
- return false;
- }
- }
-
- // Delay enter to allow the triggering button to animate before we cover it.
- private static final int ENTER_START_DELAY = 100;
- private static final int FADE_DURATION = 200;
- private static final int FADE_IN_BASE_DELAY = 150;
- private static final int FADE_IN_DELAY_OFFSET = 20;
- private static final int CLOSE_CLEANUP_DELAY = 10;
-
- private static final int MAX_TABLET_DIALOG_WIDTH_DP = 400;
-
- private final Context mContext;
- private final WindowAndroid mWindowAndroid;
- private final Tab mTab;
-
- // A pointer to the C++ object for this UI.
- private long mNativeWebsiteSettingsPopup;
-
- // The outer container, filled with the layout from website_settings.xml.
- private final LinearLayout mContainer;
-
- // UI elements in the dialog.
- private final ElidedUrlTextView mUrlTitle;
- private final TextView mConnectionSummary;
- private final TextView mConnectionMessage;
- private final LinearLayout mPermissionsList;
- private final Button mInstantAppButton;
- private final Button mSiteSettingsButton;
- private final Button mOpenOnlineButton;
-
- // The dialog the container is placed in.
- private final Dialog mDialog;
-
- // Animation which is currently running, if there is one.
- private AnimatorSet mCurrentAnimation;
-
- private boolean mDismissWithoutAnimation;
-
- // The full URL from the URL bar, which is copied to the user's clipboard when they select 'Copy
- // URL'.
- private String mFullUrl;
-
- // A parsed version of mFullUrl. Is null if the URL is invalid/cannot be
- // parsed.
- private URI mParsedUrl;
-
- // Whether or not this page is an internal chrome page (e.g. the
- // chrome://settings page).
- private boolean mIsInternalPage;
-
- // The security level of the page (a valid ConnectionSecurityLevel).
- private int mSecurityLevel;
-
- // Permissions available to be displayed in mPermissionsList.
- private List<PageInfoPermissionEntry> mDisplayedPermissions;
-
- // Creation date of an offline copy, if web contents contains an offline page.
- private String mOfflinePageCreationDate;
-
- // The name of the content publisher, if any.
- private String mContentPublisher;
-
- // The intent associated with the instant app for this URL (or null if one does not exist).
- private Intent mInstantAppIntent;
-
- /**
- * Creates the WebsiteSettingsPopup, but does not display it. Also initializes the corresponding
- * C++ object and saves a pointer to it.
- * @param activity Activity which is used for showing a popup.
- * @param tab Tab for which the pop up is shown.
- * @param offlinePageCreationDate Date when the offline page was created.
- * @param publisher The name of the content publisher, if any.
- */
- private WebsiteSettingsPopup(Activity activity, Tab tab, String offlinePageCreationDate,
- String publisher) {
- mContext = activity;
- mTab = tab;
- if (offlinePageCreationDate != null) {
- mOfflinePageCreationDate = offlinePageCreationDate;
- }
- mWindowAndroid = mTab.getWebContents().getTopLevelNativeWindow();
- mContentPublisher = publisher;
-
- // Find the container and all it's important subviews.
- mContainer = (LinearLayout) LayoutInflater.from(mContext).inflate(
- R.layout.website_settings, null);
- mContainer.setVisibility(View.INVISIBLE);
- mContainer.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
- @Override
- public void onLayoutChange(
- View v, int l, int t, int r, int b, int ol, int ot, int or, int ob) {
- // Trigger the entrance animations once the main container has been laid out and has
- // a height.
- mContainer.removeOnLayoutChangeListener(this);
- mContainer.setVisibility(View.VISIBLE);
- createAllAnimations(true).start();
- }
- });
-
- mUrlTitle = (ElidedUrlTextView) mContainer.findViewById(R.id.website_settings_url);
- mUrlTitle.setProfile(mTab.getProfile());
- mUrlTitle.setOnClickListener(this);
- // Long press the url text to copy it to the clipboard.
- mUrlTitle.setOnLongClickListener(new OnLongClickListener() {
- @Override
- public boolean onLongClick(View v) {
- ClipboardManager clipboard = (ClipboardManager) mContext
- .getSystemService(Context.CLIPBOARD_SERVICE);
- ClipData clip = ClipData.newPlainText("url", mFullUrl);
- clipboard.setPrimaryClip(clip);
- Toast.makeText(mContext, R.string.url_copied, Toast.LENGTH_SHORT).show();
- return true;
- }
- });
-
- mConnectionSummary = (TextView) mContainer
- .findViewById(R.id.website_settings_connection_summary);
- mConnectionMessage = (TextView) mContainer
- .findViewById(R.id.website_settings_connection_message);
- mPermissionsList = (LinearLayout) mContainer
- .findViewById(R.id.website_settings_permissions_list);
-
- mInstantAppButton =
- (Button) mContainer.findViewById(R.id.website_settings_instant_app_button);
- mInstantAppButton.setOnClickListener(this);
-
- mSiteSettingsButton =
- (Button) mContainer.findViewById(R.id.website_settings_site_settings_button);
- mSiteSettingsButton.setOnClickListener(this);
-
- mOpenOnlineButton =
- (Button) mContainer.findViewById(R.id.website_settings_open_online_button);
- mOpenOnlineButton.setOnClickListener(this);
-
- mDisplayedPermissions = new ArrayList<PageInfoPermissionEntry>();
-
- // Hide the permissions list for sites with no permissions.
- setVisibilityOfPermissionsList(false);
-
- // Work out the URL and connection message and status visibility.
- mFullUrl = mTab.getWebContents().getVisibleUrl();
- if (isShowingOfflinePage()) {
- mFullUrl = OfflinePageUtils.stripSchemeFromOnlineUrl(mFullUrl);
- }
-
- try {
- mParsedUrl = new URI(mFullUrl);
- mIsInternalPage = UrlUtilities.isInternalScheme(mParsedUrl);
- } catch (URISyntaxException e) {
- mParsedUrl = null;
- mIsInternalPage = false;
- }
- mSecurityLevel = SecurityStateModel.getSecurityLevelForWebContents(mTab.getWebContents());
-
- SpannableStringBuilder urlBuilder = new SpannableStringBuilder(mFullUrl);
- OmniboxUrlEmphasizer.emphasizeUrl(urlBuilder, mContext.getResources(), mTab.getProfile(),
- mSecurityLevel, mIsInternalPage, true, true);
- mUrlTitle.setText(urlBuilder);
-
- if (mParsedUrl == null || mParsedUrl.getScheme() == null
- || !(mParsedUrl.getScheme().equals(UrlConstants.HTTP_SCHEME)
- || mParsedUrl.getScheme().equals(UrlConstants.HTTPS_SCHEME))) {
- mSiteSettingsButton.setVisibility(View.GONE);
- }
-
- if (isShowingOfflinePage()) {
- boolean isConnected = OfflinePageUtils.isConnected();
- RecordHistogram.recordBooleanHistogram(
- "OfflinePages.WebsiteSettings.OpenOnlineButtonVisible", isConnected);
- if (!isConnected) mOpenOnlineButton.setVisibility(View.GONE);
- } else {
- mOpenOnlineButton.setVisibility(View.GONE);
- }
-
- mInstantAppIntent = (mIsInternalPage || isShowingOfflinePage()) ? null
- : InstantAppsHandler.getInstance().getInstantAppIntentForUrl(mFullUrl);
- if (mInstantAppIntent == null) mInstantAppButton.setVisibility(View.GONE);
-
- // Create the dialog.
- mDialog = new Dialog(mContext) {
- private void superDismiss() {
- super.dismiss();
- }
-
- @Override
- public void dismiss() {
- if (DeviceFormFactor.isTablet(mContext) || mDismissWithoutAnimation) {
- // Dismiss the dialog without any custom animations on tablet.
- super.dismiss();
- } else {
- Animator animator = createAllAnimations(false);
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- // onAnimationEnd is called during the final frame of the animation.
- // Delay the cleanup by a tiny amount to give this frame a chance to be
- // displayed before we destroy the dialog.
- mContainer.postDelayed(new Runnable() {
- @Override
- public void run() {
- superDismiss();
- }
- }, CLOSE_CLEANUP_DELAY);
- }
- });
- animator.start();
- }
- }
- };
- mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
- mDialog.setCanceledOnTouchOutside(true);
-
- // On smaller screens, place the dialog at the top of the screen, and remove its border.
- if (!DeviceFormFactor.isTablet(mContext)) {
- Window window = mDialog.getWindow();
- window.setGravity(Gravity.TOP);
- window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
- }
-
- // This needs to come after other member initialization.
- mNativeWebsiteSettingsPopup = nativeInit(this, mTab.getWebContents());
- final WebContentsObserver webContentsObserver =
- new WebContentsObserver(mTab.getWebContents()) {
- @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.
- mDialog.dismiss();
- }
-
- @Override
- public void wasHidden() {
- // The web contents were hidden (potentially by loading another URL via an intent),
- // so dismiss the dialog).
- mDialog.dismiss();
- }
-
- @Override
- public void destroy() {
- super.destroy();
- // Force the dialog to close immediately in case the destroy was from Chrome
- // quitting.
- mDismissWithoutAnimation = true;
- mDialog.dismiss();
- }
- };
- mDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
- @Override
- public void onDismiss(DialogInterface dialog) {
- assert mNativeWebsiteSettingsPopup != 0;
- webContentsObserver.destroy();
- nativeDestroy(mNativeWebsiteSettingsPopup);
- mNativeWebsiteSettingsPopup = 0;
- }
- });
-
- showDialog();
- }
-
- /**
- * Sets the visibility of the permissions list, which contains padding and borders that should
- * not be shown if a site has no permissions.
- *
- * @param isVisible Whether to show or hide the dialog area.
- */
- private void setVisibilityOfPermissionsList(boolean isVisible) {
- int visibility = isVisible ? View.VISIBLE : View.GONE;
- mPermissionsList.setVisibility(visibility);
- }
-
- /**
- * 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) {
- int icon = ContentSettingsResources.getIcon(permission);
- assert icon != 0 : "Icon requested for invalid permission: " + permission;
- return icon;
- }
-
- /**
- * Whether to show a 'Details' link to the connection info popup. The link is only shown for
- * HTTPS connections.
- */
- private boolean isConnectionDetailsLinkVisible() {
- return mContentPublisher == null && !isShowingOfflinePage() && mParsedUrl != null
- && mParsedUrl.getScheme() != null
- && mParsedUrl.getScheme().equals(UrlConstants.HTTPS_SCHEME);
- }
-
- private boolean hasAndroidPermission(int contentSettingType) {
- String[] androidPermissions =
- PrefServiceBridge.getAndroidPermissionsForContentSetting(contentSettingType);
- if (androidPermissions == null) return true;
- for (int i = 0; i < androidPermissions.length; i++) {
- if (!mWindowAndroid.hasPermission(androidPermissions[i])) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * 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 currentSettingValue The ContentSetting value of the currently selected setting.
- */
- @CalledByNative
- private void addPermissionSection(String name, int type, int currentSettingValue) {
- // We have at least one permission, so show the lower permissions area.
- setVisibilityOfPermissionsList(true);
- mDisplayedPermissions.add(new PageInfoPermissionEntry(name, type, ContentSetting
- .fromInt(currentSettingValue)));
- }
-
- /**
- * Update the permissions view based on the contents of mDisplayedPermissions.
- */
- @CalledByNative
- private void updatePermissionDisplay() {
- mPermissionsList.removeAllViews();
- for (PageInfoPermissionEntry permission : mDisplayedPermissions) {
- addReadOnlyPermissionSection(permission);
- }
- }
-
- private void addReadOnlyPermissionSection(PageInfoPermissionEntry permission) {
- View permissionRow = LayoutInflater.from(mContext).inflate(
- R.layout.website_settings_permission_row, null);
-
- ImageView permissionIcon = (ImageView) permissionRow.findViewById(
- R.id.website_settings_permission_icon);
- permissionIcon.setImageResource(getImageResourceForPermission(permission.type));
-
- if (permission.setting == ContentSetting.ALLOW) {
- int warningTextResource = 0;
-
- // If warningTextResource is non-zero, then the view must be tagged with either
- // permission_intent_override or permission_type.
- LocationUtils locationUtils = LocationUtils.getInstance();
- if (permission.type == ContentSettingsType.CONTENT_SETTINGS_TYPE_GEOLOCATION
- && !locationUtils.isSystemLocationSettingEnabled()) {
- warningTextResource = R.string.page_info_android_location_blocked;
- permissionRow.setTag(R.id.permission_intent_override,
- locationUtils.getSystemLocationSettingsIntent());
- } else if (!hasAndroidPermission(permission.type)) {
- warningTextResource = R.string.page_info_android_permission_blocked;
- permissionRow.setTag(R.id.permission_type,
- PrefServiceBridge.getAndroidPermissionsForContentSetting(permission.type));
- }
-
- if (warningTextResource != 0) {
- TextView permissionUnavailable = (TextView) permissionRow.findViewById(
- R.id.website_settings_permission_unavailable_message);
- permissionUnavailable.setVisibility(View.VISIBLE);
- permissionUnavailable.setText(warningTextResource);
-
- permissionIcon.setImageResource(R.drawable.exclamation_triangle);
- permissionIcon.setColorFilter(ApiCompatibilityUtils.getColor(
- mContext.getResources(), R.color.website_settings_popup_text_link));
-
- permissionRow.setOnClickListener(this);
- }
- }
-
- TextView permissionStatus = (TextView) permissionRow.findViewById(
- R.id.website_settings_permission_status);
- SpannableStringBuilder builder = new SpannableStringBuilder();
- SpannableString nameString = new SpannableString(permission.name);
- final StyleSpan boldSpan = new StyleSpan(android.graphics.Typeface.BOLD);
- nameString.setSpan(boldSpan, 0, nameString.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
-
- builder.append(nameString);
- builder.append(" – "); // en-dash.
- String status_text = "";
- switch (permission.setting) {
- case ALLOW:
- status_text = mContext.getString(R.string.page_info_permission_allowed);
- break;
- case BLOCK:
- status_text = mContext.getString(R.string.page_info_permission_blocked);
- break;
- default:
- assert false : "Invalid setting " + permission.setting + " for permission "
- + permission.type;
- }
- if (permission.type == ContentSettingsType.CONTENT_SETTINGS_TYPE_GEOLOCATION
- && WebsitePreferenceBridge.shouldUseDSEGeolocationSetting(mFullUrl, false)) {
- status_text = statusTextForDSEPermission(permission);
- }
- builder.append(status_text);
- permissionStatus.setText(builder);
- mPermissionsList.addView(permissionRow);
- }
-
- /**
- * Update the permission string for the Default Search Engine.
- */
- private String statusTextForDSEPermission(PageInfoPermissionEntry permission) {
- if (permission.setting == ContentSetting.ALLOW) {
- return mContext.getString(R.string.page_info_dse_permission_allowed);
- }
-
- return mContext.getString(R.string.page_info_dse_permission_blocked);
- }
-
- /**
- * Sets the connection security summary and detailed description strings. These strings may be
- * overridden based on the state of the Android UI.
- */
- @CalledByNative
- private void setSecurityDescription(String summary, String details) {
- // Display the appropriate connection message.
- SpannableStringBuilder messageBuilder = new SpannableStringBuilder();
- if (mContentPublisher != null) {
- messageBuilder.append(
- mContext.getString(R.string.page_info_domain_hidden, mContentPublisher));
- } else if (isShowingOfflinePage()) {
- messageBuilder.append(String.format(
- mContext.getString(R.string.page_info_connection_offline),
- mOfflinePageCreationDate));
- } else {
- if (!TextUtils.equals(summary, details)) {
- mConnectionSummary.setVisibility(View.VISIBLE);
- mConnectionSummary.setText(summary);
- }
- messageBuilder.append(details);
- }
-
- if (isConnectionDetailsLinkVisible()) {
- messageBuilder.append(" ");
- SpannableString detailsText = new SpannableString(
- mContext.getString(R.string.page_info_details_link));
- final ForegroundColorSpan blueSpan = new ForegroundColorSpan(
- ApiCompatibilityUtils.getColor(mContext.getResources(),
- R.color.website_settings_popup_text_link));
- detailsText.setSpan(
- blueSpan, 0, detailsText.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
- messageBuilder.append(detailsText);
- }
- mConnectionMessage.setText(messageBuilder);
- if (isConnectionDetailsLinkVisible()) mConnectionMessage.setOnClickListener(this);
- }
-
- /**
- * Displays the WebsiteSettingsPopup.
- */
- private void showDialog() {
- if (!DeviceFormFactor.isTablet(mContext)) {
- // On smaller screens, make the dialog fill the width of the screen.
- ScrollView scrollView = new ScrollView(mContext);
- scrollView.addView(mContainer);
- mDialog.addContentView(scrollView, new LinearLayout.LayoutParams(
- LinearLayout.LayoutParams.MATCH_PARENT,
- LinearLayout.LayoutParams.MATCH_PARENT));
-
- // 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);
- } else {
- // On larger screens, make the dialog centered in the screen and have a maximum width.
- ScrollView scrollView = new ScrollView(mContext) {
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- final int maxDialogWidthInPx = (int) (MAX_TABLET_DIALOG_WIDTH_DP
- * mContext.getResources().getDisplayMetrics().density);
- if (MeasureSpec.getSize(widthMeasureSpec) > maxDialogWidthInPx) {
- widthMeasureSpec = MeasureSpec.makeMeasureSpec(maxDialogWidthInPx,
- MeasureSpec.EXACTLY);
- }
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- }
- };
-
- scrollView.addView(mContainer);
- mDialog.addContentView(scrollView, new LinearLayout.LayoutParams(
- LinearLayout.LayoutParams.WRAP_CONTENT,
- LinearLayout.LayoutParams.MATCH_PARENT));
- }
-
- mDialog.show();
- }
-
- /**
- * Dismiss the popup, and then run a task after the animation has completed (if there is one).
- */
- private void runAfterDismiss(Runnable task) {
- mDialog.dismiss();
- if (DeviceFormFactor.isTablet(mContext)) {
- task.run();
- } else {
- mContainer.postDelayed(task, FADE_DURATION + CLOSE_CLEANUP_DELAY);
- }
- }
-
- @Override
- public void onClick(View view) {
- if (view == mSiteSettingsButton) {
- // Delay while the WebsiteSettingsPopup closes.
- runAfterDismiss(new Runnable() {
- @Override
- public void run() {
- recordAction(WebsiteSettingsAction.WEBSITE_SETTINGS_SITE_SETTINGS_OPENED);
- Bundle fragmentArguments =
- SingleWebsitePreferences.createFragmentArgsForSite(mFullUrl);
- fragmentArguments.putParcelable(SingleWebsitePreferences.EXTRA_WEB_CONTENTS,
- mTab.getWebContents());
- Intent preferencesIntent = PreferencesLauncher.createIntentForSettingsPage(
- mContext, SingleWebsitePreferences.class.getName());
- preferencesIntent.putExtra(
- Preferences.EXTRA_SHOW_FRAGMENT_ARGUMENTS, fragmentArguments);
- mContext.startActivity(preferencesIntent);
- }
- });
- } else if (view == mInstantAppButton) {
- try {
- mContext.startActivity(mInstantAppIntent);
- RecordUserAction.record("Android.InstantApps.LaunchedFromWebsiteSettingsPopup");
- } catch (ActivityNotFoundException e) {
- mInstantAppButton.setEnabled(false);
- }
- } else if (view == mUrlTitle) {
- // Expand/collapse the displayed URL title.
- mUrlTitle.toggleTruncation();
- } else if (view == mConnectionMessage) {
- runAfterDismiss(new Runnable() {
- @Override
- public void run() {
- if (!mTab.getWebContents().isDestroyed()) {
- recordAction(
- WebsiteSettingsAction.WEBSITE_SETTINGS_SECURITY_DETAILS_OPENED);
- ConnectionInfoPopup.show(mContext, mTab.getWebContents());
- }
- }
- });
- } else if (view.getId() == R.id.website_settings_permission_row) {
- final Object intentOverride = view.getTag(R.id.permission_intent_override);
-
- if (intentOverride == null && mWindowAndroid != null) {
- // Try and immediately request missing Android permissions where possible.
- final String[] permissionType = (String[]) view.getTag(R.id.permission_type);
- for (int i = 0; i < permissionType.length; i++) {
- if (!mWindowAndroid.canRequestPermission(permissionType[i])) continue;
-
- // If any permissions can be requested, attempt to request them all.
- mWindowAndroid.requestPermissions(permissionType, new PermissionCallback() {
- @Override
- public void onRequestPermissionsResult(
- String[] permissions, int[] grantResults) {
- boolean allGranted = true;
- for (int i = 0; i < grantResults.length; i++) {
- if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
- allGranted = false;
- break;
- }
- }
- if (allGranted) updatePermissionDisplay();
- }
- });
- return;
- }
- }
-
- runAfterDismiss(new Runnable() {
- @Override
- public void run() {
- Intent settingsIntent;
- if (intentOverride != null) {
- settingsIntent = (Intent) intentOverride;
- } else {
- settingsIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
- settingsIntent.setData(Uri.parse("package:" + mContext.getPackageName()));
- }
- settingsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- mContext.startActivity(settingsIntent);
- }
- });
- } else if (view == mOpenOnlineButton) {
- runAfterDismiss(new Runnable() {
- @Override
- public void run() {
- // Attempt to reload to an online version of the viewed offline web page. This
- // attempt might fail if the user is offline, in which case an offline copy will
- // be reloaded.
- RecordHistogram.recordBooleanHistogram(
- "OfflinePages.WebsiteSettings.ConnectedWhenOpenOnlineButtonClicked",
- OfflinePageUtils.isConnected());
- OfflinePageUtils.reload(mTab);
- }
- });
- }
- }
-
- /**
- * Create a list of all the views which we want to individually fade in.
- */
- private List<View> collectAnimatableViews() {
- List<View> animatableViews = new ArrayList<View>();
- animatableViews.add(mUrlTitle);
- if (mConnectionSummary.getVisibility() == View.VISIBLE) {
- animatableViews.add(mConnectionSummary);
- }
- animatableViews.add(mConnectionMessage);
- animatableViews.add(mInstantAppButton);
- for (int i = 0; i < mPermissionsList.getChildCount(); i++) {
- animatableViews.add(mPermissionsList.getChildAt(i));
- }
- animatableViews.add(mSiteSettingsButton);
-
- return animatableViews;
- }
-
- /**
- * Create an animator to fade an individual dialog element.
- */
- private Animator createInnerFadeAnimator(final View view, int position, boolean isEnter) {
- ObjectAnimator alphaAnim;
-
- if (isEnter) {
- view.setAlpha(0f);
- alphaAnim = ObjectAnimator.ofFloat(view, View.ALPHA, 1f);
- alphaAnim.setStartDelay(FADE_IN_BASE_DELAY + FADE_IN_DELAY_OFFSET * position);
- } else {
- alphaAnim = ObjectAnimator.ofFloat(view, View.ALPHA, 0f);
- }
-
- alphaAnim.setDuration(FADE_DURATION);
- return alphaAnim;
- }
-
- /**
- * Create an animator to slide in the entire dialog from the top of the screen.
- */
- private Animator createDialogSlideAnimator(boolean isEnter) {
- final float animHeight = -1f * mContainer.getHeight();
- ObjectAnimator translateAnim;
- if (isEnter) {
- mContainer.setTranslationY(animHeight);
- translateAnim = ObjectAnimator.ofFloat(mContainer, View.TRANSLATION_Y, 0f);
- translateAnim.setInterpolator(BakedBezierInterpolator.FADE_IN_CURVE);
- } else {
- translateAnim = ObjectAnimator.ofFloat(mContainer, View.TRANSLATION_Y, animHeight);
- translateAnim.setInterpolator(BakedBezierInterpolator.FADE_OUT_CURVE);
- }
- translateAnim.setDuration(FADE_DURATION);
- return translateAnim;
- }
-
- /**
- * Create animations for showing/hiding the popup.
- *
- * Tablets use the default Dialog fade-in instead of sliding in manually.
- */
- private Animator createAllAnimations(boolean isEnter) {
- AnimatorSet animation = new AnimatorSet();
- AnimatorSet.Builder builder = null;
- Animator startAnim;
-
- if (DeviceFormFactor.isTablet(mContext)) {
- // The start time of the entire AnimatorSet is the start time of the first animation
- // added to the Builder. We use a blank AnimatorSet on tablet as an easy way to
- // co-ordinate this start time.
- startAnim = new AnimatorSet();
- } else {
- startAnim = createDialogSlideAnimator(isEnter);
- }
-
- if (isEnter) startAnim.setStartDelay(ENTER_START_DELAY);
- builder = animation.play(startAnim);
-
- List<View> animatableViews = collectAnimatableViews();
- for (int i = 0; i < animatableViews.size(); i++) {
- View view = animatableViews.get(i);
- Animator anim = createInnerFadeAnimator(view, i, isEnter);
- builder.with(anim);
- }
-
- animation.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mCurrentAnimation = null;
- }
- });
- if (mCurrentAnimation != null) mCurrentAnimation.cancel();
- mCurrentAnimation = animation;
- return animation;
- }
-
- private void recordAction(int action) {
- if (mNativeWebsiteSettingsPopup != 0) {
- nativeRecordWebsiteSettingsAction(mNativeWebsiteSettingsPopup, action);
- }
- }
-
- /**
- * Whether website dialog is displayed for an offline page.
- */
- private boolean isShowingOfflinePage() {
- return mOfflinePageCreationDate != null;
- }
-
- /**
- * Shows a WebsiteSettings dialog for the provided Tab. The popup adds itself to the view
- * hierarchy which owns the reference while it's visible.
- *
- * @param activity Activity which is used for launching a dialog.
- * @param tab The tab hosting the web contents for which to show Website information. This
- * information is retrieved for the visible entry.
- * @param contentPublisher The name of the publisher of the content.
- * @param source Determines the source that triggered the popup.
- */
- public static void show(final Activity activity, final Tab tab, final String contentPublisher,
- @OpenedFromSource int source) {
- if (source == OPENED_FROM_MENU) {
- RecordUserAction.record("MobileWebsiteSettingsOpenedFromMenu");
- } else if (source == OPENED_FROM_TOOLBAR) {
- RecordUserAction.record("MobileWebsiteSettingsOpenedFromToolbar");
- } else {
- assert false : "Invalid source passed";
- }
-
- String offlinePageCreationDate = null;
-
- OfflinePageItem offlinePage = tab.getOfflinePage();
- if (offlinePage != null) {
- // Get formatted creation date of the offline page.
- Date creationDate = new Date(offlinePage.getCreationTimeMs());
- DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM);
- offlinePageCreationDate = df.format(creationDate);
- }
-
- new WebsiteSettingsPopup(activity, tab, offlinePageCreationDate, contentPublisher);
- }
-
- private static native long nativeInit(WebsiteSettingsPopup popup, WebContents webContents);
-
- private native void nativeDestroy(long nativeWebsiteSettingsPopupAndroid);
-
- private native void nativeRecordWebsiteSettingsAction(
- long nativeWebsiteSettingsPopupAndroid, int action);
-}

Powered by Google App Engine
This is Rietveld 408576698