mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-03-02 17:06:49 +00:00
Stub out most of TouchInteractionService for Go
Most of TouchInteractionService is not used in Go since we don't support a lot of the gestures, so this code swaps the file and stubs out everything except the atomic overview commands for Go only. Bug: 114136250 Test: Manual test NexusLauncher, l3GoIconRecents Change-Id: I449746d01d3bbf619663399deb9600f0e4ecc000
This commit is contained in:
@@ -1,390 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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;
|
||||
|
||||
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_POINTER_UP;
|
||||
import static android.view.MotionEvent.ACTION_UP;
|
||||
import static android.view.MotionEvent.INVALID_POINTER_ID;
|
||||
|
||||
import static com.android.launcher3.util.RaceConditionTracker.ENTER;
|
||||
import static com.android.launcher3.util.RaceConditionTracker.EXIT;
|
||||
import static com.android.quickstep.TouchInteractionService.EDGE_NAV_BAR;
|
||||
import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG;
|
||||
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.ActivityManager.RunningTaskInfo;
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.Intent;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Build;
|
||||
import android.view.Display;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.Surface;
|
||||
import android.view.VelocityTracker;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.util.Preconditions;
|
||||
import com.android.launcher3.util.RaceConditionTracker;
|
||||
import com.android.launcher3.util.TraceHelper;
|
||||
import com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget;
|
||||
import com.android.quickstep.util.CachedEventDispatcher;
|
||||
import com.android.quickstep.util.MotionPauseDetector;
|
||||
import com.android.quickstep.util.RecentsAnimationListenerSet;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.BackgroundExecutor;
|
||||
import com.android.systemui.shared.system.InputConsumerController;
|
||||
import com.android.systemui.shared.system.NavigationBarCompat;
|
||||
import com.android.systemui.shared.system.WindowManagerWrapper;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Touch consumer for handling events originating from an activity other than Launcher
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.P)
|
||||
public class OtherActivityTouchConsumer extends ContextWrapper implements TouchConsumer {
|
||||
|
||||
public static final String DOWN_EVT = "OtherActivityTouchConsumer.DOWN";
|
||||
private static final String UP_EVT = "OtherActivityTouchConsumer.UP";
|
||||
|
||||
private final CachedEventDispatcher mRecentsViewDispatcher = new CachedEventDispatcher();
|
||||
private final RunningTaskInfo mRunningTask;
|
||||
private final RecentsModel mRecentsModel;
|
||||
private final Intent mHomeIntent;
|
||||
private final ActivityControlHelper mActivityControlHelper;
|
||||
private final OverviewCallbacks mOverviewCallbacks;
|
||||
private final TaskOverlayFactory mTaskOverlayFactory;
|
||||
private final InputConsumerController mInputConsumer;
|
||||
private final SwipeSharedState mSwipeSharedState;
|
||||
|
||||
private final int mDisplayRotation;
|
||||
private final Rect mStableInsets = new Rect();
|
||||
|
||||
private final Consumer<OtherActivityTouchConsumer> mOnCompleteCallback;
|
||||
private final MotionPauseDetector mMotionPauseDetector;
|
||||
private VelocityTracker mVelocityTracker;
|
||||
|
||||
private WindowTransformSwipeHandler mInteractionHandler;
|
||||
|
||||
private final boolean mIsDeferredDownTarget;
|
||||
private final PointF mDownPos = new PointF();
|
||||
private final PointF mLastPos = new PointF();
|
||||
private int mActivePointerId = INVALID_POINTER_ID;
|
||||
|
||||
private final float mDragSlop;
|
||||
private final float mTouchSlop;
|
||||
|
||||
// Slop used to check when we start moving window.
|
||||
private boolean mPassedDragSlop;
|
||||
// Slop used to determine when we say that the gesture has started.
|
||||
private boolean mPassedTouchSlop;
|
||||
|
||||
// TODO: Start displacement should have both x and y
|
||||
private float mStartDisplacement;
|
||||
|
||||
public OtherActivityTouchConsumer(Context base, RunningTaskInfo runningTaskInfo,
|
||||
RecentsModel recentsModel, Intent homeIntent, ActivityControlHelper activityControl,
|
||||
boolean isDeferredDownTarget, OverviewCallbacks overviewCallbacks,
|
||||
TaskOverlayFactory taskOverlayFactory, InputConsumerController inputConsumer,
|
||||
Consumer<OtherActivityTouchConsumer> onCompleteCallback,
|
||||
SwipeSharedState swipeSharedState) {
|
||||
super(base);
|
||||
|
||||
mRunningTask = runningTaskInfo;
|
||||
mRecentsModel = recentsModel;
|
||||
mHomeIntent = homeIntent;
|
||||
|
||||
mMotionPauseDetector = new MotionPauseDetector(base);
|
||||
mOnCompleteCallback = onCompleteCallback;
|
||||
mVelocityTracker = VelocityTracker.obtain();
|
||||
|
||||
mActivityControlHelper = activityControl;
|
||||
mIsDeferredDownTarget = isDeferredDownTarget;
|
||||
mOverviewCallbacks = overviewCallbacks;
|
||||
mTaskOverlayFactory = taskOverlayFactory;
|
||||
mInputConsumer = inputConsumer;
|
||||
mSwipeSharedState = swipeSharedState;
|
||||
|
||||
Display display = getSystemService(WindowManager.class).getDefaultDisplay();
|
||||
mDisplayRotation = display.getRotation();
|
||||
WindowManagerWrapper.getInstance().getStableInsets(mStableInsets);
|
||||
|
||||
mDragSlop = NavigationBarCompat.getQuickStepDragSlopPx();
|
||||
mTouchSlop = NavigationBarCompat.getQuickStepTouchSlopPx();
|
||||
// If active listener isn't null, we are continuing the previous gesture.
|
||||
mPassedTouchSlop = mPassedDragSlop = mSwipeSharedState.getActiveListener() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(MotionEvent ev) {
|
||||
if (mVelocityTracker == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Proxy events to recents view
|
||||
if (!isNavBarOnLeft() && !isNavBarOnRight()) {
|
||||
if (mPassedDragSlop && mInteractionHandler != null
|
||||
&& !mRecentsViewDispatcher.hasConsumer()) {
|
||||
mRecentsViewDispatcher.setConsumer(mInteractionHandler.getRecentsViewDispatcher());
|
||||
}
|
||||
int edgeFlags = ev.getEdgeFlags();
|
||||
ev.setEdgeFlags(edgeFlags | EDGE_NAV_BAR);
|
||||
mRecentsViewDispatcher.dispatchEvent(ev);
|
||||
ev.setEdgeFlags(edgeFlags);
|
||||
}
|
||||
|
||||
mVelocityTracker.addMovement(ev);
|
||||
if (ev.getActionMasked() == ACTION_POINTER_UP) {
|
||||
mVelocityTracker.clear();
|
||||
mMotionPauseDetector.clear();
|
||||
}
|
||||
|
||||
switch (ev.getActionMasked()) {
|
||||
case ACTION_DOWN: {
|
||||
RaceConditionTracker.onEvent(DOWN_EVT, ENTER);
|
||||
TraceHelper.beginSection("TouchInt");
|
||||
mActivePointerId = ev.getPointerId(0);
|
||||
mDownPos.set(ev.getX(), ev.getY());
|
||||
mLastPos.set(mDownPos);
|
||||
|
||||
// Start the window animation on down to give more time for launcher to draw if the
|
||||
// user didn't start the gesture over the back button
|
||||
if (!mIsDeferredDownTarget) {
|
||||
startTouchTrackingForWindowAnimation(ev.getEventTime());
|
||||
}
|
||||
|
||||
RaceConditionTracker.onEvent(DOWN_EVT, EXIT);
|
||||
break;
|
||||
}
|
||||
case ACTION_POINTER_UP: {
|
||||
int ptrIdx = ev.getActionIndex();
|
||||
int ptrId = ev.getPointerId(ptrIdx);
|
||||
if (ptrId == mActivePointerId) {
|
||||
final int newPointerIdx = ptrIdx == 0 ? 1 : 0;
|
||||
mDownPos.set(
|
||||
ev.getX(newPointerIdx) - (mLastPos.x - mDownPos.x),
|
||||
ev.getY(newPointerIdx) - (mLastPos.y - mDownPos.y));
|
||||
mLastPos.set(ev.getX(newPointerIdx), ev.getY(newPointerIdx));
|
||||
mActivePointerId = ev.getPointerId(newPointerIdx);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ACTION_MOVE: {
|
||||
int pointerIndex = ev.findPointerIndex(mActivePointerId);
|
||||
if (pointerIndex == INVALID_POINTER_ID) {
|
||||
break;
|
||||
}
|
||||
mLastPos.set(ev.getX(pointerIndex), ev.getY(pointerIndex));
|
||||
float displacement = getDisplacement(ev);
|
||||
|
||||
if (!mPassedDragSlop) {
|
||||
if (!mIsDeferredDownTarget) {
|
||||
// Normal gesture, ensure we pass the drag slop before we start tracking
|
||||
// the gesture
|
||||
if (Math.abs(displacement) > mDragSlop) {
|
||||
mPassedDragSlop = true;
|
||||
mStartDisplacement = displacement;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!mPassedTouchSlop) {
|
||||
if (Math.hypot(mLastPos.x - mDownPos.x, mLastPos.y - mDownPos.y) >=
|
||||
mTouchSlop) {
|
||||
mPassedTouchSlop = true;
|
||||
|
||||
TOUCH_INTERACTION_LOG.startQuickStep();
|
||||
if (mIsDeferredDownTarget) {
|
||||
// Deferred gesture, start the animation and gesture tracking once
|
||||
// we pass the actual touch slop
|
||||
startTouchTrackingForWindowAnimation(ev.getEventTime());
|
||||
}
|
||||
if (!mPassedDragSlop) {
|
||||
mPassedDragSlop = true;
|
||||
mStartDisplacement = displacement;
|
||||
}
|
||||
notifyGestureStarted();
|
||||
}
|
||||
}
|
||||
|
||||
if (mPassedDragSlop && mInteractionHandler != null) {
|
||||
// Move
|
||||
mInteractionHandler.updateDisplacement(displacement - mStartDisplacement);
|
||||
|
||||
if (FeatureFlags.SWIPE_HOME.get()) {
|
||||
boolean isLandscape = isNavBarOnLeft() || isNavBarOnRight();
|
||||
float orthogonalDisplacement = !isLandscape
|
||||
? ev.getX() - mDownPos.x
|
||||
: ev.getY() - mDownPos.y;
|
||||
mMotionPauseDetector.addPosition(displacement, orthogonalDisplacement);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ACTION_CANCEL:
|
||||
// TODO: Should be different than ACTION_UP
|
||||
case ACTION_UP: {
|
||||
RaceConditionTracker.onEvent(UP_EVT, ENTER);
|
||||
TraceHelper.endSection("TouchInt");
|
||||
|
||||
finishTouchTracking(ev);
|
||||
RaceConditionTracker.onEvent(UP_EVT, EXIT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyGestureStarted() {
|
||||
if (mInteractionHandler == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mOverviewCallbacks.closeAllWindows();
|
||||
ActivityManagerWrapper.getInstance().closeSystemWindows(
|
||||
CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
|
||||
|
||||
// Notify the handler that the gesture has actually started
|
||||
mInteractionHandler.onGestureStarted();
|
||||
}
|
||||
|
||||
private boolean isNavBarOnRight() {
|
||||
return mDisplayRotation == Surface.ROTATION_90 && mStableInsets.right > 0;
|
||||
}
|
||||
|
||||
private boolean isNavBarOnLeft() {
|
||||
return mDisplayRotation == Surface.ROTATION_270 && mStableInsets.left > 0;
|
||||
}
|
||||
|
||||
private void startTouchTrackingForWindowAnimation(long touchTimeMs) {
|
||||
TOUCH_INTERACTION_LOG.startRecentsAnimation();
|
||||
|
||||
RecentsAnimationListenerSet listenerSet = mSwipeSharedState.getActiveListener();
|
||||
final WindowTransformSwipeHandler handler = new WindowTransformSwipeHandler(
|
||||
mRunningTask, this, touchTimeMs, mActivityControlHelper,
|
||||
listenerSet != null, mInputConsumer);
|
||||
|
||||
// Preload the plan
|
||||
mRecentsModel.getTasks(null);
|
||||
mInteractionHandler = handler;
|
||||
handler.setGestureEndCallback(this::onInteractionGestureFinished);
|
||||
mMotionPauseDetector.setOnMotionPauseListener(handler::onMotionPauseChanged);
|
||||
handler.initWhenReady();
|
||||
|
||||
if (listenerSet != null) {
|
||||
listenerSet.addListener(handler);
|
||||
mSwipeSharedState.applyActiveRecentsAnimationState(handler);
|
||||
} else {
|
||||
RecentsAnimationListenerSet newListenerSet =
|
||||
mSwipeSharedState.newRecentsAnimationListenerSet();
|
||||
newListenerSet.addListener(handler);
|
||||
BackgroundExecutor.get().submit(
|
||||
() -> ActivityManagerWrapper.getInstance().startRecentsActivity(
|
||||
mHomeIntent, null, newListenerSet, null, null));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the gesture has ended. Does not correlate to the completion of the interaction as
|
||||
* the animation can still be running.
|
||||
*/
|
||||
private void finishTouchTracking(MotionEvent ev) {
|
||||
if (mPassedDragSlop && mInteractionHandler != null) {
|
||||
|
||||
mVelocityTracker.computeCurrentVelocity(1000,
|
||||
ViewConfiguration.get(this).getScaledMaximumFlingVelocity());
|
||||
float velocityX = mVelocityTracker.getXVelocity(mActivePointerId);
|
||||
float velocity = isNavBarOnRight() ? velocityX
|
||||
: isNavBarOnLeft() ? -velocityX
|
||||
: mVelocityTracker.getYVelocity(mActivePointerId);
|
||||
|
||||
mInteractionHandler.updateDisplacement(getDisplacement(ev) - mStartDisplacement);
|
||||
mInteractionHandler.onGestureEnded(velocity, velocityX);
|
||||
} else {
|
||||
// Since we start touch tracking on DOWN, we may reach this state without actually
|
||||
// starting the gesture. In that case, just cleanup immediately.
|
||||
onConsumerAboutToBeSwitched();
|
||||
onInteractionGestureFinished();
|
||||
|
||||
// Also clean up in case the system has handled the UP and canceled the animation before
|
||||
// we had a chance to start the recents animation. In such a case, we will not receive
|
||||
ActivityManagerWrapper.getInstance().cancelRecentsAnimation(
|
||||
true /* restoreHomeStackPosition */);
|
||||
}
|
||||
mVelocityTracker.recycle();
|
||||
mVelocityTracker = null;
|
||||
mMotionPauseDetector.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConsumerAboutToBeSwitched() {
|
||||
Preconditions.assertUIThread();
|
||||
if (mInteractionHandler != null) {
|
||||
// The consumer is being switched while we are active. Set up the shared state to be
|
||||
// used by the next animation
|
||||
removeListener();
|
||||
GestureEndTarget endTarget = mInteractionHandler.mGestureEndTarget;
|
||||
mSwipeSharedState.canGestureBeContinued = endTarget != null && endTarget.canBeContinued;
|
||||
mSwipeSharedState.goingToLauncher = endTarget != null && endTarget.isLauncher;
|
||||
if (mSwipeSharedState.canGestureBeContinued) {
|
||||
mInteractionHandler.cancel();
|
||||
} else {
|
||||
mInteractionHandler.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void onInteractionGestureFinished() {
|
||||
Preconditions.assertUIThread();
|
||||
removeListener();
|
||||
mInteractionHandler = null;
|
||||
mOnCompleteCallback.accept(this);
|
||||
}
|
||||
|
||||
private void removeListener() {
|
||||
RecentsAnimationListenerSet listenerSet = mSwipeSharedState.getActiveListener();
|
||||
if (listenerSet != null) {
|
||||
listenerSet.removeListener(mInteractionHandler);
|
||||
}
|
||||
}
|
||||
|
||||
private float getDisplacement(MotionEvent ev) {
|
||||
float eventX = ev.getX();
|
||||
float eventY = ev.getY();
|
||||
float displacement = eventY - mDownPos.y;
|
||||
if (isNavBarOnRight()) {
|
||||
displacement = eventX - mDownPos.x;
|
||||
} else if (isNavBarOnLeft()) {
|
||||
displacement = mDownPos.x - eventX;
|
||||
}
|
||||
return displacement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return mInteractionHandler != null;
|
||||
}
|
||||
}
|
||||
@@ -1,276 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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;
|
||||
|
||||
import static android.view.MotionEvent.ACTION_DOWN;
|
||||
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_INPUT_CHANNEL;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.ActivityManager.RunningTaskInfo;
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Region;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.view.Choreographer;
|
||||
import android.view.InputEvent;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import com.android.launcher3.MainThreadExecutor;
|
||||
import com.android.launcher3.util.LooperExecutor;
|
||||
import com.android.launcher3.util.UiThreadHelper;
|
||||
import com.android.systemui.shared.recents.IOverviewProxy;
|
||||
import com.android.systemui.shared.recents.ISystemUiProxy;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.InputChannelCompat;
|
||||
import com.android.systemui.shared.system.InputChannelCompat.InputEventDispatcher;
|
||||
import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver;
|
||||
import com.android.systemui.shared.system.InputConsumerController;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* Service connected by system-UI for handling touch interaction.
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.O)
|
||||
public class TouchInteractionService extends Service {
|
||||
|
||||
public static final MainThreadExecutor MAIN_THREAD_EXECUTOR = new MainThreadExecutor();
|
||||
public static final LooperExecutor BACKGROUND_EXECUTOR =
|
||||
new LooperExecutor(UiThreadHelper.getBackgroundLooper());
|
||||
|
||||
public static final TouchInteractionLog TOUCH_INTERACTION_LOG = new TouchInteractionLog();
|
||||
|
||||
public static final int EDGE_NAV_BAR = 1 << 8;
|
||||
|
||||
private static final String TAG = "TouchInteractionService";
|
||||
|
||||
private final IBinder mMyBinder = new IOverviewProxy.Stub() {
|
||||
|
||||
public void onActiveNavBarRegionChanges(Region region) {
|
||||
mActiveNavBarRegion = region;
|
||||
}
|
||||
|
||||
public void onInitialize(Bundle bundle) {
|
||||
mISystemUiProxy = ISystemUiProxy.Stub
|
||||
.asInterface(bundle.getBinder(KEY_EXTRA_SYSUI_PROXY));
|
||||
mRecentsModel.setSystemUiProxy(mISystemUiProxy);
|
||||
mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy);
|
||||
|
||||
disposeEventHandlers();
|
||||
mInputEventReceiver = InputChannelCompat.fromBundle(bundle, KEY_EXTRA_INPUT_CHANNEL,
|
||||
Looper.getMainLooper(), mMainChoreographer,
|
||||
TouchInteractionService.this::onInputEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOverviewToggle() {
|
||||
mOverviewCommandHelper.onOverviewToggle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOverviewShown(boolean triggeredFromAltTab) {
|
||||
mOverviewCommandHelper.onOverviewShown(triggeredFromAltTab);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOverviewHidden(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
|
||||
if (triggeredFromAltTab && !triggeredFromHomeKey) {
|
||||
// onOverviewShownFromAltTab hides the overview and ends at the target app
|
||||
mOverviewCommandHelper.onOverviewHidden();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTip(int actionType, int viewType) {
|
||||
mOverviewCommandHelper.onTip(actionType, viewType);
|
||||
}
|
||||
|
||||
/** Deprecated methods **/
|
||||
public void onQuickStep(MotionEvent motionEvent) { }
|
||||
|
||||
public void onQuickScrubEnd() { }
|
||||
|
||||
public void onQuickScrubProgress(float progress) { }
|
||||
|
||||
public void onQuickScrubStart() { }
|
||||
|
||||
public void onPreMotionEvent(int downHitTarget) { }
|
||||
|
||||
public void onMotionEvent(MotionEvent ev) {
|
||||
if (mDeprecatedDispatcher == null) {
|
||||
ev.recycle();
|
||||
} else {
|
||||
mDeprecatedDispatcher.dispatch(ev);
|
||||
}
|
||||
}
|
||||
|
||||
public void onBind(ISystemUiProxy iSystemUiProxy) {
|
||||
mISystemUiProxy = iSystemUiProxy;
|
||||
mRecentsModel.setSystemUiProxy(mISystemUiProxy);
|
||||
mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy);
|
||||
|
||||
// On Bind is received before onInitialize which will dispose these handlers
|
||||
disposeEventHandlers();
|
||||
Pair<InputEventDispatcher, InputEventReceiver> pair = InputChannelCompat.createPair(
|
||||
"sysui-callbacks", Looper.getMainLooper(), mMainChoreographer,
|
||||
TouchInteractionService.this::onInputEvent);
|
||||
mDeprecatedDispatcher = pair.first;
|
||||
mInputEventReceiver = pair.second;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
private static boolean sConnected = false;
|
||||
|
||||
public static boolean isConnected() {
|
||||
return sConnected;
|
||||
}
|
||||
|
||||
private ActivityManagerWrapper mAM;
|
||||
private RecentsModel mRecentsModel;
|
||||
private ISystemUiProxy mISystemUiProxy;
|
||||
private OverviewCommandHelper mOverviewCommandHelper;
|
||||
private OverviewComponentObserver mOverviewComponentObserver;
|
||||
private OverviewInteractionState mOverviewInteractionState;
|
||||
private OverviewCallbacks mOverviewCallbacks;
|
||||
private TaskOverlayFactory mTaskOverlayFactory;
|
||||
private InputConsumerController mInputConsumer;
|
||||
private SwipeSharedState mSwipeSharedState;
|
||||
|
||||
private TouchConsumer mConsumer = TouchConsumer.NO_OP;
|
||||
private Choreographer mMainChoreographer;
|
||||
|
||||
private InputEventReceiver mInputEventReceiver;
|
||||
private Region mActiveNavBarRegion = new Region();
|
||||
|
||||
private InputEventDispatcher mDeprecatedDispatcher;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
mAM = ActivityManagerWrapper.getInstance();
|
||||
mRecentsModel = RecentsModel.INSTANCE.get(this);
|
||||
mOverviewComponentObserver = new OverviewComponentObserver(this);
|
||||
mMainChoreographer = Choreographer.getInstance();
|
||||
|
||||
mOverviewCommandHelper = new OverviewCommandHelper(this, mOverviewComponentObserver);
|
||||
mOverviewInteractionState = OverviewInteractionState.INSTANCE.get(this);
|
||||
mOverviewCallbacks = OverviewCallbacks.get(this);
|
||||
mTaskOverlayFactory = TaskOverlayFactory.INSTANCE.get(this);
|
||||
mSwipeSharedState = new SwipeSharedState(mOverviewComponentObserver);
|
||||
mInputConsumer = InputConsumerController.getRecentsAnimationInputConsumer();
|
||||
mInputConsumer.registerInputConsumer();
|
||||
|
||||
sConnected = true;
|
||||
|
||||
// Temporarily disable model preload
|
||||
// new ModelPreload().start(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
mInputConsumer.unregisterInputConsumer();
|
||||
mOverviewComponentObserver.onDestroy();
|
||||
disposeEventHandlers();
|
||||
sConnected = false;
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
private void disposeEventHandlers() {
|
||||
if (mInputEventReceiver != null) {
|
||||
mInputEventReceiver.dispose();
|
||||
mInputEventReceiver = null;
|
||||
}
|
||||
if (mDeprecatedDispatcher != null) {
|
||||
mDeprecatedDispatcher.dispose();
|
||||
mDeprecatedDispatcher = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
Log.d(TAG, "Touch service connected");
|
||||
return mMyBinder;
|
||||
}
|
||||
|
||||
private void onInputEvent(InputEvent ev) {
|
||||
if (!(ev instanceof MotionEvent)) {
|
||||
Log.e(TAG, "Unknown event " + ev);
|
||||
return;
|
||||
}
|
||||
MotionEvent event = (MotionEvent) ev;
|
||||
if (event.getAction() == ACTION_DOWN) {
|
||||
TOUCH_INTERACTION_LOG.prepareForNewGesture();
|
||||
boolean useSharedState = mConsumer.isActive();
|
||||
mConsumer.onConsumerAboutToBeSwitched();
|
||||
mConsumer = newConsumer(useSharedState, event);
|
||||
TOUCH_INTERACTION_LOG.setTouchConsumer(mConsumer);
|
||||
}
|
||||
TOUCH_INTERACTION_LOG.addMotionEvent(event);
|
||||
|
||||
mConsumer.accept(event);
|
||||
}
|
||||
|
||||
private TouchConsumer newConsumer(boolean useSharedState, MotionEvent event) {
|
||||
RunningTaskInfo runningTaskInfo = mAM.getRunningTask(0);
|
||||
if (!useSharedState) {
|
||||
mSwipeSharedState.clearAllState();
|
||||
}
|
||||
|
||||
if (runningTaskInfo == null && !mSwipeSharedState.goingToLauncher) {
|
||||
return TouchConsumer.NO_OP;
|
||||
} else if (mSwipeSharedState.goingToLauncher ||
|
||||
mOverviewComponentObserver.getActivityControlHelper().isResumed()) {
|
||||
return OverviewTouchConsumer.newInstance(
|
||||
mOverviewComponentObserver.getActivityControlHelper(), false);
|
||||
} else if (ENABLE_QUICKSTEP_LIVE_TILE.get() &&
|
||||
mOverviewComponentObserver.getActivityControlHelper().isInLiveTileMode()) {
|
||||
return OverviewTouchConsumer.newInstance(
|
||||
mOverviewComponentObserver.getActivityControlHelper(), false);
|
||||
} else {
|
||||
ActivityControlHelper activityControl =
|
||||
mOverviewComponentObserver.getActivityControlHelper();
|
||||
boolean shouldDefer = activityControl.deferStartingActivity(mActiveNavBarRegion, event);
|
||||
return new OtherActivityTouchConsumer(this, runningTaskInfo, mRecentsModel,
|
||||
mOverviewComponentObserver.getOverviewIntent(), activityControl,
|
||||
shouldDefer, mOverviewCallbacks, mTaskOverlayFactory, mInputConsumer,
|
||||
this::onConsumerInactive, mSwipeSharedState);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* To be called by the consumer when it's no longer active.
|
||||
*/
|
||||
private void onConsumerInactive(TouchConsumer caller) {
|
||||
if (mConsumer == caller) {
|
||||
mConsumer = TouchConsumer.NO_OP;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||
TOUCH_INTERACTION_LOG.dump(pw);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user