Merge "FeatureFlag: quick scrub is now quick switch" into ub-launcher3-master

This commit is contained in:
TreeHugger Robot 2018-11-01 21:39:04 +00:00 committed by Android (Google) Code Review
commit dd44c8cd08
10 changed files with 221 additions and 27 deletions

3
.gitignore vendored
View File

@ -13,4 +13,5 @@ bin/
local.properties local.properties
gradle/ gradle/
build/ build/
gradlew* gradlew*
.DS_Store

View File

@ -178,6 +178,14 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
@Override @Override
public ActivityOptions getActivityLaunchOptions(Launcher launcher, View v) { public ActivityOptions getActivityLaunchOptions(Launcher launcher, View v) {
if (hasControlRemoteAppTransitionPermission()) { if (hasControlRemoteAppTransitionPermission()) {
boolean fromRecents = mLauncher.getStateManager().getState().overviewUi
&& findTaskViewToLaunch(launcher, v, null) != null;
RecentsView recentsView = mLauncher.getOverviewPanel();
if (fromRecents && recentsView.getQuickScrubController().isQuickSwitch()) {
return ActivityOptions.makeCustomAnimation(mLauncher, R.anim.no_anim,
R.anim.no_anim);
}
RemoteAnimationRunnerCompat runner = new LauncherAnimationRunner(mHandler, RemoteAnimationRunnerCompat runner = new LauncherAnimationRunner(mHandler,
true /* startAtFrontOfQueue */) { true /* startAtFrontOfQueue */) {
@ -218,8 +226,6 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
} }
}; };
boolean fromRecents = mLauncher.getStateManager().getState().overviewUi
&& findTaskViewToLaunch(launcher, v, null) != null;
int duration = fromRecents int duration = fromRecents
? RECENTS_LAUNCH_DURATION ? RECENTS_LAUNCH_DURATION
: APP_LAUNCH_DURATION; : APP_LAUNCH_DURATION;

View File

@ -35,6 +35,7 @@ public class FastOverviewState extends OverviewState {
* Vertical transition of the task previews relative to the full container. * Vertical transition of the task previews relative to the full container.
*/ */
public static final float OVERVIEW_TRANSLATION_FACTOR = 0.4f; public static final float OVERVIEW_TRANSLATION_FACTOR = 0.4f;
public static final float OVERVIEW_CENTERED_TRANSLATION_FACTOR = 0.5f;
private static final int STATE_FLAGS = FLAG_DISABLE_RESTORE | FLAG_DISABLE_INTERACTION private static final int STATE_FLAGS = FLAG_DISABLE_RESTORE | FLAG_DISABLE_INTERACTION
| FLAG_OVERVIEW_UI | FLAG_HIDE_BACK_BUTTON | FLAG_DISABLE_ACCESSIBILITY; | FLAG_OVERVIEW_UI | FLAG_HIDE_BACK_BUTTON | FLAG_DISABLE_ACCESSIBILITY;
@ -60,12 +61,17 @@ public class FastOverviewState extends OverviewState {
RecentsView recentsView = launcher.getOverviewPanel(); RecentsView recentsView = launcher.getOverviewPanel();
recentsView.getTaskSize(sTempRect); recentsView.getTaskSize(sTempRect);
return new float[] {getOverviewScale(launcher.getDeviceProfile(), sTempRect, launcher), boolean isQuickSwitch = recentsView.getQuickScrubController().isQuickSwitch();
OVERVIEW_TRANSLATION_FACTOR}; float translationYFactor = isQuickSwitch
? OVERVIEW_CENTERED_TRANSLATION_FACTOR
: OVERVIEW_TRANSLATION_FACTOR;
return new float[] {getOverviewScale(launcher.getDeviceProfile(), sTempRect, launcher,
isQuickSwitch), translationYFactor};
} }
public static float getOverviewScale(DeviceProfile dp, Rect taskRect, Context context) { public static float getOverviewScale(DeviceProfile dp, Rect taskRect, Context context,
if (dp.isVerticalBarLayout()) { boolean isQuickSwitch) {
if (dp.isVerticalBarLayout() && !isQuickSwitch) {
return 1f; return 1f;
} }
@ -73,6 +79,10 @@ public class FastOverviewState extends OverviewState {
float usedHeight = taskRect.height() + res.getDimension(R.dimen.task_thumbnail_top_margin); float usedHeight = taskRect.height() + res.getDimension(R.dimen.task_thumbnail_top_margin);
float usedWidth = taskRect.width() + 2 * (res.getDimension(R.dimen.recents_page_spacing) float usedWidth = taskRect.width() + 2 * (res.getDimension(R.dimen.recents_page_spacing)
+ res.getDimension(R.dimen.quickscrub_adjacent_visible_width)); + res.getDimension(R.dimen.quickscrub_adjacent_visible_width));
if (isQuickSwitch) {
usedWidth = taskRect.width();
return Math.max(dp.availableHeightPx / usedHeight, dp.availableWidthPx / usedWidth);
}
return Math.min(Math.min(dp.availableHeightPx / usedHeight, return Math.min(Math.min(dp.availableHeightPx / usedHeight,
dp.availableWidthPx / usedWidth), MAX_PREVIEW_SCALE_UP); dp.availableWidthPx / usedWidth), MAX_PREVIEW_SCALE_UP);
} }

View File

@ -16,7 +16,6 @@
package com.android.quickstep; package com.android.quickstep;
import static android.view.View.TRANSLATION_Y; import static android.view.View.TRANSLATION_Y;
import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS; import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import static com.android.launcher3.LauncherState.BACKGROUND_APP; import static com.android.launcher3.LauncherState.BACKGROUND_APP;
@ -58,6 +57,7 @@ import com.android.launcher3.allapps.AllAppsTransitionController;
import com.android.launcher3.allapps.DiscoveryBounce; import com.android.launcher3.allapps.DiscoveryBounce;
import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.compat.AccessibilityManagerCompat; import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.uioverrides.FastOverviewState; import com.android.launcher3.uioverrides.FastOverviewState;
import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.userevent.nano.LauncherLogProto;
@ -192,7 +192,8 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
@InteractionType int interactionType, TransformedRect outRect) { @InteractionType int interactionType, TransformedRect outRect) {
LayoutUtils.calculateLauncherTaskSize(context, dp, outRect.rect); LayoutUtils.calculateLauncherTaskSize(context, dp, outRect.rect);
if (interactionType == INTERACTION_QUICK_SCRUB) { if (interactionType == INTERACTION_QUICK_SCRUB) {
outRect.scale = FastOverviewState.getOverviewScale(dp, outRect.rect, context); outRect.scale = FastOverviewState.getOverviewScale(dp, outRect.rect, context,
FeatureFlags.QUICK_SWITCH.get());
} }
if (dp.isVerticalBarLayout()) { if (dp.isVerticalBarLayout()) {
Rect targetInsets = dp.getInsets(); Rect targetInsets = dp.getInsets();

View File

@ -16,8 +16,18 @@
package com.android.quickstep; package com.android.quickstep;
import static com.android.launcher3.Utilities.SINGLE_FRAME_MS;
import static com.android.launcher3.anim.Interpolators.ACCEL;
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN; import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.annotation.TargetApi;
import android.os.Build;
import android.util.FloatProperty;
import android.util.Log; import android.util.Log;
import android.view.HapticFeedbackConstants; import android.view.HapticFeedbackConstants;
import android.view.animation.Interpolator; import android.view.animation.Interpolator;
@ -37,8 +47,10 @@ import com.android.quickstep.views.TaskView;
* The behavior is to evenly divide the progress into sections, each of which scrolls one page. * The behavior is to evenly divide the progress into sections, each of which scrolls one page.
* The first and last section set an alarm to auto-advance backwards or forwards, respectively. * The first and last section set an alarm to auto-advance backwards or forwards, respectively.
*/ */
@TargetApi(Build.VERSION_CODES.P)
public class QuickScrubController implements OnAlarmListener { public class QuickScrubController implements OnAlarmListener {
public static final int QUICK_SWITCH_FROM_APP_START_DURATION = 0;
public static final int QUICK_SCRUB_FROM_APP_START_DURATION = 240; public static final int QUICK_SCRUB_FROM_APP_START_DURATION = 240;
public static final int QUICK_SCRUB_FROM_HOME_START_DURATION = 200; public static final int QUICK_SCRUB_FROM_HOME_START_DURATION = 200;
// We want the translation y to finish faster than the rest of the animation. // We want the translation y to finish faster than the rest of the animation.
@ -52,6 +64,19 @@ public class QuickScrubController implements OnAlarmListener {
0.05f, 0.20f, 0.35f, 0.50f, 0.65f, 0.80f, 0.95f 0.05f, 0.20f, 0.35f, 0.50f, 0.65f, 0.80f, 0.95f
}; };
private static final FloatProperty<QuickScrubController> PROGRESS
= new FloatProperty<QuickScrubController>("progress") {
@Override
public void setValue(QuickScrubController quickScrubController, float progress) {
quickScrubController.onQuickScrubProgress(progress);
}
@Override
public Float get(QuickScrubController quickScrubController) {
return quickScrubController.mEndProgress;
}
};
private static final String TAG = "QuickScrubController"; private static final String TAG = "QuickScrubController";
private static final boolean ENABLE_AUTO_ADVANCE = true; private static final boolean ENABLE_AUTO_ADVANCE = true;
private static final long AUTO_ADVANCE_DELAY = 500; private static final long AUTO_ADVANCE_DELAY = 500;
@ -72,6 +97,13 @@ public class QuickScrubController implements OnAlarmListener {
private ActivityControlHelper mActivityControlHelper; private ActivityControlHelper mActivityControlHelper;
private TouchInteractionLog mTouchInteractionLog; private TouchInteractionLog mTouchInteractionLog;
private boolean mIsQuickSwitch;
private float mStartProgress;
private float mEndProgress;
private float mPrevProgressDelta;
private float mPrevPrevProgressDelta;
private boolean mShouldSwitchToNext;
public QuickScrubController(BaseActivity activity, RecentsView recentsView) { public QuickScrubController(BaseActivity activity, RecentsView recentsView) {
mActivity = activity; mActivity = activity;
mRecentsView = recentsView; mRecentsView = recentsView;
@ -91,17 +123,26 @@ public class QuickScrubController implements OnAlarmListener {
mActivityControlHelper = controlHelper; mActivityControlHelper = controlHelper;
mTouchInteractionLog = touchInteractionLog; mTouchInteractionLog = touchInteractionLog;
if (mIsQuickSwitch) {
mShouldSwitchToNext = true;
mPrevProgressDelta = 0;
if (mRecentsView.getTaskViewCount() > 0) {
mRecentsView.getTaskViewAt(0).setFullscreen(true);
}
if (mRecentsView.getTaskViewCount() > 1) {
mRecentsView.getTaskViewAt(1).setFullscreen(true);
}
}
snapToNextTaskIfAvailable(); snapToNextTaskIfAvailable();
mActivity.getUserEventDispatcher().resetActionDurationMillis(); mActivity.getUserEventDispatcher().resetActionDurationMillis();
} }
public void onQuickScrubEnd() { public void onQuickScrubEnd() {
mInQuickScrub = false; mInQuickScrub = false;
if (ENABLE_AUTO_ADVANCE) {
mAutoAdvanceAlarm.cancelAlarm();
}
int page = mRecentsView.getNextPage();
Runnable launchTaskRunnable = () -> { Runnable launchTaskRunnable = () -> {
int page = mRecentsView.getPageNearestToCenterOfScreen();
TaskView taskView = mRecentsView.getTaskViewAt(page); TaskView taskView = mRecentsView.getTaskViewAt(page);
if (taskView != null) { if (taskView != null) {
mWaitingForTaskLaunch = true; mWaitingForTaskLaunch = true;
@ -118,12 +159,49 @@ public class QuickScrubController implements OnAlarmListener {
TaskUtils.getLaunchComponentKeyForTask(taskView.getTask().key)); TaskUtils.getLaunchComponentKeyForTask(taskView.getTask().key));
} }
mWaitingForTaskLaunch = false; mWaitingForTaskLaunch = false;
if (mIsQuickSwitch) {
mIsQuickSwitch = false;
if (mRecentsView.getTaskViewCount() > 0) {
mRecentsView.getTaskViewAt(0).setFullscreen(false);
}
if (mRecentsView.getTaskViewCount() > 1) {
mRecentsView.getTaskViewAt(1).setFullscreen(false);
}
}
}, taskView.getHandler()); }, taskView.getHandler());
} else { } else {
breakOutOfQuickScrub(); breakOutOfQuickScrub();
} }
mActivityControlHelper = null; mActivityControlHelper = null;
}; };
if (mIsQuickSwitch) {
float progressVelocity = mPrevPrevProgressDelta / SINGLE_FRAME_MS;
// Move to the next frame immediately, then start the animation from the
// following frame since it starts a frame later.
float singleFrameProgress = progressVelocity * SINGLE_FRAME_MS;
float fromProgress = mEndProgress + singleFrameProgress;
onQuickScrubProgress(fromProgress);
fromProgress += singleFrameProgress;
float toProgress = mShouldSwitchToNext ? 1 : 0;
int duration = (int) Math.abs((toProgress - fromProgress) / progressVelocity);
duration = Utilities.boundToRange(duration, 80, 300);
Animator anim = ObjectAnimator.ofFloat(this, PROGRESS, fromProgress, toProgress);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
launchTaskRunnable.run();
}
});
anim.setDuration(duration).start();
return;
}
if (ENABLE_AUTO_ADVANCE) {
mAutoAdvanceAlarm.cancelAlarm();
}
int page = mRecentsView.getNextPage();
int snapDuration = Math.abs(page - mRecentsView.getPageNearestToCenterOfScreen()) int snapDuration = Math.abs(page - mRecentsView.getPageNearestToCenterOfScreen())
* QUICKSCRUB_END_SNAP_DURATION_PER_PAGE; * QUICKSCRUB_END_SNAP_DURATION_PER_PAGE;
if (mRecentsView.getChildCount() > 0 && mRecentsView.snapToPage(page, snapDuration)) { if (mRecentsView.getChildCount() > 0 && mRecentsView.snapToPage(page, snapDuration)) {
@ -151,19 +229,28 @@ public class QuickScrubController implements OnAlarmListener {
mLaunchingTaskId = 0; mLaunchingTaskId = 0;
} }
public boolean prepareQuickScrub(String tag) {
return prepareQuickScrub(tag, mIsQuickSwitch);
}
/** /**
* Initializes the UI for quick scrub, returns true if success. * Initializes the UI for quick scrub, returns true if success.
*/ */
public boolean prepareQuickScrub(String tag) { public boolean prepareQuickScrub(String tag, boolean isQuickSwitch) {
if (mWaitingForTaskLaunch || mInQuickScrub) { if (mWaitingForTaskLaunch || mInQuickScrub) {
Log.d(tag, "Waiting for last scrub to finish, will skip this interaction"); Log.d(tag, "Waiting for last scrub to finish, will skip this interaction");
return false; return false;
} }
mOnFinishedTransitionToQuickScrubRunnable = null; mOnFinishedTransitionToQuickScrubRunnable = null;
mRecentsView.setNextPageSwitchRunnable(null); mRecentsView.setNextPageSwitchRunnable(null);
mIsQuickSwitch = isQuickSwitch;
return true; return true;
} }
public boolean isQuickSwitch() {
return mIsQuickSwitch;
}
public boolean isWaitingForTaskLaunch() { public boolean isWaitingForTaskLaunch() {
return mWaitingForTaskLaunch; return mWaitingForTaskLaunch;
} }
@ -179,6 +266,40 @@ public class QuickScrubController implements OnAlarmListener {
} }
public void onQuickScrubProgress(float progress) { public void onQuickScrubProgress(float progress) {
if (mIsQuickSwitch) {
TaskView currentPage = mRecentsView.getTaskViewAt(0);
TaskView nextPage = mRecentsView.getTaskViewAt(1);
if (currentPage == null || nextPage == null) {
return;
}
if (!mFinishedTransitionToQuickScrub) {
mStartProgress = mEndProgress = progress;
} else {
float progressDelta = progress - mEndProgress;
mEndProgress = progress;
progress = Utilities.boundToRange(progress, mStartProgress, 1);
progress = Utilities.mapToRange(progress, mStartProgress, 1, 0, 1, LINEAR);
if (mInQuickScrub) {
mShouldSwitchToNext = mPrevProgressDelta > 0.007f || progressDelta > 0.007f
|| progress >= 0.5f;
}
mPrevPrevProgressDelta = mPrevProgressDelta;
mPrevProgressDelta = progressDelta;
float scrollDiff = nextPage.getWidth() + mRecentsView.getPageSpacing();
int scrollDir = mRecentsView.isRtl() ? -1 : 1;
int linearScrollDiff = (int) (progress * scrollDiff * scrollDir);
float accelScrollDiff = ACCEL.getInterpolation(progress) * scrollDiff * scrollDir;
currentPage.setZoomScale(1 - DEACCEL_3.getInterpolation(progress)
* TaskView.EDGE_SCALE_DOWN_FACTOR);
currentPage.setTranslationX(linearScrollDiff + accelScrollDiff);
nextPage.setTranslationZ(1);
nextPage.setTranslationY(currentPage.getTranslationY());
int startScroll = mRecentsView.isRtl() ? mRecentsView.getMaxScrollX() : 0;
mRecentsView.setScrollX(startScroll + linearScrollDiff);
}
return;
}
int quickScrubSection = 0; int quickScrubSection = 0;
for (float threshold : QUICK_SCRUB_THRESHOLDS) { for (float threshold : QUICK_SCRUB_THRESHOLDS) {
if (progress < threshold) { if (progress < threshold) {
@ -228,9 +349,14 @@ public class QuickScrubController implements OnAlarmListener {
public void snapToNextTaskIfAvailable() { public void snapToNextTaskIfAvailable() {
if (mInQuickScrub && mRecentsView.getChildCount() > 0) { if (mInQuickScrub && mRecentsView.getChildCount() > 0) {
int duration = mStartedFromHome ? QUICK_SCRUB_FROM_HOME_START_DURATION int duration = mIsQuickSwitch
: QUICK_SCRUB_FROM_APP_START_DURATION; ? QUICK_SWITCH_FROM_APP_START_DURATION
int pageToGoTo = mStartedFromHome ? 0 : mRecentsView.getNextPage() + 1; : mStartedFromHome
? QUICK_SCRUB_FROM_HOME_START_DURATION
: QUICK_SCRUB_FROM_APP_START_DURATION;
int pageToGoTo = mStartedFromHome || mIsQuickSwitch
? 0
: mRecentsView.getNextPage() + 1;
goToPageWithHaptic(pageToGoTo, duration, true /* forceHaptic */, goToPageWithHaptic(pageToGoTo, duration, true /* forceHaptic */,
QUICK_SCRUB_START_INTERPOLATOR); QUICK_SCRUB_START_INTERPOLATOR);
} }

View File

@ -23,6 +23,7 @@ import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2; import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
import static com.android.quickstep.QuickScrubController.QUICK_SCRUB_FROM_APP_START_DURATION; import static com.android.quickstep.QuickScrubController.QUICK_SCRUB_FROM_APP_START_DURATION;
import static com.android.quickstep.QuickScrubController.QUICK_SWITCH_FROM_APP_START_DURATION;
import static com.android.quickstep.TouchConsumer.INTERACTION_NORMAL; import static com.android.quickstep.TouchConsumer.INTERACTION_NORMAL;
import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SCRUB; import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SCRUB;
import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD; import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
@ -59,6 +60,7 @@ import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators; import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.logging.UserEventDispatcher; import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
@ -979,12 +981,14 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
setStateOnUiThread(STATE_QUICK_SCRUB_START | STATE_GESTURE_COMPLETED); setStateOnUiThread(STATE_QUICK_SCRUB_START | STATE_GESTURE_COMPLETED);
// Start the window animation without waiting for launcher. // Start the window animation without waiting for launcher.
animateToProgress(mCurrentShift.value, 1f, QUICK_SCRUB_FROM_APP_START_DURATION, LINEAR, long duration = FeatureFlags.QUICK_SWITCH.get()
true /* goingToHome */); ? QUICK_SWITCH_FROM_APP_START_DURATION
: QUICK_SCRUB_FROM_APP_START_DURATION;
animateToProgress(mCurrentShift.value, 1f, duration, LINEAR, true /* goingToHome */);
} }
private void onQuickScrubStartUi() { private void onQuickScrubStartUi() {
if (!mQuickScrubController.prepareQuickScrub(TAG)) { if (!mQuickScrubController.prepareQuickScrub(TAG, FeatureFlags.QUICK_SWITCH.get())) {
mQuickScrubBlocked = true; mQuickScrubBlocked = true;
setStateOnUiThread(STATE_RESUME_LAST_TASK | STATE_HANDLER_INVALIDATED); setStateOnUiThread(STATE_RESUME_LAST_TASK | STATE_HANDLER_INVALIDATED);
return; return;
@ -1009,6 +1013,13 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
mQuickScrubController.onFinishedTransitionToQuickScrub(); mQuickScrubController.onFinishedTransitionToQuickScrub();
mRecentsView.animateUpRunningTaskIconScale(); mRecentsView.animateUpRunningTaskIconScale();
if (mQuickScrubController.isQuickSwitch()) {
TaskView runningTask = mRecentsView.getRunningTaskView();
if (runningTask != null) {
runningTask.setTranslationY(-mActivity.getResources().getDimension(
R.dimen.task_thumbnail_half_top_margin) * 1f / mRecentsView.getScaleX());
}
}
RecentsModel.INSTANCE.get(mContext).onOverviewShown(false, TAG); RecentsModel.INSTANCE.get(mContext).onOverviewShown(false, TAG);
} }

View File

@ -17,7 +17,6 @@
package com.android.quickstep.views; package com.android.quickstep.views;
import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_FULLSCREEN; import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_FULLSCREEN;
import android.content.Context; import android.content.Context;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.Bitmap; import android.graphics.Bitmap;
@ -33,7 +32,7 @@ import android.util.AttributeSet;
import android.util.FloatProperty; import android.util.FloatProperty;
import android.util.Property; import android.util.Property;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import com.android.launcher3.BaseActivity; import com.android.launcher3.BaseActivity;
import com.android.launcher3.DeviceProfile; import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R; import com.android.launcher3.R;
@ -78,6 +77,7 @@ public class TaskThumbnailView extends View {
private final Matrix mMatrix = new Matrix(); private final Matrix mMatrix = new Matrix();
private float mClipBottom = -1; private float mClipBottom = -1;
private Rect mScaledInsets = new Rect();
private Task mTask; private Task mTask;
private ThumbnailData mThumbnailData; private ThumbnailData mThumbnailData;
@ -179,7 +179,17 @@ public class TaskThumbnailView extends View {
@Override @Override
protected void onDraw(Canvas canvas) { protected void onDraw(Canvas canvas) {
drawOnCanvas(canvas, 0, 0, getMeasuredWidth(), getMeasuredHeight(), mCornerRadius); if (((TaskView) getParent()).isFullscreen()) {
// Draw the insets if we're being drawn fullscreen (we do this for quick switch).
drawOnCanvas(canvas,
-mScaledInsets.left,
-mScaledInsets.top,
getMeasuredWidth() + mScaledInsets.right,
getMeasuredHeight() + mScaledInsets.bottom,
mCornerRadius);
} else {
drawOnCanvas(canvas, 0, 0, getMeasuredWidth(), getMeasuredHeight(), mCornerRadius);
}
} }
public float getCornerRadius() { public float getCornerRadius() {
@ -253,6 +263,9 @@ public class TaskThumbnailView extends View {
: getMeasuredWidth() / thumbnailWidth; : getMeasuredWidth() / thumbnailWidth;
} }
mScaledInsets.set(thumbnailInsets);
Utilities.scaleRect(mScaledInsets, thumbnailScale);
if (rotate) { if (rotate) {
int rotationDir = profile.isVerticalBarLayout() && !profile.isSeascape() ? -1 : 1; int rotationDir = profile.isVerticalBarLayout() && !profile.isSeascape() ? -1 : 1;
mMatrix.setRotate(90 * rotationDir); mMatrix.setRotate(90 * rotationDir);

View File

@ -87,7 +87,7 @@ public class TaskView extends FrameLayout implements PageCallbacks {
/** /**
* How much to scale down pages near the edge of the screen. * How much to scale down pages near the edge of the screen.
*/ */
private static final float EDGE_SCALE_DOWN_FACTOR = 0.03f; public static final float EDGE_SCALE_DOWN_FACTOR = 0.03f;
public static final long SCALE_ICON_DURATION = 120; public static final long SCALE_ICON_DURATION = 120;
private static final long DIM_ANIM_DURATION = 700; private static final long DIM_ANIM_DURATION = 700;
@ -142,6 +142,7 @@ public class TaskView extends FrameLayout implements PageCallbacks {
private IconView mIconView; private IconView mIconView;
private float mCurveScale; private float mCurveScale;
private float mZoomScale; private float mZoomScale;
private boolean mIsFullscreen;
private Animator mIconAndDimAnimator; private Animator mIconAndDimAnimator;
private float mFocusTransitionProgress = 1; private float mFocusTransitionProgress = 1;
@ -509,4 +510,18 @@ public class TaskView extends FrameLayout implements PageCallbacks {
Log.w(tag, msg); Log.w(tag, msg);
Toast.makeText(getContext(), R.string.activity_not_available, LENGTH_SHORT).show(); Toast.makeText(getContext(), R.string.activity_not_available, LENGTH_SHORT).show();
} }
/**
* Hides the icon and shows insets when this TaskView is about to be shown fullscreen.
*/
public void setFullscreen(boolean isFullscreen) {
mIsFullscreen = isFullscreen;
mIconView.setVisibility(mIsFullscreen ? INVISIBLE : VISIBLE);
setClipChildren(!mIsFullscreen);
setClipToPadding(!mIsFullscreen);
}
public boolean isFullscreen() {
return mIsFullscreen;
}
} }

View File

@ -625,6 +625,10 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
mMaxScrollX = computeMaxScrollX(); mMaxScrollX = computeMaxScrollX();
} }
public int getMaxScrollX() {
return mMaxScrollX;
}
protected int computeMaxScrollX() { protected int computeMaxScrollX() {
int childCount = getChildCount(); int childCount = getChildCount();
if (childCount > 0) { if (childCount > 0) {
@ -640,6 +644,10 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
requestLayout(); requestLayout();
} }
public int getPageSpacing() {
return mPageSpacing;
}
private void dispatchPageCountChanged() { private void dispatchPageCountChanged() {
if (mPageIndicator != null) { if (mPageIndicator != null) {
mPageIndicator.setMarkersCount(getChildCount()); mPageIndicator.setMarkersCount(getChildCount());

View File

@ -22,9 +22,6 @@ import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.provider.Settings; import android.provider.Settings;
import androidx.annotation.GuardedBy;
import androidx.annotation.Keep;
import com.android.launcher3.Utilities; import com.android.launcher3.Utilities;
import java.util.ArrayList; import java.util.ArrayList;
@ -32,6 +29,9 @@ import java.util.List;
import java.util.SortedMap; import java.util.SortedMap;
import java.util.TreeMap; import java.util.TreeMap;
import androidx.annotation.GuardedBy;
import androidx.annotation.Keep;
/** /**
* Defines a set of flags used to control various launcher behaviors. * Defines a set of flags used to control various launcher behaviors.
* *
@ -87,6 +87,9 @@ abstract class BaseFlags {
// trying to make them fit the orientation the device is in. // trying to make them fit the orientation the device is in.
public static final boolean OVERVIEW_USE_SCREENSHOT_ORIENTATION = true; public static final boolean OVERVIEW_USE_SCREENSHOT_ORIENTATION = true;
public static final TogglableFlag QUICK_SWITCH = new TogglableFlag("QUICK_SWITCH", false,
"Swiping right on the nav bar while in an app switches to the previous app");
/** /**
* Feature flag to handle define config changes dynamically instead of killing the process. * Feature flag to handle define config changes dynamically instead of killing the process.
*/ */