Merge "Using a separate InputConsumer when Launcher is resumed but not focused" into ub-launcher3-qt-dev

am: 7183795ff8

Change-Id: Idafa9bc76dc8d22b3f69388824859d86e0737a81
This commit is contained in:
Sunny Goyal
2019-06-06 12:13:57 -07:00
committed by android-build-merger
8 changed files with 255 additions and 37 deletions
@@ -98,9 +98,6 @@ public class NavBarToHomeTouchController implements TouchController, SwipeDetect
if (mStartState == OVERVIEW || mStartState == ALL_APPS) {
return true;
}
if (!mLauncher.hasWindowFocus()) {
return true;
}
if (AbstractFloatingView.getTopOpenView(mLauncher) != null) {
return true;
}
@@ -62,6 +62,7 @@ import android.view.WindowManager;
import androidx.annotation.BinderThread;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.R;
import com.android.launcher3.ResourceUtils;
@@ -79,6 +80,7 @@ import com.android.quickstep.inputconsumers.DeviceLockedInputConsumer;
import com.android.quickstep.inputconsumers.InputConsumer;
import com.android.quickstep.inputconsumers.OtherActivityInputConsumer;
import com.android.quickstep.inputconsumers.OverviewInputConsumer;
import com.android.quickstep.inputconsumers.OverviewWithoutFocusInputConsumer;
import com.android.quickstep.inputconsumers.ScreenPinnedInputConsumer;
import com.android.systemui.shared.recents.IOverviewProxy;
import com.android.systemui.shared.recents.ISystemUiProxy;
@@ -566,10 +568,9 @@ public class TouchInteractionService extends Service implements
info.id = mSwipeSharedState.nextRunningTaskId;
return createOtherActivityInputConsumer(event, info);
} else if (mSwipeSharedState.goingToLauncher || activityControl.isResumed()) {
return OverviewInputConsumer.newInstance(activityControl, mInputMonitorCompat, false);
} else if (ENABLE_QUICKSTEP_LIVE_TILE.get() &&
activityControl.isInLiveTileMode()) {
return OverviewInputConsumer.newInstance(activityControl, mInputMonitorCompat, false);
return createOverviewInputConsumer(event);
} else if (ENABLE_QUICKSTEP_LIVE_TILE.get() && activityControl.isInLiveTileMode()) {
return createOverviewInputConsumer(event);
} else if (mGestureBlockingActivity != null && runningTaskInfo != null
&& mGestureBlockingActivity.equals(runningTaskInfo.topActivity)) {
return InputConsumer.NO_OP;
@@ -578,20 +579,24 @@ public class TouchInteractionService extends Service implements
}
}
private boolean disableHorizontalSwipe(MotionEvent event) {
// mExclusionRegion can change on binder thread, use a local instance here.
Region exclusionRegion = mExclusionRegion;
return mMode == Mode.NO_BUTTON && exclusionRegion != null
&& exclusionRegion.contains((int) event.getX(), (int) event.getY());
}
private OtherActivityInputConsumer createOtherActivityInputConsumer(MotionEvent event,
RunningTaskInfo runningTaskInfo) {
final ActivityControlHelper activityControl =
mOverviewComponentObserver.getActivityControlHelper();
boolean shouldDefer = activityControl.deferStartingActivity(mActiveNavBarRegion, event);
// mExclusionRegion can change on binder thread, use a local instance here.
Region exclusionRegion = mExclusionRegion;
boolean disableHorizontalSwipe = mMode == Mode.NO_BUTTON && exclusionRegion != null
&& exclusionRegion.contains((int) event.getX(), (int) event.getY());
return new OtherActivityInputConsumer(this, runningTaskInfo, mRecentsModel,
mOverviewComponentObserver.getOverviewIntent(), activityControl,
shouldDefer, mOverviewCallbacks, mInputConsumer, this::onConsumerInactive,
mSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion, disableHorizontalSwipe);
mSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion,
disableHorizontalSwipe(event));
}
private InputConsumer createDeviceLockedInputConsumer(RunningTaskInfo taskInfo) {
@@ -603,6 +608,23 @@ public class TouchInteractionService extends Service implements
}
}
public InputConsumer createOverviewInputConsumer(MotionEvent event) {
final ActivityControlHelper activityControl =
mOverviewComponentObserver.getActivityControlHelper();
BaseDraggingActivity activity = activityControl.getCreatedActivity();
if (activity == null) {
return InputConsumer.NO_OP;
}
if (activity.getRootView().hasWindowFocus()) {
return new OverviewInputConsumer(activity, mInputMonitorCompat,
false /* startingInActivityBounds */);
} else {
return new OverviewWithoutFocusInputConsumer(this, mInputMonitorCompat,
disableHorizontalSwipe(event));
}
}
/**
* To be called by the consumer when it's no longer active.
*/
@@ -858,7 +858,9 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
setTargetAlphaProvider(WindowTransformSwipeHandler::getHiddenTargetAlpha);
}
return OverviewInputConsumer.newInstance(mActivityControlHelper, null, true);
BaseDraggingActivity activity = mActivityControlHelper.getCreatedActivity();
return activity == null
? InputConsumer.NO_OP : new OverviewInputConsumer(activity, null, true);
}
private void endRunningWindowAnim() {
@@ -31,6 +31,7 @@ public interface InputConsumer {
int TYPE_DEVICE_LOCKED = 1 << 4;
int TYPE_ACCESSIBILITY = 1 << 5;
int TYPE_SCREEN_PINNED = 1 << 6;
int TYPE_OVERVIEW_WITHOUT_FOCUS = 1 << 7;
InputConsumer NO_OP = () -> TYPE_NO_OP;
@@ -78,6 +79,8 @@ public interface InputConsumer {
return "ACCESSIBILITY";
case TYPE_SCREEN_PINNED:
return "SCREEN_PINNED";
case TYPE_OVERVIEW_WITHOUT_FOCUS:
return "TYPE_OVERVIEW_WITHOUT_FOCUS";
default:
return "NO_OP";
}
@@ -28,7 +28,6 @@ import static com.android.launcher3.uioverrides.RecentsUiFactory.ROTATION_LANDSC
import static com.android.launcher3.uioverrides.RecentsUiFactory.ROTATION_SEASCAPE;
import static com.android.launcher3.util.RaceConditionTracker.ENTER;
import static com.android.launcher3.util.RaceConditionTracker.EXIT;
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
@@ -43,10 +42,8 @@ import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import androidx.annotation.UiThread;
@@ -65,6 +62,7 @@ import com.android.quickstep.WindowTransformSwipeHandler;
import com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget;
import com.android.quickstep.util.CachedEventDispatcher;
import com.android.quickstep.util.MotionPauseDetector;
import com.android.quickstep.util.NavBarPosition;
import com.android.quickstep.util.RecentsAnimationListenerSet;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.BackgroundExecutor;
@@ -95,7 +93,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
private final SysUINavigationMode.Mode mMode;
private final RectF mSwipeTouchRegion;
private final int mDisplayRotation;
private final NavBarPosition mNavBarPosition;
private final Consumer<OtherActivityInputConsumer> mOnCompleteCallback;
private final MotionPauseDetector mMotionPauseDetector;
@@ -157,7 +155,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
mInputConsumer = inputConsumer;
mSwipeSharedState = swipeSharedState;
mDisplayRotation = getSystemService(WindowManager.class).getDefaultDisplay().getRotation();
mNavBarPosition = new NavBarPosition(base);
mDragSlop = QuickStepContract.getQuickStepDragSlopPx();
float slop = QuickStepContract.getQuickStepTouchSlopPx();
mSquaredTouchSlop = slop * slop;
@@ -188,9 +186,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
if (mPassedDragSlop && mInteractionHandler != null
&& !mRecentsViewDispatcher.hasConsumer()) {
mRecentsViewDispatcher.setConsumer(mInteractionHandler.getRecentsViewDispatcher(
isNavBarOnLeft()
? ROTATION_SEASCAPE
: (isNavBarOnRight() ? ROTATION_LANDSCAPE : RotationMode.NORMAL)));
mNavBarPosition.getRotationMode()));
}
int edgeFlags = ev.getEdgeFlags();
ev.setEdgeFlags(edgeFlags | EDGE_NAV_BAR);
@@ -329,14 +325,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
mInteractionHandler.onGestureStarted();
}
private boolean isNavBarOnRight() {
return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_90;
}
private boolean isNavBarOnLeft() {
return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_270;
}
private void startTouchTrackingForWindowAnimation(long touchTimeMs) {
TOUCH_INTERACTION_LOG.addLog("startRecentsAnimation");
@@ -382,8 +370,8 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
ViewConfiguration.get(this).getScaledMaximumFlingVelocity());
float velocityX = mVelocityTracker.getXVelocity(mActivePointerId);
float velocityY = mVelocityTracker.getYVelocity(mActivePointerId);
float velocity = isNavBarOnRight() ? velocityX
: isNavBarOnLeft() ? -velocityX
float velocity = mNavBarPosition.isRightEdge() ? velocityX
: mNavBarPosition.isLeftEdge() ? -velocityX
: velocityY;
mInteractionHandler.updateDisplacement(getDisplacement(ev) - mStartDisplacement);
@@ -444,9 +432,9 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
}
private float getDisplacement(MotionEvent ev) {
if (isNavBarOnRight()) {
if (mNavBarPosition.isRightEdge()) {
return ev.getX() - mDownPos.x;
} else if (isNavBarOnLeft()) {
} else if (mNavBarPosition.isLeftEdge()) {
return mDownPos.x - ev.getX();
} else {
return ev.getY() - mDownPos.y;
@@ -51,7 +51,7 @@ public class OverviewInputConsumer<T extends BaseDraggingActivity>
private final boolean mStartingInActivityBounds;
private boolean mTargetHandledTouch;
OverviewInputConsumer(T activity, @Nullable InputMonitorCompat inputMonitor,
public OverviewInputConsumer(T activity, @Nullable InputMonitorCompat inputMonitor,
boolean startingInActivityBounds) {
mActivity = activity;
mInputMonitor = inputMonitor;
@@ -115,12 +115,12 @@ public class OverviewInputConsumer<T extends BaseDraggingActivity>
}
}
public static InputConsumer newInstance(ActivityControlHelper activityHelper,
@Nullable InputMonitorCompat inputMonitor, boolean startingInActivityBounds) {
public static InputConsumer newInstanceWithinActivityBounds(
ActivityControlHelper activityHelper) {
BaseDraggingActivity activity = activityHelper.getCreatedActivity();
if (activity == null) {
return InputConsumer.NO_OP;
}
return new OverviewInputConsumer(activity, inputMonitor, startingInActivityBounds);
return new OverviewInputConsumer(activity, null, true);
}
}
@@ -0,0 +1,151 @@
/*
* Copyright (C) 2019 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 com.android.quickstep.inputconsumers;
import static android.view.MotionEvent.ACTION_CANCEL;
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_MOVE;
import static android.view.MotionEvent.ACTION_UP;
import static com.android.launcher3.Utilities.squaredHypot;
import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
import android.content.Context;
import android.graphics.PointF;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
import com.android.launcher3.Utilities;
import com.android.quickstep.OverviewCallbacks;
import com.android.quickstep.util.NavBarPosition;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.InputMonitorCompat;
public class OverviewWithoutFocusInputConsumer implements InputConsumer {
private final InputMonitorCompat mInputMonitor;
private final boolean mDisableHorizontalSwipe;
private final PointF mDownPos = new PointF();
private final float mSquaredTouchSlop;
private final Context mContext;
private final NavBarPosition mNavBarPosition;
private boolean mInterceptedTouch;
private VelocityTracker mVelocityTracker;
public OverviewWithoutFocusInputConsumer(Context context, InputMonitorCompat inputMonitor,
boolean disableHorizontalSwipe) {
mInputMonitor = inputMonitor;
mDisableHorizontalSwipe = disableHorizontalSwipe;
mContext = context;
mSquaredTouchSlop = Utilities.squaredTouchSlop(context);
mNavBarPosition = new NavBarPosition(context);
mVelocityTracker = VelocityTracker.obtain();
}
@Override
public int getType() {
return TYPE_OVERVIEW_WITHOUT_FOCUS;
}
@Override
public boolean allowInterceptByParent() {
return !mInterceptedTouch;
}
private void endTouchTracking() {
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
}
@Override
public void onMotionEvent(MotionEvent ev) {
if (mVelocityTracker == null) {
return;
}
mVelocityTracker.addMovement(ev);
switch (ev.getActionMasked()) {
case ACTION_DOWN: {
mDownPos.set(ev.getX(), ev.getY());
break;
}
case ACTION_MOVE: {
if (!mInterceptedTouch) {
float displacementX = ev.getX() - mDownPos.x;
float displacementY = ev.getY() - mDownPos.y;
if (squaredHypot(displacementX, displacementY) >= mSquaredTouchSlop) {
if (mDisableHorizontalSwipe
&& Math.abs(displacementX) > Math.abs(displacementY)) {
// Horizontal gesture is not allowed in this region
endTouchTracking();
break;
}
mInterceptedTouch = true;
if (mInputMonitor != null) {
mInputMonitor.pilferPointers();
}
}
}
break;
}
case ACTION_CANCEL:
endTouchTracking();
break;
case ACTION_UP: {
finishTouchTracking(ev);
endTouchTracking();
break;
}
}
}
private void finishTouchTracking(MotionEvent ev) {
mVelocityTracker.computeCurrentVelocity(100);
float velocityX = mVelocityTracker.getXVelocity();
float velocityY = mVelocityTracker.getYVelocity();
float velocity = mNavBarPosition.isRightEdge()
? -velocityX : (mNavBarPosition.isLeftEdge() ? velocityX : -velocityY);
final boolean triggerQuickstep;
if (Math.abs(velocity) >= ViewConfiguration.get(mContext).getScaledMinimumFlingVelocity()) {
triggerQuickstep = velocity > 0;
} else {
float displacementX = mDisableHorizontalSwipe ? 0 : (ev.getX() - mDownPos.x);
float displacementY = ev.getY() - mDownPos.y;
triggerQuickstep = squaredHypot(displacementX, displacementY) >= mSquaredTouchSlop;
}
if (triggerQuickstep) {
OverviewCallbacks.get(mContext).closeAllWindows();
ActivityManagerWrapper.getInstance()
.closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
TOUCH_INTERACTION_LOG.addLog("startQuickstep");
} else {
// ignore
}
}
}
@@ -0,0 +1,55 @@
/*
* Copyright (C) 2019 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 com.android.quickstep.util;
import static com.android.launcher3.uioverrides.RecentsUiFactory.ROTATION_LANDSCAPE;
import static com.android.launcher3.uioverrides.RecentsUiFactory.ROTATION_SEASCAPE;
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import android.content.Context;
import android.view.Surface;
import android.view.WindowManager;
import com.android.launcher3.graphics.RotationMode;
import com.android.quickstep.SysUINavigationMode;
/**
* Utility class to check nav bar position
*/
public class NavBarPosition {
private final SysUINavigationMode.Mode mMode;
private final int mDisplayRotation;
public NavBarPosition(Context context) {
mMode = SysUINavigationMode.getMode(context);
mDisplayRotation = context.getSystemService(WindowManager.class)
.getDefaultDisplay().getRotation();
}
public boolean isRightEdge() {
return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_90;
}
public boolean isLeftEdge() {
return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_270;
}
public RotationMode getRotationMode() {
return isLeftEdge() ? ROTATION_SEASCAPE
: (isRightEdge() ? ROTATION_LANDSCAPE : RotationMode.NORMAL);
}
}