Merge "Support for OnBackAnimationCallback: added for 3-button navigation / hardware keys" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
b98116acd2
@@ -200,8 +200,10 @@ import android.view.contentcapture.MainContentCaptureSession;
|
|||||||
import android.view.inputmethod.ImeTracker;
|
import android.view.inputmethod.ImeTracker;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.widget.Scroller;
|
import android.widget.Scroller;
|
||||||
|
import android.window.BackEvent;
|
||||||
import android.window.ClientWindowFrames;
|
import android.window.ClientWindowFrames;
|
||||||
import android.window.CompatOnBackInvokedCallback;
|
import android.window.CompatOnBackInvokedCallback;
|
||||||
|
import android.window.OnBackAnimationCallback;
|
||||||
import android.window.OnBackInvokedCallback;
|
import android.window.OnBackInvokedCallback;
|
||||||
import android.window.OnBackInvokedDispatcher;
|
import android.window.OnBackInvokedDispatcher;
|
||||||
import android.window.ScreenCapture;
|
import android.window.ScreenCapture;
|
||||||
@@ -6526,6 +6528,7 @@ public final class ViewRootImpl implements ViewParent,
|
|||||||
*/
|
*/
|
||||||
final class NativePreImeInputStage extends AsyncInputStage
|
final class NativePreImeInputStage extends AsyncInputStage
|
||||||
implements InputQueue.FinishedInputEventCallback {
|
implements InputQueue.FinishedInputEventCallback {
|
||||||
|
|
||||||
public NativePreImeInputStage(InputStage next, String traceCounter) {
|
public NativePreImeInputStage(InputStage next, String traceCounter) {
|
||||||
super(next, traceCounter);
|
super(next, traceCounter);
|
||||||
}
|
}
|
||||||
@@ -6533,32 +6536,62 @@ public final class ViewRootImpl implements ViewParent,
|
|||||||
@Override
|
@Override
|
||||||
protected int onProcess(QueuedInputEvent q) {
|
protected int onProcess(QueuedInputEvent q) {
|
||||||
if (q.mEvent instanceof KeyEvent) {
|
if (q.mEvent instanceof KeyEvent) {
|
||||||
final KeyEvent event = (KeyEvent) q.mEvent;
|
final KeyEvent keyEvent = (KeyEvent) q.mEvent;
|
||||||
|
|
||||||
// If the new back dispatch is enabled, intercept KEYCODE_BACK before it reaches the
|
// If the new back dispatch is enabled, intercept KEYCODE_BACK before it reaches the
|
||||||
// view tree or IME, and invoke the appropriate {@link OnBackInvokedCallback}.
|
// view tree or IME, and invoke the appropriate {@link OnBackInvokedCallback}.
|
||||||
if (isBack(event)
|
if (isBack(keyEvent)
|
||||||
&& mContext != null
|
&& mContext != null
|
||||||
&& mOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled()) {
|
&& mOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled()) {
|
||||||
OnBackInvokedCallback topCallback =
|
return doOnBackKeyEvent(keyEvent);
|
||||||
getOnBackInvokedDispatcher().getTopCallback();
|
}
|
||||||
if (event.getAction() == KeyEvent.ACTION_UP) {
|
|
||||||
if (topCallback != null) {
|
if (mInputQueue != null) {
|
||||||
|
mInputQueue.sendInputEvent(q.mEvent, q, true, this);
|
||||||
|
return DEFER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FORWARD;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int doOnBackKeyEvent(KeyEvent keyEvent) {
|
||||||
|
OnBackInvokedCallback topCallback = getOnBackInvokedDispatcher().getTopCallback();
|
||||||
|
if (topCallback instanceof OnBackAnimationCallback) {
|
||||||
|
final OnBackAnimationCallback animationCallback =
|
||||||
|
(OnBackAnimationCallback) topCallback;
|
||||||
|
switch (keyEvent.getAction()) {
|
||||||
|
case KeyEvent.ACTION_DOWN:
|
||||||
|
// ACTION_DOWN is emitted twice: once when the user presses the button,
|
||||||
|
// and again a few milliseconds later.
|
||||||
|
// Based on the result of `keyEvent.getRepeatCount()` we have:
|
||||||
|
// - 0 means the button was pressed.
|
||||||
|
// - 1 means the button continues to be pressed (long press).
|
||||||
|
if (keyEvent.getRepeatCount() == 0) {
|
||||||
|
animationCallback.onBackStarted(
|
||||||
|
new BackEvent(0, 0, 0f, BackEvent.EDGE_LEFT));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KeyEvent.ACTION_UP:
|
||||||
|
if (keyEvent.isCanceled()) {
|
||||||
|
animationCallback.onBackCancelled();
|
||||||
|
} else {
|
||||||
topCallback.onBackInvoked();
|
topCallback.onBackInvoked();
|
||||||
return FINISH_HANDLED;
|
return FINISH_HANDLED;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (topCallback != null) {
|
||||||
|
if (keyEvent.getAction() == KeyEvent.ACTION_UP) {
|
||||||
|
if (!keyEvent.isCanceled()) {
|
||||||
|
topCallback.onBackInvoked();
|
||||||
|
return FINISH_HANDLED;
|
||||||
} else {
|
} else {
|
||||||
// Drop other actions such as {@link KeyEvent.ACTION_DOWN}.
|
Log.d(mTag, "Skip onBackInvoked(), reason: keyEvent.isCanceled=true");
|
||||||
return FINISH_NOT_HANDLED;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mInputQueue != null && q.mEvent instanceof KeyEvent) {
|
return FINISH_NOT_HANDLED;
|
||||||
mInputQueue.sendInputEvent(q.mEvent, q, true, this);
|
|
||||||
return DEFER;
|
|
||||||
}
|
|
||||||
return FORWARD;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user