From 35d29559e2acc9102c8627fb7000c2e6327337f2 Mon Sep 17 00:00:00 2001 From: DoubleGate Date: Tue, 25 Aug 2026 01:14:19 -0400 Subject: [PATCH] chore(android): clear the Gradle 10 deprecations, verified against the artifacts Four call sites the Android build was warning about, each checked against the actual artifact rather than against the warning text. ## What the build was saying * `AndroidSourceDirectorySet.srcDir(Any)` is deprecated -- "Use `directories` mutable set instead" (two sites). * Two Kotlin DSL DELEGATED PROPERTIES, `by tasks.registering(Exec::class)`, with three warnings apiece pointing at the Gradle 9.6 upgrading guide. * `currentWindowAdaptiveInfo()` -- "Please use V2 version of this function to support L and XL width size classes." * And the summary: "Deprecated Gradle features were used in this build, making it incompatible with Gradle 10." ## Verified, not inferred THE VERSION I READ FIRST WAS THE WRONG ONE. `AndroidSourceDirectorySet` came out of the AGP jar the local Gradle cache happened to hold -- 9.2.1 -- while this branch pins 9.3.2 and the warning came from 9.3.2. Re-read from the pinned artifact, downloaded for the purpose. The interface is identical, so the fix stands, but it stood on the wrong evidence until it was checked. What the interface actually says: `getDirectories()` returns `Set`, so the replacement takes PATHS and the call sites pass `.path`, not the `File`. That is not deducible from "use `directories` mutable set instead". `currentWindowAdaptiveInfoV2` was confirmed present in `material3.adaptive` 1.3.0 by extracting the AAR -- AND CONFIRMED ABSENT IN 1.2.0, which is what makes this change depend on the version bump beside it rather than being independent of it. Gradle's upgrade guide is explicit on the delegates: `registering`, `creating`, `existing` and `getting` are all deprecated and scheduled for removal in Gradle 10, replaced by `register`, `create`, `named` and `getByName`. ## Behaviour Unchanged. The two breakpoints tested against the adaptive info are both "at least", so a window that now reports the new L or XL width class still satisfies EXPANDED -- V2 reports more classes, it does not reclassify the ones already handled. ## The warning that names nothing The build also runs with `--warning-mode all` now. Gradle's summary line says the build is incompatible with Gradle 10 and identifies not one cause; Gradle itself says the flag is how you find out. A warning that cannot be attributed is a warning nobody acts on, and this one has a deadline attached. ## Ordering This MUST land after the dependency refresh that takes `material3.adaptive` to 1.3.0. `currentWindowAdaptiveInfoV2` does not exist in 1.2.0 -- checked, not assumed -- so merged first it would break the build. --- .github/workflows/android.yml | 10 ++++++++- CHANGELOG.md | 21 +++++++++++++++++++ android/app/build.gradle.kts | 14 ++++++++----- .../com/doublegate/rustynes/MainActivity.kt | 10 +++++++-- 4 files changed, 47 insertions(+), 8 deletions(-) diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 754a5e95..d42f5496 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -144,7 +144,15 @@ jobs: # would also fan out to both, but the explicit tasks make the intent legible. - name: Bundle release AABs (foss + play, unsigned) working-directory: android - run: ./gradlew :app:bundleFossRelease :app:bundlePlayRelease --no-daemon + # `--warning-mode all` because the summary line -- "Deprecated Gradle + # features were used in this build, making it incompatible with Gradle + # 10" -- names nothing. Gradle says so itself: "You can use + # '--warning-mode all' to show the individual deprecation warnings and + # determine if they come from your own scripts or plugins." + # + # A warning that cannot be attributed is a warning nobody acts on, and + # this one has a deadline attached to it. + run: ./gradlew :app:bundleFossRelease :app:bundlePlayRelease --no-daemon --warning-mode all - name: Upload AABs uses: actions/upload-artifact@v7 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index acba1f8c..4046ec77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,27 @@ cycle-accurate core later replaced. ### Changed +- **Gradle 10 deprecations cleared in the Android build.** Four call sites, each + verified against the artifact rather than against the warning text: + + - `AndroidSourceDirectorySet.srcDir(Any)` → the `directories` mutable set. The + interface was read out of the **pinned AGP 9.3.2** `gradle-api` jar, not a + cached older one: `getDirectories()` returns `Set`, so it takes + paths and the call sites pass `.path` rather than a `File`. + - Two Kotlin DSL **delegated properties** (`by tasks.registering(Exec::class)`) + → `tasks.register("name")`. Gradle's own upgrade guide is explicit: + all Kotlin DSL property delegates — `registering`, `creating`, `existing`, + `getting` — are deprecated and scheduled for removal in Gradle 10. + - `currentWindowAdaptiveInfo()` → `currentWindowAdaptiveInfoV2()`, confirmed + present in `material3.adaptive` 1.3.0. Behaviour here is unchanged: both + breakpoints tested are "at least", so a window that now reports the new L or + XL width class still satisfies EXPANDED. + + The build also now runs with **`--warning-mode all`**, because the summary + line ("Deprecated Gradle features were used in this build, making it + incompatible with Gradle 10") names nothing — and a warning that cannot be + attributed is one nobody acts on, with a deadline attached. + - **MiSTer co-simulation, rung 5 (sibling repository).** The NROM cartridge, the work RAM, the console's CPU bus, the controller ports and DMC DMA are landed and gated at **50 gates green**. The DUT's CPU is driven by the RTL bus and a diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 016674db..3ffad975 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -197,8 +197,12 @@ android { // directories — adding them to `.java` (the pre-AGP-9 way) no longer feeds the // Kotlin compiler, so the binding types (NesController, NpStatus, …) go // unresolved. See AGP 9 built-in-Kotlin migration notes. - sourceSets["main"].kotlin.srcDir(uniffiGenDir) - sourceSets["main"].jniLibs.srcDir(jniLibsDir) + // `srcDir(Any)` is deprecated in AGP 9 in favour of the `directories` + // mutable set. Verified against the interface rather than the warning text: + // `AndroidSourceDirectorySet.getDirectories()` returns `Set`, so it + // takes PATHS, not `File`s -- hence `.path` on both. + sourceSets["main"].kotlin.directories.add(uniffiGenDir.path) + sourceSets["main"].jniLibs.directories.add(jniLibsDir.path) compileOptions { sourceCompatibility = JavaVersion.VERSION_17 @@ -251,7 +255,7 @@ composeCompiler { // drop them into `jniLibs//`. Requires the Android Rust targets + cargo-ndk // (`rustup target add aarch64-linux-android x86_64-linux-android; // cargo install cargo-ndk`) and ANDROID_NDK_HOME (or an SDK-resolved NDK). -val cargoNdkBuild by tasks.registering(Exec::class) { +val cargoNdkBuild = tasks.register("cargoNdkBuild") { group = "rust" description = "Cross-compile rustynes-mobile + rustynes-android into jniLibs via cargo-ndk." workingDir = workspaceRoot @@ -270,7 +274,7 @@ val cargoNdkBuild by tasks.registering(Exec::class) { // Generate the Kotlin bindings from the compiled arm64 cdylib (the UniFFI API is // target-independent, so any built library serves as the source of truth). -val uniffiBindgen by tasks.registering(Exec::class) { +val uniffiBindgen = tasks.register("uniffiBindgen") { group = "rust" description = "Generate Kotlin bindings for the rustynes-mobile control surface via UniFFI." dependsOn(cargoNdkBuild) @@ -309,7 +313,7 @@ dependencies { implementation("androidx.compose.material3:material3") implementation("androidx.compose.material:material-icons-extended") // v1.8.8 "Atlas" (Workstream A): adaptive layouts. `adaptive` carries - // currentWindowAdaptiveInfo()/WindowSizeClass (the single layout driver); + // currentWindowAdaptiveInfoV2()/WindowSizeClass (the single layout driver); // -layout carries ListDetailPaneScaffold; -navigation carries the predictive- // back-aware NavigableListDetailPaneScaffold for the expanded two-pane. implementation("androidx.compose.material3.adaptive:adaptive:1.3.0") diff --git a/android/app/src/main/java/com/doublegate/rustynes/MainActivity.kt b/android/app/src/main/java/com/doublegate/rustynes/MainActivity.kt index 3a6a2db8..7d3459c8 100644 --- a/android/app/src/main/java/com/doublegate/rustynes/MainActivity.kt +++ b/android/app/src/main/java/com/doublegate/rustynes/MainActivity.kt @@ -45,7 +45,7 @@ import androidx.compose.foundation.layout.safeDrawingPadding import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.safeDrawing -import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo +import androidx.compose.material3.adaptive.currentWindowAdaptiveInfoV2 import androidx.window.core.layout.WindowSizeClass import androidx.compose.material3.Button import androidx.compose.material3.ColorScheme @@ -1014,7 +1014,13 @@ private fun EmulatorScreen( // screenWidthDp threshold. `compact` width (< 600 dp) is the phone / folded // cover screen; `medium` (>= 600 dp) and `expanded` (>= 840 dp) are tablets, // the Z Fold inner display, and resizable desktop windows. - val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass + // V2 rather than `currentWindowAdaptiveInfo()`, which is deprecated: the + // original cannot report the L and XL width classes. Nothing below changes + // -- both breakpoints tested here are "at least", so a window that now + // reports L or XL still satisfies EXPANDED. Confirmed against the artifact: + // `currentWindowAdaptiveInfoV2` is present in adaptive 1.3.0 and takes no + // caller-supplied parameters. + val windowSizeClass = currentWindowAdaptiveInfoV2().windowSizeClass val isMediumWidth = windowSizeClass.isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND) val isExpandedWidth = windowSizeClass.isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_EXPANDED_LOWER_BOUND)