QuickCaptureInputConsumer -> OverscrollInputConsumer + plugin
Test: Implemented plugin interface in Compose studiow build in google_experimental, verified plugin shows up appropriately in Launcher's home settings screen, verified gesture works if Compose plugin enabled, and doesn't work if Compose plugin disabled. Bug: n/a Change-Id: Ica24ee8fe814ee02a1497a1bfbe7c7a24489b71e
This commit is contained in:
parent
d78d80beca
commit
9e57e74005
|
@ -35,6 +35,7 @@ import android.app.ActivityManager.RunningTaskInfo;
|
|||
import android.app.Service;
|
||||
import android.app.TaskInfo;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
|
@ -49,19 +50,18 @@ import android.view.InputEvent;
|
|||
import android.view.MotionEvent;
|
||||
|
||||
import androidx.annotation.BinderThread;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.UiThread;
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.allapps.DiscoveryBounce;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.logging.UserEventDispatcher;
|
||||
import com.android.launcher3.model.AppLaunchTracker;
|
||||
import com.android.launcher3.provider.RestoreDbTask;
|
||||
import com.android.launcher3.testing.TestProtocol;
|
||||
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
|
||||
import com.android.launcher3.util.TraceHelper;
|
||||
import com.android.quickstep.SysUINavigationMode.Mode;
|
||||
import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
|
||||
|
@ -70,12 +70,14 @@ import com.android.quickstep.inputconsumers.AssistantInputConsumer;
|
|||
import com.android.quickstep.inputconsumers.DeviceLockedInputConsumer;
|
||||
import com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer;
|
||||
import com.android.quickstep.inputconsumers.OtherActivityInputConsumer;
|
||||
import com.android.quickstep.inputconsumers.OverscrollInputConsumer;
|
||||
import com.android.quickstep.inputconsumers.OverviewInputConsumer;
|
||||
import com.android.quickstep.inputconsumers.OverviewWithoutFocusInputConsumer;
|
||||
import com.android.quickstep.inputconsumers.QuickCaptureInputConsumer;
|
||||
import com.android.quickstep.inputconsumers.ResetGestureInputConsumer;
|
||||
import com.android.quickstep.inputconsumers.ScreenPinnedInputConsumer;
|
||||
import com.android.quickstep.util.ActiveGestureLog;
|
||||
import com.android.systemui.plugins.OverscrollPlugin;
|
||||
import com.android.systemui.plugins.PluginListener;
|
||||
import com.android.systemui.shared.recents.IOverviewProxy;
|
||||
import com.android.systemui.shared.recents.ISystemUiProxy;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
|
@ -113,7 +115,7 @@ class ArgList extends LinkedList<String> {
|
|||
*/
|
||||
@TargetApi(Build.VERSION_CODES.Q)
|
||||
public class TouchInteractionService extends Service implements
|
||||
NavigationModeChangeListener {
|
||||
NavigationModeChangeListener, PluginListener<OverscrollPlugin> {
|
||||
|
||||
private static final String TAG = "TouchInteractionService";
|
||||
|
||||
|
@ -122,6 +124,8 @@ public class TouchInteractionService extends Service implements
|
|||
private static final String HAS_ENABLED_QUICKSTEP_ONCE = "launcher.has_enabled_quickstep_once";
|
||||
private static final int MAX_BACK_NOTIFICATION_COUNT = 3;
|
||||
private int mBackGestureNotificationCounter = -1;
|
||||
@Nullable
|
||||
private OverscrollPlugin mOverscrollPlugin;
|
||||
|
||||
private final IBinder mMyBinder = new IOverviewProxy.Stub() {
|
||||
|
||||
|
@ -280,6 +284,9 @@ public class TouchInteractionService extends Service implements
|
|||
|
||||
onNavigationModeChanged(SysUINavigationMode.INSTANCE.get(this).addModeChangeListener(this));
|
||||
sConnected = true;
|
||||
|
||||
PluginManagerWrapper.INSTANCE.get(getBaseContext()).addPluginListener(this,
|
||||
OverscrollPlugin.class, false /* allowMultiple */);
|
||||
}
|
||||
|
||||
private void disposeEventHandlers() {
|
||||
|
@ -400,6 +407,9 @@ public class TouchInteractionService extends Service implements
|
|||
if (TestProtocol.sDebugTracing) {
|
||||
Log.d(TestProtocol.LAUNCHER_DIDNT_INITIALIZE, "TIS destroyed");
|
||||
}
|
||||
|
||||
PluginManagerWrapper.INSTANCE.get(getBaseContext()).removePluginListener(this);
|
||||
|
||||
sIsInitialized = false;
|
||||
if (mDeviceState.isUserUnlocked()) {
|
||||
mInputConsumer.unregisterInputConsumer();
|
||||
|
@ -489,10 +499,10 @@ public class TouchInteractionService extends Service implements
|
|||
base = new AssistantInputConsumer(this, newGestureState, base, mInputMonitorCompat);
|
||||
}
|
||||
|
||||
if (FeatureFlags.ENABLE_QUICK_CAPTURE_GESTURE.get()) {
|
||||
// Put the Compose gesture as higher priority than the Assistant or base gestures
|
||||
base = new QuickCaptureInputConsumer(this, newGestureState, base,
|
||||
mInputMonitorCompat);
|
||||
if (mOverscrollPlugin != null) {
|
||||
// Put the overscroll gesture as higher priority than the Assistant or base gestures
|
||||
base = new OverscrollInputConsumer(this, newGestureState, base, mInputMonitorCompat,
|
||||
mOverscrollPlugin);
|
||||
}
|
||||
|
||||
if (mDeviceState.isScreenPinningActive()) {
|
||||
|
@ -531,9 +541,9 @@ public class TouchInteractionService extends Service implements
|
|||
() -> mAM.getRunningTask(ACTIVITY_TYPE_ASSISTANT));
|
||||
if (!ActivityManagerWrapper.isHomeTask(runningTaskInfo)) {
|
||||
final ComponentName homeComponent =
|
||||
mOverviewComponentObserver.getHomeIntent().getComponent();
|
||||
mOverviewComponentObserver.getHomeIntent().getComponent();
|
||||
forceOverviewInputConsumer =
|
||||
runningTaskInfo.baseIntent.getComponent(). equals(homeComponent);
|
||||
runningTaskInfo.baseIntent.getComponent().equals(homeComponent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -763,4 +773,14 @@ public class TouchInteractionService extends Service implements
|
|||
UI_HELPER_EXECUTOR.execute(() -> ActivityManagerWrapper.getInstance()
|
||||
.startRecentsActivity(intent, null, listener, null, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPluginConnected(OverscrollPlugin overscrollPlugin, Context context) {
|
||||
mOverscrollPlugin = overscrollPlugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPluginDisconnected(OverscrollPlugin overscrollPlugin) {
|
||||
mOverscrollPlugin = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,39 +24,28 @@ import static android.view.MotionEvent.ACTION_UP;
|
|||
|
||||
import static com.android.launcher3.Utilities.squaredHypot;
|
||||
|
||||
import android.app.ActivityOptions;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.PointF;
|
||||
import android.os.Bundle;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.quickstep.GestureState;
|
||||
import com.android.quickstep.InputConsumer;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.systemui.plugins.OverscrollPlugin;
|
||||
import com.android.systemui.shared.system.InputMonitorCompat;
|
||||
|
||||
/**
|
||||
* Input consumer for handling events to launch quick capture from launcher
|
||||
* Input consumer for handling events to pass to an {@code OverscrollPlugin}.
|
||||
*
|
||||
* @param <T> Draggable activity subclass used by RecentsView
|
||||
*/
|
||||
public class QuickCaptureInputConsumer<T extends BaseDraggingActivity>
|
||||
extends DelegateInputConsumer {
|
||||
public class OverscrollInputConsumer<T extends BaseDraggingActivity> extends DelegateInputConsumer {
|
||||
|
||||
private static final String TAG = "QuickCaptureInputConsumer";
|
||||
|
||||
private static final String QUICK_CAPTURE_PACKAGE = "com.google.auxe.compose";
|
||||
private static final String QUICK_CAPTURE_PACKAGE_DEV = "com.google.auxe.compose.debug";
|
||||
|
||||
private static final String EXTRA_DEVICE_STATE = "deviceState";
|
||||
private static final String DEVICE_STATE_LOCKED = "Locked";
|
||||
private static final String DEVICE_STATE_LAUNCHER = "Launcher";
|
||||
private static final String DEVICE_STATE_APP = "App";
|
||||
private static final String DEVICE_STATE_UNKNOWN = "Unknown";
|
||||
private static final String TAG = "OverscrollInputConsumer";
|
||||
|
||||
private static final int ANGLE_THRESHOLD = 35; // Degrees
|
||||
|
||||
|
@ -71,14 +60,16 @@ public class QuickCaptureInputConsumer<T extends BaseDraggingActivity>
|
|||
|
||||
private final Context mContext;
|
||||
private final GestureState mGestureState;
|
||||
@Nullable private final OverscrollPlugin mPlugin;
|
||||
|
||||
private RecentsView mRecentsView;
|
||||
|
||||
public QuickCaptureInputConsumer(Context context, GestureState gestureState,
|
||||
InputConsumer delegate, InputMonitorCompat inputMonitor) {
|
||||
public OverscrollInputConsumer(Context context, GestureState gestureState,
|
||||
InputConsumer delegate, InputMonitorCompat inputMonitor, OverscrollPlugin plugin) {
|
||||
super(delegate, inputMonitor);
|
||||
mContext = context;
|
||||
mGestureState = gestureState;
|
||||
mPlugin = plugin;
|
||||
|
||||
float slop = ViewConfiguration.get(context).getScaledTouchSlop();
|
||||
mSquaredSlop = slop * slop;
|
||||
|
@ -89,7 +80,7 @@ public class QuickCaptureInputConsumer<T extends BaseDraggingActivity>
|
|||
|
||||
@Override
|
||||
public int getType() {
|
||||
return TYPE_QUICK_CAPTURE | mDelegate.getType();
|
||||
return TYPE_OVERSCROLL | mDelegate.getType();
|
||||
}
|
||||
|
||||
private boolean onActivityInit(Boolean alreadyOnHome) {
|
||||
|
@ -149,7 +140,7 @@ public class QuickCaptureInputConsumer<T extends BaseDraggingActivity>
|
|||
mPassedSlop = true;
|
||||
mStartDragPos.set(mLastPos.x, mLastPos.y);
|
||||
|
||||
if (isValidQuickCaptureGesture()) {
|
||||
if (isOverscrolled()) {
|
||||
setActive(ev);
|
||||
} else {
|
||||
mState = STATE_DELEGATE_ACTIVE;
|
||||
|
@ -161,8 +152,8 @@ public class QuickCaptureInputConsumer<T extends BaseDraggingActivity>
|
|||
}
|
||||
case ACTION_CANCEL:
|
||||
case ACTION_UP:
|
||||
if (mState != STATE_DELEGATE_ACTIVE && mPassedSlop) {
|
||||
startQuickCapture();
|
||||
if (mState != STATE_DELEGATE_ACTIVE && mPassedSlop && mPlugin != null) {
|
||||
mPlugin.onOverscroll(getDeviceState());
|
||||
}
|
||||
|
||||
mPassedSlop = false;
|
||||
|
@ -175,7 +166,7 @@ public class QuickCaptureInputConsumer<T extends BaseDraggingActivity>
|
|||
}
|
||||
}
|
||||
|
||||
private boolean isValidQuickCaptureGesture() {
|
||||
private boolean isOverscrolled() {
|
||||
// Make sure there isn't an app to quick switch to on our right
|
||||
boolean atRightMostApp = (mRecentsView == null || mRecentsView.getRunningTaskIndex() <= 0);
|
||||
|
||||
|
@ -187,37 +178,19 @@ public class QuickCaptureInputConsumer<T extends BaseDraggingActivity>
|
|||
return atRightMostApp && angleInBounds;
|
||||
}
|
||||
|
||||
private void startQuickCapture() {
|
||||
// Inspect our delegate's type to figure out where the user invoked Compose
|
||||
String deviceState = DEVICE_STATE_UNKNOWN;
|
||||
private String getDeviceState() {
|
||||
String deviceState = OverscrollPlugin.DEVICE_STATE_UNKNOWN;
|
||||
int consumerType = mDelegate.getType();
|
||||
if (((consumerType & InputConsumer.TYPE_OVERVIEW) > 0)
|
||||
|| ((consumerType & InputConsumer.TYPE_OVERVIEW_WITHOUT_FOCUS)) > 0) {
|
||||
deviceState = DEVICE_STATE_LAUNCHER;
|
||||
deviceState = OverscrollPlugin.DEVICE_STATE_LAUNCHER;
|
||||
} else if ((consumerType & InputConsumer.TYPE_OTHER_ACTIVITY) > 0) {
|
||||
deviceState = DEVICE_STATE_APP;
|
||||
deviceState = OverscrollPlugin.DEVICE_STATE_APP;
|
||||
} else if (((consumerType & InputConsumer.TYPE_RESET_GESTURE) > 0)
|
||||
|| ((consumerType & InputConsumer.TYPE_DEVICE_LOCKED) > 0)) {
|
||||
deviceState = DEVICE_STATE_LOCKED;
|
||||
deviceState = OverscrollPlugin.DEVICE_STATE_LOCKED;
|
||||
}
|
||||
|
||||
// Then launch the app
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
|
||||
Intent qcIntent = pm.getLaunchIntentForPackage(QUICK_CAPTURE_PACKAGE);
|
||||
|
||||
if (qcIntent == null) {
|
||||
// If we couldn't find the regular app, try the dev version
|
||||
qcIntent = pm.getLaunchIntentForPackage(QUICK_CAPTURE_PACKAGE_DEV);
|
||||
}
|
||||
|
||||
if (qcIntent != null) {
|
||||
qcIntent.putExtra(EXTRA_DEVICE_STATE, deviceState);
|
||||
|
||||
Bundle options = ActivityOptions.makeCustomAnimation(mContext, R.anim.slide_in_right,
|
||||
0).toBundle();
|
||||
|
||||
mContext.startActivity(qcIntent, options);
|
||||
}
|
||||
return deviceState;
|
||||
}
|
||||
}
|
|
@ -33,7 +33,7 @@ public interface InputConsumer {
|
|||
int TYPE_SCREEN_PINNED = 1 << 6;
|
||||
int TYPE_OVERVIEW_WITHOUT_FOCUS = 1 << 7;
|
||||
int TYPE_RESET_GESTURE = 1 << 8;
|
||||
int TYPE_QUICK_CAPTURE = 1 << 9;
|
||||
int TYPE_OVERSCROLL = 1 << 9;
|
||||
|
||||
String[] NAMES = new String[] {
|
||||
"TYPE_NO_OP", // 0
|
||||
|
@ -45,7 +45,7 @@ public interface InputConsumer {
|
|||
"TYPE_SCREEN_PINNED", // 6
|
||||
"TYPE_OVERVIEW_WITHOUT_FOCUS", // 7
|
||||
"TYPE_RESET_GESTURE", // 8
|
||||
"TYPE_QUICK_CAPTURE", // 9
|
||||
"TYPE_OVERSCROLL", // 9
|
||||
};
|
||||
|
||||
InputConsumer NO_OP = () -> TYPE_NO_OP;
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shareInterpolator="false" >
|
||||
<translate
|
||||
android:duration="@android:integer/config_shortAnimTime"
|
||||
android:fromXDelta="100%"
|
||||
android:toXDelta="0%"
|
||||
/>
|
||||
</set>
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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.systemui.plugins;
|
||||
|
||||
import com.android.systemui.plugins.annotations.ProvidesInterface;
|
||||
|
||||
/**
|
||||
* Implement this interface to receive a callback when the user swipes right
|
||||
* to left on the gesture area. It won't fire if the user has quick switched to a previous app
|
||||
* (swiped right) and the current app isn't yet the active one (i.e., if swiping left would take
|
||||
* the user to a more recent app).
|
||||
*/
|
||||
@ProvidesInterface(action = com.android.systemui.plugins.OverscrollPlugin.ACTION,
|
||||
version = com.android.systemui.plugins.OverlayPlugin.VERSION)
|
||||
public interface OverscrollPlugin extends Plugin {
|
||||
|
||||
String ACTION = "com.android.systemui.action.PLUGIN_LAUNCHER_OVERSCROLL";
|
||||
int VERSION = 1;
|
||||
|
||||
String DEVICE_STATE_LOCKED = "Locked";
|
||||
String DEVICE_STATE_LAUNCHER = "Launcher";
|
||||
String DEVICE_STATE_APP = "App";
|
||||
String DEVICE_STATE_UNKNOWN = "Unknown";
|
||||
|
||||
/**
|
||||
* Called when the user completed a right to left swipe in the gesture area.
|
||||
*
|
||||
* @param deviceState One of the DEVICE_STATE_* constants.
|
||||
*/
|
||||
void onOverscroll(String deviceState);
|
||||
}
|
Loading…
Reference in New Issue