Creating a separate state for launcehr as background app
This makes is simpler to control the swipe to overview UI, and ties the
transition with the state machine
Bug: 113287120
Bug: 79755195
Bug: 112203163
Change-Id: I3041dbb659b46ccea6284855addc91e370815be6
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BackgroundAppState.java b/quickstep/src/com/android/launcher3/uioverrides/BackgroundAppState.java
new file mode 100644
index 0000000..53dcc74
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/BackgroundAppState.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 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.launcher3.uioverrides;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.allapps.AllAppsTransitionController;
+import com.android.quickstep.QuickScrubController;
+import com.android.quickstep.util.LayoutUtils;
+
+/**
+ * State indicating that the Launcher is behind an app
+ */
+public class BackgroundAppState extends OverviewState {
+
+ private static final int STATE_FLAGS =
+ FLAG_DISABLE_RESTORE | FLAG_OVERVIEW_UI | FLAG_DISABLE_ACCESSIBILITY;
+
+ public BackgroundAppState(int id) {
+ super(id, QuickScrubController.QUICK_SCRUB_FROM_HOME_START_DURATION, STATE_FLAGS);
+ }
+
+ @Override
+ public float getVerticalProgress(Launcher launcher) {
+ if (launcher.getDeviceProfile().isVerticalBarLayout()) {
+ return super.getVerticalProgress(launcher);
+ }
+ int transitionLength = LayoutUtils.getShelfTrackingDistance(launcher.getDeviceProfile());
+ AllAppsTransitionController controller = launcher.getAllAppsController();
+ float scrollRange = Math.max(controller.getShiftRange(), 1);
+ float progressDelta = (transitionLength / scrollRange);
+ return super.getVerticalProgress(launcher) + progressDelta;
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
index 25b5f57..0d77bca 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
@@ -19,6 +19,7 @@
import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
import static com.android.launcher3.states.RotationHelper.REQUEST_ROTATE;
+import android.graphics.Rect;
import android.view.View;
import com.android.launcher3.AbstractFloatingView;
@@ -38,6 +39,8 @@
*/
public class OverviewState extends LauncherState {
+ protected static final Rect sTempRect = new Rect();
+
private static final int STATE_FLAGS = FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED
| FLAG_DISABLE_RESTORE | FLAG_OVERVIEW_UI | FLAG_DISABLE_ACCESSIBILITY;
diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
index 77af211..63fc6cd 100644
--- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java
+++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
@@ -16,8 +16,10 @@
package com.android.quickstep;
import static android.view.View.TRANSLATION_Y;
+
import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
+import static com.android.launcher3.LauncherState.BACKGROUND_APP;
import static com.android.launcher3.LauncherState.FAST_OVERVIEW;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
@@ -37,7 +39,6 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Build;
import android.os.Handler;
@@ -54,7 +55,6 @@
import com.android.launcher3.TestProtocol;
import com.android.launcher3.allapps.AllAppsTransitionController;
import com.android.launcher3.allapps.DiscoveryBounce;
-import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.dragndrop.DragLayer;
@@ -100,13 +100,8 @@
void onTransitionCancelled(T activity, boolean activityVisible);
- default int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context,
- @InteractionType int interactionType, TransformedRect outRect) {
- return getSwipeUpDestinationAndLength(dp, context, interactionType, outRect, null);
- }
-
int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context,
- @InteractionType int interactionType, TransformedRect outRect, PointF touchTown);
+ @InteractionType int interactionType, TransformedRect outRect);
void onSwipeUpComplete(T activity);
@@ -190,7 +185,7 @@
@Override
public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context,
- @InteractionType int interactionType, TransformedRect outRect, PointF touchDown) {
+ @InteractionType int interactionType, TransformedRect outRect) {
LayoutUtils.calculateLauncherTaskSize(context, dp, outRect.rect);
if (interactionType == INTERACTION_QUICK_SCRUB) {
outRect.scale = FastOverviewState.getOverviewScale(dp, outRect.rect, context);
@@ -200,12 +195,7 @@
int hotseatInset = dp.isSeascape() ? targetInsets.left : targetInsets.right;
return dp.hotseatBarSizePx + hotseatInset;
} else {
- int swipeLength = LayoutUtils.getShelfTrackingDistance(dp);
- if (touchDown != null) {
- // We are already partway through based on where we touched the nav bar.
- swipeLength -= dp.heightPx - touchDown.y;
- }
- return swipeLength;
+ return LayoutUtils.getShelfTrackingDistance(dp);
}
}
@@ -233,24 +223,28 @@
}
activity.getStateManager().setRestState(resetState);
+ final LauncherState fromState;
if (!activityVisible) {
// Since the launcher is not visible, we can safely reset the scroll position.
// This ensures then the next swipe up to all-apps starts from scroll 0.
activity.getAppsView().reset(false /* animate */);
- activity.getStateManager().goToState(OVERVIEW, false);
+ fromState = BACKGROUND_APP;
+ activity.getStateManager().goToState(BACKGROUND_APP, false);
// Optimization, hide the all apps view to prevent layout while initializing
activity.getAppsView().getContentView().setVisibility(View.GONE);
AccessibilityManagerCompat.sendEventToTest(
activity, TestProtocol.SWITCHED_TO_STATE_MESSAGE);
+ } else {
+ fromState = startState;
}
return new AnimationFactory() {
@Override
public void createActivityController(long transitionLength,
@InteractionType int interactionType) {
- createActivityControllerInternal(activity, activityVisible, startState,
+ createActivityControllerInternal(activity, activityVisible, fromState,
transitionLength, interactionType, callback);
}
@@ -262,7 +256,7 @@
}
private void createActivityControllerInternal(Launcher activity, boolean wasVisible,
- LauncherState startState, long transitionLength,
+ LauncherState fromState, long transitionLength,
@InteractionType int interactionType,
Consumer<AnimatorPlaybackController> callback) {
LauncherState endState = interactionType == INTERACTION_QUICK_SCRUB
@@ -271,31 +265,18 @@
DeviceProfile dp = activity.getDeviceProfile();
long accuracy = 2 * Math.max(dp.widthPx, dp.heightPx);
callback.accept(activity.getStateManager()
- .createAnimationToNewWorkspace(startState, endState, accuracy));
+ .createAnimationToNewWorkspace(fromState, endState, accuracy));
return;
}
AnimatorSet anim = new AnimatorSet();
-
if (!activity.getDeviceProfile().isVerticalBarLayout()) {
AllAppsTransitionController controller = activity.getAllAppsController();
- float scrollRange = Math.max(controller.getShiftRange(), 1);
- float progressDelta = (transitionLength / scrollRange);
-
- float endProgress = endState.getVerticalProgress(activity);
- float startProgress = endProgress + progressDelta;
- ObjectAnimator shiftAnim = ObjectAnimator.ofFloat(
- controller, ALL_APPS_PROGRESS, startProgress, endProgress);
+ ObjectAnimator shiftAnim = ObjectAnimator.ofFloat(controller, ALL_APPS_PROGRESS,
+ fromState.getVerticalProgress(activity),
+ endState.getVerticalProgress(activity));
shiftAnim.setInterpolator(LINEAR);
anim.play(shiftAnim);
-
- // Since we are changing the start position of the UI, reapply the state, at the end
- anim.addListener(new AnimationSuccessListener() {
- @Override
- public void onAnimationSuccess(Animator animator) {
- activity.getStateManager().reapplyState();
- }
- });
}
if (interactionType == INTERACTION_NORMAL) {
@@ -304,7 +285,14 @@
anim.setDuration(transitionLength * 2);
activity.getStateManager().setCurrentAnimation(anim);
- callback.accept(AnimatorPlaybackController.wrap(anim, transitionLength * 2));
+ AnimatorPlaybackController controller =
+ AnimatorPlaybackController.wrap(anim, transitionLength * 2);
+
+ // Since we are changing the start position of the UI, reapply the state, at the end
+ controller.setEndAction(() ->
+ activity.getStateManager().goToState(
+ controller.getProgressFraction() > 0.5 ? endState : fromState, false));
+ callback.accept(controller);
}
/**
@@ -464,7 +452,7 @@
@Override
public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context,
- @InteractionType int interactionType, TransformedRect outRect, PointF touchDown) {
+ @InteractionType int interactionType, TransformedRect outRect) {
LayoutUtils.calculateFallbackTaskSize(context, dp, outRect.rect);
if (dp.isVerticalBarLayout()) {
Rect targetInsets = dp.getInsets();
diff --git a/quickstep/src/com/android/quickstep/MultiStateCallback.java b/quickstep/src/com/android/quickstep/MultiStateCallback.java
index bda3d06..98d723f 100644
--- a/quickstep/src/com/android/quickstep/MultiStateCallback.java
+++ b/quickstep/src/com/android/quickstep/MultiStateCallback.java
@@ -17,20 +17,23 @@
import android.util.SparseArray;
+import com.android.launcher3.Utilities.Consumer;
+
/**
* Utility class to help manage multiple callbacks based on different states.
*/
public class MultiStateCallback {
private final SparseArray<Runnable> mCallbacks = new SparseArray<>();
+ private final SparseArray<Consumer<Boolean>> mStateChangeHandlers = new SparseArray<>();
private int mState = 0;
/**
* Adds the provided state flags to the global state and executes any callbacks as a result.
- * @param stateFlag
*/
public void setState(int stateFlag) {
+ int oldState = mState;
mState = mState | stateFlag;
int count = mCallbacks.size();
@@ -46,6 +49,30 @@
}
}
}
+ notifyStateChangeHandlers(oldState);
+ }
+
+ /**
+ * Adds the provided state flags to the global state and executes any change handlers
+ * as a result.
+ */
+ public void clearState(int stateFlag) {
+ int oldState = mState;
+ mState = mState & ~stateFlag;
+ notifyStateChangeHandlers(oldState);
+ }
+
+ private void notifyStateChangeHandlers(int oldState) {
+ int count = mStateChangeHandlers.size();
+ for (int i = 0; i < count; i++) {
+ int state = mStateChangeHandlers.keyAt(i);
+ boolean wasOn = (state & oldState) == state;
+ boolean isOn = (state & mState) == state;
+
+ if (wasOn != isOn) {
+ mStateChangeHandlers.valueAt(i).accept(isOn);
+ }
+ }
}
/**
@@ -56,6 +83,13 @@
mCallbacks.put(stateMask, callback);
}
+ /**
+ * Sets the handler to be called when the provided states are enabled or disabled.
+ */
+ public void addChangeHandler(int stateMask, Consumer<Boolean> handler) {
+ mStateChangeHandlers.put(stateMask, handler);
+ }
+
public int getState() {
return mState;
}
diff --git a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
index c3e0568..0e811f7 100644
--- a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
@@ -444,7 +444,7 @@
} else {
TraceHelper.partitionSection("RecentsController", "Received");
mInteractionHandler.onRecentsAnimationStart(mController, mTargets,
- mHomeContentInsets, mMinimizedHomeBounds, mDownPos);
+ mHomeContentInsets, mMinimizedHomeBounds);
}
}
}
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 18fbfbb..fa36f6b 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -36,7 +36,6 @@
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Point;
-import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
@@ -123,9 +122,11 @@
private static final int STATE_CAPTURE_SCREENSHOT = 1 << 15;
private static final int STATE_SCREENSHOT_CAPTURED = 1 << 16;
+ private static final int STATE_SCREENSHOT_VIEW_SHOWN = 1 << 17;
- private static final int STATE_RESUME_LAST_TASK = 1 << 17;
- private static final int STATE_ASSIST_DATA_RECEIVED = 1 << 18;
+ private static final int STATE_RESUME_LAST_TASK = 1 << 18;
+ private static final int STATE_ASSIST_DATA_RECEIVED = 1 << 19;
+
private static final int LAUNCHER_UI_STATES =
STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_ACTIVITY_MULTIPLIER_COMPLETE
@@ -158,6 +159,7 @@
"STATE_QUICK_SCRUB_END",
"STATE_CAPTURE_SCREENSHOT",
"STATE_SCREENSHOT_CAPTURED",
+ "STATE_SCREENSHOT_VIEW_SHOWN",
"STATE_RESUME_LAST_TASK",
"STATE_ASSIST_DATA_RECEIVED",
};
@@ -176,13 +178,14 @@
protected boolean mIsGoingToHome;
private DeviceProfile mDp;
private int mTransitionDragLength;
- private PointF mTouchDown;
// Shift in the range of [0, 1].
// 0 => preview snapShot is completely visible, and hotseat is completely translated down
// 1 => preview snapShot is completely aligned with the recents view and hotseat is completely
// visible.
private final AnimatedFloat mCurrentShift = new AnimatedFloat(this::updateFinalShift);
+ // To avoid UI jump when gesture is started, we offset the animation by the threshold.
+ private float mShiftAtGestureStart = 0;
private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
@@ -324,6 +327,10 @@
mStateCallback.addCallback(LONG_SWIPE_ENTER_STATE, this::checkLongSwipeCanEnter);
mStateCallback.addCallback(LONG_SWIPE_START_STATE, this::checkLongSwipeCanStart);
+
+ mStateCallback.addChangeHandler(STATE_APP_CONTROLLER_RECEIVED | STATE_LAUNCHER_PRESENT
+ | STATE_SCREENSHOT_VIEW_SHOWN | STATE_CAPTURE_SCREENSHOT,
+ (b) -> mRecentsView.setRunningTaskHidden(!b));
}
private void executeOnUiThread(Runnable action) {
@@ -342,12 +349,12 @@
}
}
- private void initTransitionEndpoints(DeviceProfile dp, PointF touchDown) {
+ private void initTransitionEndpoints(DeviceProfile dp) {
mDp = dp;
TransformedRect tempRect = new TransformedRect();
mTransitionDragLength = mActivityControlHelper.getSwipeUpDestinationAndLength(
- dp, mContext, mInteractionType, tempRect, touchDown);
+ dp, mContext, mInteractionType, tempRect);
mClipAnimationHelper.updateTargetRect(tempRect);
}
@@ -571,14 +578,14 @@
* Called by {@link #mLayoutListener} when launcher layout changes
*/
public void buildAnimationController() {
- initTransitionEndpoints(mActivity.getDeviceProfile(), mTouchDown);
+ initTransitionEndpoints(mActivity.getDeviceProfile());
mAnimationFactory.createActivityController(mTransitionDragLength, mInteractionType);
}
private void onAnimatorPlaybackControllerCreated(AnimatorPlaybackController anim) {
mLauncherTransitionController = anim;
mLauncherTransitionController.dispatchOnStart();
- mLauncherTransitionController.setPlayFraction(mCurrentShift.value);
+ updateLauncherTransitionProgress();
}
@WorkerThread
@@ -617,12 +624,18 @@
.getAnimationPlayer().isStarted()) {
return;
}
- mLauncherTransitionController.setPlayFraction(mCurrentShift.value);
+ updateLauncherTransitionProgress();
+ }
+
+ private void updateLauncherTransitionProgress() {
+ float progress = mCurrentShift.value;
+ mLauncherTransitionController.setPlayFraction(
+ progress <= mShiftAtGestureStart || mShiftAtGestureStart >= 1
+ ? 0 : (progress - mShiftAtGestureStart) / (1 - mShiftAtGestureStart));
}
public void onRecentsAnimationStart(RecentsAnimationControllerCompat controller,
- RemoteAnimationTargetSet targets, Rect homeContentInsets, Rect minimizedHomeBounds,
- PointF touchDown) {
+ RemoteAnimationTargetSet targets, Rect homeContentInsets, Rect minimizedHomeBounds) {
DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(mContext).getDeviceProfile(mContext);
final Rect overviewStackBounds;
RemoteAnimationTargetCompat runningTaskTarget = targets.findTask(mRunningTaskId);
@@ -653,8 +666,7 @@
mClipAnimationHelper.updateSource(overviewStackBounds, runningTaskTarget);
}
mClipAnimationHelper.prepareAnimation(false /* isOpening */);
- mTouchDown = touchDown;
- initTransitionEndpoints(dp, mTouchDown);
+ initTransitionEndpoints(dp);
mRecentsAnimationWrapper.setController(controller, targets);
setStateOnUiThread(STATE_APP_CONTROLLER_RECEIVED);
@@ -670,6 +682,7 @@
public void onGestureStarted() {
notifyGestureStartedAsync();
+ mShiftAtGestureStart = mCurrentShift.value;
setStateOnUiThread(mInteractionType == INTERACTION_NORMAL
? STATE_GESTURE_STARTED_QUICKSTEP : STATE_GESTURE_STARTED_QUICKSCRUB);
mGestureStarted = true;
@@ -805,8 +818,8 @@
@Override
public void onAnimationSuccess(Animator animator) {
setStateOnUiThread(mIsGoingToHome
- ? (STATE_SCALED_CONTROLLER_RECENTS | STATE_CAPTURE_SCREENSHOT)
- : STATE_SCALED_CONTROLLER_APP);
+ ? (STATE_SCALED_CONTROLLER_RECENTS | STATE_CAPTURE_SCREENSHOT
+ | STATE_SCREENSHOT_VIEW_SHOWN) : STATE_SCALED_CONTROLLER_APP);
}
});
anim.start();
@@ -900,7 +913,6 @@
mTaskSnapshot = controller.screenshotTask(mRunningTaskId);
}
TaskView taskView = mRecentsView.updateThumbnail(mRunningTaskId, mTaskSnapshot);
- mRecentsView.setRunningTaskHidden(false);
if (taskView != null) {
// Defer finishing the animation until the next launcher frame with the
// new thumbnail
@@ -1042,6 +1054,7 @@
private void onLongSwipeDisabledUi() {
mUiLongSwipeMode = false;
+ mStateCallback.clearState(STATE_SCREENSHOT_VIEW_SHOWN);
if (mLongSwipeController != null) {
mLongSwipeController.destroy();
@@ -1067,7 +1080,7 @@
}
// We are entering long swipe mode, make sure the screen shot is captured.
- mStateCallback.setState(STATE_CAPTURE_SCREENSHOT);
+ mStateCallback.setState(STATE_CAPTURE_SCREENSHOT | STATE_SCREENSHOT_VIEW_SHOWN);
}
diff --git a/quickstep/src/com/android/quickstep/util/LayoutUtils.java b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
index 253e56f..6ca0dce 100644
--- a/quickstep/src/com/android/quickstep/util/LayoutUtils.java
+++ b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
@@ -113,8 +113,7 @@
}
public static int getShelfTrackingDistance(DeviceProfile dp) {
- int shelfHeight = dp.hotseatBarSizePx + dp.getInsets().bottom;
- // Track slightly below the top of the shelf (between top and content).
- return shelfHeight - dp.edgeMarginPx * 2;
+ // Start from a third of bottom inset to provide some shelf overlap.
+ return dp.hotseatBarSizePx + dp.getInsets().bottom / 3 - dp.edgeMarginPx * 2;
}
}
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index bbe44c0..beef97e 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -22,11 +22,11 @@
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
import static com.android.launcher3.states.RotationHelper.REQUEST_NONE;
-import android.graphics.Rect;
import android.view.animation.Interpolator;
import com.android.launcher3.states.SpringLoadedState;
import com.android.launcher3.uioverrides.AllAppsState;
+import com.android.launcher3.uioverrides.BackgroundAppState;
import com.android.launcher3.uioverrides.FastOverviewState;
import com.android.launcher3.uioverrides.OverviewState;
import com.android.launcher3.uioverrides.UiFactory;
@@ -73,7 +73,7 @@
}
};
- private static final LauncherState[] sAllStates = new LauncherState[5];
+ private static final LauncherState[] sAllStates = new LauncherState[6];
/**
* TODO: Create a separate class for NORMAL state.
@@ -89,8 +89,7 @@
public static final LauncherState OVERVIEW = new OverviewState(2);
public static final LauncherState FAST_OVERVIEW = new FastOverviewState(3);
public static final LauncherState ALL_APPS = new AllAppsState(4);
-
- protected static final Rect sTempRect = new Rect();
+ public static final LauncherState BACKGROUND_APP = new BackgroundAppState(5);
public final int ordinal;
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/BackgroundAppState.java b/src_ui_overrides/com/android/launcher3/uioverrides/BackgroundAppState.java
new file mode 100644
index 0000000..9133b07
--- /dev/null
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/BackgroundAppState.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2018 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.launcher3.uioverrides;
+
+/**
+ * A dummy background app state
+ */
+public class BackgroundAppState extends OverviewState {
+
+ public BackgroundAppState(int id) {
+ super(id);
+ }
+}