Some fixes for quickstep when configuration changes
> Creating the launcher animation after first draw, so that the UI is in correct state
> Using correct workspace size, when layout is not valid
> Snapping pagedView to correct page when page size changes
> Resoting to correct workspace page on rebind
Change-Id: I74e61a05aae3a3c4912d4c5c8eb4d5d036d9005a
diff --git a/quickstep/src/com/android/quickstep/LauncherLayoutListener.java b/quickstep/src/com/android/quickstep/LauncherLayoutListener.java
index 2854342..40cd3e6 100644
--- a/quickstep/src/com/android/quickstep/LauncherLayoutListener.java
+++ b/quickstep/src/com/android/quickstep/LauncherLayoutListener.java
@@ -28,15 +28,18 @@
public class LauncherLayoutListener extends AbstractFloatingView implements Insettable {
private final Launcher mLauncher;
- private final WindowTransformSwipeHandler mHandler;
+ private WindowTransformSwipeHandler mHandler;
- public LauncherLayoutListener(Launcher launcher, WindowTransformSwipeHandler handler) {
+ public LauncherLayoutListener(Launcher launcher) {
super(launcher, null);
mLauncher = launcher;
- mHandler = handler;
setVisibility(INVISIBLE);
}
+ public void setHandler(WindowTransformSwipeHandler handler) {
+ mHandler = handler;
+ }
+
@Override
public void setInsets(Rect insets) {
requestLayout();
@@ -45,7 +48,9 @@
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
- mHandler.onLauncherLayoutChanged();
+ if (mHandler != null) {
+ mHandler.onLauncherLayoutChanged();
+ }
}
@Override
@@ -57,7 +62,10 @@
protected void handleClose(boolean animate) {
// We dont suupport animate.
mLauncher.getDragLayer().removeView(this);
- mHandler.layoutListenerClosed();
+
+ if (mHandler != null) {
+ mHandler.layoutListenerClosed();
+ }
}
@Override
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 1351973..6416dc1 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -158,21 +158,14 @@
this::reset);
mStateCallback.addCallback(STATE_LAUNCHER_READY | STATE_SCALED_SNAPSHOT_RECENTS,
this::reset);
-
mStateCallback.addCallback(STATE_LAUNCHER_READY | STATE_LAUNCHER_DRAWN,
- mLauncherDrawnCallback);
+ this::launcherFrameDrawn);
}
private void setStateOnUiThread(int stateFlag) {
mMainExecutor.execute(() -> mStateCallback.setState(stateFlag));
}
- public void setLauncherOnDrawCallback(Runnable callback) {
- mLauncherDrawnCallback = callback;
- mStateCallback.addCallback(STATE_LAUNCHER_READY | STATE_LAUNCHER_DRAWN,
- mLauncherDrawnCallback);
- }
-
private void initTransitionEndpoints(DeviceProfile dp) {
mDp = dp;
RecentsView.getPageRect(dp, mContext, mTargetRect);
@@ -206,11 +199,18 @@
int oldState = mStateCallback.getState() & ~LAUNCHER_UI_STATES;
initStateCallbacks();
mStateCallback.setState(oldState);
+ mLauncherLayoutListener.setHandler(null);
}
mLauncher = launcher;
AbstractFloatingView.closeAllOpenViews(launcher, alreadyOnHome);
mControllerStateAnimation = alreadyOnHome;
+ mWasLauncherAlreadyVisible = alreadyOnHome;
+
+ mRecentsView = mLauncher.getOverviewPanel();
+ mLauncherLayoutListener = new LauncherLayoutListener(mLauncher);
+
+ final int state;
if (mControllerStateAnimation) {
DeviceProfile dp = mLauncher.getDeviceProfile();
long accuracy = 2 * Math.max(dp.widthPx, dp.heightPx);
@@ -218,7 +218,8 @@
.createAnimationToNewWorkspace(OVERVIEW, accuracy);
mLauncherTransitionController.setPlayFraction(mCurrentShift.value);
- mStateCallback.setState(STATE_ACTIVITY_MULTIPLIER_COMPLETE | STATE_LAUNCHER_DRAWN);
+ state = STATE_ACTIVITY_MULTIPLIER_COMPLETE | STATE_LAUNCHER_DRAWN
+ | STATE_LAUNCHER_READY;
} else {
TraceHelper.beginSection("WTS-init");
launcher.getStateManager().goToState(OVERVIEW, false);
@@ -237,6 +238,7 @@
if (launcher != mLauncher) {
return;
}
+ mStateCallback.setState(STATE_LAUNCHER_DRAWN);
if ((mStateCallback.getState() & STATE_LAUNCHER_DRAWN) == 0) {
mStateCallback.setState(STATE_LAUNCHER_DRAWN);
@@ -247,25 +249,43 @@
}
}
});
+ state = STATE_LAUNCHER_READY;
}
- mRecentsView = mLauncher.getOverviewPanel();
mRecentsView.showTask(mRunningTaskId);
- mWasLauncherAlreadyVisible = alreadyOnHome;
- mLauncherLayoutListener = new LauncherLayoutListener(mLauncher, this);
mLauncher.getDragLayer().addView(mLauncherLayoutListener);
// Optimization
- if (!mLauncher.getDeviceProfile().isVerticalBarLayout()) {
+ // We are using the internal device profile as launcher may not have got the insets yet.
+ if (!mDp.isVerticalBarLayout()) {
// All-apps search box is visible in vertical bar layout.
mLauncher.getAppsView().setVisibility(View.GONE);
}
- onLauncherLayoutChanged();
- mStateCallback.setState(STATE_LAUNCHER_READY);
+ mStateCallback.setState(state);
return true;
}
+ public void setLauncherOnDrawCallback(Runnable callback) {
+ mLauncherDrawnCallback = callback;
+ }
+
+ private void launcherFrameDrawn() {
+ View rootView = mLauncher.getRootView();
+ if (rootView.getAlpha() < 1) {
+ final MultiStateCallback callback = mStateCallback;
+ rootView.animate().alpha(1)
+ .setDuration(getFadeInDuration())
+ .withEndAction(() -> callback.setState(STATE_ACTIVITY_MULTIPLIER_COMPLETE));
+ }
+ mLauncherLayoutListener.setHandler(this);
+ onLauncherLayoutChanged();
+
+ if (mLauncherDrawnCallback != null) {
+ mLauncherDrawnCallback.run();
+ }
+ }
+
public void updateInteractionType(@InteractionType int interactionType) {
Preconditions.assertUIThread();
if (mInteractionType != INTERACTION_NORMAL) {
@@ -454,7 +474,10 @@
// TODO: These should be done as part of ActivityOptions#OnAnimationStarted
mLauncher.getStateManager().reapplyState();
mLauncher.setOnResumeCallback(() -> mLauncherLayoutListener.close(false));
- mLauncherTransitionController.setPlayFraction(1);
+
+ if (mLauncherTransitionController != null) {
+ mLauncherTransitionController.setPlayFraction(1);
+ }
}
clearReference();
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 7595793..639fb6c 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -419,7 +419,11 @@
getStateManager().reapplyState();
// TODO: We can probably avoid rebind when only screen size changed.
- mModel.startLoader(mWorkspace.getNextPage());
+ int currentPage = mWorkspace.getNextPage();
+ if (mModel.startLoader(currentPage)) {
+ mWorkspace.setCurrentPage(currentPage);
+ setWorkspaceLoading(true);
+ }
}
mOldConfig.setTo(newConfig);
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index ad94a6b..0ebae81 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -184,6 +184,9 @@
protected final Rect mInsets = new Rect();
protected final boolean mIsRtl;
+ // Similar to the platform implementation of isLayoutValid();
+ protected boolean mIsLayoutValid;
+
public PagedView(Context context) {
this(context, null);
}
@@ -582,6 +585,18 @@
}
@Override
+ public void requestLayout() {
+ mIsLayoutValid = false;
+ super.requestLayout();
+ }
+
+ @Override
+ public void forceLayout() {
+ mIsLayoutValid = false;
+ super.forceLayout();
+ }
+
+ @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (getChildCount() == 0) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
@@ -624,6 +639,7 @@
@SuppressLint("DrawAllocation")
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ mIsLayoutValid = true;
if (getChildCount() == 0) {
return;
}
@@ -640,8 +656,10 @@
int scrollOffsetLeft = mInsets.left + getPaddingLeft();
int childLeft = scrollOffsetLeft;
+ boolean pageScrollChanged = false;
if (mPageScrolls == null || childCount != mChildCountOnLastLayout) {
mPageScrolls = new int[childCount];
+ pageScrollChanged = true;
}
for (int i = startIndex; i != endIndex; i += delta) {
@@ -658,7 +676,11 @@
child.layout(childLeft, childTop,
childLeft + child.getMeasuredWidth(), childTop + childHeight);
- mPageScrolls[i] = childLeft - scrollOffsetLeft;
+ final int pageScroll = childLeft - scrollOffsetLeft;
+ if (mPageScrolls[i] != pageScroll) {
+ pageScrollChanged = true;
+ mPageScrolls[i] = pageScroll;
+ }
childLeft += childWidth + mPageSpacing + getChildGap();
}
@@ -693,7 +715,7 @@
mFirstLayout = false;
}
- if (mScroller.isFinished() && mChildCountOnLastLayout != childCount) {
+ if (mScroller.isFinished() && pageScrollChanged) {
setCurrentPage(getNextPage());
}
mChildCountOnLastLayout = childCount;
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index e6aa6be..8fb0e1c 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -22,7 +22,6 @@
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.SPRING_LOADED;
-import static com.android.launcher3.compat.AccessibilityManagerCompat.isAccessibilityEnabled;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -48,7 +47,6 @@
import android.os.UserHandle;
import android.util.AttributeSet;
import android.util.Log;
-import android.util.Property;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -3354,13 +3352,13 @@
@Override
public int getExpectedHeight() {
- return getMeasuredHeight() <= 0
+ return getMeasuredHeight() <= 0 || !mIsLayoutValid
? mLauncher.getDeviceProfile().heightPx : getMeasuredHeight();
}
@Override
public int getExpectedWidth() {
- return getMeasuredWidth() <= 0
+ return getMeasuredWidth() <= 0 || !mIsLayoutValid
? mLauncher.getDeviceProfile().widthPx : getMeasuredWidth();
}