mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-28 07:46:55 +00:00
Merge "Default to using SplitSelectSource drawable if TaskView icon drawable is null" into tm-qpr-dev
This commit is contained in:
@@ -639,7 +639,7 @@ public class QuickstepLauncher extends Launcher {
|
||||
PendingAnimation anim = new PendingAnimation(TABLET_HOME_TO_SPLIT.getDuration());
|
||||
RectF startingTaskRect = new RectF();
|
||||
final FloatingTaskView floatingTaskView = FloatingTaskView.getFloatingTaskView(this,
|
||||
source.view, null /* thumbnail */, source.drawable, startingTaskRect);
|
||||
source.getView(), null /* thumbnail */, source.getDrawable(), startingTaskRect);
|
||||
floatingTaskView.setAlpha(1);
|
||||
floatingTaskView.addStagingAnimation(anim, startingTaskRect, tempRect,
|
||||
false /* fadeWithThumbnail */, true /* isStagedTask */);
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.view.View
|
||||
import com.android.launcher3.DeviceProfile
|
||||
import com.android.launcher3.anim.PendingAnimation
|
||||
import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource
|
||||
import com.android.quickstep.views.IconView
|
||||
import com.android.quickstep.views.TaskThumbnailView
|
||||
import com.android.quickstep.views.TaskView
|
||||
import com.android.quickstep.views.TaskView.TaskIdAttributeContainer
|
||||
@@ -52,21 +53,22 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC
|
||||
* depending on the state of the surface from which the split was initiated
|
||||
*/
|
||||
fun getFirstAnimInitViews(taskViewSupplier: Supplier<TaskView>,
|
||||
splitSelectSourceSupplier: Supplier<SplitSelectSource>)
|
||||
splitSelectSourceSupplier: Supplier<SplitSelectSource?>)
|
||||
: SplitAnimInitProps {
|
||||
val splitSelectSource = splitSelectSourceSupplier.get()
|
||||
if (!splitSelectStateController.isAnimateCurrentTaskDismissal) {
|
||||
// Initiating from home
|
||||
val splitSelectSource = splitSelectSourceSupplier.get()
|
||||
return SplitAnimInitProps(splitSelectSource.view, originalBitmap = null,
|
||||
return SplitAnimInitProps(splitSelectSource!!.view, originalBitmap = null,
|
||||
splitSelectSource.drawable, fadeWithThumbnail = false, isStagedTask = true,
|
||||
iconView = null)
|
||||
} else if (splitSelectStateController.isDismissingFromSplitPair) {
|
||||
// Initiating split from overview, but on a split pair
|
||||
val taskView = taskViewSupplier.get()
|
||||
for (container : TaskIdAttributeContainer in taskView.taskIdAttributeContainers) {
|
||||
if (container.task.key.id == splitSelectStateController.initialTaskId) {
|
||||
if (container.task.getKey().getId() == splitSelectStateController.initialTaskId) {
|
||||
val drawable = getDrawable(container.iconView, splitSelectSource)
|
||||
return SplitAnimInitProps(container.thumbnailView,
|
||||
container.thumbnailView.thumbnail, container.iconView.drawable!!,
|
||||
container.thumbnailView.thumbnail, drawable!!,
|
||||
fadeWithThumbnail = true, isStagedTask = true,
|
||||
iconView = container.iconView
|
||||
)
|
||||
@@ -77,13 +79,27 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC
|
||||
} else {
|
||||
// Initiating split from overview on fullscreen task TaskView
|
||||
val taskView = taskViewSupplier.get()
|
||||
val drawable = getDrawable(taskView.iconView, splitSelectSource)
|
||||
return SplitAnimInitProps(taskView.thumbnail, taskView.thumbnail.thumbnail,
|
||||
taskView.iconView.drawable!!, fadeWithThumbnail = true, isStagedTask = true,
|
||||
drawable!!, fadeWithThumbnail = true, isStagedTask = true,
|
||||
taskView.iconView
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the drawable that's provided in iconView, however if that
|
||||
* is null it falls back to the drawable that's in splitSelectSource.
|
||||
* TaskView's icon drawable can be null if the TaskView is scrolled far enough off screen
|
||||
* @return [Drawable]
|
||||
*/
|
||||
fun getDrawable(iconView: IconView, splitSelectSource: SplitSelectSource?) : Drawable? {
|
||||
if (iconView.drawable == null && splitSelectSource != null) {
|
||||
return splitSelectSource.drawable
|
||||
}
|
||||
return iconView.drawable
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.android.quickstep.util
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.View
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.launcher3.util.SplitConfigurationOptions
|
||||
import com.android.quickstep.views.GroupedTaskView
|
||||
import com.android.quickstep.views.IconView
|
||||
import com.android.quickstep.views.TaskThumbnailView
|
||||
import com.android.quickstep.views.TaskView
|
||||
import com.android.quickstep.views.TaskView.TaskIdAttributeContainer
|
||||
import com.android.systemui.shared.recents.model.Task
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
import org.mockito.MockitoAnnotations
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class SplitAnimationControllerTest {
|
||||
|
||||
private val taskId = 9
|
||||
|
||||
@Mock lateinit var mockSplitSelectStateController: SplitSelectStateController
|
||||
// TaskView
|
||||
@Mock lateinit var mockTaskView: TaskView
|
||||
@Mock lateinit var mockThumbnailView: TaskThumbnailView
|
||||
@Mock lateinit var mockBitmap: Bitmap
|
||||
@Mock lateinit var mockIconView: IconView
|
||||
@Mock lateinit var mockTaskViewDrawable: Drawable
|
||||
// GroupedTaskView
|
||||
@Mock lateinit var mockGroupedTaskView: GroupedTaskView
|
||||
@Mock lateinit var mockTask: Task
|
||||
@Mock lateinit var mockTaskKey: Task.TaskKey
|
||||
@Mock lateinit var mockTaskIdAttributeContainer: TaskIdAttributeContainer
|
||||
|
||||
// SplitSelectSource
|
||||
@Mock lateinit var splitSelectSource: SplitConfigurationOptions.SplitSelectSource
|
||||
@Mock lateinit var mockSplitSourceDrawable: Drawable
|
||||
@Mock lateinit var mockSplitSourceView: View
|
||||
|
||||
lateinit var splitAnimationController: SplitAnimationController
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
|
||||
whenever(mockTaskView.thumbnail).thenReturn(mockThumbnailView)
|
||||
whenever(mockThumbnailView.thumbnail).thenReturn(mockBitmap)
|
||||
whenever(mockTaskView.iconView).thenReturn(mockIconView)
|
||||
whenever(mockIconView.drawable).thenReturn(mockTaskViewDrawable)
|
||||
|
||||
whenever(splitSelectSource.drawable).thenReturn(mockSplitSourceDrawable)
|
||||
whenever(splitSelectSource.view).thenReturn(mockSplitSourceView)
|
||||
|
||||
splitAnimationController = SplitAnimationController(mockSplitSelectStateController)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getFirstAnimInitViews_nullTaskViewIcon_useSplitSourceIcon() {
|
||||
// Hit fullscreen task dismissal state
|
||||
whenever(mockSplitSelectStateController.isAnimateCurrentTaskDismissal).thenReturn(true)
|
||||
whenever(mockSplitSelectStateController.isDismissingFromSplitPair).thenReturn(false)
|
||||
|
||||
// Missing taskView icon
|
||||
whenever(mockIconView.drawable).thenReturn(null)
|
||||
|
||||
val splitAnimInitProps : SplitAnimationController.Companion.SplitAnimInitProps =
|
||||
splitAnimationController.getFirstAnimInitViews(
|
||||
{ mockTaskView }, { splitSelectSource })
|
||||
|
||||
assertEquals("Did not fallback to use splitSource icon drawable",
|
||||
mockSplitSourceDrawable, splitAnimInitProps.iconDrawable)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getFirstAnimInitViews_validTaskViewIcon_useTaskViewIcon() {
|
||||
// Hit fullscreen task dismissal state
|
||||
whenever(mockSplitSelectStateController.isAnimateCurrentTaskDismissal).thenReturn(true)
|
||||
whenever(mockSplitSelectStateController.isDismissingFromSplitPair).thenReturn(false)
|
||||
|
||||
val splitAnimInitProps : SplitAnimationController.Companion.SplitAnimInitProps =
|
||||
splitAnimationController.getFirstAnimInitViews(
|
||||
{ mockTaskView }, { splitSelectSource })
|
||||
|
||||
assertEquals("Did not use taskView icon drawable", mockTaskViewDrawable,
|
||||
splitAnimInitProps.iconDrawable)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getFirstAnimInitViews_validTaskViewNullSplitSource_useTaskViewIcon() {
|
||||
// Hit fullscreen task dismissal state
|
||||
whenever(mockSplitSelectStateController.isAnimateCurrentTaskDismissal).thenReturn(true)
|
||||
whenever(mockSplitSelectStateController.isDismissingFromSplitPair).thenReturn(false)
|
||||
|
||||
// Set split source to null
|
||||
whenever(splitSelectSource.drawable).thenReturn(null)
|
||||
|
||||
val splitAnimInitProps : SplitAnimationController.Companion.SplitAnimInitProps =
|
||||
splitAnimationController.getFirstAnimInitViews(
|
||||
{ mockTaskView }, { splitSelectSource })
|
||||
|
||||
assertEquals("Did not use taskView icon drawable", mockTaskViewDrawable,
|
||||
splitAnimInitProps.iconDrawable)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getFirstAnimInitViews_nullTaskViewValidSplitSource_noTaskDismissal() {
|
||||
// Hit initiating split from home
|
||||
whenever(mockSplitSelectStateController.isAnimateCurrentTaskDismissal).thenReturn(false)
|
||||
whenever(mockSplitSelectStateController.isDismissingFromSplitPair).thenReturn(false)
|
||||
|
||||
val splitAnimInitProps : SplitAnimationController.Companion.SplitAnimInitProps =
|
||||
splitAnimationController.getFirstAnimInitViews(
|
||||
{ mockTaskView }, { splitSelectSource })
|
||||
|
||||
assertEquals("Did not use splitSource icon drawable", mockSplitSourceDrawable,
|
||||
splitAnimInitProps.iconDrawable)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getFirstAnimInitViews_nullTaskViewValidSplitSource_groupedTaskView() {
|
||||
// Hit groupedTaskView dismissal
|
||||
whenever(mockSplitSelectStateController.isAnimateCurrentTaskDismissal).thenReturn(true)
|
||||
whenever(mockSplitSelectStateController.isDismissingFromSplitPair).thenReturn(true)
|
||||
|
||||
// Remove icon view from GroupedTaskView
|
||||
whenever(mockIconView.drawable).thenReturn(null)
|
||||
|
||||
whenever(mockTaskIdAttributeContainer.task).thenReturn(mockTask)
|
||||
whenever(mockTaskIdAttributeContainer.iconView).thenReturn(mockIconView)
|
||||
whenever(mockTaskIdAttributeContainer.thumbnailView).thenReturn(mockThumbnailView)
|
||||
whenever(mockTask.getKey()).thenReturn(mockTaskKey)
|
||||
whenever(mockTaskKey.getId()).thenReturn(taskId)
|
||||
whenever(mockSplitSelectStateController.initialTaskId).thenReturn(taskId)
|
||||
whenever(mockGroupedTaskView.taskIdAttributeContainers)
|
||||
.thenReturn(Array(1) { mockTaskIdAttributeContainer })
|
||||
val splitAnimInitProps : SplitAnimationController.Companion.SplitAnimInitProps =
|
||||
splitAnimationController.getFirstAnimInitViews(
|
||||
{ mockGroupedTaskView }, { splitSelectSource })
|
||||
|
||||
assertEquals("Did not use splitSource icon drawable", mockSplitSourceDrawable,
|
||||
splitAnimInitProps.iconDrawable)
|
||||
}
|
||||
}
|
||||
@@ -200,8 +200,8 @@ public final class SplitConfigurationOptions {
|
||||
/** Keep in sync w/ ActivityTaskManager#INVALID_TASK_ID (unreference-able) */
|
||||
private static final int INVALID_TASK_ID = -1;
|
||||
|
||||
public final View view;
|
||||
public final Drawable drawable;
|
||||
private View view;
|
||||
private Drawable drawable;
|
||||
public final Intent intent;
|
||||
public final SplitPositionOption position;
|
||||
public final ItemInfo itemInfo;
|
||||
@@ -224,5 +224,13 @@ public final class SplitConfigurationOptions {
|
||||
this.itemInfo = itemInfo;
|
||||
this.splitEvent = splitEvent;
|
||||
}
|
||||
|
||||
public Drawable getDrawable() {
|
||||
return drawable;
|
||||
}
|
||||
|
||||
public View getView() {
|
||||
return view;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user