2024-05-13 14:02:27 +00:00
|
|
|
/*
|
|
|
|
|
* 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.launcher3.widget.util
|
|
|
|
|
|
|
|
|
|
import android.content.Context
|
|
|
|
|
import android.graphics.Point
|
|
|
|
|
import androidx.test.core.app.ApplicationProvider
|
|
|
|
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
|
|
|
|
import androidx.test.filters.SmallTest
|
|
|
|
|
import com.android.launcher3.DeviceProfile
|
|
|
|
|
import com.android.launcher3.LauncherAppState
|
|
|
|
|
import com.android.launcher3.R
|
|
|
|
|
import com.android.launcher3.model.data.ItemInfo
|
|
|
|
|
import com.android.launcher3.util.ActivityContextWrapper
|
|
|
|
|
import com.google.common.truth.Truth.assertThat
|
|
|
|
|
import org.junit.Assume.assumeTrue
|
|
|
|
|
import org.junit.Before
|
|
|
|
|
import org.junit.Test
|
|
|
|
|
import org.junit.runner.RunWith
|
|
|
|
|
import org.mockito.ArgumentMatchers.any
|
|
|
|
|
import org.mockito.Mockito
|
2024-05-31 17:12:19 +00:00
|
|
|
import org.mockito.kotlin.doReturn
|
2024-05-13 14:02:27 +00:00
|
|
|
import org.mockito.kotlin.whenever
|
|
|
|
|
|
|
|
|
|
@SmallTest
|
|
|
|
|
@RunWith(AndroidJUnit4::class)
|
|
|
|
|
class WidgetDragScaleUtilsTest {
|
|
|
|
|
private lateinit var context: Context
|
|
|
|
|
private lateinit var itemInfo: ItemInfo
|
|
|
|
|
private lateinit var deviceProfile: DeviceProfile
|
|
|
|
|
|
|
|
|
|
@Before
|
|
|
|
|
fun setup() {
|
|
|
|
|
context = ActivityContextWrapper(ApplicationProvider.getApplicationContext())
|
|
|
|
|
|
|
|
|
|
itemInfo = ItemInfo()
|
|
|
|
|
|
|
|
|
|
deviceProfile =
|
|
|
|
|
Mockito.spy(LauncherAppState.getIDP(context).getDeviceProfile(context).copy(context))
|
|
|
|
|
|
2024-05-31 17:12:19 +00:00
|
|
|
doReturn(0.8f)
|
|
|
|
|
.whenever(deviceProfile).getWorkspaceSpringLoadScale(any(Context::class.java))
|
2024-05-13 14:02:27 +00:00
|
|
|
deviceProfile.cellLayoutBorderSpacePx = Point(CELL_SPACING, CELL_SPACING)
|
|
|
|
|
deviceProfile.widgetPadding.setEmpty()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun getWidgetDragScalePx_largeDraggedView_downScaled() {
|
2024-05-31 17:12:19 +00:00
|
|
|
val minSize = context.resources.getDimensionPixelSize(
|
|
|
|
|
R.dimen.widget_drag_view_min_scale_down_size)
|
|
|
|
|
whenever(deviceProfile.cellSize).thenReturn(Point(minSize * 2, minSize * 2))
|
|
|
|
|
|
2024-05-13 14:02:27 +00:00
|
|
|
itemInfo.spanX = 2
|
|
|
|
|
itemInfo.spanY = 2
|
2024-05-31 17:12:19 +00:00
|
|
|
|
2024-05-13 14:02:27 +00:00
|
|
|
val widgetSize = WidgetSizes.getWidgetSizePx(deviceProfile, itemInfo.spanX, itemInfo.spanY)
|
|
|
|
|
// Assume dragged view was a drawable which was larger than widget's size.
|
|
|
|
|
val draggedViewWidthPx = widgetSize.width + 0.5f * widgetSize.width
|
|
|
|
|
val draggedViewHeightPx = widgetSize.height + 0.5f * widgetSize.height
|
|
|
|
|
// Returns negative scale pixels - i.e. downscaled
|
|
|
|
|
assertThat(
|
|
|
|
|
WidgetDragScaleUtils.getWidgetDragScalePx(
|
|
|
|
|
context,
|
|
|
|
|
deviceProfile,
|
|
|
|
|
draggedViewWidthPx,
|
|
|
|
|
draggedViewHeightPx,
|
|
|
|
|
itemInfo
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
.isLessThan(0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun getWidgetDragScalePx_draggedViewSameAsWidgetSize_downScaled() {
|
2024-05-31 17:12:19 +00:00
|
|
|
val minSize = context.resources.getDimensionPixelSize(
|
|
|
|
|
R.dimen.widget_drag_view_min_scale_down_size)
|
|
|
|
|
whenever(deviceProfile.cellSize).thenReturn(Point(minSize * 2, minSize * 2))
|
2024-05-13 14:02:27 +00:00
|
|
|
itemInfo.spanX = 4
|
|
|
|
|
itemInfo.spanY = 2
|
|
|
|
|
|
|
|
|
|
val widgetSize = WidgetSizes.getWidgetSizePx(deviceProfile, itemInfo.spanX, itemInfo.spanY)
|
|
|
|
|
// Assume dragged view was a drawable which was larger than widget's size.
|
|
|
|
|
val draggedViewWidthPx = widgetSize.width.toFloat()
|
|
|
|
|
val draggedViewHeightPx = widgetSize.height.toFloat()
|
|
|
|
|
// Returns negative scale pixels - i.e. downscaled
|
|
|
|
|
// Even if dragged view was of same size as widget's drop target, to accommodate the spring
|
|
|
|
|
// load scaling of workspace and additionally getting the view inside of drop target frame,
|
|
|
|
|
// widget would be downscaled.
|
|
|
|
|
assertThat(
|
|
|
|
|
WidgetDragScaleUtils.getWidgetDragScalePx(
|
|
|
|
|
context,
|
|
|
|
|
deviceProfile,
|
|
|
|
|
draggedViewWidthPx,
|
|
|
|
|
draggedViewHeightPx,
|
|
|
|
|
itemInfo
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
.isLessThan(0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun getWidgetDragScalePx_draggedViewSmallerThanMinSize_scaledSizeIsAtLeastMinSize() {
|
|
|
|
|
val minSizePx =
|
|
|
|
|
context.resources.getDimensionPixelSize(R.dimen.widget_drag_view_min_scale_down_size)
|
|
|
|
|
// Assume min size is greater than cell size, so that, we know the upscale of dragged view
|
|
|
|
|
// is due to min size enforcement.
|
2024-05-31 17:12:19 +00:00
|
|
|
whenever(deviceProfile.cellSize).thenReturn(Point(minSizePx / 2, minSizePx / 2))
|
|
|
|
|
itemInfo.spanX = 1
|
|
|
|
|
itemInfo.spanY = 1
|
2024-05-13 14:02:27 +00:00
|
|
|
|
|
|
|
|
val draggedViewWidthPx = minSizePx - 15f
|
|
|
|
|
val draggedViewHeightPx = minSizePx - 15f
|
|
|
|
|
|
|
|
|
|
// Returns positive scale pixels - i.e. up-scaled
|
|
|
|
|
val finalScalePx =
|
|
|
|
|
WidgetDragScaleUtils.getWidgetDragScalePx(
|
|
|
|
|
context,
|
|
|
|
|
deviceProfile,
|
|
|
|
|
draggedViewWidthPx,
|
|
|
|
|
draggedViewHeightPx,
|
|
|
|
|
itemInfo
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
val effectiveWidthPx = draggedViewWidthPx + finalScalePx
|
|
|
|
|
val scaleFactor = (draggedViewWidthPx + finalScalePx) / draggedViewWidthPx
|
|
|
|
|
val effectiveHeightPx = scaleFactor * draggedViewHeightPx
|
|
|
|
|
// Both original height and width were smaller than min size, scaling them down below min
|
|
|
|
|
// size would have made them not visible under the finger. Here, as expected, widget is
|
|
|
|
|
// at least as large as min size.
|
|
|
|
|
assertThat(effectiveWidthPx).isAtLeast(minSizePx)
|
|
|
|
|
assertThat(effectiveHeightPx).isAtLeast(minSizePx)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
companion object {
|
|
|
|
|
const val CELL_SPACING = 10
|
|
|
|
|
}
|
|
|
|
|
}
|