Commit bc8147b7 authored by Jinsuk Kim's avatar Jinsuk Kim Committed by Commit Bot

Android: Handles the case of gesture navigation closing tab

There are situations where back button closes the current tab.
Gesture navigation also need to do what back button does in this
case. This CL shows close indicator "Close Tab", and does not
open the navigation sheet.

Bug: 1009059
Change-Id: Ife4f53bb41253646d18feb1cf5e2c50a04b1d2ad
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1885135Reviewed-by: default avatarMatthew Jones <mdjones@chromium.org>
Reviewed-by: default avatarJinsuk Kim <jinsukkim@chromium.org>
Commit-Queue: Jinsuk Kim <jinsukkim@chromium.org>
Cr-Commit-Position: refs/heads/master@{#710628}
parent 6a2e670a
......@@ -17,16 +17,33 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.DrawableRes;
import androidx.annotation.IntDef;
import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.util.ColorUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* View class for a bubble used in gesture navigation UI that consists of an icon
* and an optional text.
*/
public class NavigationBubble extends LinearLayout {
/**
* Target to close when gesture navigation takes place on the beginning
* of the navigation history. It can close either the current tab or
* chrome itself (putting it background).
*/
@IntDef({CloseTarget.NONE, CloseTarget.TAB, CloseTarget.APP})
@Retention(RetentionPolicy.SOURCE)
@interface CloseTarget {
int NONE = 0;
int TAB = 1;
int APP = 2;
}
private static final int COLOR_TRANSITION_DURATION_MS = 250;
private static final float FADE_ALPHA = 0.5f;
......@@ -36,6 +53,8 @@ public class NavigationBubble extends LinearLayout {
private final ValueAnimator mColorAnimator;
private final int mBlue;
private final int mBlack;
private final String mCloseApp;
private final String mCloseTab;
private class ColorUpdateListener implements ValueAnimator.AnimatorUpdateListener {
private int mStart;
......@@ -63,6 +82,8 @@ public class NavigationBubble extends LinearLayout {
// True if arrow bubble is faded out.
private boolean mArrowFaded;
private @CloseTarget int mCloseTarget;
/**
* Constructor for inflating from XML.
*/
......@@ -88,6 +109,10 @@ public class NavigationBubble extends LinearLayout {
getBackground().setColorFilter(ApiCompatibilityUtils.getColor(getResources(),
R.color.navigation_bubble_background_color),
Mode.MULTIPLY);
mCloseApp = getResources().getString(R.string.overscroll_navigation_close_chrome,
getContext().getString(R.string.app_name));
mCloseTab = getResources().getString(R.string.overscroll_navigation_close_tab);
mCloseTarget = CloseTarget.NONE;
}
@Override
......@@ -114,19 +139,27 @@ public class NavigationBubble extends LinearLayout {
}
/**
* Shows or hides the close chrome indicator.
* @param on {@code true} if the indicator should appear.
* Shows or hides the close indicator.
* @param target Target to close. if {@code NONE}, hide the indicator.
*/
public void showCaption(boolean on) {
if (on && !isShowingCaption()) {
public void showCaption(@CloseTarget int target) {
if (target != CloseTarget.NONE && !isShowingCaption()) {
setCloseIndicator(target);
getTextView().setVisibility(View.VISIBLE);
// Measure the width again after the indicator text becomes visible.
measure(0, 0);
} else if (!on && isShowingCaption()) {
} else if (target == CloseTarget.NONE && isShowingCaption()) {
getTextView().setVisibility(View.GONE);
}
}
private void setCloseIndicator(@CloseTarget int target) {
assert target == CloseTarget.APP || target == CloseTarget.TAB;
if (mCloseTarget == target) return;
mCloseTarget = target;
getTextView().setText(target == CloseTarget.APP ? mCloseApp : mCloseTab);
}
@Override
public void onAnimationStart() {
super.onAnimationStart();
......
......@@ -15,6 +15,7 @@ import androidx.annotation.IntDef;
import org.chromium.base.Supplier;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.browser.gesturenav.NavigationBubble.CloseTarget;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
......@@ -84,6 +85,11 @@ public class NavigationHandler {
*/
void navigate(boolean forward);
/**
* @return {@code true} if back action will close the current tab.
*/
boolean willBackCloseTab();
/**
* @return {@code true} if back action will cause the app to exit.
*/
......@@ -192,11 +198,12 @@ public class NavigationHandler {
if (mSideSlideLayout == null) createLayout();
mSideSlideLayout.setEnabled(true);
mSideSlideLayout.setDirection(forward);
boolean showCloseIndicator = shouldShowCloseIndicator(forward);
mSideSlideLayout.setEnableCloseIndicator(showCloseIndicator);
@CloseTarget
int closeIndicator = getCloseIndicator(forward);
mSideSlideLayout.setCloseIndicator(closeIndicator);
attachLayoutIfNecessary();
mSideSlideLayout.start();
mNavigationSheet.start(forward, showCloseIndicator);
mNavigationSheet.start(forward, closeIndicator != CloseTarget.NONE);
mState = GestureState.DRAGGED;
}
......@@ -218,6 +225,18 @@ public class NavigationHandler {
return !forward && mActionDelegate.willBackExitApp();
}
private @CloseTarget int getCloseIndicator(boolean forward) {
// Some tabs, upon back at the beginning of the history stack, should be just closed
// than closing the entire app.
if (!forward && mActionDelegate.willBackCloseTab()) {
return CloseTarget.TAB;
} else if (!forward && mActionDelegate.willBackExitApp()) {
return CloseTarget.APP;
} else {
return CloseTarget.NONE;
}
}
/**
* Signals a pull update.
* @param delta The change in horizontal pull distance (positive if toward right,
......
......@@ -18,6 +18,7 @@ import android.view.animation.ScaleAnimation;
import android.view.animation.Transformation;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.gesturenav.NavigationBubble.CloseTarget;
import org.chromium.chrome.browser.ui.widget.animation.Interpolators;
/**
......@@ -95,7 +96,7 @@ public class SideSlideLayout extends ViewGroup {
private int mAnimationViewWidth;
private boolean mIsForward;
private boolean mCloseIndicatorEnabled;
private @CloseTarget int mCloseIndicator;
// True while swiped to a distance where, if released, the navigation would be triggered.
private boolean mWillNavigate;
......@@ -224,8 +225,8 @@ public class SideSlideLayout extends ViewGroup {
forward ? R.drawable.ic_arrow_forward_blue_24dp : R.drawable.ic_arrow_back_24dp);
}
public void setEnableCloseIndicator(boolean enable) {
mCloseIndicatorEnabled = enable;
public void setCloseIndicator(@CloseTarget int target) {
mCloseIndicator = target;
}
@Override
......@@ -303,9 +304,9 @@ public class SideSlideLayout extends ViewGroup {
}
mWillNavigate = navigating;
if (mCloseIndicatorEnabled) {
if (mCloseIndicator != CloseTarget.NONE) {
if (mWillNavigate) {
mArrowView.showCaption(true);
mArrowView.showCaption(mCloseIndicator);
mArrowViewWidth = mArrowView.getMeasuredWidth();
} else {
hideCloseIndicator();
......@@ -343,7 +344,7 @@ public class SideSlideLayout extends ViewGroup {
}
private void hideCloseIndicator() {
mArrowView.showCaption(false);
mArrowView.showCaption(CloseTarget.NONE);
// The width when indicator text view is hidden is slightly bigger than the height.
// Set the width to circle's diameter for the widget to be of completely round shape.
mArrowViewWidth = mCircleWidth;
......
......@@ -39,6 +39,11 @@ public class TabbedActionDelegate implements NavigationHandler.ActionDelegate {
}
}
@Override
public boolean willBackCloseTab() {
return !mTab.canGoBack() && mTab.getActivity().backShouldCloseTab(mTab);
}
@Override
public boolean willBackExitApp() {
return !mTab.canGoBack()
......
......@@ -3350,6 +3350,9 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
<message name="IDS_OVERSCROLL_NAVIGATION_CLOSE_CHROME" desc="Message displayed on overscroll navigation UI widget when the back navigation is attempted at the beginning of navigation history stack. The widget only has an arrow icon but expands to display this message next to it.">
Close <ph name="APP_NAME">%1$s<ex>Chrome</ex></ph>
</message>
<message name="IDS_OVERSCROLL_NAVIGATION_CLOSE_TAB" desc="Message displayed on overscroll navigation UI widget when the back navigation is attempted at the beginning of navigation history stack. The widget only has an arrow icon but expands to display this message next to it.">
Close tab
</message>
<message name="IDS_OVERSCROLL_NAVIGATION_SHEET_DESCRIPTION" desc="The content description of the navigation bottom sheet.">
Navigation history
</message>
......
ecf313d305d56db7c25dcb3fd5882cbd74ee23d6
\ No newline at end of file
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