Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
5d56d79
Add Gradle wrapper files and update settings for Android project
Kief5555 May 14, 2026
f97710e
feat: Enhance streaming experience and UI updates
Kief5555 May 16, 2026
d0771a6
feat: Enhance session proxy settings and ad playback functionality
Kief5555 May 16, 2026
36149af
feat: Implement QR code generation and enhance streaming stats
Kief5555 May 16, 2026
97b644e
feat: Add functionality to remove completed ads from session state an…
Kief5555 May 16, 2026
02a7bfe
Refactor UI colors and enhance device login experience
Kief5555 May 16, 2026
05e8eff
feat: Enhance device code login support and improve session handling
Kief5555 May 16, 2026
fbd669d
feat: Replace loading skeleton with pulsing animation for game images
Kief5555 May 16, 2026
2eed4bd
feat: Enhance OpenNowViewModel with account switching and stream retu…
Kief5555 May 17, 2026
d2036a5
Potential fix for pull request finding
Kief5555 May 17, 2026
d525803
feat: Enhance stream resolution options and implement membership tier…
Kief5555 May 17, 2026
3b7d1c1
Merge branch 'android-native' of https://github.com/OpenCloudGaming/O…
Kief5555 May 17, 2026
49f6847
feat: Remove release artifacts and update .gitignore for cleaner builds
Kief5555 May 17, 2026
380a69a
feat: Update minimum SDK version and increment version code; enhance …
Kief5555 May 17, 2026
5963880
feat: Refactor token management to use milliseconds for refresh windo…
Kief5555 May 18, 2026
c722a8f
feat: Enhance WebRTC codec handling and input channel management
Kief5555 May 23, 2026
3837fae
feat: Refactor mouse capture handling and enhance stream settings adj…
Kief5555 May 24, 2026
d9cbf2c
feat: Implement display refresh rate management and enhance stream se…
Kief5555 May 31, 2026
556bdfe
Add vector drawable icons for various game stores and implement unit …
Kief5555 Jun 14, 2026
4898a2e
feat: Add HDR support and enhance haptic feedback for gamepad control…
Kief5555 Jun 15, 2026
c0a866d
feat: Enhance sorting and filtering UI with improved layout and funct…
Kief5555 Jun 15, 2026
b81beaa
feat: Implement settings reset and cache clearing functionality; enha…
Kief5555 Jun 16, 2026
6bc4504
Add new strings for empty search states and filters; enhance tests fo…
Kief5555 Jun 22, 2026
82a146c
feat: Implement Android update functionality
Kief5555 Jun 23, 2026
6ead986
Add unit test for OpenNow analytics configuration
Kief5555 Jun 26, 2026
e5d36e6
feat: Update versioning, enhance stream settings, and improve UI/UX
Kief5555 Jun 27, 2026
9e8d0ca
feat: Add donation section and debug event logging
Kief5555 Jun 27, 2026
97e839c
Implement persistent storage management and game store connectors for…
Kief5555 Jun 29, 2026
f4f736c
Fix(android): add storage addon filter and connector state/token fixe…
Kief5555 Jun 29, 2026
6dc97ac
feat: Update version and enhance audio cue functionality
Kief5555 Jun 29, 2026
3845723
Merge branch 'android-native' of https://github.com/OpenCloudGaming/O…
Kief5555 Jun 29, 2026
8204694
Add in-app store connector connect/disconnect actions (#548)
Kief5555 Jun 29, 2026
41a95d2
feat(android): update version code to 16 and version name to 0.6.1
Kief5555 Jun 29, 2026
1353777
Merge branch 'android-native' of https://github.com/OpenCloudGaming/O…
Kief5555 Jun 29, 2026
5f808f7
Fix Android account linking and add missing Steam provider (#550)
Kief5555 Jun 29, 2026
859d909
Fix Android connector refresh polling (#553)
Kief5555 Jun 29, 2026
9f091fc
Fix account-link ALS 401 error and add toasts (#554)
Kief5555 Jun 29, 2026
b702052
Fix Android ALS endpoint and client ID to match desktop (#559)
Kief5555 Jun 29, 2026
0be6ebc
feat: Add settings screen with various configuration options
Kief5555 Jun 30, 2026
2af413a
feat: Add Android update notice handling and improve codec negotiation
Kief5555 Jul 1, 2026
6abb5fa
chore: Remove unused Kotlin compiler session file
Kief5555 Jul 1, 2026
26c0aa5
feat: Enhance storage usage progress indicator with dynamic height an…
Kief5555 Jul 1, 2026
36b311f
feat: Enhance stream resolution handling and gamepad input support
Kief5555 Jul 1, 2026
e5eb361
feat: Add play time stats panel and enhance session management
Kief5555 Jul 3, 2026
405fcda
feat: Implement APK update support and enhance update management for …
Kief5555 Jul 4, 2026
f695e88
feat: Enhance settings UI with descriptions and add account provider …
Kief5555 Jul 5, 2026
0a3b94c
feat: Enhance diagnostic logging and redaction for sensitive information
Kief5555 Jul 5, 2026
7ed7106
Refactor OpenNowViewModel for improved debugging and diagnostics
Kief5555 Jul 5, 2026
b19868b
feat: Refactor SDP handling to improve candidate endpoint resolution …
Kief5555 Jul 5, 2026
3c95f3f
Refactor code structure for improved readability and maintainability
Kief5555 Jul 6, 2026
bc48bc4
feat: Enhance streaming settings and diagnostics
Kief5555 Jul 8, 2026
4496299
Refactor mouse assist functionality and update related tests
Kief5555 Jul 9, 2026
9b56102
Refactor catalog background image handling and improve haptics parsing
Kief5555 Jul 10, 2026
ff2d029
feat: Update version code and name, enhance controller navigation han…
Kief5555 Jul 11, 2026
9bac3cb
feat: Update version code to 34 and name to 0.7.9; enhance streaming …
Kief5555 Jul 11, 2026
1944eb4
feat: Update version code to 35 and name to 0.8.0; improve SurfaceVie…
Kief5555 Jul 11, 2026
b2c7b28
feat: Implement nextSessionAdId function and refactor queue ad handli…
Kief5555 Jul 12, 2026
c619185
feat: Update version code to 36 and name to 0.8.1
Kief5555 Jul 12, 2026
4153ed6
feat: Add appCategory to manifest and adjust windowSoftInputMode in M…
Kief5555 Jul 12, 2026
a2e6168
Add unit tests for AndroidStreamKeepAliveNotifier and CellularNetwork…
Kief5555 Jul 12, 2026
b1e5831
feat(android): redesign virtual touch controller, secure auth storage…
Chizuui Jul 12, 2026
28b7f10
Merge pull request #634 from Chizuui/android-native
Kief5555 Jul 13, 2026
01e58c5
feat(android): implement multi-style touch overlay, unified sliding D…
Chizuui Jul 14, 2026
f279685
Merge pull request #641 from Chizuui/dev-android-native
Kief5555 Jul 15, 2026
f5f9cd3
Improve Android auth refresh and stream recovery
Kief5555 Jul 15, 2026
5fd8ede
Add tests for launch errors, ownership, stream settings, and local TV…
Kief5555 Jul 16, 2026
59aef68
Refactor stream handling and improve artwork logic
Kief5555 Jul 16, 2026
9eeb55b
fix(android): improve virtual stick pointer handling and state manage…
Kief5555 Jul 16, 2026
714a0c5
fix(android): resolve input thread lag, TV controller navigation, hal…
Chizuui Jul 16, 2026
26f3ec6
Merge pull request #646 from Chizuui/dev-android-native-pr
Kief5555 Jul 16, 2026
d5c8d22
fix(android): fix virtual stick getting stuck on release outside stic…
Chizuui Jul 17, 2026
d3268b8
fix(android): fix analog stick held state not cleared when touch rele…
Chizuui Jul 17, 2026
d87e837
Merge pull request #647 from Chizuui/android-native
Kief5555 Jul 17, 2026
9e153f4
fix(android): update version code and name, enhance game card scaling…
Kief5555 Jul 17, 2026
f90b3ec
Merge branch 'android-native' of https://github.com/OpenCloudGaming/O…
Kief5555 Jul 17, 2026
6e55d55
feat: TV and input experience improvements
Chizuui Jul 17, 2026
49b6b2a
Merge pull request #648 from Chizuui/pr-tv-input-improvements
Kief5555 Jul 17, 2026
a6cb5d4
Refactor settings UI and enhance controller focus handling
Kief5555 Jul 18, 2026
d743870
feat: Update version and enhance HDR support
Kief5555 Jul 18, 2026
7b88bad
feat: Add microphone support and bug reporting functionality
Kief5555 Jul 19, 2026
bf01a98
feat: Enhance resolution handling for 1440p streams and add correspon…
Kief5555 Jul 19, 2026
0b27de5
feat: Update version code to 47 and version name to 0.9.2
Kief5555 Jul 19, 2026
40b2194
feat: add native low latency video decoder wrapper with MediaTek support
Chizuui Jul 19, 2026
086d9c9
Refactor streaming settings and performance warnings
Kief5555 Jul 20, 2026
aa44fa1
Merge branch 'android-native' of https://github.com/OpenCloudGaming/O…
Kief5555 Jul 20, 2026
fb02a34
feat: implement Android controller slot management and enhance input …
Kief5555 Jul 20, 2026
fb72c35
feat: update version code to 49 and version name to 0.9.4; add pinch …
Kief5555 Jul 20, 2026
fac02fd
feat: update version code to 51 and version name to 0.9.6; refactor G…
Kief5555 Jul 20, 2026
19d848e
Refactor and enhance session reporting and stream settings tests
Kief5555 Jul 21, 2026
bd8e482
feat: Enhance AV1 support and performance tuning
Kief5555 Jul 22, 2026
9e29e0d
feat: update version code to 55 and version name to 1.0.0
Kief5555 Jul 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ native/opennow-streamer/bin/*/*
.serena/
*.xcuserstate
xcuserdata/

.logs/
# Xcode build outputs
DerivedData/

Expand All @@ -44,6 +44,8 @@ gfn_tokens.json

# Test files
test/
!android/app/src/test/
!android/app/src/test/**

package-lock.json
opennow-stable/package-lock.json
Expand All @@ -56,3 +58,6 @@ release-notes.md
result
.deriveddata/
.deriveddata-device/

/android/app/.cxx
/android/app/release
8 changes: 8 additions & 0 deletions android/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.gradle/
.idea/
build/
local.properties
captures/
*.iml
app/build/
app/release/
37 changes: 37 additions & 0 deletions android/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# OpenNOW Native Android

This folder is a standalone Android Studio project for the native Kotlin / Jetpack Compose OpenNOW target.

Open it from Android Studio with **File > Open > `OpenNOW/android`**. Android Studio will install/use the required Gradle, Android SDK, CMake, and NDK components from the project configuration.

## Build Targets

- `:app:assembleDebug` builds a debug APK.
- `:app:assembleRelease` builds the direct-distribution release APK with APK update support.
- `:app:bundleRelease` builds the Google Play Android App Bundle. This task removes `REQUEST_INSTALL_PACKAGES` and disables APK self-updates so Play installs use Google Play's update mechanism.

Release and debug builds include `arm64-v8a`, `armeabi-v7a`, and `x86_64`. The `armeabi-v7a` slice supports 32-bit ARM phones and 32-bit Android TV firmware. OpenNOW recommends 720p/30 FPS/12 Mbps for 32-bit processes and memory-constrained TVs, and warns when a custom profile exceeds that recommendation without overriding the user's selection.

## APK Update Manifest

APK and debug builds check `https://api.printedwaste.com/releases/opennow/latest` and can download the returned APK. App Bundle builds installed from Google Play detect `com.android.vending` as the install source and do not check, download, or install APK updates. The manifest should look like this:

```json
{
"versionCode": 7,
"versionName": "0.5.2",
"apkUrl": "https://api.printedwaste.com/release-files/opennow/app-release.apk",
"artifactUrl": "https://api.printedwaste.com/release-files/opennow/app-release.apk",
"sha256": "optional lowercase apk checksum",
"releaseNotes": "Short notes shown in Settings\nSecond line"
}
```

`apkUrl`, `artifactUrl`, or `url` may point at the APK. `releaseNotes` may use real newlines or literal `\n` separators. The app compares `versionCode` against its installed build and asks Android's package installer to confirm the downloaded APK.

## Runtime Notes

- UI is native Compose.
- GFN auth, catalog, subscription, CloudMatch session creation/polling/claim/stop, signaling, and input packet behavior are implemented in Kotlin from the Electron project contracts.
- Streaming uses Android WebRTC plus hardware MediaCodec probing. The bundled `opennow_native` JNI library exposes native runtime diagnostics and keeps the NDK/CMake path wired for media-sensitive code.
- Queue ad metadata is preserved in `SessionInfo`; ad playback can use the included Media3 dependency when the server returns an ad media URL.
165 changes: 165 additions & 0 deletions android/app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import java.util.Properties

plugins {
id("com.android.application")
id("org.jetbrains.kotlin.plugin.compose")
id("org.jetbrains.kotlin.plugin.serialization")
}

val localProperties = Properties().apply {
rootProject.file("local.properties").takeIf { it.exists() }?.inputStream()?.use { load(it) }
}
fun Sequence<String?>.firstNonBlankOrNull(): String? =
mapNotNull { value -> value?.trim()?.takeIf { it.isNotEmpty() } }.firstOrNull()

fun gradlePropertyValue(vararg names: String): String? =
names.asSequence().map { name -> providers.gradleProperty(name).orNull }.firstNonBlankOrNull()

fun localPropertyValue(vararg names: String): String? =
names.asSequence().map { name -> localProperties.getProperty(name) }.firstNonBlankOrNull()

fun environmentValue(vararg names: String): String? =
names.asSequence().map { name -> providers.environmentVariable(name).orNull }.firstNonBlankOrNull()

fun firstNonBlankValue(vararg values: String?): String =
values.asSequence().firstNonBlankOrNull().orEmpty()

fun buildConfigString(value: String): String =
"\"" + value
.replace("\\", "\\\\")
.replace("\"", "\\\"")
.replace("\n", "\\n")
.replace("\r", "\\r") + "\""

val defaultPostHogProjectToken = "phc_pdob6BhBvbayfd7BA6zXBkty8o6EkxKYY7sF3ZwLymk3"
val defaultPostHogHost = "https://aa.printedwaste.com"

val postHogProjectToken = firstNonBlankValue(
gradlePropertyValue("posthog.apiKey", "posthog.projectToken"),
environmentValue("POSTHOG_API_KEY", "POSTHOG_PROJECT_TOKEN"),
localPropertyValue("posthog.apiKey", "posthog.projectToken"),
defaultPostHogProjectToken,
)
val postHogHost = firstNonBlankValue(
gradlePropertyValue("posthog.host"),
environmentValue("POSTHOG_HOST"),
localPropertyValue("posthog.host"),
defaultPostHogHost,
)
val buildingPlayReleaseBundle = gradle.startParameter.taskNames.any { taskName ->
taskName.substringAfterLast(":").equals("bundleRelease", ignoreCase = true)
}

android {
namespace = "com.opencloudgaming.opennow"
compileSdk = 37

defaultConfig {
applicationId = "com.opencloudgaming.opennow"
minSdk = 23
targetSdk = 36
versionCode = 55
versionName = "1.0.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

buildConfigField("String", "POSTHOG_PROJECT_TOKEN", buildConfigString(postHogProjectToken))
buildConfigField("String", "POSTHOG_HOST", buildConfigString(postHogHost))
buildConfigField("boolean", "APK_UPDATES_SUPPORTED", "true")

ndk {
abiFilters += listOf("arm64-v8a", "armeabi-v7a", "x86_64")
}

}

buildTypes {
debug {
isMinifyEnabled = false
}
release {
isMinifyEnabled = true
isShrinkResources = true
buildConfigField("boolean", "APK_UPDATES_SUPPORTED", (!buildingPlayReleaseBundle).toString())
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro",
)
}
}

sourceSets {
if (buildingPlayReleaseBundle) {
getByName("release").manifest.srcFile("src/playBundle/AndroidManifest.xml")
}
}

buildFeatures {
compose = true
buildConfig = true
}

externalNativeBuild {
cmake {
path = file("src/main/cpp/CMakeLists.txt")
version = "3.22.1"
}
}

packaging {
jniLibs {
useLegacyPackaging = false
}
resources {
excludes += setOf(
"META-INF/AL2.0",
"META-INF/LGPL2.1",
"META-INF/LICENSE*",
"META-INF/NOTICE*",
)
}
}
}

kotlin {
jvmToolchain(17)
}

dependencies {
implementation(platform("androidx.compose:compose-bom:2026.06.00"))
androidTestImplementation(platform("androidx.compose:compose-bom:2026.06.00"))

implementation("androidx.activity:activity-compose:1.13.0")
implementation("androidx.browser:browser:1.10.0")
implementation("androidx.compose.foundation:foundation")
implementation("androidx.compose.material:material-icons-extended")
implementation("androidx.compose.material3:material3")
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.core:core:1.19.0")
implementation("androidx.lifecycle:lifecycle-runtime-compose:2.11.0")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.11.0")
implementation("androidx.media3:media3-common:1.10.1")
implementation("androidx.media3:media3-exoplayer:1.10.1")
implementation("androidx.media3:media3-ui:1.10.1")
implementation("androidx.work:work-runtime:2.11.2")

implementation("io.coil-kt.coil3:coil-compose:3.4.0")
implementation("io.coil-kt.coil3:coil-network-okhttp:3.4.0")

implementation("com.squareup.okhttp3:logging-interceptor:5.4.0")
implementation("com.squareup.okhttp3:okhttp-dnsoverhttps:5.4.0")
implementation("com.squareup.okhttp3:okhttp:5.4.0")
implementation("io.github.webrtc-sdk:android:144.7559.09")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.11.0")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.11.0")
implementation("com.posthog:posthog-android:3.51.2")

debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")

testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.3.0")
androidTestImplementation("androidx.test:runner:1.7.0")
androidTestImplementation("androidx.test.espresso:espresso-core:3.7.0")
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
}
6 changes: 6 additions & 0 deletions android/app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
-keep class org.webrtc.** { *; }
-keep class org.jni_zero.** { *; }
-keep class kotlinx.serialization.** { *; }
-keepclassmembers class com.opencloudgaming.opennow.** {
@kotlinx.serialization.Serializable *;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package com.opencloudgaming.opennow

import android.net.Uri
import androidx.test.ext.junit.runners.AndroidJUnit4
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withTimeout
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class LocalTvConnectorInstrumentedTest {
@Test
fun encryptedLocalPairingTransfersLaunchAndSignIn() = runBlocking {
val tv = LocalTvConnector()
val phone = LocalTvConnector()
try {
tv.startHosting()
val pairingState = awaitState(tv) { it.hosting && it.pairUri != null }
assertTrue(pairingState.pairingCode.orEmpty().matches(Regex("[0-9]{4}")))
val pairUri = pairingState.pairUri!!

phone.pairPhone(Uri.parse(pairUri))
val phoneState = awaitState(phone) { it.phoneConnected || it.error != null }
assertTrue(phoneState.error.orEmpty(), phoneState.phoneConnected)
val pairedState = awaitState(tv) { it.pairedDeviceName != null }
assertTrue(pairedState.trustRequestedByDevice)

val launchResult = async { withTimeout(5_000L) { tv.launchRequests.first() } }
phone.sendLaunch("test-game-42", "Connector test game")
assertEquals("test-game-42", launchResult.await().gameId)

phone.sendRemoteAction("open_stream_menu")
val untrustedState = awaitState(phone) { it.error?.contains("Trust this phone") == true }
assertTrue(untrustedState.error.orEmpty(), untrustedState.error?.contains("Trust this phone") == true)

tv.setPairedDeviceTrusted(true)
val remoteResult = async { withTimeout(5_000L) { tv.remoteRequests.first() } }
phone.sendRemoteAction("open_stream_menu")
assertEquals("open_stream_menu", remoteResult.await().action)

val transferred = AuthSession(
provider = LoginProvider(
idpId = "test",
code = "TEST",
displayName = "Test provider",
streamingServiceUrl = "https://example.invalid",
),
tokens = AuthTokens(
accessToken = "instrumentation-access-token",
refreshToken = "instrumentation-refresh-token",
expiresAt = System.currentTimeMillis() + 60_000L,
),
user = AuthUser(
userId = "instrumentation-user",
displayName = "Instrumentation user",
membershipTier = "FREE",
),
)
val signInResult = async { withTimeout(5_000L) { tv.signInRequests.first() } }
phone.sendSignIn(transferred)
assertEquals(transferred, signInResult.await())
} finally {
phone.close()
tv.close()
}
}

private suspend fun awaitState(
connector: LocalTvConnector,
predicate: (LocalTvConnectorState) -> Boolean,
): LocalTvConnectorState = withTimeout(8_000L) {
while (true) {
connector.state.value.takeIf(predicate)?.let { return@withTimeout it }
delay(25L)
}
@Suppress("UNREACHABLE_CODE")
connector.state.value
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.opencloudgaming.opennow

import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class StreamingProfileInstrumentedTest {
@Test
fun commonResolutionAspectAndCodecMatrixResolvesToUsableHardwareProfile() {
val report = CodecProbe.report(ApplicationProvider.getApplicationContext())
val h264 = report.capabilities.firstOrNull { it.codec == VideoCodec.H264 }
assertNotNull("Every supported Android target must provide H264 decoding", h264)
assertTrue("H264 must be usable by the WebRTC launch path", h264?.streamingDecoderUsableForLaunch() == true)

val modes = listOf(
"1280x720" to "16:9",
"1366x768" to "16:9",
"1600x900" to "16:9",
"1920x1080" to "16:9",
"2560x1440" to "16:9",
"3840x2160" to "16:9",
"1280x800" to "16:10",
"1920x1200" to "16:10",
"2560x1600" to "16:10",
"1024x768" to "4:3",
"1680x720" to "21:9",
"2560x1080" to "21:9",
"3440x1440" to "21:9",
)
for ((resolution, aspectRatio) in modes) {
for (codec in VideoCodec.entries) {
val requested = StreamSettings(
resolution = resolution,
aspectRatio = aspectRatio,
fps = 60,
codec = codec,
colorQuality = if (codec == VideoCodec.H264) ColorQuality.EightBit420 else ColorQuality.TenBit420,
)
val adjusted = requested.adjustedForDevice(report)
val effectiveCapability = report.capabilities.first { it.codec == adjusted.codec }

assertTrue("$resolution $codec did not resolve to a usable decoder", effectiveCapability.streamingDecoderUsableForLaunch())
assertEquals(
"$resolution $codec resolved with inconsistent aspect metadata",
streamAspectRatioForResolution(adjusted.resolution),
adjusted.aspectRatio,
)
assertEquals(
"$resolution $codec was unnecessarily reduced despite explicit decoder support",
resolution,
adjusted.resolution,
)
println(
"STREAM_MATRIX requested=$resolution/$aspectRatio/$codec effective=${adjusted.resolution}/${adjusted.aspectRatio}/${adjusted.codec} " +
"fps=${adjusted.fps} decoder=${effectiveCapability.webRtcDecoderName ?: effectiveCapability.decoderName} " +
"max=${effectiveCapability.maxSupportedWidth}x${effectiveCapability.maxSupportedHeight}",
)
}
}
}
}
Loading
Loading