Merge "Initial screenshot tests for bubble bar view" into main
This commit is contained in:
committed by
Android (Google) Code Review
commit
6138138d99
@@ -64,3 +64,11 @@ filegroup {
|
||||
"tests/multivalentScreenshotTests/src/**/*.kt",
|
||||
],
|
||||
}
|
||||
|
||||
filegroup {
|
||||
name: "launcher3-quickstep-testing",
|
||||
path: "testing",
|
||||
srcs: [
|
||||
"testing/**/*.kt",
|
||||
],
|
||||
}
|
||||
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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.taskbar.bubbles.testing
|
||||
|
||||
import android.app.Notification
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.graphics.Paint
|
||||
import android.util.PathParser
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import com.android.launcher3.R
|
||||
import com.android.launcher3.taskbar.bubbles.BubbleBarBubble
|
||||
import com.android.launcher3.taskbar.bubbles.BubbleView
|
||||
import com.android.wm.shell.shared.bubbles.BubbleInfo
|
||||
|
||||
object FakeBubbleViewFactory {
|
||||
|
||||
/** Inflates a [BubbleView] and adds it to the [parent] view if it is present. */
|
||||
fun createBubble(
|
||||
context: Context,
|
||||
key: String,
|
||||
parent: ViewGroup?,
|
||||
iconSize: Int = 50,
|
||||
iconColor: Int,
|
||||
badgeColor: Int = Color.RED,
|
||||
dotColor: Int = Color.BLUE,
|
||||
suppressNotification: Boolean = false,
|
||||
): BubbleView {
|
||||
val inflater = LayoutInflater.from(context)
|
||||
// BubbleView uses launcher's badge to icon ratio and expects the badge image to already
|
||||
// have the right size
|
||||
val badgeToIconRatio = 0.444f
|
||||
val badgeRadius = iconSize * badgeToIconRatio / 2
|
||||
val icon = createCircleBitmap(radius = iconSize / 2, color = iconColor)
|
||||
val badge = createCircleBitmap(radius = badgeRadius.toInt(), color = badgeColor)
|
||||
|
||||
val flags =
|
||||
if (suppressNotification) Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION else 0
|
||||
val bubbleInfo =
|
||||
BubbleInfo(key, flags, null, null, 0, context.packageName, null, null, false, true)
|
||||
val bubbleView = inflater.inflate(R.layout.bubblebar_item_view, parent, false) as BubbleView
|
||||
val dotPath =
|
||||
PathParser.createPathFromPathData(
|
||||
context.resources.getString(com.android.internal.R.string.config_icon_mask)
|
||||
)
|
||||
val bubble =
|
||||
BubbleBarBubble(bubbleInfo, bubbleView, badge, icon, dotColor, dotPath, "test app")
|
||||
bubbleView.setBubble(bubble)
|
||||
return bubbleView
|
||||
}
|
||||
|
||||
private fun createCircleBitmap(radius: Int, color: Int): Bitmap {
|
||||
val bitmap = Bitmap.createBitmap(radius * 2, radius * 2, Bitmap.Config.ARGB_8888)
|
||||
val canvas = Canvas(bitmap)
|
||||
canvas.drawARGB(0, 0, 0, 0)
|
||||
val paint = Paint()
|
||||
paint.color = color
|
||||
canvas.drawCircle(radius.toFloat(), radius.toFloat(), radius.toFloat(), paint)
|
||||
return bitmap
|
||||
}
|
||||
}
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* 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.taskbar.bubbles
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.platform.test.rule.ScreenRecordRule
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.FrameLayout.LayoutParams.MATCH_PARENT
|
||||
import android.widget.FrameLayout.LayoutParams.WRAP_CONTENT
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import com.android.launcher3.R
|
||||
import com.android.launcher3.taskbar.bubbles.testing.FakeBubbleViewFactory
|
||||
import com.google.android.apps.nexuslauncher.imagecomparison.goldenpathmanager.ViewScreenshotGoldenPathManager
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import platform.test.runner.parameterized.ParameterizedAndroidJunit4
|
||||
import platform.test.runner.parameterized.Parameters
|
||||
import platform.test.screenshot.DeviceEmulationSpec
|
||||
import platform.test.screenshot.Displays
|
||||
import platform.test.screenshot.ViewScreenshotTestRule
|
||||
import platform.test.screenshot.getEmulatedDevicePathConfig
|
||||
|
||||
/** Screenshot tests for [BubbleBarView]. */
|
||||
@RunWith(ParameterizedAndroidJunit4::class)
|
||||
@ScreenRecordRule.ScreenRecord
|
||||
class BubbleBarViewScreenshotTest(emulationSpec: DeviceEmulationSpec) {
|
||||
|
||||
private val context = ApplicationProvider.getApplicationContext<Context>()
|
||||
private lateinit var bubbleBarView: BubbleBarView
|
||||
|
||||
companion object {
|
||||
@Parameters(name = "{0}")
|
||||
@JvmStatic
|
||||
fun getTestSpecs() =
|
||||
DeviceEmulationSpec.forDisplays(
|
||||
Displays.Phone,
|
||||
isDarkTheme = false,
|
||||
isLandscape = false,
|
||||
)
|
||||
}
|
||||
|
||||
@get:Rule
|
||||
val screenshotRule =
|
||||
ViewScreenshotTestRule(
|
||||
emulationSpec,
|
||||
ViewScreenshotGoldenPathManager(getEmulatedDevicePathConfig(emulationSpec)),
|
||||
)
|
||||
|
||||
@Test
|
||||
fun bubbleBarView_collapsed_oneBubble() {
|
||||
screenshotRule.screenshotTest("bubbleBarView_collapsed_oneBubble") { activity ->
|
||||
activity.actionBar?.hide()
|
||||
setupBubbleBarView()
|
||||
bubbleBarView.addBubble(createBubble("key1", Color.GREEN))
|
||||
val container = FrameLayout(context)
|
||||
val lp = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
|
||||
container.layoutParams = lp
|
||||
container.addView(bubbleBarView)
|
||||
container
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun bubbleBarView_collapsed_twoBubbles() {
|
||||
screenshotRule.screenshotTest("bubbleBarView_collapsed_twoBubbles") { activity ->
|
||||
activity.actionBar?.hide()
|
||||
setupBubbleBarView()
|
||||
bubbleBarView.addBubble(createBubble("key1", Color.GREEN))
|
||||
bubbleBarView.addBubble(createBubble("key2", Color.CYAN))
|
||||
val container = FrameLayout(context)
|
||||
val lp = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
|
||||
container.layoutParams = lp
|
||||
container.addView(bubbleBarView)
|
||||
container
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun bubbleBarView_expanded_threeBubbles() {
|
||||
// if we're still expanding, wait with taking a screenshot
|
||||
val shouldWait: (ComponentActivity, View) -> Boolean = { _, _ -> bubbleBarView.isExpanding }
|
||||
screenshotRule.screenshotTest(
|
||||
"bubbleBarView_expanded_threeBubbles",
|
||||
checkView = shouldWait,
|
||||
) { activity ->
|
||||
activity.actionBar?.hide()
|
||||
setupBubbleBarView()
|
||||
bubbleBarView.addBubble(createBubble("key1", Color.GREEN))
|
||||
bubbleBarView.addBubble(createBubble("key2", Color.CYAN))
|
||||
bubbleBarView.addBubble(createBubble("key3", Color.MAGENTA))
|
||||
val container = FrameLayout(context)
|
||||
val lp = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
|
||||
container.layoutParams = lp
|
||||
container.addView(bubbleBarView)
|
||||
bubbleBarView.isExpanded = true
|
||||
container
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupBubbleBarView() {
|
||||
bubbleBarView = BubbleBarView(context)
|
||||
val lp = FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)
|
||||
bubbleBarView.layoutParams = lp
|
||||
val paddingTop =
|
||||
context.resources.getDimensionPixelSize(R.dimen.bubblebar_pointer_visible_size)
|
||||
bubbleBarView.setPadding(0, paddingTop, 0, 0)
|
||||
bubbleBarView.visibility = View.VISIBLE
|
||||
bubbleBarView.alpha = 1f
|
||||
}
|
||||
|
||||
private fun createBubble(key: String, color: Int): BubbleView {
|
||||
val bubbleView =
|
||||
FakeBubbleViewFactory.createBubble(
|
||||
context,
|
||||
key,
|
||||
parent = bubbleBarView,
|
||||
iconColor = color,
|
||||
)
|
||||
bubbleView.showDotIfNeeded(1f)
|
||||
bubbleBarView.setSelectedBubble(bubbleView)
|
||||
return bubbleView
|
||||
}
|
||||
}
|
||||
+11
-41
@@ -15,17 +15,10 @@
|
||||
*/
|
||||
package com.android.launcher3.taskbar.bubbles
|
||||
|
||||
import android.app.Notification
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.graphics.Paint
|
||||
import android.util.PathParser
|
||||
import android.view.LayoutInflater
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import com.android.launcher3.R
|
||||
import com.android.wm.shell.shared.bubbles.BubbleInfo
|
||||
import com.android.launcher3.taskbar.bubbles.testing.FakeBubbleViewFactory
|
||||
import com.google.android.apps.nexuslauncher.imagecomparison.goldenpathmanager.ViewScreenshotGoldenPathManager
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
@@ -50,7 +43,7 @@ class BubbleViewScreenshotTest(emulationSpec: DeviceEmulationSpec) {
|
||||
DeviceEmulationSpec.forDisplays(
|
||||
Displays.Phone,
|
||||
isDarkTheme = false,
|
||||
isLandscape = false
|
||||
isLandscape = false,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -58,7 +51,7 @@ class BubbleViewScreenshotTest(emulationSpec: DeviceEmulationSpec) {
|
||||
val screenshotRule =
|
||||
ViewScreenshotTestRule(
|
||||
emulationSpec,
|
||||
ViewScreenshotGoldenPathManager(getEmulatedDevicePathConfig(emulationSpec))
|
||||
ViewScreenshotGoldenPathManager(getEmulatedDevicePathConfig(emulationSpec)),
|
||||
)
|
||||
|
||||
@Test
|
||||
@@ -86,39 +79,16 @@ class BubbleViewScreenshotTest(emulationSpec: DeviceEmulationSpec) {
|
||||
}
|
||||
|
||||
private fun setupBubbleView(suppressNotification: Boolean = false): BubbleView {
|
||||
val inflater = LayoutInflater.from(context)
|
||||
|
||||
val iconSize = 100
|
||||
// BubbleView uses launcher's badge to icon ratio and expects the badge image to already
|
||||
// have the right size
|
||||
val badgeToIconRatio = 0.444f
|
||||
val badgeRadius = iconSize * badgeToIconRatio / 2
|
||||
val icon = createCircleBitmap(radius = iconSize / 2, color = Color.LTGRAY)
|
||||
val badge = createCircleBitmap(radius = badgeRadius.toInt(), color = Color.RED)
|
||||
|
||||
val flags =
|
||||
if (suppressNotification) Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION else 0
|
||||
val bubbleInfo =
|
||||
BubbleInfo("key", flags, null, null, 0, context.packageName, null, null, false, true)
|
||||
val bubbleView = inflater.inflate(R.layout.bubblebar_item_view, null) as BubbleView
|
||||
val dotPath =
|
||||
PathParser.createPathFromPathData(
|
||||
context.resources.getString(com.android.internal.R.string.config_icon_mask)
|
||||
val bubbleView =
|
||||
FakeBubbleViewFactory.createBubble(
|
||||
context,
|
||||
key = "key",
|
||||
parent = null,
|
||||
iconSize = 100,
|
||||
iconColor = Color.LTGRAY,
|
||||
suppressNotification = suppressNotification,
|
||||
)
|
||||
val bubble =
|
||||
BubbleBarBubble(bubbleInfo, bubbleView, badge, icon, Color.BLUE, dotPath, "test app")
|
||||
bubbleView.setBubble(bubble)
|
||||
bubbleView.showDotIfNeeded(1f)
|
||||
return bubbleView
|
||||
}
|
||||
|
||||
private fun createCircleBitmap(radius: Int, color: Int): Bitmap {
|
||||
val bitmap = Bitmap.createBitmap(radius * 2, radius * 2, Bitmap.Config.ARGB_8888)
|
||||
val canvas = Canvas(bitmap)
|
||||
canvas.drawARGB(0, 0, 0, 0)
|
||||
val paint = Paint()
|
||||
paint.color = color
|
||||
canvas.drawCircle(radius.toFloat(), radius.toFloat(), radius.toFloat(), paint)
|
||||
return bitmap
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user