Create BackEvent interface for back navigation parameters.
Bug: b/210539672, b/195946584 Test: m -j Change-Id: I0264d0995aed8a73563bece0d15d2a9aac0ebf06
This commit is contained in:
@@ -18,6 +18,7 @@ package android.view;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.window.BackEvent;
|
||||
|
||||
/**
|
||||
* Interface for applications to register back invocation callbacks. This allows the client
|
||||
@@ -46,14 +47,12 @@ public interface OnBackInvokedCallback {
|
||||
/**
|
||||
* Called on back gesture progress.
|
||||
*
|
||||
* @param touchX Absolute X location of the touch point.
|
||||
* @param touchY Absolute Y location of the touch point.
|
||||
* @param progress Value between 0 and 1 on how far along the back gesture is.
|
||||
* @param backEvent An {@link android.window.BackEvent} object describing the progress event.
|
||||
*
|
||||
* @see android.window.BackEvent
|
||||
* @hide
|
||||
*/
|
||||
// TODO(b/210539672): combine back progress params into BackEvent.
|
||||
default void onBackProgressed(int touchX, int touchY, float progress) { };
|
||||
default void onBackProgressed(BackEvent backEvent) { };
|
||||
|
||||
/**
|
||||
* Called when a back gesture or back button press has been cancelled.
|
||||
|
||||
22
core/java/android/window/BackEvent.aidl
Normal file
22
core/java/android/window/BackEvent.aidl
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.window;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
parcelable BackEvent;
|
||||
159
core/java/android/window/BackEvent.java
Normal file
159
core/java/android/window/BackEvent.java
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.window;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.view.RemoteAnimationTarget;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Represents an event that is sent out by the system during back navigation gesture.
|
||||
* Holds information about the touch event, swipe direction and overall progress of the gesture
|
||||
* interaction.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class BackEvent implements Parcelable {
|
||||
/** Indicates that the edge swipe starts from the left edge of the screen */
|
||||
public static final int EDGE_LEFT = 0;
|
||||
/** Indicates that the edge swipe starts from the right edge of the screen */
|
||||
public static final int EDGE_RIGHT = 1;
|
||||
|
||||
@IntDef({
|
||||
EDGE_LEFT,
|
||||
EDGE_RIGHT,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface SwipeEdge{}
|
||||
|
||||
private final int mTouchX;
|
||||
private final int mTouchY;
|
||||
private final float mProgress;
|
||||
|
||||
@SwipeEdge
|
||||
private final int mSwipeEdge;
|
||||
@Nullable
|
||||
private final RemoteAnimationTarget mDepartingAnimationTarget;
|
||||
|
||||
/**
|
||||
* Creates a new {@link BackEvent} instance.
|
||||
*
|
||||
* @param touchX Absolute X location of the touch point.
|
||||
* @param touchY Absolute Y location of the touch point.
|
||||
* @param progress Value between 0 and 1 on how far along the back gesture is.
|
||||
* @param swipeEdge Indicates which edge the swipe starts from.
|
||||
* @param departingAnimationTarget The remote animation target of the departing application
|
||||
* window.
|
||||
*/
|
||||
public BackEvent(int touchX, int touchY, float progress, @SwipeEdge int swipeEdge,
|
||||
@Nullable RemoteAnimationTarget departingAnimationTarget) {
|
||||
mTouchX = touchX;
|
||||
mTouchY = touchY;
|
||||
mProgress = progress;
|
||||
mSwipeEdge = swipeEdge;
|
||||
mDepartingAnimationTarget = departingAnimationTarget;
|
||||
}
|
||||
|
||||
private BackEvent(@NonNull Parcel in) {
|
||||
mTouchX = in.readInt();
|
||||
mTouchY = in.readInt();
|
||||
mProgress = in.readFloat();
|
||||
mSwipeEdge = in.readInt();
|
||||
mDepartingAnimationTarget = in.readTypedObject(RemoteAnimationTarget.CREATOR);
|
||||
}
|
||||
|
||||
public static final Creator<BackEvent> CREATOR = new Creator<BackEvent>() {
|
||||
@Override
|
||||
public BackEvent createFromParcel(Parcel in) {
|
||||
return new BackEvent(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BackEvent[] newArray(int size) {
|
||||
return new BackEvent[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeInt(mTouchX);
|
||||
dest.writeInt(mTouchY);
|
||||
dest.writeFloat(mProgress);
|
||||
dest.writeInt(mSwipeEdge);
|
||||
dest.writeTypedObject(mDepartingAnimationTarget, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value between 0 and 1 on how far along the back gesture is.
|
||||
*/
|
||||
public float getProgress() {
|
||||
return mProgress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute X location of the touch point.
|
||||
*/
|
||||
public int getTouchX() {
|
||||
return mTouchX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute Y location of the touch point.
|
||||
*/
|
||||
public int getTouchY() {
|
||||
return mTouchY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the screen edge that the swipe starts from.
|
||||
*/
|
||||
public int getSwipeEdge() {
|
||||
return mSwipeEdge;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link RemoteAnimationTarget} of the top departing application window,
|
||||
* or {@code null} if the top window should not be moved for the current type of back
|
||||
* destination.
|
||||
*/
|
||||
@Nullable
|
||||
public RemoteAnimationTarget getDepartingAnimationTarget() {
|
||||
return mDepartingAnimationTarget;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BackEvent{"
|
||||
+ "mTouchX=" + mTouchX
|
||||
+ ", mTouchY=" + mTouchY
|
||||
+ ", mProgress=" + mProgress
|
||||
+ ", mSwipeEdge" + mSwipeEdge
|
||||
+ ", mDepartingAnimationTarget" + mDepartingAnimationTarget
|
||||
+ "}";
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
package android.window;
|
||||
|
||||
import android.window.BackEvent;
|
||||
|
||||
/**
|
||||
* Interface that wraps a {@link OnBackInvokedCallback} object, to be stored in window manager
|
||||
* and called from back handling process when back is invoked.
|
||||
@@ -38,7 +40,7 @@ oneway interface IOnBackInvokedCallback {
|
||||
* @param touchY Absolute Y location of the touch point.
|
||||
* @param progress Value between 0 and 1 on how far along the back gesture is.
|
||||
*/
|
||||
void onBackProgressed(int touchX, int touchY, float progress);
|
||||
void onBackProgressed(in BackEvent backEvent);
|
||||
|
||||
/**
|
||||
* Called when a back gesture or back button press has been cancelled.
|
||||
|
||||
@@ -202,9 +202,9 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackProgressed(int touchX, int touchY, float progress)
|
||||
public void onBackProgressed(BackEvent backEvent)
|
||||
throws RemoteException {
|
||||
Handler.getMain().post(() -> mCallback.onBackProgressed(touchX, touchY, progress));
|
||||
Handler.getMain().post(() -> mCallback.onBackProgressed(backEvent));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.wm.shell.back;
|
||||
|
||||
import android.view.MotionEvent;
|
||||
import android.window.BackEvent;
|
||||
|
||||
import com.android.wm.shell.common.annotations.ExternalThread;
|
||||
|
||||
@@ -29,7 +30,7 @@ public interface BackAnimation {
|
||||
/**
|
||||
* Called when a {@link MotionEvent} is generated by a back gesture.
|
||||
*/
|
||||
void onBackMotion(MotionEvent event);
|
||||
void onBackMotion(MotionEvent event, @BackEvent.SwipeEdge int swipeEdge);
|
||||
|
||||
/**
|
||||
* Sets whether the back gesture is past the trigger threshold or not.
|
||||
|
||||
@@ -36,6 +36,7 @@ import android.os.SystemProperties;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceControl;
|
||||
import android.window.BackEvent;
|
||||
import android.window.BackNavigationInfo;
|
||||
import android.window.IOnBackInvokedCallback;
|
||||
|
||||
@@ -127,8 +128,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackMotion(MotionEvent event) {
|
||||
mShellExecutor.execute(() -> onMotionEvent(event));
|
||||
public void onBackMotion(MotionEvent event, @BackEvent.SwipeEdge int swipeEdge) {
|
||||
mShellExecutor.execute(() -> onMotionEvent(event, swipeEdge));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -183,12 +184,12 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
||||
* Called when a new motion event needs to be transferred to this
|
||||
* {@link BackAnimationController}
|
||||
*/
|
||||
public void onMotionEvent(MotionEvent event) {
|
||||
public void onMotionEvent(MotionEvent event, @BackEvent.SwipeEdge int swipeEdge) {
|
||||
int action = event.getActionMasked();
|
||||
if (action == MotionEvent.ACTION_DOWN) {
|
||||
initAnimation(event);
|
||||
} else if (action == MotionEvent.ACTION_MOVE) {
|
||||
onMove(event);
|
||||
onMove(event, swipeEdge);
|
||||
} else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
|
||||
onGestureFinished();
|
||||
}
|
||||
@@ -264,7 +265,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
||||
mTransaction.setVisibility(screenshotSurface, true);
|
||||
}
|
||||
|
||||
private void onMove(MotionEvent event) {
|
||||
private void onMove(MotionEvent event, @BackEvent.SwipeEdge int swipeEdge) {
|
||||
if (!mBackGestureStarted || mBackNavigationInfo == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.os.RemoteException;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceControl;
|
||||
import android.window.BackEvent;
|
||||
import android.window.BackNavigationInfo;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
@@ -94,7 +95,9 @@ public class BackAnimationControllerTest {
|
||||
SurfaceControl screenshotSurface = new SurfaceControl();
|
||||
HardwareBuffer hardwareBuffer = mock(HardwareBuffer.class);
|
||||
createNavigationInfo(topWindowLeash, screenshotSurface, hardwareBuffer);
|
||||
mController.onMotionEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0));
|
||||
mController.onMotionEvent(
|
||||
MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0),
|
||||
BackEvent.EDGE_LEFT);
|
||||
verify(mTransaction).setBuffer(screenshotSurface, hardwareBuffer);
|
||||
verify(mTransaction).setVisibility(screenshotSurface, true);
|
||||
verify(mTransaction).apply();
|
||||
@@ -106,8 +109,12 @@ public class BackAnimationControllerTest {
|
||||
SurfaceControl screenshotSurface = new SurfaceControl();
|
||||
HardwareBuffer hardwareBuffer = mock(HardwareBuffer.class);
|
||||
createNavigationInfo(topWindowLeash, screenshotSurface, hardwareBuffer);
|
||||
mController.onMotionEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0));
|
||||
mController.onMotionEvent(MotionEvent.obtain(10, 0, MotionEvent.ACTION_MOVE, 100, 100, 0));
|
||||
mController.onMotionEvent(
|
||||
MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0),
|
||||
BackEvent.EDGE_LEFT);
|
||||
mController.onMotionEvent(
|
||||
MotionEvent.obtain(10, 0, MotionEvent.ACTION_MOVE, 100, 100, 0),
|
||||
BackEvent.EDGE_LEFT);
|
||||
verify(mTransaction).setPosition(topWindowLeash, 100, 100);
|
||||
verify(mTransaction, atLeastOnce()).apply();
|
||||
}
|
||||
|
||||
@@ -263,11 +263,14 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
|
||||
// Notify FalsingManager that an intentional gesture has occurred.
|
||||
// TODO(b/186519446): use a different method than isFalseTouch
|
||||
mFalsingManager.isFalseTouch(BACK_GESTURE);
|
||||
boolean sendDown = sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);
|
||||
boolean sendUp = sendEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK);
|
||||
if (DEBUG_MISSING_GESTURE) {
|
||||
Log.d(DEBUG_MISSING_GESTURE_TAG, "Triggered back: down=" + sendDown
|
||||
+ ", up=" + sendUp);
|
||||
// Only inject back keycodes when ahead-of-time back dispatching is disabled.
|
||||
if (mBackAnimation == null) {
|
||||
boolean sendDown = sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);
|
||||
boolean sendUp = sendEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK);
|
||||
if (DEBUG_MISSING_GESTURE) {
|
||||
Log.d(DEBUG_MISSING_GESTURE_TAG, "Triggered back: down="
|
||||
+ sendDown + ", up=" + sendUp);
|
||||
}
|
||||
}
|
||||
|
||||
mOverviewProxyService.notifyBackAction(true, (int) mDownPoint.x,
|
||||
|
||||
@@ -43,6 +43,7 @@ import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.view.animation.PathInterpolator;
|
||||
import android.window.BackEvent;
|
||||
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
import androidx.dynamicanimation.animation.DynamicAnimation;
|
||||
@@ -464,7 +465,8 @@ public class NavigationBarEdgePanel extends View implements NavigationEdgeBackPl
|
||||
@Override
|
||||
public void onMotionEvent(MotionEvent event) {
|
||||
if (mBackAnimation != null) {
|
||||
mBackAnimation.onBackMotion(event);
|
||||
mBackAnimation.onBackMotion(
|
||||
event, mIsLeftPanel ? BackEvent.EDGE_LEFT : BackEvent.EDGE_RIGHT);
|
||||
}
|
||||
if (mVelocityTracker == null) {
|
||||
mVelocityTracker = VelocityTracker.obtain();
|
||||
|
||||
Reference in New Issue
Block a user