Commit 666fbc65 authored by fgorski's avatar fgorski Committed by Commit bot

[Offline pages] Reinstating the offline icon on tablet and fixing verbose state/URL emphasis

This patch addresses the following problems:
* Offline icon is not shown in omnibox on tablets
* Offline verbose status is sometimes shown with green padlock
* URL emphasis lags behind security icon update.

This fix does the following:
* Moves the offline icon from the navigation button to security button
* Ensures that navigation button is never shown on phones
* Calculates when to show: navigation/security/no button, to properly
  show or hide icon container.
* Moves verbose status visibility control to security button related
  code (as that is where we show offline stuff and would show verbose
  security states)

BUG=656088,648129
R=tedchoc@chromium.org

Review-Url: https://codereview.chromium.org/2438413002
Cr-Commit-Position: refs/heads/master@{#427209}
parent 9154331c
...@@ -31,6 +31,7 @@ import android.os.Parcelable; ...@@ -31,6 +31,7 @@ import android.os.Parcelable;
import android.os.SystemClock; import android.os.SystemClock;
import android.provider.Settings; import android.provider.Settings;
import android.speech.RecognizerIntent; import android.speech.RecognizerIntent;
import android.support.annotation.IntDef;
import android.text.InputType; import android.text.InputType;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.AttributeSet; import android.util.AttributeSet;
...@@ -99,6 +100,8 @@ import org.chromium.ui.base.PageTransition; ...@@ -99,6 +100,8 @@ import org.chromium.ui.base.PageTransition;
import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.base.WindowAndroid;
import org.chromium.ui.interpolators.BakedBezierInterpolator; import org.chromium.ui.interpolators.BakedBezierInterpolator;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
...@@ -163,7 +166,7 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener, ...@@ -163,7 +166,7 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener,
private NavigationButtonType mNavigationButtonType; private NavigationButtonType mNavigationButtonType;
// The type of the security icon currently active. // The type of the security icon currently active.
private int mSecurityIconType; private int mSecurityIconResource;
private final OmniboxResultsAdapter mSuggestionListAdapter; private final OmniboxResultsAdapter mSuggestionListAdapter;
private OmniboxSuggestionsList mSuggestionList; private OmniboxSuggestionsList mSuggestionList;
...@@ -206,7 +209,7 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener, ...@@ -206,7 +209,7 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener,
// modifying the omnibox with new input. // modifying the omnibox with new input.
private long mNewOmniboxEditSessionTimestamp = -1; private long mNewOmniboxEditSessionTimestamp = -1;
private boolean mSecurityButtonShown; @LocationBarButtonType private int mLocationBarButtonType;
private AnimatorSet mLocationBarIconActiveAnimator; private AnimatorSet mLocationBarIconActiveAnimator;
private AnimatorSet mSecurityButtonShowAnimator; private AnimatorSet mSecurityButtonShowAnimator;
...@@ -399,9 +402,19 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener, ...@@ -399,9 +402,19 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener,
PAGE, PAGE,
MAGNIFIER, MAGNIFIER,
EMPTY, EMPTY,
OFFLINE,
} }
/** Specifies which button should be shown in location bar, if any. */
@Retention(RetentionPolicy.SOURCE)
@IntDef({BUTTON_TYPE_NONE, BUTTON_TYPE_SECURITY_ICON, BUTTON_TYPE_NAVIGATION_ICON})
public @interface LocationBarButtonType {}
/** No button should be shown. */
public static final int BUTTON_TYPE_NONE = 0;
/** Security button should be shown (includes offline icon). */
public static final int BUTTON_TYPE_SECURITY_ICON = 1;
/** Navigation button should be shown. */
public static final int BUTTON_TYPE_NAVIGATION_ICON = 2;
/** /**
* @param outRect Populated with a {@link Rect} that represents the {@link Tab} specific content * @param outRect Populated with a {@link Rect} that represents the {@link Tab} specific content
* of this {@link LocationBar}. * of this {@link LocationBar}.
...@@ -625,11 +638,12 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener, ...@@ -625,11 +638,12 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener,
LayoutInflater.from(context).inflate(R.layout.location_bar, this, true); LayoutInflater.from(context).inflate(R.layout.location_bar, this, true);
mNavigationButton = (ImageView) findViewById(R.id.navigation_button); mNavigationButton = (ImageView) findViewById(R.id.navigation_button);
assert mNavigationButton != null : "Missing navigation type view."; assert mNavigationButton != null : "Missing navigation type view.";
mNavigationButtonType = DeviceFormFactor.isTablet(context) mNavigationButtonType = DeviceFormFactor.isTablet(context)
? NavigationButtonType.PAGE : NavigationButtonType.EMPTY; ? NavigationButtonType.PAGE : NavigationButtonType.EMPTY;
mSecurityButton = (TintedImageButton) findViewById(R.id.security_button); mSecurityButton = (TintedImageButton) findViewById(R.id.security_button);
mSecurityIconType = ConnectionSecurityLevel.NONE; mSecurityIconResource = 0;
mVerboseStatusTextView = (TextView) findViewById(R.id.location_bar_verbose_status); mVerboseStatusTextView = (TextView) findViewById(R.id.location_bar_verbose_status);
...@@ -661,8 +675,12 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener, ...@@ -661,8 +675,12 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener,
super.onFinishInflate(); super.onFinishInflate();
mUrlBar.setCursorVisible(false); mUrlBar.setCursorVisible(false);
mNavigationButton.setVisibility(VISIBLE);
mSecurityButton.setVisibility(INVISIBLE); mLocationBarButtonType = getLocationBarButtonToShow();
mNavigationButton.setVisibility(
mLocationBarButtonType == BUTTON_TYPE_NAVIGATION_ICON ? VISIBLE : INVISIBLE);
mSecurityButton.setVisibility(
mLocationBarButtonType == BUTTON_TYPE_SECURITY_ICON ? VISIBLE : INVISIBLE);
setLayoutTransition(null); setLayoutTransition(null);
...@@ -865,19 +883,45 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener, ...@@ -865,19 +883,45 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener,
mOmniboxPrerender.initializeForProfile(profile); mOmniboxPrerender.initializeForProfile(profile);
} }
private void changeLocationBarIcon(boolean showSecurityButton) { @LocationBarButtonType private int getLocationBarButtonToShow() {
boolean isOffline = getCurrentTab() != null && getCurrentTab().isOfflinePage();
boolean isTablet = DeviceFormFactor.isTablet(getContext());
if (mUrlHasFocus) {
return isTablet ? BUTTON_TYPE_NAVIGATION_ICON : BUTTON_TYPE_NONE;
}
return getSecurityIconResource(getSecurityLevel(), !isTablet, isOffline) != 0
? BUTTON_TYPE_SECURITY_ICON
: BUTTON_TYPE_NONE;
}
private void changeLocationBarIcon() {
if (mLocationBarIconActiveAnimator != null && mLocationBarIconActiveAnimator.isRunning()) { if (mLocationBarIconActiveAnimator != null && mLocationBarIconActiveAnimator.isRunning()) {
mLocationBarIconActiveAnimator.cancel(); mLocationBarIconActiveAnimator.cancel();
} }
View viewToBeShown = showSecurityButton ? mSecurityButton : mNavigationButton;
mLocationBarButtonType = getLocationBarButtonToShow();
View viewToBeShown = null;
switch (mLocationBarButtonType) {
case BUTTON_TYPE_SECURITY_ICON:
viewToBeShown = mSecurityButton;
mLocationBarIconActiveAnimator = mSecurityButtonShowAnimator;
break;
case BUTTON_TYPE_NAVIGATION_ICON:
viewToBeShown = mNavigationButton;
mLocationBarIconActiveAnimator = mNavigationIconShowAnimator;
break;
case BUTTON_TYPE_NONE:
default:
mLocationBarIconActiveAnimator = null;
return;
}
if (viewToBeShown.getVisibility() == VISIBLE && viewToBeShown.getAlpha() == 1) { if (viewToBeShown.getVisibility() == VISIBLE && viewToBeShown.getAlpha() == 1) {
return; return;
} }
if (showSecurityButton) {
mLocationBarIconActiveAnimator = mSecurityButtonShowAnimator;
} else {
mLocationBarIconActiveAnimator = mNavigationIconShowAnimator;
}
if (shouldAnimateIconChanges()) { if (shouldAnimateIconChanges()) {
mLocationBarIconActiveAnimator.setDuration(URL_FOCUS_CHANGE_ANIMATION_DURATION_MS); mLocationBarIconActiveAnimator.setDuration(URL_FOCUS_CHANGE_ANIMATION_DURATION_MS);
} else { } else {
...@@ -975,8 +1019,7 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener, ...@@ -975,8 +1019,7 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener,
if (mUrlHasFocus) mUrlBar.selectAll(); if (mUrlHasFocus) mUrlBar.selectAll();
} }
changeLocationBarIcon( changeLocationBarIcon();
(!DeviceFormFactor.isTablet(getContext()) || !hasFocus) && isSecurityButtonShown());
mUrlBar.setCursorVisible(hasFocus); mUrlBar.setCursorVisible(hasFocus);
if (!mUrlFocusedWithoutAnimations) handleUrlFocusAnimation(hasFocus); if (!mUrlFocusedWithoutAnimations) handleUrlFocusAnimation(hasFocus);
...@@ -1206,8 +1249,6 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener, ...@@ -1206,8 +1249,6 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener,
// If there are suggestions showing, show the icon for the default suggestion. // If there are suggestions showing, show the icon for the default suggestion.
type = suggestionTypeToNavigationButtonType( type = suggestionTypeToNavigationButtonType(
mSuggestionItems.get(0).getSuggestion()); mSuggestionItems.get(0).getSuggestion());
} else if (!mUrlHasFocus && getCurrentTab() != null && getCurrentTab().isOfflinePage()) {
type = NavigationButtonType.OFFLINE;
} else if (isTablet) { } else if (isTablet) {
type = NavigationButtonType.PAGE; type = NavigationButtonType.PAGE;
} }
...@@ -1227,7 +1268,12 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener, ...@@ -1227,7 +1268,12 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener,
* (like a tablet). * (like a tablet).
* @return The resource ID of the icon that should be displayed, 0 if no icon should show. * @return The resource ID of the icon that should be displayed, 0 if no icon should show.
*/ */
public static int getSecurityIconResource(int securityLevel, boolean isSmallDevice) { public static int getSecurityIconResource(
int securityLevel, boolean isSmallDevice, boolean isOfflinePage) {
// Both conditions should be met, because isOfflinePage might take longer to be cleared.
if (securityLevel == ConnectionSecurityLevel.NONE && isOfflinePage) {
return R.drawable.offline_pin;
}
switch (securityLevel) { switch (securityLevel) {
case ConnectionSecurityLevel.NONE: case ConnectionSecurityLevel.NONE:
case ConnectionSecurityLevel.HTTP_SHOW_WARNING: case ConnectionSecurityLevel.HTTP_SHOW_WARNING:
...@@ -1286,7 +1332,8 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener, ...@@ -1286,7 +1332,8 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener,
@Override @Override
public void updateSecurityIcon(int securityLevel) { public void updateSecurityIcon(int securityLevel) {
boolean isSmallDevice = !DeviceFormFactor.isTablet(getContext()); boolean isSmallDevice = !DeviceFormFactor.isTablet(getContext());
int id = getSecurityIconResource(securityLevel, isSmallDevice); boolean isOfflinePage = getCurrentTab() != null && getCurrentTab().isOfflinePage();
int id = getSecurityIconResource(securityLevel, isSmallDevice, isOfflinePage);
if (id == 0) { if (id == 0) {
mSecurityButton.setImageDrawable(null); mSecurityButton.setImageDrawable(null);
} else { } else {
...@@ -1297,14 +1344,17 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener, ...@@ -1297,14 +1344,17 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener,
getToolbarDataProvider().getPrimaryColor()))); getToolbarDataProvider().getPrimaryColor())));
} }
updateVerboseStatusVisibility();
boolean shouldEmphasizeHttpsScheme = shouldEmphasizeHttpsScheme(); boolean shouldEmphasizeHttpsScheme = shouldEmphasizeHttpsScheme();
if (mSecurityIconType == securityLevel if (mSecurityIconResource == id
&& mIsEmphasizingHttpsScheme == shouldEmphasizeHttpsScheme) { && mIsEmphasizingHttpsScheme == shouldEmphasizeHttpsScheme) {
return; return;
} }
mSecurityIconType = securityLevel; mSecurityIconResource = id;
updateSecurityButton(!(securityLevel == ConnectionSecurityLevel.NONE && isSmallDevice)); changeLocationBarIcon();
updateLocationBarIconContainerVisibility();
// Since we emphasize the scheme of the URL based on the security type, we need to // Since we emphasize the scheme of the URL based on the security type, we need to
// refresh the emphasis. // refresh the emphasis.
mUrlBar.deEmphasizeUrl(); mUrlBar.deEmphasizeUrl();
...@@ -1323,23 +1373,12 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener, ...@@ -1323,23 +1373,12 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener,
return true; return true;
} }
/**
* Updates the display of the security button.
* @param enabled Whether the security button should be displayed.
*/
private void updateSecurityButton(boolean enabled) {
changeLocationBarIcon(enabled
&& (!DeviceFormFactor.isTablet(getContext()) || !mUrlHasFocus));
mSecurityButtonShown = enabled;
updateLocationBarIconContainerVisibility();
}
/** /**
* @return Whether the security button is currently being displayed. * @return Whether the security button is currently being displayed.
*/ */
@VisibleForTesting @VisibleForTesting
public boolean isSecurityButtonShown() { public boolean isSecurityButtonShown() {
return mSecurityButtonShown; return mLocationBarButtonType == BUTTON_TYPE_SECURITY_ICON;
} }
/** /**
...@@ -1347,6 +1386,7 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener, ...@@ -1347,6 +1386,7 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener,
* @param buttonType The type of navigation button to be shown. * @param buttonType The type of navigation button to be shown.
*/ */
private void setNavigationButtonType(NavigationButtonType buttonType) { private void setNavigationButtonType(NavigationButtonType buttonType) {
if (!DeviceFormFactor.isTablet(getContext())) return;
switch (buttonType) { switch (buttonType) {
case PAGE: case PAGE:
Drawable page = ApiCompatibilityUtils.getDrawable( Drawable page = ApiCompatibilityUtils.getDrawable(
...@@ -1362,15 +1402,6 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener, ...@@ -1362,15 +1402,6 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener,
case EMPTY: case EMPTY:
mNavigationButton.setImageDrawable(null); mNavigationButton.setImageDrawable(null);
break; break;
case OFFLINE:
Drawable bolt = ApiCompatibilityUtils.getDrawable(
getResources(), R.drawable.offline_pin);
bolt.mutate().setColorFilter(
ApiCompatibilityUtils.getColor(getResources(), mUseDarkColors
? R.color.locationbar_status_color
: R.color.locationbar_status_color_light), PorterDuff.Mode.SRC_IN);
mNavigationButton.setImageDrawable(bolt);
break;
default: default:
assert false; assert false;
} }
...@@ -1380,7 +1411,6 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener, ...@@ -1380,7 +1411,6 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener,
} }
mNavigationButtonType = buttonType; mNavigationButtonType = buttonType;
updateVerboseStatusVisibility();
updateLocationBarIconContainerVisibility(); updateLocationBarIconContainerVisibility();
} }
...@@ -1389,8 +1419,11 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener, ...@@ -1389,8 +1419,11 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener,
* omnibox. * omnibox.
*/ */
private void updateVerboseStatusVisibility() { private void updateVerboseStatusVisibility() {
boolean verboseStatusVisible = // Because is offline page is cleared a bit slower, we also ensure that connection security
mNavigationButtonType == NavigationButtonType.OFFLINE && !mUrlHasFocus; // level is NONE.
boolean verboseStatusVisible = !mUrlHasFocus && getCurrentTab() != null
&& getCurrentTab().isOfflinePage()
&& getSecurityLevel() == ConnectionSecurityLevel.NONE;
int verboseStatusVisibility = verboseStatusVisible ? VISIBLE : GONE; int verboseStatusVisibility = verboseStatusVisible ? VISIBLE : GONE;
...@@ -1414,9 +1447,10 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener, ...@@ -1414,9 +1447,10 @@ public class LocationBarLayout extends FrameLayout implements OnClickListener,
* security and navigation icons. * security and navigation icons.
*/ */
protected void updateLocationBarIconContainerVisibility() { protected void updateLocationBarIconContainerVisibility() {
boolean showContainer = @LocationBarButtonType
mSecurityButtonShown || mNavigationButtonType != NavigationButtonType.EMPTY; int buttonToShow = getLocationBarButtonToShow();
findViewById(R.id.location_bar_icon).setVisibility(showContainer ? VISIBLE : GONE); findViewById(R.id.location_bar_icon)
.setVisibility(buttonToShow != BUTTON_TYPE_NONE ? VISIBLE : GONE);
} }
/** /**
......
...@@ -497,29 +497,22 @@ public class CustomTabToolbar extends ToolbarLayout implements LocationBar, ...@@ -497,29 +497,22 @@ public class CustomTabToolbar extends ToolbarLayout implements LocationBar,
mSecurityIconType = securityLevel; mSecurityIconType = securityLevel;
boolean isSmallDevice = !DeviceFormFactor.isTablet(getContext());
boolean isOfflinePage = getCurrentTab() != null && getCurrentTab().isOfflinePage(); boolean isOfflinePage = getCurrentTab() != null && getCurrentTab().isOfflinePage();
boolean showSecurityButton = securityLevel != ConnectionSecurityLevel.NONE || isOfflinePage;
int id = LocationBarLayout.getSecurityIconResource(
if (securityLevel == ConnectionSecurityLevel.NONE) { securityLevel, isSmallDevice, isOfflinePage);
if (isOfflinePage && mShowsOfflinePage != isOfflinePage) { boolean showSecurityButton = true;
TintedDrawable bolt = TintedDrawable.constructTintedDrawable( if (id == 0) {
getResources(), R.drawable.offline_pin); // Hide the button if we don't have an actual icon to display.
bolt.setTint(mUseDarkColors ? mDarkModeTint : mLightModeTint); showSecurityButton = false;
mSecurityButton.setImageDrawable(bolt); mSecurityButton.setImageDrawable(null);
}
} else { } else {
boolean isSmallDevice = !DeviceFormFactor.isTablet(getContext()); // ImageView#setImageResource is no-op if given resource is the current one.
int id = LocationBarLayout.getSecurityIconResource(securityLevel, isSmallDevice); mSecurityButton.setImageResource(id);
if (id == 0) { mSecurityButton.setTint(
// Hide the button if we don't have an actual icon to display. LocationBarLayout.getColorStateList(securityLevel, getToolbarDataProvider(),
showSecurityButton = false; getResources(), false /* omnibox is not opaque */));
} else {
// ImageView#setImageResource is no-op if given resource is the current one.
mSecurityButton.setImageResource(id);
mSecurityButton.setTint(
LocationBarLayout.getColorStateList(securityLevel, getToolbarDataProvider(),
getResources(), false /* omnibox is not opaque */));
}
} }
mShowsOfflinePage = isOfflinePage; mShowsOfflinePage = isOfflinePage;
......
...@@ -18,6 +18,7 @@ import org.chromium.chrome.browser.tab.Tab; ...@@ -18,6 +18,7 @@ import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.toolbar.ToolbarModel.ToolbarModelDelegate; import org.chromium.chrome.browser.toolbar.ToolbarModel.ToolbarModelDelegate;
import org.chromium.components.dom_distiller.core.DomDistillerService; import org.chromium.components.dom_distiller.core.DomDistillerService;
import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils;
import org.chromium.components.security_state.ConnectionSecurityLevel;
import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContents;
/** /**
...@@ -107,7 +108,8 @@ class ToolbarModelImpl extends ToolbarModel implements ToolbarDataProvider, Tool ...@@ -107,7 +108,8 @@ class ToolbarModelImpl extends ToolbarModel implements ToolbarDataProvider, Tool
displayText = displayText =
DomDistillerTabUtils.getFormattedUrlFromOriginalDistillerUrl(originalUrl); DomDistillerTabUtils.getFormattedUrlFromOriginalDistillerUrl(originalUrl);
} }
} else if (mTab.isOfflinePage()) { } else if (mTab.isOfflinePage()
&& mTab.getSecurityLevel() == ConnectionSecurityLevel.NONE) {
String originalUrl = mTab.getOriginalUrl(); String originalUrl = mTab.getOriginalUrl();
displayText = OfflinePageUtils.stripSchemeFromOnlineUrl( displayText = OfflinePageUtils.stripSchemeFromOnlineUrl(
DomDistillerTabUtils.getFormattedUrlFromOriginalDistillerUrl(originalUrl)); DomDistillerTabUtils.getFormattedUrlFromOriginalDistillerUrl(originalUrl));
......
...@@ -150,7 +150,7 @@ public class WebappUrlBar extends FrameLayout implements View.OnLayoutChangeList ...@@ -150,7 +150,7 @@ public class WebappUrlBar extends FrameLayout implements View.OnLayoutChangeList
private void updateSecurityIcon(int securityLevel) { private void updateSecurityIcon(int securityLevel) {
boolean isSmallDevice = !DeviceFormFactor.isTablet(getContext()); boolean isSmallDevice = !DeviceFormFactor.isTablet(getContext());
mCurrentIconResource = mCurrentIconResource =
LocationBarLayout.getSecurityIconResource(securityLevel, isSmallDevice); LocationBarLayout.getSecurityIconResource(securityLevel, isSmallDevice, false);
if (mCurrentIconResource != 0 && mIconResourceWidths.get(mCurrentIconResource, -1) == -1) { if (mCurrentIconResource != 0 && mIconResourceWidths.get(mCurrentIconResource, -1) == -1) {
Drawable icon = ApiCompatibilityUtils.getDrawable(getResources(), mCurrentIconResource); Drawable icon = ApiCompatibilityUtils.getDrawable(getResources(), mCurrentIconResource);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment