Test Cards grid rendering lifecycle
This commit is contained in:
+67
@@ -0,0 +1,67 @@
|
||||
package se.ajpanton.notificationsmaster.module
|
||||
|
||||
import android.content.Intent
|
||||
import android.graphics.drawable.Icon
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import se.ajpanton.notificationsmaster.visibility.CardsGridSettings
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class OneUiCardsGridRendererTest {
|
||||
private val instrumentation = InstrumentationRegistry.getInstrumentation()
|
||||
|
||||
@Test fun hidesStockOnlyAfterRenderingAndRestoresIt() {
|
||||
val activity = instrumentation.startActivitySync(
|
||||
Intent(instrumentation.targetContext, GridTestActivity::class.java)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
|
||||
)
|
||||
val renderer = OneUiCardsGridRenderer()
|
||||
lateinit var root: ViewGroup
|
||||
lateinit var source: FrameLayout
|
||||
|
||||
instrumentation.runOnMainSync {
|
||||
root = activity.window.decorView as ViewGroup
|
||||
source = FrameLayout(activity)
|
||||
root.addView(source, ViewGroup.LayoutParams(300, 80))
|
||||
renderer.updateSources(source, listOf(OneUiCardsGridRenderer.Source(
|
||||
"test-key",
|
||||
view = null,
|
||||
Icon.createWithResource(activity, android.R.drawable.ic_dialog_info),
|
||||
)))
|
||||
renderer.refresh(source, active = true, emptySet(), CONFIG)
|
||||
}
|
||||
instrumentation.waitForIdleSync()
|
||||
|
||||
instrumentation.runOnMainSync {
|
||||
assertEquals(0f, source.alpha)
|
||||
val host = root.findViewWithTag<ViewGroup>("notifications-master:cards-grid")
|
||||
assertEquals(View.VISIBLE, host.visibility)
|
||||
assertEquals(1, host.childCount)
|
||||
renderer.refresh(source, active = false, emptySet(), CONFIG)
|
||||
}
|
||||
instrumentation.waitForIdleSync()
|
||||
|
||||
instrumentation.runOnMainSync {
|
||||
assertEquals(1f, source.alpha)
|
||||
renderer.release(source)
|
||||
assertNull(root.findViewWithTag<View>("notifications-master:cards-grid"))
|
||||
root.removeView(source)
|
||||
activity.finish()
|
||||
}
|
||||
}
|
||||
|
||||
private companion object {
|
||||
val CONFIG = OneUiCardsGridRenderer.Config(
|
||||
CardsGridSettings(1, 5, true, true, 60),
|
||||
showPills = false,
|
||||
hideShelf = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<application>
|
||||
<activity
|
||||
android:name="se.ajpanton.notificationsmaster.module.GridTestActivity"
|
||||
android:exported="false" />
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -0,0 +1,12 @@
|
||||
package se.ajpanton.notificationsmaster.module
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import android.widget.FrameLayout
|
||||
|
||||
class GridTestActivity : Activity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(FrameLayout(this))
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,17 @@ internal class OneUiCardsGridRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
fun release(container: ViewGroup) {
|
||||
val state = states.remove(container) ?: return
|
||||
restoreNative(state)
|
||||
state.attachListener?.let(container::removeOnAttachStateChangeListener)
|
||||
state.layoutListener?.let { state.root?.removeOnLayoutChangeListener(it) }
|
||||
state.host?.let { host ->
|
||||
clearHost(host)
|
||||
(host.parent as? ViewGroup)?.removeView(host)
|
||||
}
|
||||
}
|
||||
|
||||
private fun render(container: ViewGroup, state: State, active: Boolean) {
|
||||
if (!active || !container.isAttachedToWindow) {
|
||||
failOpen(state)
|
||||
@@ -139,13 +150,14 @@ internal class OneUiCardsGridRenderer {
|
||||
}
|
||||
|
||||
private fun notificationIcon(root: View, source: Source, size: Int): ImageView? {
|
||||
val drawable = findDrawable(source.view)
|
||||
var drawable = findDrawable(source.view)
|
||||
?: runCatching {
|
||||
val context = source.packageName?.let { root.context.createPackageContext(it, 0) }
|
||||
?: root.context
|
||||
source.smallIcon?.loadDrawable(context)
|
||||
}.getOrNull()
|
||||
?: return null
|
||||
source.tintColor?.let { color -> drawable = drawable.mutate().apply { setTint(color) } }
|
||||
val bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888)
|
||||
val bounds = Rect(drawable.bounds)
|
||||
try {
|
||||
@@ -271,13 +283,21 @@ internal class OneUiCardsGridRenderer {
|
||||
|
||||
private fun dp(view: View, value: Int) = (value * view.resources.displayMetrics.density).toInt()
|
||||
|
||||
private fun state(container: ViewGroup) = states.getOrPut(container, ::State)
|
||||
private fun state(container: ViewGroup) = states.getOrPut(container) {
|
||||
State().also { state ->
|
||||
state.attachListener = object : View.OnAttachStateChangeListener {
|
||||
override fun onViewAttachedToWindow(view: View) = Unit
|
||||
override fun onViewDetachedFromWindow(view: View) = release(container)
|
||||
}.also(container::addOnAttachStateChangeListener)
|
||||
}
|
||||
}
|
||||
|
||||
data class Source(
|
||||
val key: String,
|
||||
val view: View?,
|
||||
val smallIcon: android.graphics.drawable.Icon?,
|
||||
val packageName: String? = null,
|
||||
val tintColor: Int? = null,
|
||||
)
|
||||
|
||||
data class Config(
|
||||
@@ -292,6 +312,7 @@ internal class OneUiCardsGridRenderer {
|
||||
var host: FrameLayout? = null
|
||||
var root: ViewGroup? = null
|
||||
var layoutListener: View.OnLayoutChangeListener? = null
|
||||
var attachListener: View.OnAttachStateChangeListener? = null
|
||||
var active = false
|
||||
var nativeSurface: View? = null
|
||||
var nativeAlpha = 1f
|
||||
|
||||
Reference in New Issue
Block a user