Use snapshotView references in TaskContainer when possible
- Moved majority of TaskContainer.thumbnailViewDeprecated usage to TaskContainer.snapshotView, so they'll cover the new TaskThumbnailView as well - There are afew location left that will be handled as a follow-up - Removed TaskThumbnailView's splitTranslation and use translation directly as it's the only translation we use Bug: 336612373 Test: Ensure all Task CUJs still work without refacorting Test: Ensure major Task CUJs work with refactoring Flag: EXEMPT refactor Flag: com.android.launcher3.enable_refactor_task_thumbnail Change-Id: Ieb52236bc503ce0d0a511249978c1821a82d406e
This commit is contained in:
@@ -269,8 +269,8 @@ public class TaskbarUIController {
|
||||
foundTaskView,
|
||||
foundTask,
|
||||
taskContainer.getIconView().getDrawable(),
|
||||
taskContainer.getThumbnailViewDeprecated(),
|
||||
taskContainer.getThumbnailViewDeprecated().getThumbnail(),
|
||||
taskContainer.getSnapshotView(),
|
||||
taskContainer.getThumbnail(),
|
||||
null /* intent */,
|
||||
null /* user */,
|
||||
info);
|
||||
|
||||
+1
-1
@@ -252,7 +252,7 @@ public abstract class TaskViewTouchController<CONTAINER extends Context & Recent
|
||||
mTaskBeingDragged, maxDuration, currentInterpolator);
|
||||
|
||||
// Since the thumbnail is what is filling the screen, based the end displacement on it.
|
||||
View thumbnailView = mTaskBeingDragged.getFirstThumbnailViewDeprecated();
|
||||
View thumbnailView = mTaskBeingDragged.getFirstSnapshotView();
|
||||
mTempCords[1] = orientationHandler.getSecondaryDimension(thumbnailView);
|
||||
dl.getDescendantCoordRelativeToSelf(thumbnailView, mTempCords);
|
||||
mEndDisplacement = secondaryLayerDimension - mTempCords[1];
|
||||
|
||||
@@ -44,7 +44,6 @@ import com.android.quickstep.views.GroupedTaskView;
|
||||
import com.android.quickstep.views.OverviewActionsView;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
import com.android.quickstep.views.TaskThumbnailViewDeprecated;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.quickstep.views.TaskView.TaskContainer;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
@@ -134,20 +133,20 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
|
||||
mApplicationContext = taskContainer.getTaskView().getContext().getApplicationContext();
|
||||
mTaskContainer = taskContainer;
|
||||
mImageApi = new ImageActionsApi(
|
||||
mApplicationContext, mTaskContainer.getThumbnailViewDeprecated()::getThumbnail);
|
||||
mApplicationContext, mTaskContainer::getThumbnail);
|
||||
}
|
||||
|
||||
protected T getActionsView() {
|
||||
if (mActionsView == null) {
|
||||
mActionsView = BaseActivity.fromContext(
|
||||
mTaskContainer.getThumbnailViewDeprecated().getContext()).findViewById(
|
||||
mTaskContainer.getTaskView().getContext()).findViewById(
|
||||
R.id.overview_actions_view);
|
||||
}
|
||||
return mActionsView;
|
||||
}
|
||||
|
||||
public TaskThumbnailViewDeprecated getThumbnailView() {
|
||||
return mTaskContainer.getThumbnailViewDeprecated();
|
||||
public TaskView getTaskView() {
|
||||
return mTaskContainer.getTaskView();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,8 +158,7 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
|
||||
|
||||
if (thumbnail != null) {
|
||||
getActionsView().updateDisabledFlags(DISABLED_ROTATED, rotated);
|
||||
boolean isAllowedByPolicy =
|
||||
mTaskContainer.getThumbnailViewDeprecated().isRealSnapshot();
|
||||
boolean isAllowedByPolicy = mTaskContainer.isRealSnapshot();
|
||||
getActionsView().setCallbacks(new OverlayUICallbacksImpl(isAllowedByPolicy, task));
|
||||
}
|
||||
}
|
||||
@@ -172,7 +170,7 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
|
||||
*/
|
||||
public void endLiveTileMode(@NonNull Runnable callback) {
|
||||
RecentsView recentsView =
|
||||
mTaskContainer.getThumbnailViewDeprecated().getTaskView().getRecentsView();
|
||||
mTaskContainer.getTaskView().getRecentsView();
|
||||
// Task has already been dismissed
|
||||
if (recentsView == null) return;
|
||||
recentsView.switchToScreenshot(
|
||||
@@ -185,8 +183,8 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
|
||||
*/
|
||||
@SuppressLint("NewApi")
|
||||
protected void saveScreenshot(Task task) {
|
||||
if (mTaskContainer.getThumbnailViewDeprecated().isRealSnapshot()) {
|
||||
mImageApi.saveScreenshot(mTaskContainer.getThumbnailViewDeprecated().getThumbnail(),
|
||||
if (mTaskContainer.isRealSnapshot()) {
|
||||
mImageApi.saveScreenshot(mTaskContainer.getThumbnail(),
|
||||
getTaskSnapshotBounds(), getTaskSnapshotInsets(), task.key);
|
||||
} else {
|
||||
showBlockedByPolicyMessage();
|
||||
@@ -194,17 +192,14 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
|
||||
}
|
||||
|
||||
protected void enterSplitSelect() {
|
||||
RecentsView overviewPanel =
|
||||
mTaskContainer.getThumbnailViewDeprecated().getTaskView().getRecentsView();
|
||||
RecentsView overviewPanel = mTaskContainer.getTaskView().getRecentsView();
|
||||
// Task has already been dismissed
|
||||
if (overviewPanel == null) return;
|
||||
overviewPanel.initiateSplitSelect(
|
||||
mTaskContainer.getThumbnailViewDeprecated().getTaskView());
|
||||
overviewPanel.initiateSplitSelect(mTaskContainer.getTaskView());
|
||||
}
|
||||
|
||||
protected void saveAppPair() {
|
||||
GroupedTaskView taskView =
|
||||
(GroupedTaskView) mTaskContainer.getThumbnailViewDeprecated().getTaskView();
|
||||
GroupedTaskView taskView = (GroupedTaskView) mTaskContainer.getTaskView();
|
||||
taskView.getRecentsView().getSplitSelectController().getAppPairsController()
|
||||
.saveAppPair(taskView);
|
||||
}
|
||||
@@ -250,11 +245,11 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
|
||||
*/
|
||||
public Rect getTaskSnapshotBounds() {
|
||||
int[] location = new int[2];
|
||||
mTaskContainer.getThumbnailViewDeprecated().getLocationOnScreen(location);
|
||||
mTaskContainer.getSnapshotView().getLocationOnScreen(location);
|
||||
|
||||
return new Rect(location[0], location[1],
|
||||
mTaskContainer.getThumbnailViewDeprecated().getWidth() + location[0],
|
||||
mTaskContainer.getThumbnailViewDeprecated().getHeight() + location[1]);
|
||||
mTaskContainer.getSnapshotView().getWidth() + location[0],
|
||||
mTaskContainer.getSnapshotView().getHeight() + location[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -264,7 +259,7 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
|
||||
*/
|
||||
@RequiresApi(api = Build.VERSION_CODES.Q)
|
||||
public Insets getTaskSnapshotInsets() {
|
||||
return mTaskContainer.getThumbnailViewDeprecated().getScaledInsets();
|
||||
return mTaskContainer.getScaledInsets();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -275,14 +270,14 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
|
||||
|
||||
protected void showBlockedByPolicyMessage() {
|
||||
ActivityContext activityContext = ActivityContext.lookupContext(
|
||||
mTaskContainer.getThumbnailViewDeprecated().getContext());
|
||||
mTaskContainer.getTaskView().getContext());
|
||||
String message = activityContext.getStringCache() != null
|
||||
? activityContext.getStringCache().disabledByAdminMessage
|
||||
: mTaskContainer.getThumbnailViewDeprecated().getContext().getString(
|
||||
: mTaskContainer.getTaskView().getContext().getString(
|
||||
R.string.blocked_by_policy);
|
||||
|
||||
Snackbar.show(BaseActivity.fromContext(
|
||||
mTaskContainer.getThumbnailViewDeprecated().getContext()), message, null);
|
||||
mTaskContainer.getTaskView().getContext()), message, null);
|
||||
}
|
||||
|
||||
/** Called when the snapshot has updated its full screen drawing parameters. */
|
||||
@@ -304,8 +299,7 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
saveScreenshot(
|
||||
mTaskContainer.getThumbnailViewDeprecated().getTaskView().getFirstTask());
|
||||
saveScreenshot(mTaskContainer.getTaskView().getFirstTask());
|
||||
dismissTaskMenuView();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
|
||||
import static android.view.Surface.ROTATION_0;
|
||||
|
||||
import static com.android.launcher3.Flags.enableRefactorTaskThumbnail;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_FREE_FORM_TAP;
|
||||
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
|
||||
import static com.android.window.flags.Flags.enableDesktopWindowingMode;
|
||||
@@ -55,7 +56,6 @@ import com.android.quickstep.util.RecentsOrientedState;
|
||||
import com.android.quickstep.views.GroupedTaskView;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
import com.android.quickstep.views.TaskThumbnailViewDeprecated;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.quickstep.views.TaskView.TaskContainer;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
@@ -174,7 +174,7 @@ public interface TaskShortcutFactory {
|
||||
private Handler mHandler;
|
||||
|
||||
private final RecentsView mRecentsView;
|
||||
private final TaskThumbnailViewDeprecated mThumbnailView;
|
||||
private final TaskContainer mTaskContainer;
|
||||
private final TaskView mTaskView;
|
||||
private final LauncherEvent mLauncherEvent;
|
||||
|
||||
@@ -186,7 +186,7 @@ public interface TaskShortcutFactory {
|
||||
mHandler = new Handler(Looper.getMainLooper());
|
||||
mTaskView = taskContainer.getTaskView();
|
||||
mRecentsView = container.getOverviewPanel();
|
||||
mThumbnailView = taskContainer.getThumbnailViewDeprecated();
|
||||
mTaskContainer = taskContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -220,20 +220,25 @@ public interface TaskShortcutFactory {
|
||||
};
|
||||
|
||||
final int[] position = new int[2];
|
||||
mThumbnailView.getLocationOnScreen(position);
|
||||
final int width = (int) (mThumbnailView.getWidth() * mTaskView.getScaleX());
|
||||
final int height = (int) (mThumbnailView.getHeight() * mTaskView.getScaleY());
|
||||
View snapShotView = mTaskContainer.getSnapshotView();
|
||||
snapShotView.getLocationOnScreen(position);
|
||||
final int width = (int) (snapShotView.getWidth() * mTaskView.getScaleX());
|
||||
final int height = (int) (snapShotView.getHeight() * mTaskView.getScaleY());
|
||||
final Rect taskBounds = new Rect(position[0], position[1],
|
||||
position[0] + width, position[1] + height);
|
||||
|
||||
// Take the thumbnail of the task without a scrim and apply it back after
|
||||
float alpha = mThumbnailView.getDimAlpha();
|
||||
// TODO(b/348643341) add ability to get override the scrim for this Bitmap retrieval
|
||||
mThumbnailView.setDimAlpha(0);
|
||||
float alpha = 0f;
|
||||
if (!enableRefactorTaskThumbnail()) {
|
||||
alpha = mTaskContainer.getThumbnailViewDeprecated().getDimAlpha();
|
||||
mTaskContainer.getThumbnailViewDeprecated().setDimAlpha(0);
|
||||
}
|
||||
Bitmap thumbnail = RecentsTransition.drawViewIntoHardwareBitmap(
|
||||
taskBounds.width(), taskBounds.height(), mThumbnailView, 1f,
|
||||
Color.BLACK);
|
||||
mThumbnailView.setDimAlpha(alpha);
|
||||
taskBounds.width(), taskBounds.height(), snapShotView, 1f, Color.BLACK);
|
||||
if (!enableRefactorTaskThumbnail()) {
|
||||
mTaskContainer.getThumbnailViewDeprecated().setDimAlpha(alpha);
|
||||
}
|
||||
|
||||
AppTransitionAnimationSpecsFuture future =
|
||||
new AppTransitionAnimationSpecsFuture(mHandler) {
|
||||
|
||||
@@ -80,7 +80,6 @@ import com.android.quickstep.util.TransformParams;
|
||||
import com.android.quickstep.views.DesktopTaskView;
|
||||
import com.android.quickstep.views.GroupedTaskView;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.TaskThumbnailViewDeprecated;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.systemui.animation.RemoteAnimationTargetCompat;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
@@ -334,7 +333,7 @@ public final class TaskViewUtils {
|
||||
// During animation we apply transformation on the thumbnailView (and not the rootView)
|
||||
// to follow the TaskViewSimulator. So the final matrix applied on the thumbnailView is:
|
||||
// Mt K(0)` K(t) Mt`
|
||||
TaskThumbnailViewDeprecated[] thumbnails = v.getThumbnailViews();
|
||||
View[] thumbnails = v.getSnapshotViews();
|
||||
|
||||
// In case simulator copies and thumbnail size do no match, ensure we get the lesser.
|
||||
// This ensures we do not create arrays with empty elements or attempt to references
|
||||
@@ -344,7 +343,7 @@ public final class TaskViewUtils {
|
||||
Matrix[] mt = new Matrix[matrixSize];
|
||||
Matrix[] mti = new Matrix[matrixSize];
|
||||
for (int i = 0; i < matrixSize; i++) {
|
||||
TaskThumbnailViewDeprecated ttv = thumbnails[i];
|
||||
View ttv = thumbnails[i];
|
||||
RectF localBounds = new RectF(0, 0, ttv.getWidth(), ttv.getHeight());
|
||||
float[] tvBoundsMapped = new float[]{0, 0, ttv.getWidth(), ttv.getHeight()};
|
||||
getDescendantCoordRelativeToAncestor(ttv, ttv.getRootView(), tvBoundsMapped, false);
|
||||
@@ -391,7 +390,7 @@ public final class TaskViewUtils {
|
||||
out.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
for (TaskThumbnailViewDeprecated ttv : thumbnails) {
|
||||
for (View ttv : thumbnails) {
|
||||
ttv.setAnimationMatrix(null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ import androidx.annotation.VisibleForTesting
|
||||
import com.android.app.animation.Interpolators
|
||||
import com.android.launcher3.DeviceProfile
|
||||
import com.android.launcher3.Flags.enableOverviewIconMenu
|
||||
import com.android.launcher3.Flags.enableRefactorTaskThumbnail
|
||||
import com.android.launcher3.InsettableFrameLayout
|
||||
import com.android.launcher3.QuickstepTransitionManager
|
||||
import com.android.launcher3.R
|
||||
@@ -118,8 +119,8 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC
|
||||
if (container.task.getKey().getId() == splitSelectStateController.initialTaskId) {
|
||||
val drawable = getDrawable(container.iconView, splitSelectSource)
|
||||
return SplitAnimInitProps(
|
||||
container.thumbnailViewDeprecated,
|
||||
container.thumbnailViewDeprecated.thumbnail,
|
||||
container.snapshotView,
|
||||
container.thumbnail,
|
||||
drawable!!,
|
||||
fadeWithThumbnail = true,
|
||||
isStagedTask = true,
|
||||
@@ -137,8 +138,8 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC
|
||||
taskView.taskContainers.first().let {
|
||||
val drawable = getDrawable(it.iconView, splitSelectSource)
|
||||
return SplitAnimInitProps(
|
||||
it.thumbnailViewDeprecated,
|
||||
it.thumbnailViewDeprecated.thumbnail,
|
||||
it.snapshotView,
|
||||
it.thumbnail,
|
||||
drawable!!,
|
||||
fadeWithThumbnail = true,
|
||||
isStagedTask = true,
|
||||
@@ -165,27 +166,37 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC
|
||||
/**
|
||||
* When selecting first app from split pair, second app's thumbnail remains. This animates the
|
||||
* second thumbnail by expanding it to take up the full taskViewWidth/Height and overlaying it
|
||||
* with [TaskThumbnailViewDeprecated]'s splashView. Adds animations to the provided builder.
|
||||
* Note: The app that **was not** selected as the first split app should be the container that's
|
||||
* passed through.
|
||||
* with [TaskContainer]'s splashView. Adds animations to the provided builder. Note: The app
|
||||
* that **was not** selected as the first split app should be the container that's passed
|
||||
* through.
|
||||
*
|
||||
* @param builder Adds animation to this
|
||||
* @param taskIdAttributeContainer container of the app that **was not** selected
|
||||
* @param taskContainer container of the app that **was not** selected
|
||||
* @param isPrimaryTaskSplitting if true, task that was split would be top/left in the pair
|
||||
* (opposite of that representing [taskIdAttributeContainer])
|
||||
* (opposite of that representing [taskContainer])
|
||||
*/
|
||||
fun addInitialSplitFromPair(
|
||||
taskIdAttributeContainer: TaskContainer,
|
||||
taskContainer: TaskContainer,
|
||||
builder: PendingAnimation,
|
||||
deviceProfile: DeviceProfile,
|
||||
taskViewWidth: Int,
|
||||
taskViewHeight: Int,
|
||||
isPrimaryTaskSplitting: Boolean
|
||||
) {
|
||||
val thumbnail = taskIdAttributeContainer.thumbnailViewDeprecated
|
||||
val iconView: View = taskIdAttributeContainer.iconView.asView()
|
||||
builder.add(ObjectAnimator.ofFloat(thumbnail, TaskThumbnailViewDeprecated.SPLASH_ALPHA, 1f))
|
||||
thumbnail.setShowSplashForSplitSelection(true)
|
||||
val snapshot = taskContainer.snapshotView
|
||||
val iconView: View = taskContainer.iconView.asView()
|
||||
// TODO(334826842): Switch to splash state in TaskThumbnailView
|
||||
if (!enableRefactorTaskThumbnail()) {
|
||||
val thumbnailViewDeprecated = taskContainer.thumbnailViewDeprecated
|
||||
builder.add(
|
||||
ObjectAnimator.ofFloat(
|
||||
thumbnailViewDeprecated,
|
||||
TaskThumbnailViewDeprecated.SPLASH_ALPHA,
|
||||
1f
|
||||
)
|
||||
)
|
||||
thumbnailViewDeprecated.setShowSplashForSplitSelection(true)
|
||||
}
|
||||
// With the new `IconAppChipView`, we always want to keep the chip pinned to the
|
||||
// top left of the task / thumbnail.
|
||||
if (enableOverviewIconMenu()) {
|
||||
@@ -202,14 +213,10 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC
|
||||
}
|
||||
if (deviceProfile.isLeftRightSplit) {
|
||||
// Center view first so scaling happens uniformly, alternatively we can move pivotX to 0
|
||||
val centerThumbnailTranslationX: Float = (taskViewWidth - thumbnail.width) / 2f
|
||||
val finalScaleX: Float = taskViewWidth.toFloat() / thumbnail.width
|
||||
val centerThumbnailTranslationX: Float = (taskViewWidth - snapshot.width) / 2f
|
||||
val finalScaleX: Float = taskViewWidth.toFloat() / snapshot.width
|
||||
builder.add(
|
||||
ObjectAnimator.ofFloat(
|
||||
thumbnail,
|
||||
TaskThumbnailViewDeprecated.SPLIT_SELECT_TRANSLATE_X,
|
||||
centerThumbnailTranslationX
|
||||
)
|
||||
ObjectAnimator.ofFloat(snapshot, View.TRANSLATION_X, centerThumbnailTranslationX)
|
||||
)
|
||||
if (!enableOverviewIconMenu()) {
|
||||
// icons are anchored from Gravity.END, so need to use negative translation
|
||||
@@ -218,21 +225,15 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC
|
||||
ObjectAnimator.ofFloat(iconView, View.TRANSLATION_X, -centerIconTranslationX)
|
||||
)
|
||||
}
|
||||
builder.add(ObjectAnimator.ofFloat(thumbnail, View.SCALE_X, finalScaleX))
|
||||
builder.add(ObjectAnimator.ofFloat(snapshot, View.SCALE_X, finalScaleX))
|
||||
|
||||
// Reset other dimensions
|
||||
// TODO(b/271468547), can't set Y translate to 0, need to account for top space
|
||||
thumbnail.scaleY = 1f
|
||||
snapshot.scaleY = 1f
|
||||
val translateYResetVal: Float =
|
||||
if (!isPrimaryTaskSplitting) 0f
|
||||
else deviceProfile.overviewTaskThumbnailTopMarginPx.toFloat()
|
||||
builder.add(
|
||||
ObjectAnimator.ofFloat(
|
||||
thumbnail,
|
||||
TaskThumbnailViewDeprecated.SPLIT_SELECT_TRANSLATE_Y,
|
||||
translateYResetVal
|
||||
)
|
||||
)
|
||||
builder.add(ObjectAnimator.ofFloat(snapshot, View.TRANSLATION_Y, translateYResetVal))
|
||||
} else {
|
||||
val thumbnailSize = taskViewHeight - deviceProfile.overviewTaskThumbnailTopMarginPx
|
||||
// Center view first so scaling happens uniformly, alternatively we can move pivotY to 0
|
||||
@@ -247,36 +248,26 @@ 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 - thumbnail.height) / 2f
|
||||
centerThumbnailTranslationY = (thumbnailSize - snapshot.height) / 2f
|
||||
centerThumbnailTranslationY +=
|
||||
deviceProfile.overviewTaskThumbnailTopMarginPx.toFloat()
|
||||
} else {
|
||||
centerThumbnailTranslationY = (thumbnailSize - thumbnail.height) / 2f
|
||||
centerThumbnailTranslationY = (thumbnailSize - snapshot.height) / 2f
|
||||
}
|
||||
val finalScaleY: Float = thumbnailSize.toFloat() / thumbnail.height
|
||||
val finalScaleY: Float = thumbnailSize.toFloat() / snapshot.height
|
||||
builder.add(
|
||||
ObjectAnimator.ofFloat(
|
||||
thumbnail,
|
||||
TaskThumbnailViewDeprecated.SPLIT_SELECT_TRANSLATE_Y,
|
||||
centerThumbnailTranslationY
|
||||
)
|
||||
ObjectAnimator.ofFloat(snapshot, View.TRANSLATION_Y, centerThumbnailTranslationY)
|
||||
)
|
||||
|
||||
if (!enableOverviewIconMenu()) {
|
||||
// icons are anchored from Gravity.END, so need to use negative translation
|
||||
builder.add(ObjectAnimator.ofFloat(iconView, View.TRANSLATION_X, 0f))
|
||||
}
|
||||
builder.add(ObjectAnimator.ofFloat(thumbnail, View.SCALE_Y, finalScaleY))
|
||||
builder.add(ObjectAnimator.ofFloat(snapshot, View.SCALE_Y, finalScaleY))
|
||||
|
||||
// Reset other dimensions
|
||||
thumbnail.scaleX = 1f
|
||||
builder.add(
|
||||
ObjectAnimator.ofFloat(
|
||||
thumbnail,
|
||||
TaskThumbnailViewDeprecated.SPLIT_SELECT_TRANSLATE_X,
|
||||
0f
|
||||
)
|
||||
)
|
||||
snapshot.scaleX = 1f
|
||||
builder.add(ObjectAnimator.ofFloat(snapshot, View.TRANSLATION_X, 0f))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ class DesktopTaskView @JvmOverloads constructor(context: Context, attrs: Attribu
|
||||
}
|
||||
val thumbWidth = (taskSize.width() * scaleWidth).toInt()
|
||||
val thumbHeight = (taskSize.height() * scaleHeight).toInt()
|
||||
it.thumbnailViewDeprecated.measure(
|
||||
it.snapshotView.measure(
|
||||
MeasureSpec.makeMeasureSpec(thumbWidth, MeasureSpec.EXACTLY),
|
||||
MeasureSpec.makeMeasureSpec(thumbHeight, MeasureSpec.EXACTLY)
|
||||
)
|
||||
@@ -139,8 +139,8 @@ class DesktopTaskView @JvmOverloads constructor(context: Context, attrs: Attribu
|
||||
var taskY = (positionInParent.y * scaleHeight).toInt()
|
||||
// move task down by margin size
|
||||
taskY += thumbnailTopMarginPx
|
||||
it.thumbnailViewDeprecated.x = taskX.toFloat()
|
||||
it.thumbnailViewDeprecated.y = taskY.toFloat()
|
||||
it.snapshotView.x = taskX.toFloat()
|
||||
it.snapshotView.y = taskY.toFloat()
|
||||
if (DEBUG) {
|
||||
Log.d(
|
||||
TAG,
|
||||
|
||||
@@ -332,12 +332,12 @@ public final class DigitalWellBeingToast {
|
||||
(FrameLayout.LayoutParams) mBanner.getLayoutParams();
|
||||
DeviceProfile deviceProfile = mContainer.getDeviceProfile();
|
||||
layoutParams.bottomMargin = ((ViewGroup.MarginLayoutParams)
|
||||
mTaskView.getFirstThumbnailViewDeprecated().getLayoutParams()).bottomMargin;
|
||||
mTaskView.getFirstSnapshotView().getLayoutParams()).bottomMargin;
|
||||
RecentsPagedOrientationHandler orientationHandler = mTaskView.getPagedOrientationHandler();
|
||||
Pair<Float, Float> translations = orientationHandler
|
||||
.getDwbLayoutTranslations(mTaskView.getMeasuredWidth(),
|
||||
mTaskView.getMeasuredHeight(), mSplitBounds, deviceProfile,
|
||||
mTaskView.getThumbnailViews(), mTask.key.id, mBanner);
|
||||
mTaskView.getSnapshotViews(), mTask.key.id, mBanner);
|
||||
mSplitOffsetTranslationX = translations.first;
|
||||
mSplitOffsetTranslationY = translations.second;
|
||||
updateTranslationY();
|
||||
|
||||
@@ -68,36 +68,20 @@ class GroupedTaskView @JvmOverloads constructor(context: Context, attrs: Attribu
|
||||
val initSplitTaskId = getThisTaskCurrentlyInSplitSelection()
|
||||
if (initSplitTaskId == INVALID_TASK_ID) {
|
||||
pagedOrientationHandler.measureGroupedTaskViewThumbnailBounds(
|
||||
taskContainers[0].thumbnailViewDeprecated,
|
||||
taskContainers[1].thumbnailViewDeprecated,
|
||||
taskContainers[0].snapshotView,
|
||||
taskContainers[1].snapshotView,
|
||||
widthSize,
|
||||
heightSize,
|
||||
splitBoundsConfig,
|
||||
container.deviceProfile,
|
||||
layoutDirection == LAYOUT_DIRECTION_RTL
|
||||
)
|
||||
// Should we be having a separate translation step apart from the measuring above?
|
||||
// The following only applies to large screen for now, but for future reference
|
||||
// we'd want to abstract this out in PagedViewHandlers to get the primary/secondary
|
||||
// translation directions
|
||||
taskContainers[0]
|
||||
.thumbnailViewDeprecated
|
||||
.applySplitSelectTranslateX(taskContainers[0].thumbnailViewDeprecated.translationX)
|
||||
taskContainers[0]
|
||||
.thumbnailViewDeprecated
|
||||
.applySplitSelectTranslateY(taskContainers[0].thumbnailViewDeprecated.translationY)
|
||||
taskContainers[1]
|
||||
.thumbnailViewDeprecated
|
||||
.applySplitSelectTranslateX(taskContainers[1].thumbnailViewDeprecated.translationX)
|
||||
taskContainers[1]
|
||||
.thumbnailViewDeprecated
|
||||
.applySplitSelectTranslateY(taskContainers[1].thumbnailViewDeprecated.translationY)
|
||||
} 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 }
|
||||
?.thumbnailViewDeprecated
|
||||
?.snapshotView
|
||||
?.measure(
|
||||
widthMeasureSpec,
|
||||
MeasureSpec.makeMeasureSpec(
|
||||
@@ -212,8 +196,8 @@ class GroupedTaskView @JvmOverloads constructor(context: Context, attrs: Attribu
|
||||
taskContainers[0].iconView.asView(),
|
||||
taskContainers[1].iconView.asView(),
|
||||
taskIconHeight,
|
||||
taskContainers[0].thumbnailViewDeprecated.measuredWidth,
|
||||
taskContainers[0].thumbnailViewDeprecated.measuredHeight,
|
||||
taskContainers[0].snapshotView.measuredWidth,
|
||||
taskContainers[0].snapshotView.measuredHeight,
|
||||
measuredHeight,
|
||||
measuredWidth,
|
||||
isRtl,
|
||||
@@ -308,7 +292,7 @@ class GroupedTaskView @JvmOverloads constructor(context: Context, attrs: Attribu
|
||||
// Check which of the two apps was selected
|
||||
if (
|
||||
taskContainers[1].iconView.asView().containsPoint(lastTouchDownPosition) ||
|
||||
taskContainers[1].thumbnailViewDeprecated.containsPoint(lastTouchDownPosition)
|
||||
taskContainers[1].snapshotView.containsPoint(lastTouchDownPosition)
|
||||
) {
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -238,12 +238,12 @@ public class TaskMenuView extends AbstractFloatingView {
|
||||
mContainer.getDragLayer().getDescendantRectRelativeToSelf(
|
||||
enableOverviewIconMenu()
|
||||
? getIconView().findViewById(R.id.icon_view_menu_anchor)
|
||||
: taskContainer.getThumbnailViewDeprecated(),
|
||||
: taskContainer.getSnapshotView(),
|
||||
sTempRect);
|
||||
Rect insets = mContainer.getDragLayer().getInsets();
|
||||
BaseDragLayer.LayoutParams params = (BaseDragLayer.LayoutParams) getLayoutParams();
|
||||
params.width = orientationHandler.getTaskMenuWidth(
|
||||
taskContainer.getThumbnailViewDeprecated(), deviceProfile,
|
||||
taskContainer.getSnapshotView(), deviceProfile,
|
||||
taskContainer.getStagePosition());
|
||||
// Gravity set to Left instead of Start as sTempRect.left measures Left distance not Start
|
||||
params.gravity = Gravity.LEFT;
|
||||
@@ -277,10 +277,10 @@ public class TaskMenuView extends AbstractFloatingView {
|
||||
// Margin that insets the menuView inside the taskView
|
||||
float taskInsetMargin = getResources().getDimension(R.dimen.task_card_margin);
|
||||
setTranslationX(orientationHandler.getTaskMenuX(thumbnailAlignedX,
|
||||
mTaskContainer.getThumbnailViewDeprecated(), deviceProfile, taskInsetMargin,
|
||||
mTaskContainer.getSnapshotView(), deviceProfile, taskInsetMargin,
|
||||
getIconView()));
|
||||
setTranslationY(orientationHandler.getTaskMenuY(
|
||||
thumbnailAlignedY, mTaskContainer.getThumbnailViewDeprecated(),
|
||||
thumbnailAlignedY, mTaskContainer.getSnapshotView(),
|
||||
mTaskContainer.getStagePosition(), this, taskInsetMargin,
|
||||
getIconView()));
|
||||
}
|
||||
@@ -316,7 +316,7 @@ public class TaskMenuView extends AbstractFloatingView {
|
||||
.createRevealAnimator(this, closing, revealAnimationStartProgress);
|
||||
mRevealAnimator.setInterpolator(enableOverviewIconMenu() ? Interpolators.EMPHASIZED
|
||||
: Interpolators.DECELERATE);
|
||||
|
||||
AnimatorSet.Builder openCloseAnimatorBuilder = mOpenCloseAnimator.play(mRevealAnimator);
|
||||
if (enableOverviewIconMenu()) {
|
||||
IconAppChipView iconAppChip = (IconAppChipView) mTaskContainer.getIconView().asView();
|
||||
|
||||
@@ -334,11 +334,13 @@ public class TaskMenuView extends AbstractFloatingView {
|
||||
closing ? mMenuTranslationYBeforeOpen
|
||||
: mMenuTranslationYBeforeOpen + additionalTranslationY);
|
||||
translationYAnim.setInterpolator(EMPHASIZED);
|
||||
openCloseAnimatorBuilder.with(translationYAnim);
|
||||
|
||||
ObjectAnimator menuTranslationYAnim = ObjectAnimator.ofFloat(
|
||||
iconAppChip.getMenuTranslationY(),
|
||||
MULTI_PROPERTY_VALUE, closing ? 0 : additionalTranslationY);
|
||||
menuTranslationYAnim.setInterpolator(EMPHASIZED);
|
||||
openCloseAnimatorBuilder.with(menuTranslationYAnim);
|
||||
|
||||
float additionalTranslationX = 0;
|
||||
if (mContainer.getDeviceProfile().isLandscape
|
||||
@@ -354,20 +356,15 @@ public class TaskMenuView extends AbstractFloatingView {
|
||||
closing ? mMenuTranslationXBeforeOpen
|
||||
: mMenuTranslationXBeforeOpen - additionalTranslationX);
|
||||
translationXAnim.setInterpolator(EMPHASIZED);
|
||||
openCloseAnimatorBuilder.with(translationXAnim);
|
||||
|
||||
ObjectAnimator menuTranslationXAnim = ObjectAnimator.ofFloat(
|
||||
iconAppChip.getMenuTranslationX(),
|
||||
MULTI_PROPERTY_VALUE, closing ? 0 : -additionalTranslationX);
|
||||
menuTranslationXAnim.setInterpolator(EMPHASIZED);
|
||||
|
||||
mOpenCloseAnimator.playTogether(translationYAnim, translationXAnim,
|
||||
menuTranslationXAnim, menuTranslationYAnim);
|
||||
openCloseAnimatorBuilder.with(menuTranslationXAnim);
|
||||
}
|
||||
mOpenCloseAnimator.playTogether(mRevealAnimator,
|
||||
ObjectAnimator.ofFloat(
|
||||
mTaskContainer.getThumbnailViewDeprecated(), DIM_ALPHA,
|
||||
closing ? 0 : TaskView.MAX_PAGE_SCRIM_ALPHA),
|
||||
ObjectAnimator.ofFloat(this, ALPHA, closing ? 0 : 1));
|
||||
openCloseAnimatorBuilder.with(ObjectAnimator.ofFloat(this, ALPHA, closing ? 0 : 1));
|
||||
if (enableRefactorTaskThumbnail()) {
|
||||
mRevealAnimator.addUpdateListener(animation -> {
|
||||
float animatedFraction = animation.getAnimatedFraction();
|
||||
@@ -375,6 +372,10 @@ public class TaskMenuView extends AbstractFloatingView {
|
||||
mTaskContainer.getTaskContainerData()
|
||||
.getTaskMenuOpenProgress().setValue(openProgress);
|
||||
});
|
||||
} else {
|
||||
openCloseAnimatorBuilder.with(ObjectAnimator.ofFloat(
|
||||
mTaskContainer.getThumbnailViewDeprecated(), DIM_ALPHA,
|
||||
closing ? 0 : TaskView.MAX_PAGE_SCRIM_ALPHA));
|
||||
}
|
||||
mOpenCloseAnimator.addListener(new AnimationSuccessListener() {
|
||||
@Override
|
||||
|
||||
@@ -99,36 +99,6 @@ public class TaskThumbnailViewDeprecated extends View implements ViewPool.Reusab
|
||||
}
|
||||
};
|
||||
|
||||
/** Use to animate thumbnail translationX while first app in split selection is initiated */
|
||||
public static final Property<TaskThumbnailViewDeprecated, Float> SPLIT_SELECT_TRANSLATE_X =
|
||||
new FloatProperty<TaskThumbnailViewDeprecated>("splitSelectTranslateX") {
|
||||
@Override
|
||||
public void setValue(TaskThumbnailViewDeprecated thumbnail,
|
||||
float splitSelectTranslateX) {
|
||||
thumbnail.applySplitSelectTranslateX(splitSelectTranslateX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(TaskThumbnailViewDeprecated thumbnailView) {
|
||||
return thumbnailView.mSplitSelectTranslateX;
|
||||
}
|
||||
};
|
||||
|
||||
/** Use to animate thumbnail translationY while first app in split selection is initiated */
|
||||
public static final Property<TaskThumbnailViewDeprecated, Float> SPLIT_SELECT_TRANSLATE_Y =
|
||||
new FloatProperty<TaskThumbnailViewDeprecated>("splitSelectTranslateY") {
|
||||
@Override
|
||||
public void setValue(TaskThumbnailViewDeprecated thumbnail,
|
||||
float splitSelectTranslateY) {
|
||||
thumbnail.applySplitSelectTranslateY(splitSelectTranslateY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(TaskThumbnailViewDeprecated thumbnailView) {
|
||||
return thumbnailView.mSplitSelectTranslateY;
|
||||
}
|
||||
};
|
||||
|
||||
private final RecentsViewContainer mContainer;
|
||||
private TaskOverlay<?> mOverlay;
|
||||
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
@@ -160,8 +130,6 @@ public class TaskThumbnailViewDeprecated extends View implements ViewPool.Reusab
|
||||
private boolean mOverlayEnabled;
|
||||
/** Used as a placeholder when the original thumbnail animates out to. */
|
||||
private boolean mShowSplashForSplitSelection;
|
||||
private float mSplitSelectTranslateX;
|
||||
private float mSplitSelectTranslateY;
|
||||
|
||||
public TaskThumbnailViewDeprecated(Context context) {
|
||||
this(context, null);
|
||||
@@ -415,31 +383,6 @@ public class TaskThumbnailViewDeprecated extends View implements ViewPool.Reusab
|
||||
}
|
||||
}
|
||||
|
||||
/** See {@link #SPLIT_SELECT_TRANSLATE_X} */
|
||||
protected void applySplitSelectTranslateX(float splitSelectTranslateX) {
|
||||
mSplitSelectTranslateX = splitSelectTranslateX;
|
||||
applyTranslateX();
|
||||
}
|
||||
|
||||
/** See {@link #SPLIT_SELECT_TRANSLATE_Y} */
|
||||
protected void applySplitSelectTranslateY(float splitSelectTranslateY) {
|
||||
mSplitSelectTranslateY = splitSelectTranslateY;
|
||||
applyTranslateY();
|
||||
}
|
||||
|
||||
private void applyTranslateX() {
|
||||
setTranslationX(mSplitSelectTranslateX);
|
||||
}
|
||||
|
||||
private void applyTranslateY() {
|
||||
setTranslationY(mSplitSelectTranslateY);
|
||||
}
|
||||
|
||||
protected void resetViewTransforms() {
|
||||
mSplitSelectTranslateX = 0;
|
||||
mSplitSelectTranslateY = 0;
|
||||
}
|
||||
|
||||
public TaskView getTaskView() {
|
||||
return (TaskView) getParent();
|
||||
}
|
||||
|
||||
@@ -23,7 +23,9 @@ import android.annotation.IdRes
|
||||
import android.app.ActivityOptions
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Insets
|
||||
import android.graphics.PointF
|
||||
import android.graphics.Rect
|
||||
import android.graphics.drawable.Drawable
|
||||
@@ -138,8 +140,8 @@ constructor(
|
||||
/** Returns a copy of integer array containing taskIds of all tasks in the TaskView. */
|
||||
get() = taskContainers.map { it.task.key.id }.toIntArray()
|
||||
|
||||
val thumbnailViews: Array<TaskThumbnailViewDeprecated>
|
||||
get() = taskContainers.map { it.thumbnailViewDeprecated }.toTypedArray()
|
||||
val snapshotViews: Array<View>
|
||||
get() = taskContainers.map { it.snapshotView }.toTypedArray()
|
||||
|
||||
val isGridTask: Boolean
|
||||
/** Returns whether the task is part of overview grid and not being focused. */
|
||||
@@ -170,6 +172,11 @@ constructor(
|
||||
/** Returns the first thumbnailView of the TaskView. */
|
||||
get() = taskContainers[0].thumbnailViewDeprecated
|
||||
|
||||
@get:Deprecated("Use [taskContainers] instead.")
|
||||
val firstSnapshotView: View
|
||||
/** Returns the first snapshotView of the TaskView. */
|
||||
get() = taskContainers[0].snapshotView
|
||||
|
||||
@get:Deprecated("Use [taskContainers] instead.")
|
||||
val firstItemInfo: ItemInfo
|
||||
get() = taskContainers[0].itemInfo
|
||||
@@ -1197,10 +1204,10 @@ constructor(
|
||||
this,
|
||||
container.task,
|
||||
container.iconView.drawable,
|
||||
container.thumbnailViewDeprecated,
|
||||
container.thumbnailViewDeprecated.thumbnail, /* intent */
|
||||
null, /* user */
|
||||
null,
|
||||
container.snapshotView,
|
||||
container.thumbnail,
|
||||
/* intent */ null,
|
||||
/* user */ null,
|
||||
container.itemInfo
|
||||
)
|
||||
}
|
||||
@@ -1512,6 +1519,10 @@ constructor(
|
||||
gridTranslationY = 0f
|
||||
boxTranslationY = 0f
|
||||
nonGridPivotTranslationX = 0f
|
||||
taskContainers.forEach {
|
||||
it.snapshotView.translationX = 0f
|
||||
it.snapshotView.translationY = 0f
|
||||
}
|
||||
resetViewTransforms()
|
||||
}
|
||||
|
||||
@@ -1537,10 +1548,6 @@ constructor(
|
||||
alpha = stableAlpha
|
||||
setIconScaleAndDim(1f)
|
||||
setColorTint(0f, 0)
|
||||
if (!enableRefactorTaskThumbnail()) {
|
||||
// TODO(b/335399428) add split select functionality to new TTV
|
||||
taskContainers.forEach { it.thumbnailViewDeprecated.resetViewTransforms() }
|
||||
}
|
||||
}
|
||||
|
||||
private fun getGridTrans(endTranslation: Float) =
|
||||
@@ -1624,6 +1631,18 @@ constructor(
|
||||
val snapshotView: View
|
||||
get() = thumbnailView ?: thumbnailViewDeprecated
|
||||
|
||||
// TODO(b/349120849): Extract ThumbnailData from TaskContainerData/TaskThumbnailViewModel
|
||||
val thumbnail: Bitmap?
|
||||
get() = thumbnailViewDeprecated.thumbnail
|
||||
|
||||
// TODO(b/349120849): Extract ThumbnailData from TaskContainerData/TaskThumbnailViewModel
|
||||
val isRealSnapshot: Boolean
|
||||
get() = thumbnailViewDeprecated.isRealSnapshot()
|
||||
|
||||
// TODO(b/349120849): Extract ThumbnailData from TaskContainerData/TaskThumbnailViewModel
|
||||
val scaledInsets: Insets
|
||||
get() = thumbnailViewDeprecated.scaledInsets
|
||||
|
||||
/** Builds proto for logging */
|
||||
val itemInfo: WorkspaceItemInfo
|
||||
get() =
|
||||
|
||||
+3
-5
@@ -33,7 +33,6 @@ import com.android.launcher3.taskbar.TaskbarActivityContext
|
||||
import com.android.launcher3.util.SplitConfigurationOptions
|
||||
import com.android.quickstep.views.GroupedTaskView
|
||||
import com.android.quickstep.views.IconView
|
||||
import com.android.quickstep.views.TaskThumbnailViewDeprecated
|
||||
import com.android.quickstep.views.TaskView
|
||||
import com.android.quickstep.views.TaskView.TaskContainer
|
||||
import com.android.systemui.shared.recents.model.Task
|
||||
@@ -59,7 +58,7 @@ class SplitAnimationControllerTest {
|
||||
private val mockSplitSelectStateController: SplitSelectStateController = mock()
|
||||
// TaskView
|
||||
private val mockTaskView: TaskView = mock()
|
||||
private val mockThumbnailView: TaskThumbnailViewDeprecated = mock()
|
||||
private val mockSnapshotView: View = mock()
|
||||
private val mockBitmap: Bitmap = mock()
|
||||
private val mockIconView: IconView = mock()
|
||||
private val mockTaskViewDrawable: Drawable = mock()
|
||||
@@ -87,8 +86,8 @@ class SplitAnimationControllerTest {
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
whenever(mockTaskContainer.thumbnailViewDeprecated).thenReturn(mockThumbnailView)
|
||||
whenever(mockThumbnailView.thumbnail).thenReturn(mockBitmap)
|
||||
whenever(mockTaskContainer.snapshotView).thenReturn(mockSnapshotView)
|
||||
whenever(mockTaskContainer.thumbnail).thenReturn(mockBitmap)
|
||||
whenever(mockTaskContainer.iconView).thenReturn(mockIconView)
|
||||
whenever(mockIconView.drawable).thenReturn(mockTaskViewDrawable)
|
||||
whenever(mockTaskView.taskContainers).thenReturn(List(1) { mockTaskContainer })
|
||||
@@ -180,7 +179,6 @@ class SplitAnimationControllerTest {
|
||||
|
||||
whenever(mockTaskContainer.task).thenReturn(mockTask)
|
||||
whenever(mockTaskContainer.iconView).thenReturn(mockIconView)
|
||||
whenever(mockTaskContainer.thumbnailViewDeprecated).thenReturn(mockThumbnailView)
|
||||
whenever(mockTask.getKey()).thenReturn(mockTaskKey)
|
||||
whenever(mockTaskKey.getId()).thenReturn(taskId)
|
||||
whenever(mockSplitSelectStateController.initialTaskId).thenReturn(taskId)
|
||||
|
||||
Reference in New Issue
Block a user