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:
Winson Chung
2019-05-23 13:56:10 -07:00
parent 9e26fccacc
commit dd71ca0437
7 changed files with 96 additions and 38 deletions
@@ -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
@@ -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;
}
@@ -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());
@@ -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()
@@ -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;