Support individual lock task features
- If screen pinning is enabled, disable gestures and wrap with input consumer to break out of screen pinning (existing logic) - If Home & Overview are both disabled, disable gestures completely - If only Home is disabled, then always launch the user into fallback recents (to simplify logic around breaking out of overview into Home) - If only Overview is disabled, then prevent swiping from going into overview or from triggering overview from home - Switch to using screen pinning flag check instead of binder call Bug: 133113732 Bug: 131698989 Change-Id: Ie6f447520d4cc3fa1eaaf8427ee014851688bf37
This commit is contained in:
+5
-1
@@ -22,6 +22,7 @@ import static com.android.launcher3.LauncherState.OVERVIEW_PEEK;
|
||||
import static com.android.launcher3.LauncherStateManager.ANIM_ALL;
|
||||
import static com.android.launcher3.LauncherStateManager.ATOMIC_OVERVIEW_PEEK_COMPONENT;
|
||||
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
@@ -34,8 +35,10 @@ import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.anim.AnimatorSetBuilder;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
|
||||
import com.android.quickstep.OverviewInteractionState;
|
||||
import com.android.quickstep.util.MotionPauseDetector;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.systemui.shared.system.QuickStepContract;
|
||||
|
||||
/**
|
||||
* Touch controller which handles swipe and hold to go to Overview
|
||||
@@ -99,7 +102,8 @@ public class FlingAndHoldTouchController extends PortraitStatesTouchController {
|
||||
* having it as part of the existing animation to the target state.
|
||||
*/
|
||||
private boolean handlingOverviewAnim() {
|
||||
return mStartState == NORMAL;
|
||||
int stateFlags = OverviewInteractionState.INSTANCE.get(mLauncher).getSystemUiStateFlags();
|
||||
return mStartState == NORMAL && (stateFlags & SYSUI_STATE_OVERVIEW_DISABLED) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+7
@@ -30,6 +30,7 @@ import static com.android.launcher3.anim.Interpolators.INSTANT;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW;
|
||||
import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
|
||||
|
||||
import android.view.MotionEvent;
|
||||
|
||||
@@ -44,10 +45,12 @@ import com.android.launcher3.touch.AbstractStateChangeTouchController;
|
||||
import com.android.launcher3.touch.SwipeDetector;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
|
||||
import com.android.quickstep.OverviewInteractionState;
|
||||
import com.android.quickstep.SysUINavigationMode;
|
||||
import com.android.quickstep.SysUINavigationMode.Mode;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.systemui.shared.system.QuickStepContract;
|
||||
|
||||
/**
|
||||
* Handles quick switching to a recent task from the home screen.
|
||||
@@ -80,6 +83,10 @@ public class QuickSwitchTouchController extends AbstractStateChangeTouchControll
|
||||
|
||||
@Override
|
||||
protected LauncherState getTargetState(LauncherState fromState, boolean isDragTowardPositive) {
|
||||
int stateFlags = OverviewInteractionState.INSTANCE.get(mLauncher).getSystemUiStateFlags();
|
||||
if ((stateFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0) {
|
||||
return NORMAL;
|
||||
}
|
||||
return isDragTowardPositive ? QUICK_SWITCH : NORMAL;
|
||||
}
|
||||
|
||||
|
||||
+21
-19
@@ -22,8 +22,11 @@ import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_INP
|
||||
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.ActivityManager;
|
||||
@@ -79,6 +82,7 @@ import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver;
|
||||
import com.android.systemui.shared.system.InputConsumerController;
|
||||
import com.android.systemui.shared.system.InputMonitorCompat;
|
||||
import com.android.systemui.shared.system.QuickStepContract;
|
||||
import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
@@ -197,6 +201,8 @@ public class TouchInteractionService extends Service implements
|
||||
|
||||
public void onSystemUiStateChanged(int stateFlags) {
|
||||
mSystemUiStateFlags = stateFlags;
|
||||
mOverviewInteractionState.setSystemUiStateFlags(stateFlags);
|
||||
mOverviewComponentObserver.onSystemUiStateChanged(stateFlags);
|
||||
}
|
||||
|
||||
/** Deprecated methods **/
|
||||
@@ -472,16 +478,13 @@ public class TouchInteractionService extends Service implements
|
||||
|
||||
private boolean validSystemUiFlags() {
|
||||
return (mSystemUiStateFlags & SYSUI_STATE_NAV_BAR_HIDDEN) == 0
|
||||
&& (mSystemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) == 0;
|
||||
}
|
||||
|
||||
private boolean topTaskLocked() {
|
||||
return ActivityManagerWrapper.getInstance().isLockToAppActive();
|
||||
&& (mSystemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) == 0
|
||||
&& ((mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) == 0
|
||||
|| (mSystemUiStateFlags & SYSUI_STATE_OVERVIEW_DISABLED) == 0);
|
||||
}
|
||||
|
||||
private InputConsumer newConsumer(boolean useSharedState, MotionEvent event) {
|
||||
boolean topTaskLocked = topTaskLocked();
|
||||
boolean isInValidSystemUiState = validSystemUiFlags() && !topTaskLocked;
|
||||
boolean isInValidSystemUiState = validSystemUiFlags();
|
||||
|
||||
if (!mIsUserUnlocked) {
|
||||
if (isInValidSystemUiState) {
|
||||
@@ -498,13 +501,15 @@ public class TouchInteractionService extends Service implements
|
||||
if (mMode == Mode.NO_BUTTON) {
|
||||
final ActivityControlHelper activityControl =
|
||||
mOverviewComponentObserver.getActivityControlHelper();
|
||||
if (mAssistantAvailable && !topTaskLocked
|
||||
&& AssistantTouchConsumer.withinTouchRegion(this, event)) {
|
||||
if (mAssistantAvailable
|
||||
&& !QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags)
|
||||
&& AssistantTouchConsumer.withinTouchRegion(this, event)
|
||||
&& !ActivityManagerWrapper.getInstance().isLockToAppActive()) {
|
||||
base = new AssistantTouchConsumer(this, mISystemUiProxy, activityControl, base,
|
||||
mInputMonitorCompat);
|
||||
}
|
||||
|
||||
if (ActivityManagerWrapper.getInstance().isScreenPinningActive()) {
|
||||
if ((mSystemUiStateFlags & SYSUI_STATE_SCREEN_PINNING) != 0) {
|
||||
// Note: we only allow accessibility to wrap this, and it replaces the previous
|
||||
// base input consumer (which should be NO_OP anyway since topTaskLocked == true).
|
||||
base = new ScreenPinnedInputConsumer(this, mISystemUiProxy, activityControl);
|
||||
@@ -593,17 +598,14 @@ public class TouchInteractionService extends Service implements
|
||||
// Dump everything
|
||||
pw.println("TouchState:");
|
||||
pw.println(" navMode=" + mMode);
|
||||
pw.println(" validSystemUiFlags=" + validSystemUiFlags()
|
||||
+ " flags=" + mSystemUiStateFlags);
|
||||
pw.println(" topTaskLocked=" + topTaskLocked());
|
||||
pw.println(" validSystemUiFlags=" + validSystemUiFlags());
|
||||
pw.println(" systemUiFlags=" + mSystemUiStateFlags);
|
||||
pw.println(" systemUiFlagsDesc="
|
||||
+ QuickStepContract.getSystemUiStateString(mSystemUiStateFlags));
|
||||
pw.println(" isDeviceLocked=" + mKM.isDeviceLocked());
|
||||
pw.println(" screenPinned=" +
|
||||
ActivityManagerWrapper.getInstance().isScreenPinningActive());
|
||||
pw.println(" assistantAvailable=" + mAssistantAvailable);
|
||||
pw.println(" a11yClickable="
|
||||
+ ((mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0));
|
||||
pw.println(" a11yLongClickable="
|
||||
+ ((mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0));
|
||||
pw.println(" assistantDisabled="
|
||||
+ QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags));
|
||||
pw.println(" resumed="
|
||||
+ mOverviewComponentObserver.getActivityControlHelper().isResumed());
|
||||
pw.println(" useSharedState=" + mConsumer.useSharedSwipeState());
|
||||
|
||||
+33
-17
@@ -39,6 +39,7 @@ import static com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget
|
||||
import static com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget.NEW_TASK;
|
||||
import static com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget.RECENTS;
|
||||
import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorSet;
|
||||
@@ -105,6 +106,7 @@ import com.android.quickstep.views.TaskView;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
import com.android.systemui.shared.system.InputConsumerController;
|
||||
import com.android.systemui.shared.system.LatencyTrackerCompat;
|
||||
import com.android.systemui.shared.system.QuickStepContract;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
|
||||
import com.android.systemui.shared.system.WindowCallbacksCompat;
|
||||
@@ -835,16 +837,9 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void handleNormalGestureEnd(float endVelocity, boolean isFling, PointF velocity,
|
||||
private GestureEndTarget calculateEndTarget(PointF velocity, float endVelocity, boolean isFling,
|
||||
boolean isCancel) {
|
||||
PointF velocityPxPerMs = new PointF(velocity.x / 1000, velocity.y / 1000);
|
||||
long duration = MAX_SWIPE_DURATION;
|
||||
float currentShift = mCurrentShift.value;
|
||||
final GestureEndTarget endTarget;
|
||||
float endShift;
|
||||
final float startShift;
|
||||
Interpolator interpolator = DEACCEL;
|
||||
final boolean goingToNewTask;
|
||||
if (mRecentsView != null) {
|
||||
if (!mRecentsAnimationWrapper.hasTargets()) {
|
||||
@@ -859,7 +854,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
} else {
|
||||
goingToNewTask = false;
|
||||
}
|
||||
final boolean reachedOverviewThreshold = currentShift >= MIN_PROGRESS_FOR_OVERVIEW;
|
||||
final boolean reachedOverviewThreshold = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW;
|
||||
if (!isFling) {
|
||||
if (isCancel) {
|
||||
endTarget = LAST_TASK;
|
||||
@@ -869,7 +864,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
} else if (goingToNewTask) {
|
||||
endTarget = NEW_TASK;
|
||||
} else {
|
||||
endTarget = currentShift < MIN_PROGRESS_FOR_OVERVIEW ? LAST_TASK : HOME;
|
||||
endTarget = !reachedOverviewThreshold ? LAST_TASK : HOME;
|
||||
}
|
||||
} else {
|
||||
endTarget = reachedOverviewThreshold && mGestureStarted
|
||||
@@ -878,12 +873,6 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
? NEW_TASK
|
||||
: LAST_TASK;
|
||||
}
|
||||
endShift = endTarget.endShift;
|
||||
long expectedDuration = Math.abs(Math.round((endShift - currentShift)
|
||||
* MAX_SWIPE_DURATION * SWIPE_DURATION_MULTIPLIER));
|
||||
duration = Math.min(MAX_SWIPE_DURATION, expectedDuration);
|
||||
startShift = currentShift;
|
||||
interpolator = endTarget == RECENTS ? OVERSHOOT_1_2 : DEACCEL;
|
||||
} else {
|
||||
if (mMode == Mode.NO_BUTTON && endVelocity < 0 && !mIsShelfPeeking) {
|
||||
// If swiping at a diagonal, base end target on the faster velocity.
|
||||
@@ -896,7 +885,34 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
} else {
|
||||
endTarget = goingToNewTask ? NEW_TASK : LAST_TASK;
|
||||
}
|
||||
endShift = endTarget.endShift;
|
||||
}
|
||||
|
||||
int stateFlags = OverviewInteractionState.INSTANCE.get(mActivity).getSystemUiStateFlags();
|
||||
if ((stateFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0
|
||||
&& (endTarget == RECENTS || endTarget == LAST_TASK)) {
|
||||
return LAST_TASK;
|
||||
}
|
||||
return endTarget;
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void handleNormalGestureEnd(float endVelocity, boolean isFling, PointF velocity,
|
||||
boolean isCancel) {
|
||||
PointF velocityPxPerMs = new PointF(velocity.x / 1000, velocity.y / 1000);
|
||||
long duration = MAX_SWIPE_DURATION;
|
||||
float currentShift = mCurrentShift.value;
|
||||
final GestureEndTarget endTarget = calculateEndTarget(velocity, endVelocity,
|
||||
isFling, isCancel);
|
||||
float endShift = endTarget.endShift;
|
||||
final float startShift;
|
||||
Interpolator interpolator = DEACCEL;
|
||||
if (!isFling) {
|
||||
long expectedDuration = Math.abs(Math.round((endShift - currentShift)
|
||||
* MAX_SWIPE_DURATION * SWIPE_DURATION_MULTIPLIER));
|
||||
duration = Math.min(MAX_SWIPE_DURATION, expectedDuration);
|
||||
startShift = currentShift;
|
||||
interpolator = endTarget == RECENTS ? OVERSHOOT_1_2 : DEACCEL;
|
||||
} else {
|
||||
startShift = Utilities.boundToRange(currentShift - velocityPxPerMs.y
|
||||
* SINGLE_FRAME_MS / mTransitionDragLength, 0, 1);
|
||||
float minFlingVelocity = mContext.getResources()
|
||||
|
||||
+6
@@ -26,6 +26,7 @@ import static com.android.launcher3.anim.Interpolators.ACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
|
||||
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.animation.ValueAnimator;
|
||||
@@ -46,9 +47,11 @@ import com.android.launcher3.touch.SwipeDetector;
|
||||
import com.android.launcher3.uioverrides.states.OverviewState;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
|
||||
import com.android.quickstep.OverviewInteractionState;
|
||||
import com.android.quickstep.RecentsModel;
|
||||
import com.android.quickstep.TouchInteractionService;
|
||||
import com.android.quickstep.util.LayoutUtils;
|
||||
import com.android.systemui.shared.system.QuickStepContract;
|
||||
|
||||
/**
|
||||
* Touch controller for handling various state transitions in portrait UI.
|
||||
@@ -135,7 +138,10 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
|
||||
} else if (fromState == OVERVIEW) {
|
||||
return isDragTowardPositive ? ALL_APPS : NORMAL;
|
||||
} else if (fromState == NORMAL && isDragTowardPositive) {
|
||||
int stateFlags = OverviewInteractionState.INSTANCE.get(mLauncher)
|
||||
.getSystemUiStateFlags();
|
||||
return mAllowDragToOverview && TouchInteractionService.isConnected()
|
||||
&& (stateFlags & SYSUI_STATE_OVERVIEW_DISABLED) == 0
|
||||
? OVERVIEW : ALL_APPS;
|
||||
}
|
||||
return fromState;
|
||||
|
||||
@@ -22,6 +22,7 @@ import static android.content.Intent.ACTION_PACKAGE_REMOVED;
|
||||
|
||||
import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter;
|
||||
import static com.android.systemui.shared.system.PackageManagerWrapper.ACTION_PREFERRED_ACTIVITY_CHANGED;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
@@ -32,6 +33,7 @@ import android.content.pm.ResolveInfo;
|
||||
|
||||
import com.android.systemui.shared.system.PackageManagerWrapper;
|
||||
|
||||
import com.android.systemui.shared.system.QuickStepContract;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
@@ -56,6 +58,7 @@ public final class OverviewComponentObserver {
|
||||
private String mUpdateRegisteredPackage;
|
||||
private ActivityControlHelper mActivityControlHelper;
|
||||
private Intent mOverviewIntent;
|
||||
private int mSystemUiStateFlags;
|
||||
|
||||
public OverviewComponentObserver(Context context) {
|
||||
mContext = context;
|
||||
@@ -71,6 +74,15 @@ public final class OverviewComponentObserver {
|
||||
updateOverviewTargets();
|
||||
}
|
||||
|
||||
public void onSystemUiStateChanged(int stateFlags) {
|
||||
boolean homeDisabledChanged = (mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED)
|
||||
!= (stateFlags & SYSUI_STATE_HOME_DISABLED);
|
||||
mSystemUiStateFlags = stateFlags;
|
||||
if (homeDisabledChanged) {
|
||||
updateOverviewTargets();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update overview intent and {@link ActivityControlHelper} based off the current launcher home
|
||||
* component.
|
||||
@@ -81,7 +93,8 @@ public final class OverviewComponentObserver {
|
||||
|
||||
final String overviewIntentCategory;
|
||||
ComponentName overviewComponent;
|
||||
if (defaultHome == null || mMyHomeComponent.equals(defaultHome)) {
|
||||
if ((mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) == 0 &&
|
||||
(defaultHome == null || mMyHomeComponent.equals(defaultHome))) {
|
||||
// User default home is same as out home app. Use Overview integrated in Launcher.
|
||||
overviewComponent = mMyHomeComponent;
|
||||
mActivityControlHelper = new LauncherActivityControllerHelper();
|
||||
|
||||
@@ -53,6 +53,8 @@ public class OverviewInteractionState {
|
||||
private ISystemUiProxy mISystemUiProxy;
|
||||
private float mBackButtonAlpha = 1;
|
||||
|
||||
private int mSystemUiStateFlags;
|
||||
|
||||
private OverviewInteractionState(Context context) {
|
||||
mContext = context;
|
||||
|
||||
@@ -83,6 +85,14 @@ public class OverviewInteractionState {
|
||||
mBgHandler.obtainMessage(MSG_SET_PROXY, proxy).sendToTarget();
|
||||
}
|
||||
|
||||
public void setSystemUiStateFlags(int stateFlags) {
|
||||
mSystemUiStateFlags = stateFlags;
|
||||
}
|
||||
|
||||
public int getSystemUiStateFlags() {
|
||||
return mSystemUiStateFlags;
|
||||
}
|
||||
|
||||
private boolean handleUiMessage(Message msg) {
|
||||
if (msg.what == MSG_SET_BACK_BUTTON_ALPHA) {
|
||||
mBackButtonAlpha = (float) msg.obj;
|
||||
|
||||
Reference in New Issue
Block a user