Adding finish signal to GestureNavContract.

Also fixing also-closing behavior for FloatingSurfaceView for Android S

Bug: 228260232
Test: Verified manually on device
Change-Id: I83f6417a756c1459533294d681e83abba6ea58aa
This commit is contained in:
Sunny Goyal
2022-04-05 20:58:03 -07:00
parent b266baa64d
commit 5c20fdd73f
4 changed files with 105 additions and 12 deletions
@@ -21,8 +21,10 @@ import static android.content.Intent.EXTRA_USER;
import static com.android.launcher3.GestureNavContract.EXTRA_GESTURE_CONTRACT;
import static com.android.launcher3.GestureNavContract.EXTRA_ICON_POSITION;
import static com.android.launcher3.GestureNavContract.EXTRA_ICON_SURFACE;
import static com.android.launcher3.GestureNavContract.EXTRA_ON_FINISH_CALLBACK;
import static com.android.launcher3.GestureNavContract.EXTRA_REMOTE_CALLBACK;
import static com.android.launcher3.Utilities.createHomeIntent;
import static com.android.launcher3.anim.AnimatorListeners.forEndCallback;
import static com.android.launcher3.anim.Interpolators.ACCEL;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME;
@@ -44,7 +46,9 @@ import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.ParcelUuid;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
@@ -82,6 +86,8 @@ import java.util.function.Consumer;
public class FallbackSwipeHandler extends
AbsSwipeUpHandler<RecentsActivity, FallbackRecentsView, RecentsState> {
private static final String TAG = "FallbackSwipeHandler";
/**
* Message used for receiving gesture nav contract information. We use a static messenger to
* avoid leaking too make binders in case the receiving launcher does not handle the contract
@@ -224,7 +230,8 @@ public class FallbackSwipeHandler extends
}
}
private class FallbackHomeAnimationFactory extends HomeAnimationFactory {
private class FallbackHomeAnimationFactory extends HomeAnimationFactory
implements Consumer<Message> {
private final Rect mTempRect = new Rect();
private final TransformParams mHomeAlphaParams = new TransformParams();
private final AnimatedFloat mHomeAlpha;
@@ -235,6 +242,9 @@ public class FallbackSwipeHandler extends
private final RectF mTargetRect = new RectF();
private SurfaceControl mSurfaceControl;
private boolean mAnimationFinished;
private Message mOnFinishCallback;
private final long mDuration;
private RectFSpringAnim mSpringAnim;
@@ -336,9 +346,26 @@ public class FallbackSwipeHandler extends
@Override
public void setAnimation(RectFSpringAnim anim) {
mSpringAnim = anim;
mSpringAnim.addAnimatorListener(forEndCallback(this::onRectAnimationEnd));
}
private void onMessageReceived(Message msg) {
private void onRectAnimationEnd() {
mAnimationFinished = true;
maybeSendEndMessage();
}
private void maybeSendEndMessage() {
if (mAnimationFinished && mOnFinishCallback != null) {
try {
mOnFinishCallback.replyTo.send(mOnFinishCallback);
} catch (RemoteException e) {
Log.e(TAG, "Error sending icon position", e);
}
}
}
@Override
public void accept(Message msg) {
try {
Bundle data = msg.getData();
RectF position = data.getParcelable(EXTRA_ICON_POSITION);
@@ -348,7 +375,9 @@ public class FallbackSwipeHandler extends
if (mSpringAnim != null) {
mSpringAnim.onTargetPositionChanged();
}
mOnFinishCallback = data.getParcelable(EXTRA_ON_FINISH_CALLBACK);
}
maybeSendEndMessage();
} catch (Exception e) {
// Ignore
}
@@ -382,8 +411,8 @@ public class FallbackSwipeHandler extends
Bundle gestureNavContract = new Bundle();
gestureNavContract.putParcelable(EXTRA_COMPONENT_NAME, key.getComponent());
gestureNavContract.putParcelable(EXTRA_USER, UserHandle.of(key.userId));
gestureNavContract.putParcelable(EXTRA_REMOTE_CALLBACK,
sMessageReceiver.newCallback(this::onMessageReceived));
gestureNavContract.putParcelable(
EXTRA_REMOTE_CALLBACK, sMessageReceiver.newCallback(this));
intent.putExtra(EXTRA_GESTURE_CONTRACT, gestureNavContract);
}
}
@@ -18,20 +18,30 @@ package com.android.launcher3;
import static android.content.Intent.EXTRA_COMPONENT_NAME;
import static android.content.Intent.EXTRA_USER;
import static com.android.launcher3.AbstractFloatingView.TYPE_ICON_SURFACE;
import android.annotation.TargetApi;
import android.content.ComponentName;
import android.content.Intent;
import android.graphics.RectF;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
import android.view.SurfaceControl;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.views.ActivityContext;
import java.lang.ref.WeakReference;
/**
* Class to encapsulate the handshake protocol between Launcher and gestureNav.
*/
@@ -43,6 +53,7 @@ public class GestureNavContract {
public static final String EXTRA_ICON_POSITION = "gesture_nav_contract_icon_position";
public static final String EXTRA_ICON_SURFACE = "gesture_nav_contract_surface_control";
public static final String EXTRA_REMOTE_CALLBACK = "android.intent.extra.REMOTE_CALLBACK";
public static final String EXTRA_ON_FINISH_CALLBACK = "gesture_nav_contract_finish_callback";
public final ComponentName componentName;
public final UserHandle user;
@@ -59,10 +70,15 @@ public class GestureNavContract {
* Sends the position information to the receiver
*/
@TargetApi(Build.VERSION_CODES.R)
public void sendEndPosition(RectF position, @Nullable SurfaceControl surfaceControl) {
public void sendEndPosition(RectF position, ActivityContext context,
@Nullable SurfaceControl surfaceControl) {
Bundle result = new Bundle();
result.putParcelable(EXTRA_ICON_POSITION, position);
result.putParcelable(EXTRA_ICON_SURFACE, surfaceControl);
if (sMessageReceiver == null) {
sMessageReceiver = new StaticMessageReceiver();
}
result.putParcelable(EXTRA_ON_FINISH_CALLBACK, sMessageReceiver.setCurrentContext(context));
Message callback = Message.obtain();
callback.copyFrom(mCallback);
@@ -98,4 +114,42 @@ public class GestureNavContract {
}
return null;
}
/**
* Message used for receiving gesture nav contract information. We use a static messenger to
* avoid leaking too make binders in case the receiving launcher does not handle the contract
* properly.
*/
private static StaticMessageReceiver sMessageReceiver = null;
private static class StaticMessageReceiver implements Handler.Callback {
private static final int MSG_CLOSE_LAST_TARGET = 0;
private final Messenger mMessenger =
new Messenger(new Handler(Looper.getMainLooper(), this));
private WeakReference<ActivityContext> mLastTarget = new WeakReference<>(null);
public Message setCurrentContext(ActivityContext context) {
mLastTarget = new WeakReference<>(context);
Message msg = Message.obtain();
msg.replyTo = mMessenger;
msg.what = MSG_CLOSE_LAST_TARGET;
return msg;
}
@Override
public boolean handleMessage(@NonNull Message message) {
if (message.what == MSG_CLOSE_LAST_TARGET) {
ActivityContext lastContext = mLastTarget.get();
if (lastContext != null) {
AbstractFloatingView.closeOpenViews(lastContext, false, TYPE_ICON_SURFACE);
}
return true;
}
return false;
}
}
}
+7 -1
View File
@@ -604,7 +604,13 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
public void onEnterAnimationComplete() {
super.onEnterAnimationComplete();
mRotationHelper.setCurrentTransitionRequest(REQUEST_NONE);
AbstractFloatingView.closeOpenViews(this, false, TYPE_ICON_SURFACE);
// Starting with Android S, onEnterAnimationComplete is sent immediately
// causing the surface to get removed before the animation completed (b/175345344).
// Instead we rely on next user touch event to remove the view and optionally a callback
// from system from Android T onwards.
if (!Utilities.ATLEAST_S) {
AbstractFloatingView.closeOpenViews(this, false, TYPE_ICON_SURFACE);
}
}
@Override
@@ -62,7 +62,6 @@ public class FloatingSurfaceView extends AbstractFloatingView implements
private final SurfaceView mSurfaceView;
private View mIcon;
private GestureNavContract mContract;
@@ -103,7 +102,13 @@ public class FloatingSurfaceView extends AbstractFloatingView implements
private void removeViewFromParent() {
mPicture.beginRecording(1, 1);
mPicture.endRecording();
mLauncher.getDragLayer().removeView(this);
mLauncher.getDragLayer().removeViewInLayout(this);
}
private void removeViewImmediate() {
// Cancel any pending remove
Executors.MAIN_EXECUTOR.getHandler().removeCallbacks(mRemoveViewRunnable);
removeViewFromParent();
}
/**
@@ -115,9 +120,7 @@ public class FloatingSurfaceView extends AbstractFloatingView implements
view.mContract = contract;
view.mIsOpen = true;
// Cancel any pending remove
Executors.MAIN_EXECUTOR.getHandler().removeCallbacks(view.mRemoveViewRunnable);
view.removeViewFromParent();
view.removeViewImmediate();
launcher.getDragLayer().addView(view);
}
@@ -129,6 +132,7 @@ public class FloatingSurfaceView extends AbstractFloatingView implements
@Override
public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
close(false);
removeViewImmediate();
return false;
}
@@ -197,7 +201,7 @@ public class FloatingSurfaceView extends AbstractFloatingView implements
private void sendIconInfo() {
if (mContract != null && !mIconPosition.isEmpty()) {
mContract.sendEndPosition(mIconPosition, mSurfaceView.getSurfaceControl());
mContract.sendEndPosition(mIconPosition, mLauncher, mSurfaceView.getSurfaceControl());
}
}