Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6d2bb0b5 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Added assistant gesture swipe up right side region on nav bar" into ub-launcher3-master

parents dd79438e 077c29e0
Loading
Loading
Loading
Loading
+760 B (152 KiB)

File changed.

No diff preview for this file type.

+195 −0
Original line number Diff line number Diff line
/*
 * 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);
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -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(
+4 −0
Original line number Diff line number Diff line
@@ -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>
+4 −0
Original line number Diff line number Diff line
@@ -116,6 +116,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) {