Merge changes I31d9a51e,I1bc14be7 into main
* changes: Prevent requestLayout() when updating drawables that don't change size Fix splash icon size to 52dp
This commit is contained in:
@@ -15,22 +15,23 @@
|
||||
-->
|
||||
<com.android.quickstep.task.thumbnail.TaskThumbnailView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent" >
|
||||
|
||||
<ImageView
|
||||
<com.android.quickstep.views.FixedSizeImageView
|
||||
android:id="@+id/task_thumbnail"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:importantForAccessibility="no"
|
||||
android:scaleType="matrix"
|
||||
android:visibility="gone"/>
|
||||
android:visibility="invisible"/>
|
||||
|
||||
<com.android.quickstep.task.thumbnail.LiveTileView
|
||||
android:id="@+id/task_thumbnail_live_tile"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone"/>
|
||||
android:visibility="invisible"/>
|
||||
|
||||
<View
|
||||
android:id="@+id/task_thumbnail_scrim"
|
||||
@@ -39,16 +40,23 @@
|
||||
android:background="@color/overview_foreground_scrim_color"
|
||||
android:alpha="0" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/splash_container"
|
||||
<View
|
||||
android:id="@+id/splash_background"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone">
|
||||
<ImageView
|
||||
android:id="@+id/splash_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:importantForAccessibility="no" />
|
||||
</FrameLayout>
|
||||
android:background="@android:color/black"
|
||||
android:alpha="0"
|
||||
android:importantForAccessibility="no" />
|
||||
|
||||
<com.android.quickstep.views.FixedSizeImageView
|
||||
android:id="@+id/splash_icon"
|
||||
android:layout_width="@dimen/task_thumbnail_splash_icon_size"
|
||||
android:layout_height="@dimen/task_thumbnail_splash_icon_size"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:scaleType="fitCenter"
|
||||
android:alpha="0"
|
||||
android:importantForAccessibility="no" />
|
||||
</com.android.quickstep.task.thumbnail.TaskThumbnailView>
|
||||
@@ -41,6 +41,8 @@
|
||||
<dimen name="task_thumbnail_icon_size">48dp</dimen>
|
||||
<!-- The icon size for the focused task, placed in center of touch target -->
|
||||
<dimen name="task_thumbnail_icon_drawable_size">44dp</dimen>
|
||||
<!-- The splash icon size on in Overview when a task is settled in the list -->
|
||||
<dimen name="task_thumbnail_splash_icon_size">52dp</dimen>
|
||||
<!-- The border width shown when task is hovered -->
|
||||
<dimen name="task_hover_border_width">4dp</dimen>
|
||||
<!-- The space under the focused task icon -->
|
||||
|
||||
@@ -23,6 +23,4 @@ package com.android.quickstep.recents.data
|
||||
*/
|
||||
data class RecentsDeviceProfile(
|
||||
val isLargeScreen: Boolean,
|
||||
val widthPx: Int,
|
||||
val heightPx: Int,
|
||||
)
|
||||
|
||||
+1
-3
@@ -26,7 +26,5 @@ class RecentsDeviceProfileRepositoryImpl(private val container: RecentsViewConta
|
||||
RecentsDeviceProfileRepository {
|
||||
|
||||
override fun getRecentsDeviceProfile() =
|
||||
with(container.deviceProfile) {
|
||||
RecentsDeviceProfile(isLargeScreen = isTablet, widthPx = widthPx, heightPx = heightPx)
|
||||
}
|
||||
with(container.deviceProfile) { RecentsDeviceProfile(isLargeScreen = isTablet) }
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import com.android.quickstep.recents.usecase.GetThumbnailPositionUseCase
|
||||
import com.android.quickstep.recents.usecase.GetThumbnailUseCase
|
||||
import com.android.quickstep.recents.usecase.SysUiStatusNavFlagsUseCase
|
||||
import com.android.quickstep.recents.viewmodel.RecentsViewData
|
||||
import com.android.quickstep.task.thumbnail.GetSplashSizeUseCase
|
||||
import com.android.quickstep.task.thumbnail.SplashAlphaUseCase
|
||||
import com.android.quickstep.task.thumbnail.TaskThumbnailViewData
|
||||
import com.android.quickstep.task.viewmodel.TaskContainerData
|
||||
@@ -176,7 +175,6 @@ class RecentsDependencies private constructor(private val appContext: Context) {
|
||||
getThumbnailPositionUseCase = inject(),
|
||||
tasksRepository = inject(),
|
||||
splashAlphaUseCase = inject(scopeId),
|
||||
getSplashSizeUseCase = inject(scopeId),
|
||||
)
|
||||
TaskOverlayViewModel::class.java -> {
|
||||
val task = extras["Task"] as Task
|
||||
@@ -204,12 +202,6 @@ class RecentsDependencies private constructor(private val appContext: Context) {
|
||||
tasksRepository = inject(),
|
||||
rotationStateRepository = inject(),
|
||||
)
|
||||
GetSplashSizeUseCase::class.java ->
|
||||
GetSplashSizeUseCase(
|
||||
taskThumbnailViewData = inject(scopeId),
|
||||
taskViewData = inject(scopeId, extras),
|
||||
deviceProfileRepository = inject(),
|
||||
)
|
||||
else -> {
|
||||
log("Factory for ${modelClass.simpleName} not defined!", Log.ERROR)
|
||||
error("Factory for ${modelClass.simpleName} not defined!")
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.task.thumbnail
|
||||
|
||||
import android.graphics.Point
|
||||
import android.graphics.drawable.Drawable
|
||||
import com.android.quickstep.recents.data.RecentsDeviceProfileRepository
|
||||
import com.android.quickstep.task.viewmodel.TaskViewData
|
||||
import kotlin.math.min
|
||||
|
||||
class GetSplashSizeUseCase(
|
||||
private val taskThumbnailViewData: TaskThumbnailViewData,
|
||||
private val taskViewData: TaskViewData,
|
||||
private val deviceProfileRepository: RecentsDeviceProfileRepository,
|
||||
) {
|
||||
fun execute(splashImage: Drawable): Point {
|
||||
val recentsDeviceProfile = deviceProfileRepository.getRecentsDeviceProfile()
|
||||
val screenWidth = recentsDeviceProfile.widthPx
|
||||
val screenHeight = recentsDeviceProfile.heightPx
|
||||
val scaleAtFullscreen =
|
||||
min(
|
||||
screenWidth / taskThumbnailViewData.width.value,
|
||||
screenHeight / taskThumbnailViewData.height.value,
|
||||
)
|
||||
val scaleFactor: Float = 1f / taskViewData.nonGridScale.value / scaleAtFullscreen
|
||||
return Point(
|
||||
(splashImage.intrinsicWidth * scaleFactor / taskThumbnailViewData.scaleX.value).toInt(),
|
||||
(splashImage.intrinsicHeight * scaleFactor / taskThumbnailViewData.scaleY.value)
|
||||
.toInt(),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.android.quickstep.task.thumbnail
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Point
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.Surface
|
||||
import androidx.annotation.ColorInt
|
||||
@@ -31,7 +30,7 @@ sealed class TaskThumbnailUiState {
|
||||
|
||||
data class SnapshotSplash(
|
||||
val snapshot: Snapshot,
|
||||
val splash: Splash,
|
||||
val splash: Drawable?,
|
||||
) : TaskThumbnailUiState()
|
||||
|
||||
data class Snapshot(
|
||||
@@ -39,9 +38,4 @@ sealed class TaskThumbnailUiState {
|
||||
@Surface.Rotation val thumbnailRotation: Int,
|
||||
@ColorInt val backgroundColor: Int
|
||||
)
|
||||
|
||||
data class Splash(
|
||||
val icon: Drawable?,
|
||||
val size: Point,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -24,11 +24,9 @@ import android.graphics.Rect
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.view.ViewOutlineProvider
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageView
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.view.isInvisible
|
||||
import com.android.launcher3.R
|
||||
import com.android.launcher3.Utilities
|
||||
import com.android.launcher3.util.ViewPool
|
||||
@@ -41,6 +39,7 @@ import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.SnapshotSplash
|
||||
import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.Uninitialized
|
||||
import com.android.quickstep.task.viewmodel.TaskThumbnailViewModel
|
||||
import com.android.quickstep.util.TaskCornerRadius
|
||||
import com.android.quickstep.views.FixedSizeImageView
|
||||
import com.android.systemui.shared.system.QuickStepContract
|
||||
import kotlin.math.abs
|
||||
import kotlinx.coroutines.CoroutineName
|
||||
@@ -51,7 +50,7 @@ import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
|
||||
class TaskThumbnailView : FrameLayout, ViewPool.Reusable {
|
||||
class TaskThumbnailView : ConstraintLayout, ViewPool.Reusable {
|
||||
|
||||
private val viewData: TaskThumbnailViewData by RecentsDependencies.inject(this)
|
||||
private val viewModel: TaskThumbnailViewModel by RecentsDependencies.inject(this)
|
||||
@@ -60,9 +59,9 @@ class TaskThumbnailView : FrameLayout, ViewPool.Reusable {
|
||||
|
||||
private val scrimView: View by lazy { findViewById(R.id.task_thumbnail_scrim) }
|
||||
private val liveTileView: LiveTileView by lazy { findViewById(R.id.task_thumbnail_live_tile) }
|
||||
private val thumbnailView: ImageView by lazy { findViewById(R.id.task_thumbnail) }
|
||||
private val splashContainer: FrameLayout by lazy { findViewById(R.id.splash_container) }
|
||||
private val splashIcon: ImageView by lazy { findViewById(R.id.splash_icon) }
|
||||
private val thumbnailView: FixedSizeImageView by lazy { findViewById(R.id.task_thumbnail) }
|
||||
private val splashBackground: View by lazy { findViewById(R.id.splash_background) }
|
||||
private val splashIcon: FixedSizeImageView by lazy { findViewById(R.id.splash_icon) }
|
||||
|
||||
private var uiState: TaskThumbnailUiState = Uninitialized
|
||||
private var inheritedScale: Float = 1f
|
||||
@@ -107,7 +106,10 @@ class TaskThumbnailView : FrameLayout, ViewPool.Reusable {
|
||||
.onEach { dimProgress -> scrimView.alpha = dimProgress }
|
||||
.launchIn(viewAttachedScope)
|
||||
viewModel.splashAlpha
|
||||
.onEach { splashAlpha -> splashContainer.alpha = splashAlpha }
|
||||
.onEach { splashAlpha ->
|
||||
splashBackground.alpha = splashAlpha
|
||||
splashIcon.alpha = splashAlpha
|
||||
}
|
||||
.launchIn(viewAttachedScope)
|
||||
viewModel.cornerRadiusProgress.onEach { invalidateOutline() }.launchIn(viewAttachedScope)
|
||||
viewModel.inheritedScale
|
||||
@@ -152,15 +154,13 @@ class TaskThumbnailView : FrameLayout, ViewPool.Reusable {
|
||||
|
||||
override fun setScaleX(scaleX: Float) {
|
||||
super.setScaleX(scaleX)
|
||||
viewData.scaleX.value = scaleX
|
||||
// Splash icon should ignore scale
|
||||
// Splash icon should ignore scale on TTV
|
||||
splashIcon.scaleX = 1 / scaleX
|
||||
}
|
||||
|
||||
override fun setScaleY(scaleY: Float) {
|
||||
super.setScaleY(scaleY)
|
||||
viewData.scaleY.value = scaleY
|
||||
// Splash icon should ignore scale
|
||||
// Splash icon should ignore scale on TTV
|
||||
splashIcon.scaleY = 1 / scaleY
|
||||
}
|
||||
|
||||
@@ -173,9 +173,10 @@ class TaskThumbnailView : FrameLayout, ViewPool.Reusable {
|
||||
}
|
||||
|
||||
private fun resetViews() {
|
||||
liveTileView.isVisible = false
|
||||
thumbnailView.isVisible = false
|
||||
splashContainer.alpha = 0f
|
||||
liveTileView.isInvisible = true
|
||||
thumbnailView.isInvisible = true
|
||||
splashBackground.alpha = 0f
|
||||
splashIcon.alpha = 0f
|
||||
scrimView.alpha = 0f
|
||||
setBackgroundColor(Color.BLACK)
|
||||
}
|
||||
@@ -185,25 +186,20 @@ class TaskThumbnailView : FrameLayout, ViewPool.Reusable {
|
||||
}
|
||||
|
||||
private fun drawLiveWindow() {
|
||||
liveTileView.isVisible = true
|
||||
liveTileView.isInvisible = false
|
||||
}
|
||||
|
||||
private fun drawSnapshotSplash(snapshotSplash: SnapshotSplash) {
|
||||
drawSnapshot(snapshotSplash.snapshot)
|
||||
|
||||
splashContainer.isVisible = true
|
||||
splashContainer.setBackgroundColor(snapshotSplash.snapshot.backgroundColor)
|
||||
splashIcon.setImageDrawable(snapshotSplash.splash.icon)
|
||||
splashIcon.updateLayoutParams<LayoutParams> {
|
||||
width = snapshotSplash.splash.size.x
|
||||
height = snapshotSplash.splash.size.y
|
||||
}
|
||||
splashBackground.setBackgroundColor(snapshotSplash.snapshot.backgroundColor)
|
||||
splashIcon.setImageDrawable(snapshotSplash.splash)
|
||||
}
|
||||
|
||||
private fun drawSnapshot(snapshot: Snapshot) {
|
||||
drawBackground(snapshot.backgroundColor)
|
||||
thumbnailView.setImageBitmap(snapshot.bitmap)
|
||||
thumbnailView.isVisible = true
|
||||
thumbnailView.isInvisible = false
|
||||
setImageMatrix()
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,4 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
||||
class TaskThumbnailViewData {
|
||||
val width = MutableStateFlow(0)
|
||||
val height = MutableStateFlow(0)
|
||||
val scaleX = MutableStateFlow(1f)
|
||||
val scaleY = MutableStateFlow(1f)
|
||||
}
|
||||
|
||||
@@ -19,20 +19,17 @@ package com.android.quickstep.task.viewmodel
|
||||
import android.annotation.ColorInt
|
||||
import android.app.ActivityTaskManager.INVALID_TASK_ID
|
||||
import android.graphics.Matrix
|
||||
import android.graphics.Point
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import com.android.quickstep.recents.data.RecentTasksRepository
|
||||
import com.android.quickstep.recents.usecase.GetThumbnailPositionUseCase
|
||||
import com.android.quickstep.recents.usecase.ThumbnailPositionState
|
||||
import com.android.quickstep.recents.viewmodel.RecentsViewData
|
||||
import com.android.quickstep.task.thumbnail.GetSplashSizeUseCase
|
||||
import com.android.quickstep.task.thumbnail.SplashAlphaUseCase
|
||||
import com.android.quickstep.task.thumbnail.TaskThumbnailUiState
|
||||
import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.BackgroundOnly
|
||||
import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.LiveTile
|
||||
import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.Snapshot
|
||||
import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.SnapshotSplash
|
||||
import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.Splash
|
||||
import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.Uninitialized
|
||||
import com.android.systemui.shared.recents.model.Task
|
||||
import kotlin.math.max
|
||||
@@ -55,7 +52,6 @@ class TaskThumbnailViewModel(
|
||||
private val tasksRepository: RecentTasksRepository,
|
||||
private val getThumbnailPositionUseCase: GetThumbnailPositionUseCase,
|
||||
private val splashAlphaUseCase: SplashAlphaUseCase,
|
||||
private val getSplashSizeUseCase: GetSplashSizeUseCase,
|
||||
) {
|
||||
private val task = MutableStateFlow<Flow<Task?>>(flowOf(null))
|
||||
private val splashProgress = MutableStateFlow(flowOf(0f))
|
||||
@@ -100,7 +96,7 @@ class TaskThumbnailViewModel(
|
||||
isBackgroundOnly(taskVal) ->
|
||||
BackgroundOnly(taskVal.colorBackground.removeAlpha())
|
||||
isSnapshotSplashState(taskVal) ->
|
||||
SnapshotSplash(createSnapshotState(taskVal), createSplashState(taskVal))
|
||||
SnapshotSplash(createSnapshotState(taskVal), taskVal.icon)
|
||||
else -> Uninitialized
|
||||
}
|
||||
}
|
||||
@@ -139,12 +135,6 @@ class TaskThumbnailViewModel(
|
||||
return Snapshot(bitmap, thumbnailData.rotation, task.colorBackground.removeAlpha())
|
||||
}
|
||||
|
||||
private fun createSplashState(task: Task): Splash {
|
||||
val taskIcon = task.icon
|
||||
val size = if (taskIcon == null) Point() else getSplashSizeUseCase.execute(taskIcon)
|
||||
return Splash(taskIcon, size)
|
||||
}
|
||||
|
||||
@ColorInt private fun Int.removeAlpha(): Int = ColorUtils.setAlphaComponent(this, 0xff)
|
||||
|
||||
private companion object {
|
||||
|
||||
@@ -23,8 +23,6 @@ class TaskViewData(taskViewType: TaskViewType) {
|
||||
// This is typically a View concern but it is used to invalidate rendering in other Views
|
||||
val scale = MutableStateFlow(1f)
|
||||
|
||||
val nonGridScale = MutableStateFlow(1f)
|
||||
|
||||
// TODO(b/331753115): This property should not be in TaskViewData once TaskView is MVVM.
|
||||
/** Whether outline of TaskView is formed by outline thumbnail view(s). */
|
||||
val isOutlineFormedByThumbnailView: Boolean = taskViewType != TaskViewType.DESKTOP
|
||||
|
||||
@@ -22,8 +22,4 @@ class TaskViewModel(private val taskViewData: TaskViewData) : ViewModel() {
|
||||
fun updateScale(scale: Float) {
|
||||
taskViewData.scale.value = scale
|
||||
}
|
||||
|
||||
fun updateNonGridScale(nonGridScale: Float) {
|
||||
taskViewData.nonGridScale.value = nonGridScale
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.views
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
|
||||
/**
|
||||
* An [ImageView] that does not requestLayout() unless setLayoutParams is called.
|
||||
*
|
||||
* This is useful, particularly during animations, for [ImageView]s that are not supposed to be
|
||||
* resized.
|
||||
*/
|
||||
@SuppressLint("AppCompatCustomView")
|
||||
class FixedSizeImageView : ImageView {
|
||||
private var shouldRequestLayoutOnChanges = false
|
||||
|
||||
constructor(context: Context) : super(context)
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
|
||||
|
||||
constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet?,
|
||||
defStyleAttr: Int,
|
||||
) : super(context, attrs, defStyleAttr)
|
||||
|
||||
override fun setLayoutParams(params: ViewGroup.LayoutParams?) {
|
||||
shouldRequestLayoutOnChanges = true
|
||||
super.setLayoutParams(params)
|
||||
shouldRequestLayoutOnChanges = false
|
||||
}
|
||||
|
||||
override fun requestLayout() {
|
||||
if (shouldRequestLayoutOnChanges) {
|
||||
super.requestLayout()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -293,9 +293,6 @@ constructor(
|
||||
set(value) {
|
||||
field = value
|
||||
applyScale()
|
||||
if (enableRefactorTaskThumbnail()) {
|
||||
taskViewModel.updateNonGridScale(value)
|
||||
}
|
||||
}
|
||||
|
||||
private var dismissScale = 1f
|
||||
|
||||
-2
@@ -20,8 +20,6 @@ class FakeRecentsDeviceProfileRepository : RecentsDeviceProfileRepository {
|
||||
private var recentsDeviceProfile =
|
||||
RecentsDeviceProfile(
|
||||
isLargeScreen = false,
|
||||
widthPx = 1080,
|
||||
heightPx = 1920,
|
||||
)
|
||||
|
||||
override fun getRecentsDeviceProfile() = recentsDeviceProfile
|
||||
|
||||
+1
-1
@@ -39,6 +39,6 @@ class RecentsDeviceProfileRepositoryImplTest : FakeInvariantDeviceProfileTest()
|
||||
whenever(recentsViewContainer.deviceProfile).thenReturn(tabletDeviceProfile)
|
||||
|
||||
assertThat(systemUnderTest.getRecentsDeviceProfile())
|
||||
.isEqualTo(RecentsDeviceProfile(isLargeScreen = true, widthPx = 1600, heightPx = 2560))
|
||||
.isEqualTo(RecentsDeviceProfile(isLargeScreen = true))
|
||||
}
|
||||
}
|
||||
|
||||
-84
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.task.thumbnail
|
||||
|
||||
import android.graphics.Point
|
||||
import android.graphics.drawable.Drawable
|
||||
import com.android.quickstep.recents.data.FakeRecentsDeviceProfileRepository
|
||||
import com.android.quickstep.task.viewmodel.TaskViewData
|
||||
import com.android.quickstep.views.TaskViewType
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Test
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.whenever
|
||||
|
||||
class GetSplashSizeUseCaseTest {
|
||||
private val taskThumbnailViewData = TaskThumbnailViewData()
|
||||
private val taskViewData = TaskViewData(TaskViewType.SINGLE)
|
||||
private val recentsDeviceProfileRepository = FakeRecentsDeviceProfileRepository()
|
||||
private val systemUnderTest =
|
||||
GetSplashSizeUseCase(taskThumbnailViewData, taskViewData, recentsDeviceProfileRepository)
|
||||
|
||||
@Test
|
||||
fun execute_whenNoScaleRequired_returnsIntrinsicSize() {
|
||||
taskThumbnailViewData.width.value =
|
||||
recentsDeviceProfileRepository.getRecentsDeviceProfile().widthPx
|
||||
taskThumbnailViewData.height.value =
|
||||
recentsDeviceProfileRepository.getRecentsDeviceProfile().heightPx
|
||||
|
||||
assertThat(systemUnderTest.execute(createIcon(100, 100))).isEqualTo(Point(100, 100))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun execute_whenThumbnailViewIsSmallerThanScreen_returnsScaledSize() {
|
||||
taskThumbnailViewData.width.value =
|
||||
recentsDeviceProfileRepository.getRecentsDeviceProfile().widthPx / 2
|
||||
taskThumbnailViewData.height.value =
|
||||
recentsDeviceProfileRepository.getRecentsDeviceProfile().heightPx / 2
|
||||
|
||||
assertThat(systemUnderTest.execute(createIcon(100, 100))).isEqualTo(Point(50, 50))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun execute_whenThumbnailViewIsSmallerThanScreen_withNonGridScale_returnsScaledSize() {
|
||||
taskThumbnailViewData.width.value =
|
||||
recentsDeviceProfileRepository.getRecentsDeviceProfile().widthPx / 2
|
||||
taskThumbnailViewData.height.value =
|
||||
recentsDeviceProfileRepository.getRecentsDeviceProfile().heightPx / 2
|
||||
taskViewData.nonGridScale.value = 2f
|
||||
|
||||
assertThat(systemUnderTest.execute(createIcon(100, 100))).isEqualTo(Point(25, 25))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun execute_whenThumbnailViewIsSmallerThanScreen_withThumbnailViewScale_returnsScaledSize() {
|
||||
taskThumbnailViewData.width.value =
|
||||
recentsDeviceProfileRepository.getRecentsDeviceProfile().widthPx / 2
|
||||
taskThumbnailViewData.height.value =
|
||||
recentsDeviceProfileRepository.getRecentsDeviceProfile().heightPx / 2
|
||||
taskThumbnailViewData.scaleX.value = 2f
|
||||
taskThumbnailViewData.scaleY.value = 2f
|
||||
|
||||
assertThat(systemUnderTest.execute(createIcon(100, 100))).isEqualTo(Point(25, 25))
|
||||
}
|
||||
|
||||
private fun createIcon(width: Int, height: Int): Drawable =
|
||||
mock<Drawable>().apply {
|
||||
whenever(intrinsicWidth).thenReturn(width)
|
||||
whenever(intrinsicHeight).thenReturn(height)
|
||||
}
|
||||
}
|
||||
+3
-31
@@ -21,7 +21,6 @@ import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Color
|
||||
import android.graphics.Matrix
|
||||
import android.graphics.Point
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.Surface
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
@@ -35,7 +34,6 @@ import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.BackgroundOnly
|
||||
import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.LiveTile
|
||||
import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.Snapshot
|
||||
import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.SnapshotSplash
|
||||
import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.Splash
|
||||
import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.Uninitialized
|
||||
import com.android.quickstep.task.viewmodel.TaskContainerData
|
||||
import com.android.quickstep.task.viewmodel.TaskThumbnailViewModel
|
||||
@@ -46,10 +44,8 @@ import com.android.systemui.shared.recents.model.ThumbnailData
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.whenever
|
||||
|
||||
@@ -63,7 +59,6 @@ class TaskThumbnailViewModelTest {
|
||||
private val tasksRepository = FakeTasksRepository()
|
||||
private val mGetThumbnailPositionUseCase = mock<GetThumbnailPositionUseCase>()
|
||||
private val splashAlphaUseCase: SplashAlphaUseCase = mock()
|
||||
private val getSplashSizeUseCase: GetSplashSizeUseCase = mock()
|
||||
private val systemUnderTest by lazy {
|
||||
TaskThumbnailViewModel(
|
||||
recentsViewData,
|
||||
@@ -72,17 +67,11 @@ class TaskThumbnailViewModelTest {
|
||||
tasksRepository,
|
||||
mGetThumbnailPositionUseCase,
|
||||
splashAlphaUseCase,
|
||||
getSplashSizeUseCase,
|
||||
)
|
||||
}
|
||||
|
||||
private val tasks = (0..5).map(::createTaskWithId)
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
whenever(getSplashSizeUseCase.execute(any())).thenReturn(Point())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun initialStateIsUninitialized() = runTest {
|
||||
assertThat(systemUnderTest.uiState.first()).isEqualTo(Uninitialized)
|
||||
@@ -120,7 +109,7 @@ class TaskThumbnailViewModelTest {
|
||||
bitmap = expectedThumbnailData.thumbnail!!,
|
||||
thumbnailRotation = Surface.ROTATION_0,
|
||||
),
|
||||
Splash(expectedIconData.icon, Point())
|
||||
expectedIconData.icon
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -215,7 +204,7 @@ class TaskThumbnailViewModelTest {
|
||||
bitmap = expectedThumbnailData.thumbnail!!,
|
||||
thumbnailRotation = Surface.ROTATION_270,
|
||||
),
|
||||
Splash(expectedIconData.icon, Point())
|
||||
expectedIconData.icon
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -241,28 +230,11 @@ class TaskThumbnailViewModelTest {
|
||||
bitmap = expectedThumbnailData.thumbnail!!,
|
||||
thumbnailRotation = Surface.ROTATION_0,
|
||||
),
|
||||
Splash(expectedIconData.icon, Point())
|
||||
expectedIconData.icon
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun bindStoppedTask_thenStateContainsSplashSizeFromUseCase() = runTest {
|
||||
val taskId = 2
|
||||
val expectedSplashSize = Point(100, 150)
|
||||
whenever(getSplashSizeUseCase.execute(any())).thenReturn(expectedSplashSize)
|
||||
val expectedThumbnailData = createThumbnailData(rotation = Surface.ROTATION_270)
|
||||
tasksRepository.seedThumbnailData(mapOf(taskId to expectedThumbnailData))
|
||||
val expectedIconData = createIconData("Task 2")
|
||||
tasksRepository.seedIconData(mapOf(taskId to expectedIconData))
|
||||
tasksRepository.seedTasks(tasks)
|
||||
tasksRepository.setVisibleTasks(listOf(taskId))
|
||||
|
||||
systemUnderTest.bind(taskId)
|
||||
val uiState = systemUnderTest.uiState.first() as SnapshotSplash
|
||||
assertThat(uiState.splash.size).isEqualTo(expectedSplashSize)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getSnapshotMatrix_MissingThumbnail() = runTest {
|
||||
val taskId = 2
|
||||
|
||||
@@ -456,6 +456,7 @@
|
||||
<!-- Overview placeholder to compile in Launcher3 without Quickstep -->
|
||||
<dimen name="task_thumbnail_icon_size">0dp</dimen>
|
||||
<dimen name="task_thumbnail_icon_drawable_size">0dp</dimen>
|
||||
<dimen name="task_thumbnail_splash_icon_size">0dp</dimen>
|
||||
<dimen name="task_thumbnail_icon_drawable_size_grid">0dp</dimen>
|
||||
<dimen name="task_thumbnail_icon_menu_drawable_touch_size">0dp</dimen>
|
||||
<dimen name="task_menu_edge_padding">0dp</dimen>
|
||||
|
||||
Reference in New Issue
Block a user