Added assistant gesture swipe up right side region on nav bar

Bug: 112934365
Test: manual
Change-Id: I467e71f13da4afba3a556fafb0bfdf01650ab4bf
This commit is contained in:
Matthew Ng 2019-02-20 16:43:12 -08:00
parent 7419d8174d
commit 077c29e091
5 changed files with 208 additions and 0 deletions

Binary file not shown.

View File

@ -0,0 +1,195 @@
/*
* 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;
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 android.content.Context;
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import com.android.systemui.shared.recents.ISystemUiProxy;
import com.android.systemui.shared.system.NavigationBarCompat;
import com.android.systemui.shared.system.WindowManagerWrapper;
import com.android.launcher3.R;
/**
* Touch consumer for handling events to launch assistant from launcher
*/
public class AssistantTouchConsumer implements InputConsumer {
private static final String TAG = "AssistantTouchConsumer";
private final PointF mDownPos = new PointF();
private final PointF mLastPos = new PointF();
private int mActivePointerId = -1;
private final int mDisplayRotation;
private final Rect mStableInsets = new Rect();
private final float mDragSlop;
private final float mTouchSlop;
private final float mThreshold;
private float mStartDisplacement;
private boolean mPassedDragSlop;
private boolean mPassedTouchSlop;
private long mPassedTouchSlopTime;
private boolean mLaunchedAssistant;
private float mLastProgress;
private final ISystemUiProxy mSysUiProxy;
public AssistantTouchConsumer(Context context, ISystemUiProxy systemUiProxy) {
mSysUiProxy = systemUiProxy;
mDragSlop = NavigationBarCompat.getQuickStepDragSlopPx();
mTouchSlop = NavigationBarCompat.getQuickStepTouchSlopPx();
mThreshold = context.getResources().getDimension(R.dimen.gestures_assistant_threshold);
Display display = context.getSystemService(WindowManager.class).getDefaultDisplay();
mDisplayRotation = display.getRotation();
WindowManagerWrapper.getInstance().getStableInsets(mStableInsets);
}
@Override
public void onMotionEvent(MotionEvent ev) {
// TODO add logging
switch (ev.getActionMasked()) {
case ACTION_DOWN: {
mActivePointerId = ev.getPointerId(0);
mDownPos.set(ev.getX(), ev.getY());
mLastPos.set(mDownPos);
mLastProgress = -1;
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 == -1) {
break;
}
mLastPos.set(ev.getX(pointerIndex), ev.getY(pointerIndex));
float displacement = getDisplacement(ev);
if (!mPassedDragSlop) {
// Normal gesture, ensure we pass the drag slop before we start tracking
// the gesture
if (Math.abs(displacement) > mDragSlop) {
mPassedDragSlop = true;
mStartDisplacement = displacement;
mPassedTouchSlopTime = SystemClock.uptimeMillis();
}
}
if (!mPassedTouchSlop) {
if (Math.hypot(mLastPos.x - mDownPos.x, mLastPos.y - mDownPos.y) >=
mTouchSlop) {
mPassedTouchSlop = true;
if (!mPassedDragSlop) {
mPassedDragSlop = true;
mStartDisplacement = displacement;
mPassedTouchSlopTime = SystemClock.uptimeMillis();
}
}
}
if (mPassedDragSlop) {
// Move
float distance = mStartDisplacement - displacement;
if (distance >= 0) {
onAssistantProgress(distance / mThreshold);
}
}
break;
}
case ACTION_CANCEL:
break;
case ACTION_UP: {
if (ev.getEventTime() - mPassedTouchSlopTime < ViewConfiguration.getTapTimeout()) {
onAssistantProgress(1);
}
break;
}
}
}
private void onAssistantProgress(float progress) {
if (mLastProgress == progress) {
return;
}
try {
mSysUiProxy.onAssistantProgress(Math.max(0, Math.min(1, progress)));
if (progress >= 1 && !mLaunchedAssistant) {
mSysUiProxy.startAssistant(new Bundle());
mLaunchedAssistant = true;
}
mLastProgress = progress;
} catch (RemoteException e) {
Log.w(TAG, "Failed to notify SysUI to start/send assistant progress: " + progress, e);
}
}
private boolean isNavBarOnRight() {
return mDisplayRotation == Surface.ROTATION_90 && mStableInsets.right > 0;
}
private boolean isNavBarOnLeft() {
return mDisplayRotation == Surface.ROTATION_270 && mStableInsets.left > 0;
}
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;
}
static boolean withinTouchRegion(Context context, float x) {
return x > context.getResources().getDisplayMetrics().widthPixels
- context.getResources().getDimension(R.dimen.gestures_assistant_width);
}
}

View File

@ -44,6 +44,7 @@ import android.view.MotionEvent;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.Utilities;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.LooperExecutor;
import com.android.launcher3.util.UiThreadHelper;
import com.android.systemui.shared.recents.IOverviewProxy;
@ -307,6 +308,10 @@ public class TouchInteractionService extends Service {
if (runningTaskInfo == null && !mSwipeSharedState.goingToLauncher) {
return InputConsumer.NO_OP;
} else if (mOverviewInteractionState.isSwipeUpGestureEnabled()
&& FeatureFlags.ENABLE_ASSISTANT_GESTURE.get()
&& AssistantTouchConsumer.withinTouchRegion(this, event.getX())) {
return new AssistantTouchConsumer(this, mRecentsModel.getSystemUiProxy());
} else if (mSwipeSharedState.goingToLauncher ||
mOverviewComponentObserver.getActivityControlHelper().isResumed()) {
return OverviewInputConsumer.newInstance(

View File

@ -65,4 +65,8 @@
<dimen name="shelf_surface_radius">16dp</dimen>
<!-- same as vertical_drag_handle_size -->
<dimen name="shelf_surface_offset">24dp</dimen>
<!-- Assistant Gestures -->
<dimen name="gestures_assistant_width">70dp</dimen>
<dimen name="gestures_assistant_threshold">200dp</dimen>
</resources>

View File

@ -112,6 +112,10 @@ abstract class BaseFlags {
"ENABLE_HINTS_IN_OVERVIEW", false,
"Show chip hints and gleams on the overview screen");
public static final TogglableFlag ENABLE_ASSISTANT_GESTURE = new TogglableFlag(
"ENABLE_ASSISTANT_GESTURE", false,
"Enable swipe up from the bottom right corner to start assistant");
public static void initialize(Context context) {
// Avoid the disk read for user builds
if (Utilities.IS_DEBUG_DEVICE) {