Verify native notification artwork with real JPEG regression
This commit is contained in:
@@ -58,6 +58,38 @@ class CompanionAudioTest {
|
||||
} finally { CompanionAudioBridge.release(web); lifecycle.destroy(); web.destroy() }
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = [RecordingAudioMediaSession::class])
|
||||
fun jpegArtworkReachesNotificationAndMediaDescription() {
|
||||
// Real 16x16 JPEG generated by Chromium canvas, independent of Android bitmap shadows.
|
||||
val artwork = "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAQABADASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAn/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhEDEQA/AJVAA//Z"
|
||||
assertNotNull(decodeArtwork(artwork))
|
||||
val app = RuntimeEnvironment.getApplication()
|
||||
val web = android.webkit.WebView(app); web.loadUrl("https://node.test/cloud")
|
||||
val payload = state().put("session", "32345678-1234-1234-1234-123456789abc").put("artwork", artwork)
|
||||
CompanionAudioBridge.receive(web, payload.toString(), "https://node.test", true, setOf("https://node.test")) {}
|
||||
val lifecycle = Robolectric.buildService(CompanionAudioService::class.java).create()
|
||||
try {
|
||||
lifecycle.get().onStartCommand(null, 0, 1)
|
||||
val notification = Shadows.shadowOf(lifecycle.get()).lastForegroundNotification
|
||||
assertNotNull(notification.getLargeIcon())
|
||||
// Robolectric's MediaController does not read MediaSession metadata;
|
||||
// capture the actual service's setMetadata call instead.
|
||||
val metadata = RecordingAudioMediaSession.metadata!!
|
||||
assertNotNull(metadata.getBitmap(android.media.MediaMetadata.METADATA_KEY_ALBUM_ART))
|
||||
assertNotNull(metadata.description.iconBitmap)
|
||||
// Position-only refresh must retain the same thumbnail.
|
||||
CompanionAudioBridge.receive(web, state().put("session", payload.getString("session")).put("sequence", 2).toString(),
|
||||
"https://node.test", true, setOf("https://node.test")) {}
|
||||
assertNotNull(Shadows.shadowOf(lifecycle.get()).lastForegroundNotification.getLargeIcon())
|
||||
// A following song without art must not keep the previous cover.
|
||||
CompanionAudioBridge.receive(web, state().put("session", payload.getString("session")).put("sequence", 3).put("artwork", "").toString(),
|
||||
"https://node.test", true, setOf("https://node.test")) {}
|
||||
assertNull(Shadows.shadowOf(lifecycle.get()).lastForegroundNotification.getLargeIcon())
|
||||
assertNull(RecordingAudioMediaSession.metadata!!.description.iconBitmap)
|
||||
} finally { CompanionAudioBridge.release(web); lifecycle.destroy(); web.destroy() }
|
||||
}
|
||||
|
||||
@Test fun diagnosticReportExcludesPrivateMessagesAndRecordsRejectionStage() {
|
||||
val app = RuntimeEnvironment.getApplication()
|
||||
val web = android.webkit.WebView(app)
|
||||
@@ -116,3 +148,10 @@ class CompanionAudioTest {
|
||||
} finally { lifecycle.destroy() }
|
||||
}
|
||||
}
|
||||
|
||||
@org.robolectric.annotation.Implements(android.media.session.MediaSession::class)
|
||||
class RecordingAudioMediaSession : org.robolectric.shadows.ShadowMediaSession() {
|
||||
companion object { var metadata: android.media.MediaMetadata? = null }
|
||||
@org.robolectric.annotation.Implementation
|
||||
fun setMetadata(value: android.media.MediaMetadata) { metadata = value }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user