diff --git a/Android/app/proguard-rules.pro b/Android/app/proguard-rules.pro index 6698b4e..4d3bbed 100644 --- a/Android/app/proguard-rules.pro +++ b/Android/app/proguard-rules.pro @@ -1,31 +1,20 @@ --keeppackagenames ** +# Skip framework packages must be kept verbatim — JNI looks them up by name. +-keeppackagenames maxi80.** +-keeppackagenames skip.** +-keeppackagenames tools.skip.** -keep class skip.** { *; } -keep class tools.skip.** { *; } --keep class kotlin.jvm.functions.** {*;} +-keep class kotlin.jvm.functions.** { *; } -keep class com.sun.jna.** { *; } -dontwarn java.awt.** -keep class * implements com.sun.jna.** { *; } -keep class * implements skip.bridge.** { *; } -keep class **._ModuleBundleAccessor_* { *; } -keep class maxi80.module.** { *; } -# Transpiled Maxi80Services classes are reached only via JNI-by-name from the native -# Swift bridge (e.g. PlatformEnvironment), so R8 can't see the reference and would -# strip/rename them — causing ClassNotFoundException at launch in minified builds. +# Transpiled Maxi80Services classes are reached only via JNI-by-name from the native Swift bridge. -keep class maxi80.services.** { *; } -# Media3 (ExoPlayer) surface used by the now-playing writeback. The phone playback path drives -# the notification metadata through the Skip JNI-by-name bridge: -# AndroidNowPlayingController.platformUpdateNowPlaying → player.getCurrentMediaItem / -# getCurrentMediaItemIndex / replaceMediaItem, rendered by DefaultMediaNotificationProvider from -# MediaItem.getMediaMetadata(). R8 can't see those by-name references in a minified release build -# and could strip/rename them, leaving the initial metadata stuck — matching issue #13. -# -# Deliberately broad (whole `androidx.media3.**`, not just `.common.**`) rather than relying on -# Media3's own consumer ProGuard rules: the by-name bridge reflects on the CONCRETE runtime type -# returned by SharedAudioPlayer.shared() — an ExoPlayer whose implementation lives in -# `androidx.media3.exoplayer` (ExoPlayerImpl), not `androidx.media3.common`. Scoping the keep to -# `.common.**` would leave the actually-reflected methods (getCurrentMediaItem / replaceMediaItem / -# getCurrentMediaItemIndex) on the impl class renamable, reintroducing the R8-strips-JNI-bridged- -# class crash. The keep is chosen over Media3's consumer rules for that reason. --keep class androidx.media3.** { *; } +# ExoPlayerImpl is the concrete class the JNI bridge receives from SharedAudioPlayer.shared(). +# Media3's own consumer ProGuard rules keep the rest of the public API. +-keep class androidx.media3.exoplayer.ExoPlayerImpl { *; } -dontwarn androidx.media3.** diff --git a/Android/app/src/main/res/values-v35/themes.xml b/Android/app/src/main/res/values-v35/themes.xml new file mode 100644 index 0000000..d70440b --- /dev/null +++ b/Android/app/src/main/res/values-v35/themes.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/Sources/Maxi80Services/Skip/skip.yml b/Sources/Maxi80Services/Skip/skip.yml index 8c0421f..e39c18a 100644 --- a/Sources/Maxi80Services/Skip/skip.yml +++ b/Sources/Maxi80Services/Skip/skip.yml @@ -11,5 +11,5 @@ build: - 'implementation("androidx.media3:media3-extractor:1.9.4")' # Supplies androidx.core.app.NotificationCompat, used by Maxi80MediaService to build the # MediaStyle foreground/lock-screen notification. Not pulled in transitively by media3. - - 'implementation("androidx.core:core-ktx:1.15.0")' + - 'implementation("androidx.core:core-ktx:1.16.0")' - 'implementation("com.google.guava:guava:31.1-android")'