Snap for 12406339 from e792bc3a5c to 24Q4-release
Change-Id: I590e4d80112ab1b36a8070d921dd090b96ed34b3
This commit is contained in:
@@ -24,7 +24,6 @@ import static com.android.launcher3.taskbar.TaskbarLauncherStateController.FLAG_
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.graphics.Rect;
|
||||
import android.window.RemoteTransition;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -189,24 +188,6 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
|
||||
placeholderDuration));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bounds of launcher's hotseat.
|
||||
*/
|
||||
public void getHotseatBounds(Rect hotseatBoundsOut) {
|
||||
DeviceProfile launcherDP = mLauncher.getDeviceProfile();
|
||||
if (launcherDP.isQsbInline) {
|
||||
// Not currently supported.
|
||||
hotseatBoundsOut.setEmpty();
|
||||
return;
|
||||
}
|
||||
int left = (launcherDP.widthPx - launcherDP.getHotseatWidthPx()
|
||||
- mLauncher.getHotseat().getUnusedHorizontalSpace()) / 2;
|
||||
int right = left + launcherDP.getHotseatWidthPx();
|
||||
int bottom = launcherDP.getHotseatLayoutPadding(mLauncher).bottom;
|
||||
int top = bottom - launcherDP.hotseatCellHeightPx;
|
||||
hotseatBoundsOut.set(left, top, right, bottom);
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be called from onResume() and onPause(), and animates the Taskbar accordingly.
|
||||
*/
|
||||
|
||||
@@ -208,11 +208,8 @@ public class StashedHandleViewController implements TaskbarControllers.LoggableT
|
||||
* Creates and returns a {@link RevealOutlineAnimation} Animator that updates the stashed handle
|
||||
* shape and size. When stashed, the shape is a thin rounded pill. When unstashed, the shape
|
||||
* morphs into the size of where the taskbar icons will be.
|
||||
*
|
||||
* @param taskbarToHotseatOffsets A Rect of offsets used to transform the bounds of the
|
||||
* stashed handle to wrap around the hotseat items.
|
||||
*/
|
||||
public Animator createRevealAnimToIsStashed(boolean isStashed, Rect taskbarToHotseatOffsets) {
|
||||
public Animator createRevealAnimToIsStashed(boolean isStashed) {
|
||||
Rect visualBounds = mControllers.taskbarViewController.getIconLayoutVisualBounds();
|
||||
float startRadius = mStashedHandleRadius;
|
||||
|
||||
@@ -223,13 +220,6 @@ public class StashedHandleViewController implements TaskbarControllers.LoggableT
|
||||
visualBounds.bottom += heightDiff;
|
||||
|
||||
startRadius = visualBounds.height() / 2f;
|
||||
|
||||
// We use these offsets to create a larger stashed handle to wrap around the items
|
||||
// of the hotseat. This is only used for certain animations.
|
||||
visualBounds.top += taskbarToHotseatOffsets.top;
|
||||
visualBounds.bottom += taskbarToHotseatOffsets.bottom;
|
||||
visualBounds.left += taskbarToHotseatOffsets.left;
|
||||
visualBounds.right += taskbarToHotseatOffsets.right;
|
||||
}
|
||||
|
||||
final RevealOutlineAnimation handleRevealProvider = new RoundedRectRevealOutlineProvider(
|
||||
|
||||
@@ -361,38 +361,6 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
|
||||
dispatchDeviceProfileChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the offsets needed to transform the transient taskbar bounds to the hotseat bounds.
|
||||
* @return The offsets will be stored in a Rect
|
||||
*/
|
||||
public Rect calculateTaskbarToHotseatOffsets(Rect hotseatBounds) {
|
||||
Rect taskbar = getTransientTaskbarBounds();
|
||||
Rect offsets = new Rect();
|
||||
|
||||
offsets.left = hotseatBounds.left - taskbar.left;
|
||||
offsets.right = hotseatBounds.right - taskbar.right;
|
||||
|
||||
int heightDiff = hotseatBounds.height() - taskbar.height();
|
||||
offsets.top = (taskbar.height() - heightDiff) / 2;
|
||||
|
||||
int gleanedTaskbarPadding = (mDeviceProfile.taskbarHeight
|
||||
- getTransientTaskbarBounds().height()) / 2;
|
||||
offsets.left -= gleanedTaskbarPadding;
|
||||
offsets.top -= gleanedTaskbarPadding;
|
||||
offsets.right += gleanedTaskbarPadding;
|
||||
|
||||
// Bottom is relative to the bottom of layout, so we can calculate it with padding included.
|
||||
offsets.bottom = (hotseatBounds.height() - taskbar.height()) / 2;
|
||||
|
||||
// Update bounds in taskbar background
|
||||
if (hotseatBounds.isEmpty()) {
|
||||
mDragLayer.getTaskbarToHotseatOffsetRect().setEmpty();
|
||||
} else {
|
||||
mDragLayer.getTaskbarToHotseatOffsetRect().set(offsets);
|
||||
}
|
||||
return offsets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the original DeviceProfile, match the number of hotseat icons and qsb width and update
|
||||
* the icon size
|
||||
@@ -1716,18 +1684,6 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
|
||||
return AnimatorPlaybackController.wrap(fullAnimation, duration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bounds of launcher's hotseat (if exists).
|
||||
*/
|
||||
public void getHotseatBounds(Rect hotseatBoundsOut) {
|
||||
TaskbarUIController uiController = mControllers.uiController;
|
||||
if (uiController instanceof LauncherTaskbarUIController launcherController) {
|
||||
launcherController.getHotseatBounds(hotseatBoundsOut);
|
||||
} else {
|
||||
hotseatBoundsOut.setEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when we determine the touchable region.
|
||||
*
|
||||
|
||||
@@ -21,7 +21,6 @@ import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.graphics.Paint
|
||||
import android.graphics.Path
|
||||
import android.graphics.Rect
|
||||
import android.graphics.RectF
|
||||
import com.android.app.animation.Interpolators
|
||||
import com.android.internal.policy.ScreenDecorationsUtils
|
||||
@@ -60,9 +59,6 @@ class TaskbarBackgroundRenderer(private val context: TaskbarActivityContext) {
|
||||
var translationYForSwipe = 0f
|
||||
var translationYForStash = 0f
|
||||
|
||||
// When not empty, we can use this to transform transient taskbar background to hotseat bounds.
|
||||
val taskbarToHotseatOffsetRect = Rect()
|
||||
|
||||
private val transientBackgroundBounds = context.transientTaskbarBounds
|
||||
|
||||
private val shadowAlpha: Float
|
||||
@@ -230,12 +226,6 @@ class TaskbarBackgroundRenderer(private val context: TaskbarActivityContext) {
|
||||
val radius = newBackgroundHeight / 2f
|
||||
val bottomMarginProgress = bottomMargin * ((1f - progress) / 2f)
|
||||
|
||||
// Used to transform the background so that it wraps around the items on the hotseat.
|
||||
val hotseatOffsetLeft = taskbarToHotseatOffsetRect.left * progress
|
||||
val hotseatOffsetTop = taskbarToHotseatOffsetRect.top * progress
|
||||
val hotseatOffsetRight = taskbarToHotseatOffsetRect.right * progress
|
||||
val hotseatOffsetBottom = taskbarToHotseatOffsetRect.bottom * progress
|
||||
|
||||
// Aligns the bottom with the bottom of the stashed handle.
|
||||
val bottom =
|
||||
canvas.height - bottomMargin +
|
||||
@@ -260,10 +250,10 @@ class TaskbarBackgroundRenderer(private val context: TaskbarActivityContext) {
|
||||
strokePaint.alpha = (paint.alpha * strokeAlpha) / 255
|
||||
|
||||
lastDrawnTransientRect.set(
|
||||
transientBackgroundBounds.left + halfWidthDelta + hotseatOffsetLeft,
|
||||
bottom - newBackgroundHeight + hotseatOffsetTop,
|
||||
transientBackgroundBounds.right - halfWidthDelta + hotseatOffsetRight,
|
||||
bottom + hotseatOffsetBottom,
|
||||
transientBackgroundBounds.left + halfWidthDelta,
|
||||
bottom - newBackgroundHeight,
|
||||
transientBackgroundBounds.right - halfWidthDelta,
|
||||
bottom
|
||||
)
|
||||
val horizontalInset = fullWidth * widthInsetPercentage
|
||||
lastDrawnTransientRect.inset(horizontalInset, 0f)
|
||||
|
||||
@@ -22,7 +22,6 @@ import static com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_NAVBAR_UN
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.media.permission.SafeCloseable;
|
||||
import android.util.AttributeSet;
|
||||
@@ -260,11 +259,6 @@ public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
|
||||
return mBackgroundRenderer.getLastDrawnTransientRect();
|
||||
}
|
||||
|
||||
/** Returns the rect used to transform transient taskbar to the hotseat */
|
||||
public Rect getTaskbarToHotseatOffsetRect() {
|
||||
return mBackgroundRenderer.getTaskbarToHotseatOffsetRect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||
TestLogging.recordMotionEvent(TestProtocol.SEQUENCE_MAIN, "Touch event", ev);
|
||||
|
||||
@@ -42,7 +42,6 @@ import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.app.RemoteAction;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
@@ -209,7 +208,6 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
* by not scaling the height of the taskbar background.
|
||||
*/
|
||||
private static final int TRANSITION_UNSTASH_SUW_MANUAL = 3;
|
||||
private static final Rect EMPTY_RECT = new Rect();
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(value = {
|
||||
@@ -771,7 +769,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
}
|
||||
|
||||
fullLengthAnimatorSet.play(mControllers.stashedHandleViewController
|
||||
.createRevealAnimToIsStashed(isStashed, EMPTY_RECT));
|
||||
.createRevealAnimToIsStashed(isStashed));
|
||||
// Return the stashed handle to its default scale in case it was changed as part of the
|
||||
// feedforward hint. Note that the reveal animation above also visually scales it.
|
||||
fullLengthAnimatorSet.play(mTaskbarStashedHandleHintScale.animateToValue(1f));
|
||||
@@ -821,19 +819,6 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Rect taskbarToHotseatOffsets = new Rect();
|
||||
if (enableScalingRevealHomeAnimation() && animationType == TRANSITION_HOME_TO_APP) {
|
||||
Rect hotseatRect = new Rect();
|
||||
mActivity.getHotseatBounds(hotseatRect);
|
||||
|
||||
// Calculate and store offsets so that we can sync with the taskbar stashed handle
|
||||
taskbarToHotseatOffsets.set(
|
||||
mActivity.calculateTaskbarToHotseatOffsets(hotseatRect));
|
||||
as.addListener(AnimatorListeners.forEndCallback(
|
||||
() -> mActivity.calculateTaskbarToHotseatOffsets(EMPTY_RECT)));
|
||||
}
|
||||
|
||||
play(as, mTaskbarStashedHandleAlpha.animateToValue(stashedHandleAlphaTarget),
|
||||
backgroundAndHandleAlphaStartDelay,
|
||||
backgroundAndHandleAlphaDuration, LINEAR);
|
||||
@@ -882,12 +867,10 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
}
|
||||
|
||||
mControllers.taskbarViewController.addRevealAnimToIsStashed(skippable, isStashed, duration,
|
||||
EMPHASIZED, animationType == TRANSITION_UNSTASH_SUW_MANUAL,
|
||||
animationType == TRANSITION_HOME_TO_APP);
|
||||
EMPHASIZED, animationType == TRANSITION_UNSTASH_SUW_MANUAL);
|
||||
|
||||
play(skippable, mControllers.stashedHandleViewController
|
||||
.createRevealAnimToIsStashed(isStashed, taskbarToHotseatOffsets), 0, duration,
|
||||
EMPHASIZED);
|
||||
.createRevealAnimToIsStashed(isStashed), 0, duration, EMPHASIZED);
|
||||
|
||||
// Return the stashed handle to its default scale in case it was changed as part of the
|
||||
// feedforward hint. Note that the reveal animation above also visually scales it.
|
||||
|
||||
@@ -36,7 +36,6 @@ import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_NAV_BAR_AN
|
||||
import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_TASKBAR_ALIGNMENT_ANIM;
|
||||
import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_TASKBAR_PINNING_ANIM;
|
||||
import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_TASKBAR_REVEAL_ANIM;
|
||||
import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorSet;
|
||||
@@ -671,8 +670,7 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
|
||||
* @param interpolator The interpolator to use for all animations.
|
||||
*/
|
||||
public void addRevealAnimToIsStashed(AnimatorSet as, boolean isStashed, long duration,
|
||||
Interpolator interpolator, boolean dispatchOnAnimationStart,
|
||||
boolean isHomeToAppAnimation) {
|
||||
Interpolator interpolator, boolean dispatchOnAnimationStart) {
|
||||
AnimatorSet reveal = new AnimatorSet();
|
||||
|
||||
Rect stashedBounds = new Rect();
|
||||
@@ -721,21 +719,8 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
|
||||
reveal.play(ObjectAnimator.ofFloat(mtd.getTranslationX(INDEX_TASKBAR_REVEAL_ANIM),
|
||||
MULTI_PROPERTY_VALUE, transX)
|
||||
.setDuration(duration));
|
||||
|
||||
if (enableScalingRevealHomeAnimation()) {
|
||||
// Delay y-translation by 1 frame to keep icons within the bounds of the bg.
|
||||
int delay = isHomeToAppAnimation ? getSingleFrameMs(mActivity) : 0;
|
||||
ObjectAnimator yAnimator =
|
||||
ObjectAnimator.ofFloat(mtd.getTranslationY(INDEX_TASKBAR_REVEAL_ANIM),
|
||||
MULTI_PROPERTY_VALUE, transY)
|
||||
.setDuration(Math.max(0, duration - delay));
|
||||
yAnimator.setStartDelay(delay);
|
||||
reveal.play(yAnimator);
|
||||
} else {
|
||||
reveal.play(
|
||||
ObjectAnimator.ofFloat(mtd.getTranslationY(INDEX_TASKBAR_REVEAL_ANIM),
|
||||
MULTI_PROPERTY_VALUE, transY));
|
||||
}
|
||||
reveal.play(ObjectAnimator.ofFloat(mtd.getTranslationY(INDEX_TASKBAR_REVEAL_ANIM),
|
||||
MULTI_PROPERTY_VALUE, transY));
|
||||
as.addListener(forEndCallback(() ->
|
||||
mtd.setTranslation(INDEX_TASKBAR_REVEAL_ANIM, 0, 0)));
|
||||
} else {
|
||||
|
||||
@@ -453,6 +453,10 @@ open class LandscapePagedViewHandler : RecentsPagedOrientationHandler {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param inSplitSelection Whether user currently has a task from this task group staged for
|
||||
* split screen. Currently this state is not reachable in fake landscape.
|
||||
*/
|
||||
override fun measureGroupedTaskViewThumbnailBounds(
|
||||
primarySnapshot: View,
|
||||
secondarySnapshot: View,
|
||||
@@ -460,7 +464,8 @@ open class LandscapePagedViewHandler : RecentsPagedOrientationHandler {
|
||||
parentHeight: Int,
|
||||
splitBoundsConfig: SplitBounds,
|
||||
dp: DeviceProfile,
|
||||
isRtl: Boolean
|
||||
isRtl: Boolean,
|
||||
inSplitSelection: Boolean
|
||||
) {
|
||||
val primaryParams = primarySnapshot.layoutParams as FrameLayout.LayoutParams
|
||||
val secondaryParams = secondarySnapshot.layoutParams as FrameLayout.LayoutParams
|
||||
@@ -569,6 +574,10 @@ open class LandscapePagedViewHandler : RecentsPagedOrientationHandler {
|
||||
iconAppChipView.setRotation(degreesRotated)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param inSplitSelection Whether user currently has a task from this task group staged for
|
||||
* split screen. Currently this state is not reachable in fake landscape.
|
||||
*/
|
||||
override fun setSplitIconParams(
|
||||
primaryIconView: View,
|
||||
secondaryIconView: View,
|
||||
@@ -579,7 +588,8 @@ open class LandscapePagedViewHandler : RecentsPagedOrientationHandler {
|
||||
groupedTaskViewWidth: Int,
|
||||
isRtl: Boolean,
|
||||
deviceProfile: DeviceProfile,
|
||||
splitConfig: SplitBounds
|
||||
splitConfig: SplitBounds,
|
||||
inSplitSelection: Boolean
|
||||
) {
|
||||
val spaceAboveSnapshot = deviceProfile.overviewTaskThumbnailTopMarginPx
|
||||
val totalThumbnailHeight = groupedTaskViewHeight - spaceAboveSnapshot
|
||||
|
||||
@@ -530,10 +530,16 @@ public class PortraitPagedViewHandler extends DefaultPagedViewHandler implements
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param inSplitSelection Whether user currently has a task from this task group staged for
|
||||
* split screen. If true, we have custom translations/scaling in place
|
||||
* for the remaining snapshot, so we'll skip setting translation/scale
|
||||
* here.
|
||||
*/
|
||||
@Override
|
||||
public void measureGroupedTaskViewThumbnailBounds(View primarySnapshot, View secondarySnapshot,
|
||||
int parentWidth, int parentHeight, SplitBounds splitBoundsConfig,
|
||||
DeviceProfile dp, boolean isRtl) {
|
||||
DeviceProfile dp, boolean isRtl, boolean inSplitSelection) {
|
||||
int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx;
|
||||
|
||||
FrameLayout.LayoutParams primaryParams =
|
||||
@@ -541,11 +547,10 @@ public class PortraitPagedViewHandler extends DefaultPagedViewHandler implements
|
||||
FrameLayout.LayoutParams secondaryParams =
|
||||
(FrameLayout.LayoutParams) secondarySnapshot.getLayoutParams();
|
||||
|
||||
// Reset margin and translations that aren't used in this method, but are used in other
|
||||
// Reset margins that aren't used in this method, but are used in other
|
||||
// `RecentsPagedOrientationHandler` variants.
|
||||
secondaryParams.topMargin = 0;
|
||||
primaryParams.topMargin = spaceAboveSnapshot;
|
||||
primarySnapshot.setTranslationY(0);
|
||||
|
||||
int totalThumbnailHeight = parentHeight - spaceAboveSnapshot;
|
||||
float dividerScale = splitBoundsConfig.appsStackedVertically
|
||||
@@ -553,28 +558,35 @@ public class PortraitPagedViewHandler extends DefaultPagedViewHandler implements
|
||||
: splitBoundsConfig.dividerWidthPercent;
|
||||
Pair<Point, Point> taskViewSizes =
|
||||
getGroupedTaskViewSizes(dp, splitBoundsConfig, parentWidth, parentHeight);
|
||||
if (dp.isLeftRightSplit) {
|
||||
int scaledDividerBar = Math.round(parentWidth * dividerScale);
|
||||
if (isRtl) {
|
||||
int translationX = taskViewSizes.second.x + scaledDividerBar;
|
||||
primarySnapshot.setTranslationX(-translationX);
|
||||
secondarySnapshot.setTranslationX(0);
|
||||
if (!inSplitSelection) {
|
||||
// Reset translations that aren't used in this method, but are used in other
|
||||
// `RecentsPagedOrientationHandler` variants.
|
||||
primarySnapshot.setTranslationY(0);
|
||||
|
||||
if (dp.isLeftRightSplit) {
|
||||
int scaledDividerBar = Math.round(parentWidth * dividerScale);
|
||||
if (isRtl) {
|
||||
int translationX = taskViewSizes.second.x + scaledDividerBar;
|
||||
primarySnapshot.setTranslationX(-translationX);
|
||||
secondarySnapshot.setTranslationX(0);
|
||||
} else {
|
||||
int translationX = taskViewSizes.first.x + scaledDividerBar;
|
||||
secondarySnapshot.setTranslationX(translationX);
|
||||
primarySnapshot.setTranslationX(0);
|
||||
}
|
||||
secondarySnapshot.setTranslationY(spaceAboveSnapshot);
|
||||
} else {
|
||||
int translationX = taskViewSizes.first.x + scaledDividerBar;
|
||||
secondarySnapshot.setTranslationX(translationX);
|
||||
float finalDividerHeight = Math.round(totalThumbnailHeight * dividerScale);
|
||||
float translationY =
|
||||
taskViewSizes.first.y + spaceAboveSnapshot + finalDividerHeight;
|
||||
secondarySnapshot.setTranslationY(translationY);
|
||||
|
||||
// Reset unused translations.
|
||||
secondarySnapshot.setTranslationX(0);
|
||||
primarySnapshot.setTranslationX(0);
|
||||
}
|
||||
|
||||
secondarySnapshot.setTranslationY(spaceAboveSnapshot);
|
||||
} else {
|
||||
float finalDividerHeight = Math.round(totalThumbnailHeight * dividerScale);
|
||||
float translationY = taskViewSizes.first.y + spaceAboveSnapshot + finalDividerHeight;
|
||||
secondarySnapshot.setTranslationY(translationY);
|
||||
|
||||
// Reset unused translations.
|
||||
secondarySnapshot.setTranslationX(0);
|
||||
primarySnapshot.setTranslationX(0);
|
||||
}
|
||||
|
||||
primarySnapshot.measure(
|
||||
View.MeasureSpec.makeMeasureSpec(taskViewSizes.first.x, View.MeasureSpec.EXACTLY),
|
||||
View.MeasureSpec.makeMeasureSpec(taskViewSizes.first.y, View.MeasureSpec.EXACTLY));
|
||||
@@ -582,10 +594,6 @@ public class PortraitPagedViewHandler extends DefaultPagedViewHandler implements
|
||||
View.MeasureSpec.makeMeasureSpec(taskViewSizes.second.x, View.MeasureSpec.EXACTLY),
|
||||
View.MeasureSpec.makeMeasureSpec(taskViewSizes.second.y,
|
||||
View.MeasureSpec.EXACTLY));
|
||||
primarySnapshot.setScaleX(1);
|
||||
secondarySnapshot.setScaleX(1);
|
||||
primarySnapshot.setScaleY(1);
|
||||
secondarySnapshot.setScaleY(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -662,11 +670,16 @@ public class PortraitPagedViewHandler extends DefaultPagedViewHandler implements
|
||||
iconAppChipView.setRotation(getDegreesRotated());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param inSplitSelection Whether user currently has a task from this task group staged for
|
||||
* split screen. If true, we have custom translations in place for the
|
||||
* remaining icon, so we'll skip setting translations here.
|
||||
*/
|
||||
@Override
|
||||
public void setSplitIconParams(View primaryIconView, View secondaryIconView,
|
||||
int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight,
|
||||
int groupedTaskViewHeight, int groupedTaskViewWidth, boolean isRtl,
|
||||
DeviceProfile deviceProfile, SplitBounds splitConfig) {
|
||||
DeviceProfile deviceProfile, SplitBounds splitConfig, boolean inSplitSelection) {
|
||||
FrameLayout.LayoutParams primaryIconParams =
|
||||
(FrameLayout.LayoutParams) primaryIconView.getLayoutParams();
|
||||
FrameLayout.LayoutParams secondaryIconParams = enableOverviewIconMenu()
|
||||
@@ -680,20 +693,23 @@ public class PortraitPagedViewHandler extends DefaultPagedViewHandler implements
|
||||
secondaryIconParams.gravity = TOP | START;
|
||||
secondaryIconParams.topMargin = primaryIconParams.topMargin;
|
||||
secondaryIconParams.setMarginStart(primaryIconParams.getMarginStart());
|
||||
if (deviceProfile.isLeftRightSplit) {
|
||||
if (isRtl) {
|
||||
int secondarySnapshotWidth = groupedTaskViewWidth - primarySnapshotWidth;
|
||||
primaryAppChipView.setSplitTranslationX(-secondarySnapshotWidth);
|
||||
if (!inSplitSelection) {
|
||||
if (deviceProfile.isLeftRightSplit) {
|
||||
if (isRtl) {
|
||||
int secondarySnapshotWidth = groupedTaskViewWidth - primarySnapshotWidth;
|
||||
primaryAppChipView.setSplitTranslationX(-secondarySnapshotWidth);
|
||||
} else {
|
||||
secondaryAppChipView.setSplitTranslationX(primarySnapshotWidth);
|
||||
}
|
||||
} else {
|
||||
secondaryAppChipView.setSplitTranslationX(primarySnapshotWidth);
|
||||
primaryAppChipView.setSplitTranslationX(0);
|
||||
secondaryAppChipView.setSplitTranslationX(0);
|
||||
int dividerThickness = Math.min(splitConfig.visualDividerBounds.width(),
|
||||
splitConfig.visualDividerBounds.height());
|
||||
secondaryAppChipView.setSplitTranslationY(
|
||||
primarySnapshotHeight + (deviceProfile.isTablet ? 0
|
||||
: dividerThickness));
|
||||
}
|
||||
} else {
|
||||
primaryAppChipView.setSplitTranslationX(0);
|
||||
secondaryAppChipView.setSplitTranslationX(0);
|
||||
int dividerThickness = Math.min(splitConfig.visualDividerBounds.width(),
|
||||
splitConfig.visualDividerBounds.height());
|
||||
secondaryAppChipView.setSplitTranslationY(
|
||||
primarySnapshotHeight + (deviceProfile.isTablet ? 0 : dividerThickness));
|
||||
}
|
||||
} else if (deviceProfile.isLeftRightSplit) {
|
||||
// We calculate the "midpoint" of the thumbnail area, and place the icons there.
|
||||
@@ -716,46 +732,53 @@ public class PortraitPagedViewHandler extends DefaultPagedViewHandler implements
|
||||
if (deviceProfile.isSeascape()) {
|
||||
primaryIconParams.gravity = TOP | (isRtl ? END : START);
|
||||
secondaryIconParams.gravity = TOP | (isRtl ? END : START);
|
||||
if (splitConfig.initiatedFromSeascape) {
|
||||
// if the split was initiated from seascape,
|
||||
// the task on the right (secondary) is slightly larger
|
||||
primaryIconView.setTranslationX(bottomToMidpointOffset - taskIconHeight);
|
||||
secondaryIconView.setTranslationX(bottomToMidpointOffset);
|
||||
} else {
|
||||
// if not,
|
||||
// the task on the left (primary) is slightly larger
|
||||
primaryIconView.setTranslationX(bottomToMidpointOffset + insetOffset
|
||||
- taskIconHeight);
|
||||
secondaryIconView.setTranslationX(bottomToMidpointOffset + insetOffset);
|
||||
if (!inSplitSelection) {
|
||||
if (splitConfig.initiatedFromSeascape) {
|
||||
// if the split was initiated from seascape,
|
||||
// the task on the right (secondary) is slightly larger
|
||||
primaryIconView.setTranslationX(bottomToMidpointOffset - taskIconHeight);
|
||||
secondaryIconView.setTranslationX(bottomToMidpointOffset);
|
||||
} else {
|
||||
// if not,
|
||||
// the task on the left (primary) is slightly larger
|
||||
primaryIconView.setTranslationX(bottomToMidpointOffset + insetOffset
|
||||
- taskIconHeight);
|
||||
secondaryIconView.setTranslationX(bottomToMidpointOffset + insetOffset);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
primaryIconParams.gravity = TOP | (isRtl ? START : END);
|
||||
secondaryIconParams.gravity = TOP | (isRtl ? START : END);
|
||||
if (!splitConfig.initiatedFromSeascape) {
|
||||
// if the split was initiated from landscape,
|
||||
// the task on the left (primary) is slightly larger
|
||||
primaryIconView.setTranslationX(-bottomToMidpointOffset);
|
||||
secondaryIconView.setTranslationX(-bottomToMidpointOffset + taskIconHeight);
|
||||
} else {
|
||||
// if not,
|
||||
// the task on the right (secondary) is slightly larger
|
||||
primaryIconView.setTranslationX(-bottomToMidpointOffset - insetOffset);
|
||||
secondaryIconView.setTranslationX(-bottomToMidpointOffset - insetOffset
|
||||
+ taskIconHeight);
|
||||
if (!inSplitSelection) {
|
||||
if (!splitConfig.initiatedFromSeascape) {
|
||||
// if the split was initiated from landscape,
|
||||
// the task on the left (primary) is slightly larger
|
||||
primaryIconView.setTranslationX(-bottomToMidpointOffset);
|
||||
secondaryIconView.setTranslationX(-bottomToMidpointOffset + taskIconHeight);
|
||||
} else {
|
||||
// if not,
|
||||
// the task on the right (secondary) is slightly larger
|
||||
primaryIconView.setTranslationX(-bottomToMidpointOffset - insetOffset);
|
||||
secondaryIconView.setTranslationX(-bottomToMidpointOffset - insetOffset
|
||||
+ taskIconHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
primaryIconParams.gravity = TOP | CENTER_HORIZONTAL;
|
||||
// shifts icon half a width left (height is used here since icons are square)
|
||||
primaryIconView.setTranslationX(-(taskIconHeight / 2f));
|
||||
secondaryIconParams.gravity = TOP | CENTER_HORIZONTAL;
|
||||
secondaryIconView.setTranslationX(taskIconHeight / 2f);
|
||||
if (!inSplitSelection) {
|
||||
// shifts icon half a width left (height is used here since icons are square)
|
||||
primaryIconView.setTranslationX(-(taskIconHeight / 2f));
|
||||
secondaryIconView.setTranslationX(taskIconHeight / 2f);
|
||||
}
|
||||
}
|
||||
if (!enableOverviewIconMenu()) {
|
||||
if (!enableOverviewIconMenu() && !inSplitSelection) {
|
||||
primaryIconView.setTranslationY(0);
|
||||
secondaryIconView.setTranslationY(0);
|
||||
}
|
||||
|
||||
|
||||
primaryIconView.setLayoutParams(primaryIconParams);
|
||||
secondaryIconView.setLayoutParams(secondaryIconParams);
|
||||
}
|
||||
|
||||
@@ -184,7 +184,8 @@ interface RecentsPagedOrientationHandler : PagedOrientationHandler {
|
||||
parentHeight: Int,
|
||||
splitBoundsConfig: SplitConfigurationOptions.SplitBounds,
|
||||
dp: DeviceProfile,
|
||||
isRtl: Boolean
|
||||
isRtl: Boolean,
|
||||
inSplitSelection: Boolean
|
||||
)
|
||||
|
||||
/**
|
||||
@@ -235,7 +236,8 @@ interface RecentsPagedOrientationHandler : PagedOrientationHandler {
|
||||
groupedTaskViewWidth: Int,
|
||||
isRtl: Boolean,
|
||||
deviceProfile: DeviceProfile,
|
||||
splitConfig: SplitConfigurationOptions.SplitBounds
|
||||
splitConfig: SplitConfigurationOptions.SplitBounds,
|
||||
inSplitSelection: Boolean
|
||||
)
|
||||
|
||||
/*
|
||||
|
||||
@@ -277,6 +277,10 @@ class SeascapePagedViewHandler : LandscapePagedViewHandler() {
|
||||
iconAppChipView.setRotation(degreesRotated)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param inSplitSelection Whether user currently has a task from this task group staged for
|
||||
* split screen. Currently this state is not reachable in fake seascape.
|
||||
*/
|
||||
override fun measureGroupedTaskViewThumbnailBounds(
|
||||
primarySnapshot: View,
|
||||
secondarySnapshot: View,
|
||||
@@ -284,7 +288,8 @@ class SeascapePagedViewHandler : LandscapePagedViewHandler() {
|
||||
parentHeight: Int,
|
||||
splitBoundsConfig: SplitBounds,
|
||||
dp: DeviceProfile,
|
||||
isRtl: Boolean
|
||||
isRtl: Boolean,
|
||||
inSplitSelection: Boolean
|
||||
) {
|
||||
val primaryParams = primarySnapshot.layoutParams as FrameLayout.LayoutParams
|
||||
val secondaryParams = secondarySnapshot.layoutParams as FrameLayout.LayoutParams
|
||||
|
||||
@@ -42,6 +42,8 @@ import android.window.TransitionInfo
|
||||
import android.window.TransitionInfo.Change
|
||||
import android.window.WindowContainerToken
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.core.util.component1
|
||||
import androidx.core.util.component2
|
||||
import com.android.app.animation.Interpolators
|
||||
import com.android.launcher3.DeviceProfile
|
||||
import com.android.launcher3.Flags.enableOverviewIconMenu
|
||||
@@ -225,10 +227,22 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC
|
||||
ObjectAnimator.ofFloat(iconView.splitTranslationY, MULTI_PROPERTY_VALUE, 0f)
|
||||
)
|
||||
}
|
||||
|
||||
val splitBoundsConfig =
|
||||
(taskContainer.taskView as? GroupedTaskView)?.splitBoundsConfig ?: return
|
||||
val (primarySnapshotViewSize, secondarySnapshotViewSize) =
|
||||
taskContainer.taskView.pagedOrientationHandler.getGroupedTaskViewSizes(
|
||||
deviceProfile,
|
||||
splitBoundsConfig,
|
||||
taskViewWidth,
|
||||
taskViewHeight,
|
||||
)
|
||||
val snapshotViewSize =
|
||||
if (isPrimaryTaskSplitting) primarySnapshotViewSize else secondarySnapshotViewSize
|
||||
if (deviceProfile.isLeftRightSplit) {
|
||||
// Center view first so scaling happens uniformly, alternatively we can move pivotX to 0
|
||||
val centerThumbnailTranslationX: Float = (taskViewWidth - snapshot.width) / 2f
|
||||
val finalScaleX: Float = taskViewWidth.toFloat() / snapshot.width
|
||||
val centerThumbnailTranslationX: Float = (taskViewWidth - snapshotViewSize.x) / 2f
|
||||
val finalScaleX: Float = taskViewWidth.toFloat() / snapshotViewSize.x
|
||||
builder.add(
|
||||
ObjectAnimator.ofFloat(snapshot, View.TRANSLATION_X, centerThumbnailTranslationX)
|
||||
)
|
||||
@@ -262,13 +276,13 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC
|
||||
// thumbnail needs to take that into account. We should migrate to only using
|
||||
// translations otherwise this asymmetry causes problems..
|
||||
if (isPrimaryTaskSplitting) {
|
||||
centerThumbnailTranslationY = (thumbnailSize - snapshot.height) / 2f
|
||||
centerThumbnailTranslationY = (thumbnailSize - snapshotViewSize.y) / 2f
|
||||
centerThumbnailTranslationY +=
|
||||
deviceProfile.overviewTaskThumbnailTopMarginPx.toFloat()
|
||||
} else {
|
||||
centerThumbnailTranslationY = (thumbnailSize - snapshot.height) / 2f
|
||||
centerThumbnailTranslationY = (thumbnailSize - snapshotViewSize.y) / 2f
|
||||
}
|
||||
val finalScaleY: Float = thumbnailSize.toFloat() / snapshot.height
|
||||
val finalScaleY: Float = thumbnailSize.toFloat() / snapshotViewSize.y
|
||||
builder.add(
|
||||
ObjectAnimator.ofFloat(snapshot, View.TRANSLATION_Y, centerThumbnailTranslationY)
|
||||
)
|
||||
|
||||
@@ -65,31 +65,18 @@ class GroupedTaskView @JvmOverloads constructor(context: Context, attrs: Attribu
|
||||
val heightSize = MeasureSpec.getSize(heightMeasureSpec)
|
||||
setMeasuredDimension(widthSize, heightSize)
|
||||
val splitBoundsConfig = splitBoundsConfig ?: return
|
||||
val initSplitTaskId = getThisTaskCurrentlyInSplitSelection()
|
||||
if (initSplitTaskId == INVALID_TASK_ID) {
|
||||
pagedOrientationHandler.measureGroupedTaskViewThumbnailBounds(
|
||||
taskContainers[0].snapshotView,
|
||||
taskContainers[1].snapshotView,
|
||||
widthSize,
|
||||
heightSize,
|
||||
splitBoundsConfig,
|
||||
container.deviceProfile,
|
||||
layoutDirection == LAYOUT_DIRECTION_RTL
|
||||
)
|
||||
} else {
|
||||
// Currently being split with this taskView, let the non-split selected thumbnail
|
||||
// take up full thumbnail area
|
||||
taskContainers
|
||||
.firstOrNull { it.task.key.id != initSplitTaskId }
|
||||
?.snapshotView
|
||||
?.measure(
|
||||
widthMeasureSpec,
|
||||
MeasureSpec.makeMeasureSpec(
|
||||
heightSize - container.deviceProfile.overviewTaskThumbnailTopMarginPx,
|
||||
MeasureSpec.EXACTLY
|
||||
)
|
||||
)
|
||||
}
|
||||
val inSplitSelection = getThisTaskCurrentlyInSplitSelection() != INVALID_TASK_ID
|
||||
pagedOrientationHandler.measureGroupedTaskViewThumbnailBounds(
|
||||
taskContainers[0].snapshotView,
|
||||
taskContainers[1].snapshotView,
|
||||
widthSize,
|
||||
heightSize,
|
||||
splitBoundsConfig,
|
||||
container.deviceProfile,
|
||||
layoutDirection == LAYOUT_DIRECTION_RTL,
|
||||
inSplitSelection,
|
||||
)
|
||||
|
||||
if (!enableOverviewIconMenu()) {
|
||||
updateIconPlacement()
|
||||
}
|
||||
@@ -173,6 +160,8 @@ class GroupedTaskView @JvmOverloads constructor(context: Context, attrs: Attribu
|
||||
val splitBoundsConfig = splitBoundsConfig ?: return
|
||||
val taskIconHeight = container.deviceProfile.overviewTaskIconSizePx
|
||||
val isRtl = layoutDirection == LAYOUT_DIRECTION_RTL
|
||||
val inSplitSelection = getThisTaskCurrentlyInSplitSelection() != INVALID_TASK_ID
|
||||
|
||||
if (enableOverviewIconMenu()) {
|
||||
val groupedTaskViewSizes =
|
||||
pagedOrientationHandler.getGroupedTaskViewSizes(
|
||||
@@ -191,7 +180,8 @@ class GroupedTaskView @JvmOverloads constructor(context: Context, attrs: Attribu
|
||||
layoutParams.width,
|
||||
isRtl,
|
||||
container.deviceProfile,
|
||||
splitBoundsConfig
|
||||
splitBoundsConfig,
|
||||
inSplitSelection
|
||||
)
|
||||
} else {
|
||||
pagedOrientationHandler.setSplitIconParams(
|
||||
@@ -204,7 +194,8 @@ class GroupedTaskView @JvmOverloads constructor(context: Context, attrs: Attribu
|
||||
measuredWidth,
|
||||
isRtl,
|
||||
container.deviceProfile,
|
||||
splitBoundsConfig
|
||||
splitBoundsConfig,
|
||||
inSplitSelection
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4994,7 +4994,8 @@ public abstract class RecentsView<
|
||||
mSplitSelectStateController.getSplitAnimationController()
|
||||
.addInitialSplitFromPair(taskContainer, builder,
|
||||
mContainer.getDeviceProfile(),
|
||||
mSplitHiddenTaskView.getWidth(), mSplitHiddenTaskView.getHeight(),
|
||||
mSplitHiddenTaskView.getLayoutParams().width,
|
||||
mSplitHiddenTaskView.getLayoutParams().height,
|
||||
primaryTaskSelected);
|
||||
builder.addOnFrameCallback(() -> {
|
||||
if (!enableRefactorTaskThumbnail()) {
|
||||
|
||||
@@ -160,6 +160,8 @@ class TaskContainer(
|
||||
if (enableRefactorTaskThumbnail()) {
|
||||
taskView.removeView(thumbnailView)
|
||||
}
|
||||
snapshotView.scaleX = 1f
|
||||
snapshotView.scaleY = 1f
|
||||
overlay.destroy()
|
||||
}
|
||||
|
||||
|
||||
@@ -1056,6 +1056,7 @@ public class DeviceProfile {
|
||||
return mHotseatColumnSpan;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public int getHotseatWidthPx() {
|
||||
return mHotseatWidthPx;
|
||||
}
|
||||
|
||||
@@ -28,8 +28,6 @@ import android.content.ComponentName;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.database.DatabaseUtils;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
@@ -47,7 +45,6 @@ import com.android.launcher3.LauncherSettings;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.pm.InstallSessionHelper;
|
||||
import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
|
||||
import com.android.launcher3.util.ContentWriter;
|
||||
import com.android.launcher3.util.GridOccupancy;
|
||||
@@ -100,7 +97,7 @@ public class GridSizeMigrationUtil {
|
||||
@VisibleForTesting
|
||||
public static List<DbEntry> readAllEntries(SQLiteDatabase db, String tableName,
|
||||
Context context) {
|
||||
DbReader dbReader = new DbReader(db, tableName, context, getValidPackages(context));
|
||||
DbReader dbReader = new DbReader(db, tableName, context);
|
||||
List<DbEntry> result = dbReader.loadAllWorkspaceEntries();
|
||||
result.addAll(dbReader.loadHotseatEntries());
|
||||
return result;
|
||||
@@ -144,11 +141,10 @@ public class GridSizeMigrationUtil {
|
||||
}
|
||||
copyTable(source, TABLE_NAME, target.getWritableDatabase(), TMP_TABLE, context);
|
||||
|
||||
HashSet<String> validPackages = getValidPackages(context);
|
||||
long migrationStartTime = System.currentTimeMillis();
|
||||
try (SQLiteTransaction t = new SQLiteTransaction(target.getWritableDatabase())) {
|
||||
DbReader srcReader = new DbReader(t.getDb(), TMP_TABLE, context, validPackages);
|
||||
DbReader destReader = new DbReader(t.getDb(), TABLE_NAME, context, validPackages);
|
||||
DbReader srcReader = new DbReader(t.getDb(), TMP_TABLE, context);
|
||||
DbReader destReader = new DbReader(t.getDb(), TABLE_NAME, context);
|
||||
|
||||
Point targetSize = new Point(destDeviceState.getColumns(), destDeviceState.getRows());
|
||||
migrate(target, srcReader, destReader, destDeviceState.getNumHotseat(),
|
||||
@@ -348,23 +344,6 @@ public class GridSizeMigrationUtil {
|
||||
Utilities.createDbSelectionQuery(LauncherSettings.Favorites._ID, entryIds), null);
|
||||
}
|
||||
|
||||
private static HashSet<String> getValidPackages(Context context) {
|
||||
// Initialize list of valid packages. This contain all the packages which are already on
|
||||
// the device and packages which are being installed. Any item which doesn't belong to
|
||||
// this set is removed.
|
||||
// Since the loader removes such items anyway, removing these items here doesn't cause
|
||||
// any extra data loss and gives us more free space on the grid for better migration.
|
||||
HashSet<String> validPackages = new HashSet<>();
|
||||
for (PackageInfo info : context.getPackageManager()
|
||||
.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES)) {
|
||||
validPackages.add(info.packageName);
|
||||
}
|
||||
InstallSessionHelper.INSTANCE.get(context)
|
||||
.getActiveSessions().keySet()
|
||||
.forEach(packageUserKey -> validPackages.add(packageUserKey.mPackageName));
|
||||
return validPackages;
|
||||
}
|
||||
|
||||
private static void solveGridPlacement(@NonNull final DatabaseHelper helper,
|
||||
@NonNull final DbReader srcReader, @NonNull final DbReader destReader,
|
||||
final int screenId, final int trgX, final int trgY,
|
||||
@@ -461,18 +440,15 @@ public class GridSizeMigrationUtil {
|
||||
private final SQLiteDatabase mDb;
|
||||
private final String mTableName;
|
||||
private final Context mContext;
|
||||
private final Set<String> mValidPackages;
|
||||
private int mLastScreenId = -1;
|
||||
|
||||
private final Map<Integer, ArrayList<DbEntry>> mWorkspaceEntriesByScreenId =
|
||||
new ArrayMap<>();
|
||||
|
||||
public DbReader(SQLiteDatabase db, String tableName, Context context,
|
||||
Set<String> validPackages) {
|
||||
public DbReader(SQLiteDatabase db, String tableName, Context context) {
|
||||
mDb = db;
|
||||
mTableName = tableName;
|
||||
mContext = context;
|
||||
mValidPackages = validPackages;
|
||||
}
|
||||
|
||||
protected List<DbEntry> loadHotseatEntries() {
|
||||
@@ -504,7 +480,6 @@ public class GridSizeMigrationUtil {
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: {
|
||||
entry.mIntent = c.getString(indexIntent);
|
||||
verifyIntent(c.getString(indexIntent));
|
||||
break;
|
||||
}
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: {
|
||||
@@ -586,14 +561,12 @@ public class GridSizeMigrationUtil {
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: {
|
||||
entry.mIntent = c.getString(indexIntent);
|
||||
verifyIntent(entry.mIntent);
|
||||
break;
|
||||
}
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: {
|
||||
entry.mProvider = c.getString(indexAppWidgetProvider);
|
||||
entry.appWidgetId = c.getInt(indexAppWidgetId);
|
||||
ComponentName cn = ComponentName.unflattenFromString(entry.mProvider);
|
||||
verifyPackage(cn.getPackageName());
|
||||
|
||||
LauncherAppWidgetProviderInfo pInfo = widgetManagerHelper
|
||||
.getLauncherAppWidgetInfo(entry.appWidgetId, cn);
|
||||
@@ -656,7 +629,6 @@ public class GridSizeMigrationUtil {
|
||||
try {
|
||||
int id = c.getInt(0);
|
||||
String intent = c.getString(1);
|
||||
verifyIntent(intent);
|
||||
total++;
|
||||
if (!entry.mFolderItems.containsKey(intent)) {
|
||||
entry.mFolderItems.put(intent, new HashSet<>());
|
||||
@@ -673,27 +645,6 @@ public class GridSizeMigrationUtil {
|
||||
private Cursor queryWorkspace(String[] columns, String where) {
|
||||
return mDb.query(mTableName, columns, where, null, null, null, null);
|
||||
}
|
||||
|
||||
/** Verifies if the mIntent should be restored. */
|
||||
private void verifyIntent(String intentStr)
|
||||
throws Exception {
|
||||
Intent intent = Intent.parseUri(intentStr, 0);
|
||||
if (intent.getComponent() != null) {
|
||||
verifyPackage(intent.getComponent().getPackageName());
|
||||
} else if (intent.getPackage() != null) {
|
||||
// Only verify package if the component was null.
|
||||
verifyPackage(intent.getPackage());
|
||||
}
|
||||
}
|
||||
|
||||
/** Verifies if the package should be restored */
|
||||
private void verifyPackage(String packageName)
|
||||
throws Exception {
|
||||
if (!mValidPackages.contains(packageName)) {
|
||||
// TODO(b/151468819): Handle promise app icon restoration during grid migration.
|
||||
throw new Exception("Package not available");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class DbEntry extends ItemInfo implements Comparable<DbEntry> {
|
||||
|
||||
+56
-83
@@ -45,7 +45,6 @@ class GridSizeMigrationUtilTest {
|
||||
|
||||
private lateinit var modelHelper: LauncherModelHelper
|
||||
private lateinit var context: Context
|
||||
private lateinit var validPackages: Set<String>
|
||||
private lateinit var idp: InvariantDeviceProfile
|
||||
private lateinit var dbHelper: DatabaseHelper
|
||||
private lateinit var db: SQLiteDatabase
|
||||
@@ -68,24 +67,10 @@ class GridSizeMigrationUtilTest {
|
||||
DatabaseHelper(
|
||||
context,
|
||||
null,
|
||||
UserCache.INSTANCE.get(context)::getSerialNumberForUser
|
||||
UserCache.INSTANCE.get(context)::getSerialNumberForUser,
|
||||
) {}
|
||||
db = dbHelper.writableDatabase
|
||||
|
||||
validPackages =
|
||||
setOf(
|
||||
testPackage1,
|
||||
testPackage2,
|
||||
testPackage3,
|
||||
testPackage4,
|
||||
testPackage5,
|
||||
testPackage6,
|
||||
testPackage7,
|
||||
testPackage8,
|
||||
testPackage9,
|
||||
testPackage10
|
||||
)
|
||||
|
||||
idp = InvariantDeviceProfile.INSTANCE[context]
|
||||
val userSerial = UserCache.INSTANCE[context].getSerialNumberForUser(Process.myUserHandle())
|
||||
LauncherDbUtils.dropTable(db, TMP_TABLE)
|
||||
@@ -126,8 +111,8 @@ class GridSizeMigrationUtilTest {
|
||||
idp.numDatabaseHotseatIcons = 4
|
||||
idp.numColumns = 4
|
||||
idp.numRows = 4
|
||||
val srcReader = DbReader(db, TMP_TABLE, context, validPackages)
|
||||
val destReader = DbReader(db, TABLE_NAME, context, validPackages)
|
||||
val srcReader = DbReader(db, TMP_TABLE, context)
|
||||
val destReader = DbReader(db, TABLE_NAME, context)
|
||||
GridSizeMigrationUtil.migrate(
|
||||
dbHelper,
|
||||
srcReader,
|
||||
@@ -135,7 +120,7 @@ class GridSizeMigrationUtilTest {
|
||||
idp.numDatabaseHotseatIcons,
|
||||
Point(idp.numColumns, idp.numRows),
|
||||
DeviceGridState(context),
|
||||
DeviceGridState(idp)
|
||||
DeviceGridState(idp),
|
||||
)
|
||||
|
||||
// Check hotseat items
|
||||
@@ -147,9 +132,8 @@ class GridSizeMigrationUtilTest {
|
||||
null,
|
||||
SCREEN,
|
||||
null,
|
||||
null
|
||||
)
|
||||
?: throw IllegalStateException()
|
||||
null,
|
||||
) ?: throw IllegalStateException()
|
||||
|
||||
assertThat(c.count).isEqualTo(idp.numDatabaseHotseatIcons)
|
||||
|
||||
@@ -178,9 +162,8 @@ class GridSizeMigrationUtilTest {
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
)
|
||||
?: throw IllegalStateException()
|
||||
null,
|
||||
) ?: throw IllegalStateException()
|
||||
|
||||
intentIndex = c.getColumnIndex(INTENT)
|
||||
val cellXIndex = c.getColumnIndex(CELLX)
|
||||
@@ -238,8 +221,8 @@ class GridSizeMigrationUtilTest {
|
||||
idp.numDatabaseHotseatIcons = 4
|
||||
idp.numColumns = 4
|
||||
idp.numRows = 4
|
||||
val readerGridA = DbReader(db, TMP_TABLE, context, validPackages)
|
||||
val readerGridB = DbReader(db, TABLE_NAME, context, validPackages)
|
||||
val readerGridA = DbReader(db, TMP_TABLE, context)
|
||||
val readerGridB = DbReader(db, TABLE_NAME, context)
|
||||
// migrate from A -> B
|
||||
GridSizeMigrationUtil.migrate(
|
||||
dbHelper,
|
||||
@@ -248,7 +231,7 @@ class GridSizeMigrationUtilTest {
|
||||
idp.numDatabaseHotseatIcons,
|
||||
Point(idp.numColumns, idp.numRows),
|
||||
DeviceGridState(context),
|
||||
DeviceGridState(idp)
|
||||
DeviceGridState(idp),
|
||||
)
|
||||
|
||||
// Check hotseat items in grid B
|
||||
@@ -260,15 +243,14 @@ class GridSizeMigrationUtilTest {
|
||||
null,
|
||||
SCREEN,
|
||||
null,
|
||||
null
|
||||
)
|
||||
?: throw IllegalStateException()
|
||||
null,
|
||||
) ?: throw IllegalStateException()
|
||||
// Expected hotseat items in grid B
|
||||
// 2 1 3 4
|
||||
verifyHotseat(
|
||||
c,
|
||||
idp,
|
||||
mutableListOf(testPackage2, testPackage1, testPackage3, testPackage4).toList()
|
||||
mutableListOf(testPackage2, testPackage1, testPackage3, testPackage4).toList(),
|
||||
)
|
||||
|
||||
// Check workspace items in grid B
|
||||
@@ -280,9 +262,8 @@ class GridSizeMigrationUtilTest {
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
)
|
||||
?: throw IllegalStateException()
|
||||
null,
|
||||
) ?: throw IllegalStateException()
|
||||
var locMap = parseLocMap(c)
|
||||
// Expected items in grid B
|
||||
// _ _ _ _
|
||||
@@ -306,7 +287,7 @@ class GridSizeMigrationUtilTest {
|
||||
5,
|
||||
Point(5, 5),
|
||||
DeviceGridState(idp),
|
||||
DeviceGridState(context)
|
||||
DeviceGridState(context),
|
||||
)
|
||||
// Check hotseat items in grid A
|
||||
c =
|
||||
@@ -317,15 +298,14 @@ class GridSizeMigrationUtilTest {
|
||||
null,
|
||||
SCREEN,
|
||||
null,
|
||||
null
|
||||
)
|
||||
?: throw IllegalStateException()
|
||||
null,
|
||||
) ?: throw IllegalStateException()
|
||||
// Expected hotseat items in grid A
|
||||
// 1 2 _ 3 4
|
||||
verifyHotseat(
|
||||
c,
|
||||
idp,
|
||||
mutableListOf(testPackage1, testPackage2, null, testPackage3, testPackage4).toList()
|
||||
mutableListOf(testPackage1, testPackage2, null, testPackage3, testPackage4).toList(),
|
||||
)
|
||||
|
||||
// Check workspace items in grid A
|
||||
@@ -337,9 +317,8 @@ class GridSizeMigrationUtilTest {
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
)
|
||||
?: throw IllegalStateException()
|
||||
null,
|
||||
) ?: throw IllegalStateException()
|
||||
locMap = parseLocMap(c)
|
||||
// Expected workspace items in grid A
|
||||
// _ _ _ _ _
|
||||
@@ -367,7 +346,7 @@ class GridSizeMigrationUtilTest {
|
||||
idp.numDatabaseHotseatIcons,
|
||||
Point(idp.numColumns, idp.numRows),
|
||||
DeviceGridState(context),
|
||||
DeviceGridState(idp)
|
||||
DeviceGridState(idp),
|
||||
)
|
||||
|
||||
// Check hotseat items in grid B
|
||||
@@ -379,15 +358,14 @@ class GridSizeMigrationUtilTest {
|
||||
null,
|
||||
SCREEN,
|
||||
null,
|
||||
null
|
||||
)
|
||||
?: throw IllegalStateException()
|
||||
null,
|
||||
) ?: throw IllegalStateException()
|
||||
// Expected hotseat items in grid B
|
||||
// 2 1 3 4
|
||||
verifyHotseat(
|
||||
c,
|
||||
idp,
|
||||
mutableListOf(testPackage2, testPackage1, testPackage3, testPackage4).toList()
|
||||
mutableListOf(testPackage2, testPackage1, testPackage3, testPackage4).toList(),
|
||||
)
|
||||
|
||||
// Check workspace items in grid B
|
||||
@@ -399,9 +377,8 @@ class GridSizeMigrationUtilTest {
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
)
|
||||
?: throw IllegalStateException()
|
||||
null,
|
||||
) ?: throw IllegalStateException()
|
||||
locMap = parseLocMap(c)
|
||||
// Expected workspace items in grid B
|
||||
// _ _ _ _
|
||||
@@ -455,7 +432,7 @@ class GridSizeMigrationUtilTest {
|
||||
0,
|
||||
testPackage1,
|
||||
1,
|
||||
TMP_TABLE
|
||||
TMP_TABLE,
|
||||
),
|
||||
addItem(
|
||||
ITEM_TYPE_DEEP_SHORTCUT,
|
||||
@@ -465,7 +442,7 @@ class GridSizeMigrationUtilTest {
|
||||
0,
|
||||
testPackage2,
|
||||
2,
|
||||
TMP_TABLE
|
||||
TMP_TABLE,
|
||||
),
|
||||
addItem(
|
||||
ITEM_TYPE_APPLICATION,
|
||||
@@ -475,7 +452,7 @@ class GridSizeMigrationUtilTest {
|
||||
0,
|
||||
testPackage3,
|
||||
3,
|
||||
TMP_TABLE
|
||||
TMP_TABLE,
|
||||
),
|
||||
addItem(
|
||||
ITEM_TYPE_DEEP_SHORTCUT,
|
||||
@@ -485,15 +462,15 @@ class GridSizeMigrationUtilTest {
|
||||
0,
|
||||
testPackage4,
|
||||
4,
|
||||
TMP_TABLE
|
||||
)
|
||||
TMP_TABLE,
|
||||
),
|
||||
)
|
||||
val numSrcDatabaseHotseatIcons = srcHotseatItems.size
|
||||
idp.numDatabaseHotseatIcons = 6
|
||||
idp.numColumns = 4
|
||||
idp.numRows = 4
|
||||
val srcReader = DbReader(db, TMP_TABLE, context, validPackages)
|
||||
val destReader = DbReader(db, TABLE_NAME, context, validPackages)
|
||||
val srcReader = DbReader(db, TMP_TABLE, context)
|
||||
val destReader = DbReader(db, TABLE_NAME, context)
|
||||
GridSizeMigrationUtil.migrate(
|
||||
dbHelper,
|
||||
srcReader,
|
||||
@@ -501,7 +478,7 @@ class GridSizeMigrationUtilTest {
|
||||
idp.numDatabaseHotseatIcons,
|
||||
Point(idp.numColumns, idp.numRows),
|
||||
DeviceGridState(context),
|
||||
DeviceGridState(idp)
|
||||
DeviceGridState(idp),
|
||||
)
|
||||
|
||||
// Check hotseat items
|
||||
@@ -513,9 +490,8 @@ class GridSizeMigrationUtilTest {
|
||||
null,
|
||||
SCREEN,
|
||||
null,
|
||||
null
|
||||
)
|
||||
?: throw IllegalStateException()
|
||||
null,
|
||||
) ?: throw IllegalStateException()
|
||||
|
||||
assertThat(c.count.toLong()).isEqualTo(numSrcDatabaseHotseatIcons.toLong())
|
||||
val screenIndex = c.getColumnIndex(SCREEN)
|
||||
@@ -550,8 +526,8 @@ class GridSizeMigrationUtilTest {
|
||||
idp.numDatabaseHotseatIcons = 4
|
||||
idp.numColumns = 4
|
||||
idp.numRows = 4
|
||||
val srcReader = DbReader(db, TMP_TABLE, context, validPackages)
|
||||
val destReader = DbReader(db, TABLE_NAME, context, validPackages)
|
||||
val srcReader = DbReader(db, TMP_TABLE, context)
|
||||
val destReader = DbReader(db, TABLE_NAME, context)
|
||||
GridSizeMigrationUtil.migrate(
|
||||
dbHelper,
|
||||
srcReader,
|
||||
@@ -559,7 +535,7 @@ class GridSizeMigrationUtilTest {
|
||||
idp.numDatabaseHotseatIcons,
|
||||
Point(idp.numColumns, idp.numRows),
|
||||
DeviceGridState(context),
|
||||
DeviceGridState(idp)
|
||||
DeviceGridState(idp),
|
||||
)
|
||||
|
||||
// Check hotseat items
|
||||
@@ -571,9 +547,8 @@ class GridSizeMigrationUtilTest {
|
||||
null,
|
||||
SCREEN,
|
||||
null,
|
||||
null
|
||||
)
|
||||
?: throw IllegalStateException()
|
||||
null,
|
||||
) ?: throw IllegalStateException()
|
||||
|
||||
assertThat(c.count.toLong()).isEqualTo(idp.numDatabaseHotseatIcons.toLong())
|
||||
val screenIndex = c.getColumnIndex(SCREEN)
|
||||
@@ -617,8 +592,8 @@ class GridSizeMigrationUtilTest {
|
||||
idp.numDatabaseHotseatIcons = 4
|
||||
idp.numColumns = 5
|
||||
idp.numRows = 5
|
||||
val srcReader = DbReader(db, TMP_TABLE, context, validPackages)
|
||||
val destReader = DbReader(db, TABLE_NAME, context, validPackages)
|
||||
val srcReader = DbReader(db, TMP_TABLE, context)
|
||||
val destReader = DbReader(db, TABLE_NAME, context)
|
||||
GridSizeMigrationUtil.migrate(
|
||||
dbHelper,
|
||||
srcReader,
|
||||
@@ -626,7 +601,7 @@ class GridSizeMigrationUtilTest {
|
||||
idp.numDatabaseHotseatIcons,
|
||||
Point(idp.numColumns, idp.numRows),
|
||||
DeviceGridState(context),
|
||||
DeviceGridState(idp)
|
||||
DeviceGridState(idp),
|
||||
)
|
||||
|
||||
// Get workspace items
|
||||
@@ -638,9 +613,8 @@ class GridSizeMigrationUtilTest {
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
)
|
||||
?: throw IllegalStateException()
|
||||
null,
|
||||
) ?: throw IllegalStateException()
|
||||
|
||||
val intentIndex = c.getColumnIndex(INTENT)
|
||||
val screenIndex = c.getColumnIndex(SCREEN)
|
||||
@@ -678,8 +652,8 @@ class GridSizeMigrationUtilTest {
|
||||
idp.numDatabaseHotseatIcons = 4
|
||||
idp.numColumns = 4
|
||||
idp.numRows = 4
|
||||
val srcReader = DbReader(db, TMP_TABLE, context, validPackages)
|
||||
val destReader = DbReader(db, TABLE_NAME, context, validPackages)
|
||||
val srcReader = DbReader(db, TMP_TABLE, context)
|
||||
val destReader = DbReader(db, TABLE_NAME, context)
|
||||
GridSizeMigrationUtil.migrate(
|
||||
dbHelper,
|
||||
srcReader,
|
||||
@@ -687,7 +661,7 @@ class GridSizeMigrationUtilTest {
|
||||
idp.numDatabaseHotseatIcons,
|
||||
Point(idp.numColumns, idp.numRows),
|
||||
DeviceGridState(context),
|
||||
DeviceGridState(idp)
|
||||
DeviceGridState(idp),
|
||||
)
|
||||
|
||||
// Get workspace items
|
||||
@@ -699,9 +673,8 @@ class GridSizeMigrationUtilTest {
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
)
|
||||
?: throw IllegalStateException()
|
||||
null,
|
||||
) ?: throw IllegalStateException()
|
||||
val intentIndex = c.getColumnIndex(INTENT)
|
||||
val screenIndex = c.getColumnIndex(SCREEN)
|
||||
|
||||
@@ -732,7 +705,7 @@ class GridSizeMigrationUtilTest {
|
||||
container: Int,
|
||||
x: Int,
|
||||
y: Int,
|
||||
packageName: String?
|
||||
packageName: String?,
|
||||
): Int {
|
||||
return addItem(
|
||||
type,
|
||||
@@ -742,7 +715,7 @@ class GridSizeMigrationUtilTest {
|
||||
y,
|
||||
packageName,
|
||||
dbHelper.generateNewItemId(),
|
||||
TABLE_NAME
|
||||
TABLE_NAME,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -754,7 +727,7 @@ class GridSizeMigrationUtilTest {
|
||||
y: Int,
|
||||
packageName: String?,
|
||||
id: Int,
|
||||
tableName: String
|
||||
tableName: String,
|
||||
): Int {
|
||||
val values = ContentValues()
|
||||
values.put(_ID, id)
|
||||
|
||||
@@ -114,17 +114,14 @@ class ValidGridMigrationUnitTest {
|
||||
}
|
||||
}
|
||||
|
||||
private fun migrate(
|
||||
srcGrid: Grid,
|
||||
dstGrid: Grid,
|
||||
): List<WorkspaceItem> {
|
||||
private fun migrate(srcGrid: Grid, dstGrid: Grid): List<WorkspaceItem> {
|
||||
val userSerial = UserCache.INSTANCE[context].getSerialNumberForUser(Process.myUserHandle())
|
||||
val dbHelper =
|
||||
DatabaseHelper(
|
||||
context,
|
||||
null,
|
||||
{ UserCache.INSTANCE.get(context).getSerialNumberForUser(it) },
|
||||
{}
|
||||
{},
|
||||
)
|
||||
|
||||
Favorites.addTableToDb(dbHelper.writableDatabase, userSerial, false, srcGrid.tableName)
|
||||
@@ -135,12 +132,12 @@ class ValidGridMigrationUnitTest {
|
||||
LauncherDbUtils.SQLiteTransaction(dbHelper.writableDatabase).use {
|
||||
GridSizeMigrationUtil.migrate(
|
||||
dbHelper,
|
||||
GridSizeMigrationUtil.DbReader(it.db, srcGrid.tableName, context, MockSet(1)),
|
||||
GridSizeMigrationUtil.DbReader(it.db, dstGrid.tableName, context, MockSet(1)),
|
||||
GridSizeMigrationUtil.DbReader(it.db, srcGrid.tableName, context),
|
||||
GridSizeMigrationUtil.DbReader(it.db, dstGrid.tableName, context),
|
||||
dstGrid.size.x,
|
||||
dstGrid.size,
|
||||
srcGrid.toGridState(),
|
||||
dstGrid.toGridState()
|
||||
dstGrid.toGridState(),
|
||||
)
|
||||
it.commit()
|
||||
}
|
||||
@@ -157,7 +154,7 @@ class ValidGridMigrationUnitTest {
|
||||
Grid(
|
||||
tableName = Favorites.TMP_TABLE,
|
||||
size = testCase.srcSize,
|
||||
items = generateItemsForTest(testCase.boards, REPEAT_AFTER)
|
||||
items = generateItemsForTest(testCase.boards, REPEAT_AFTER),
|
||||
)
|
||||
val dstGrid =
|
||||
Grid(tableName = Favorites.TABLE_NAME, size = testCase.targetSize, items = listOf())
|
||||
@@ -175,13 +172,13 @@ class ValidGridMigrationUnitTest {
|
||||
Grid(
|
||||
tableName = Favorites.TMP_TABLE,
|
||||
size = testCase.srcSize,
|
||||
items = generateItemsForTest(testCase.boards, REPEAT_AFTER)
|
||||
items = generateItemsForTest(testCase.boards, REPEAT_AFTER),
|
||||
)
|
||||
val dstGrid =
|
||||
Grid(
|
||||
tableName = Favorites.TABLE_NAME,
|
||||
size = testCase.targetSize,
|
||||
items = generateItemsForTest(testCase.destBoards, REPEAT_AFTER_DST)
|
||||
items = generateItemsForTest(testCase.destBoards, REPEAT_AFTER_DST),
|
||||
)
|
||||
validate(srcGrid, dstGrid, migrate(srcGrid, dstGrid))
|
||||
}
|
||||
@@ -199,7 +196,7 @@ class ValidGridMigrationUnitTest {
|
||||
Grid(
|
||||
tableName = Favorites.TMP_TABLE,
|
||||
size = testCase.srcSize,
|
||||
items = generateItemsForTest(testCase.boards, REPEAT_AFTER)
|
||||
items = generateItemsForTest(testCase.boards, REPEAT_AFTER),
|
||||
)
|
||||
val dstGrid =
|
||||
Grid(tableName = Favorites.TABLE_NAME, size = testCase.targetSize, items = listOf())
|
||||
|
||||
Reference in New Issue
Block a user