mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
chore: review-cleanup fleet (audit + fix + hardening) (#5158)
This commit is contained in:
parent
872c566ef1
commit
17e69c6d4c
68 changed files with 784 additions and 459 deletions
|
|
@ -127,7 +127,10 @@ compose.desktop {
|
|||
isEnabled.set(true)
|
||||
obfuscate.set(false) // Open-source project — obfuscation adds no value
|
||||
optimize.set(true)
|
||||
configurationFiles.from(project.file("proguard-rules.pro"))
|
||||
configurationFiles.from(
|
||||
rootProject.file("config/proguard/shared-rules.pro"),
|
||||
project.file("proguard-rules.pro"),
|
||||
)
|
||||
}
|
||||
|
||||
nativeDistributions {
|
||||
|
|
|
|||
194
desktop/proguard-rules.pro
vendored
194
desktop/proguard-rules.pro
vendored
|
|
@ -4,202 +4,56 @@
|
|||
# Open-source project: we rely on tree-shaking (unused code removal) for size
|
||||
# reduction. Obfuscation is disabled in build.gradle.kts (obfuscate.set(false)).
|
||||
#
|
||||
# Key libraries requiring keep-rules (reflection, JNI, code generation):
|
||||
# Koin (DI via reflection), kotlinx-serialization (generated serializers),
|
||||
# Wire protobuf (ADAPTER reflection), Room KMP (generated DB + converters),
|
||||
# Ktor (Java engine + ServiceLoader), Kable BLE, Coil, Compose Multiplatform
|
||||
# resources, SQLite bundled (JNI), AboutLibraries.
|
||||
# Cross-platform library rules (Koin, kotlinx-serialization, Wire, Room,
|
||||
# Ktor, Coil, Kable, Kermit, Okio, DataStore, Paging, Lifecycle, Navigation 3,
|
||||
# AboutLibraries, Markdown, QRCode, CMP resources, core model) live in
|
||||
# config/proguard/shared-rules.pro and are wired in by this module's
|
||||
# build.gradle.kts. This file holds only desktop/JVM-specific rules.
|
||||
# ============================================================================
|
||||
|
||||
# ---- General ----------------------------------------------------------------
|
||||
|
||||
# Preserve line numbers for meaningful stack traces
|
||||
-keepattributes SourceFile,LineNumberTable,*Annotation*,Signature,InnerClasses,EnclosingMethod,Exceptions
|
||||
|
||||
# Suppress notes about duplicate resource files (common in fat JARs)
|
||||
-dontnote **
|
||||
|
||||
# Disable ProGuard optimization passes. Tree-shaking (unused code removal) still
|
||||
# runs — only method-body rewrites and call-site transformations are suppressed.
|
||||
#
|
||||
# Why: CMP 1.11 ships consumer rules with -assumenosideeffects on
|
||||
# Composer.<clinit>() and ComposerImpl.<clinit>(), plus -assumevalues on
|
||||
# ComposeRuntimeFlags and ComposeStackTraceMode. These optimization directives
|
||||
# let the optimizer rewrite *call sites* (class-init triggers, flag reads) even
|
||||
# when the target classes are preserved by -keep rules. The result is that the
|
||||
# Compose recomposer/frame-clock/animation state machines silently freeze on
|
||||
# their first frame in release builds. -dontoptimize is the only directive that
|
||||
# disables processing of -assumenosideeffects/-assumevalues. The desktop compose
|
||||
# build sets optimize.set(true), so this applies here as well as to R8. See #5146.
|
||||
-dontoptimize
|
||||
|
||||
# Do not parse/rewrite Kotlin metadata during shrinking/optimization.
|
||||
# ProGuard's KotlinShrinker cannot handle the metadata produced by Compose
|
||||
# Multiplatform 1.11.x + Kotlin 2.3.x, causing a NullPointerException.
|
||||
# Since we disable obfuscation (class names remain stable), metadata references
|
||||
# stay valid and do not need rewriting. The annotations themselves are preserved
|
||||
# by -keepattributes *Annotation*.
|
||||
#
|
||||
# NOTE: -dontprocesskotlinmetadata is a ProGuard-only directive; R8 does not
|
||||
# recognize it, which is why it lives in the desktop-only file.
|
||||
-dontprocesskotlinmetadata
|
||||
|
||||
# ---- Entry point ------------------------------------------------------------
|
||||
|
||||
-keep class org.meshtastic.desktop.MainKt { *; }
|
||||
|
||||
# ---- Kotlin / Coroutines ---------------------------------------------------
|
||||
# ---- Ktor Java engine (desktop-only; Android uses OkHttp) -------------------
|
||||
|
||||
# Keep Kotlin metadata for reflection-dependent libraries
|
||||
-keep class kotlin.Metadata { *; }
|
||||
-keep class kotlin.reflect.** { *; }
|
||||
|
||||
# Coroutines internals
|
||||
-dontwarn kotlinx.coroutines.**
|
||||
-keep class kotlinx.coroutines.** { *; }
|
||||
-keep class kotlin.coroutines.Continuation { *; }
|
||||
|
||||
# ---- Koin DI (reflection-based injection) -----------------------------------
|
||||
|
||||
# Koin core — uses reflection to instantiate definitions
|
||||
-keep class org.koin.** { *; }
|
||||
-dontwarn org.koin.**
|
||||
|
||||
# Keep all Koin-annotated @Module / @ComponentScan classes and their generated
|
||||
# counterparts so Koin K2 plugin output survives tree-shaking.
|
||||
-keep @org.koin.core.annotation.Module class * { *; }
|
||||
-keep @org.koin.core.annotation.ComponentScan class * { *; }
|
||||
-keep @org.koin.core.annotation.Single class * { *; }
|
||||
-keep @org.koin.core.annotation.Factory class * { *; }
|
||||
|
||||
# Generated Koin module extensions (K2 plugin output)
|
||||
-keep class org.meshtastic.**.di.** { *; }
|
||||
|
||||
# ---- kotlinx-serialization --------------------------------------------------
|
||||
|
||||
# The serialization plugin generates companion $serializer classes and
|
||||
# serializer() factory methods that are invoked reflectively.
|
||||
-keepattributes RuntimeVisibleAnnotations
|
||||
-keep class kotlinx.serialization.** { *; }
|
||||
-dontwarn kotlinx.serialization.**
|
||||
|
||||
# Keep @Serializable classes and their generated serializers
|
||||
-keepclassmembers @kotlinx.serialization.Serializable class ** {
|
||||
# Companion object that holds the serializer() factory
|
||||
static ** Companion;
|
||||
kotlinx.serialization.KSerializer serializer(...);
|
||||
}
|
||||
-keepclassmembers class **.$serializer { *; }
|
||||
-keep class **.$serializer { *; }
|
||||
-keepclasseswithmembers class ** {
|
||||
kotlinx.serialization.KSerializer serializer(...);
|
||||
}
|
||||
|
||||
# ---- Wire protobuf ----------------------------------------------------------
|
||||
|
||||
# Wire generates ADAPTER companion objects accessed via reflection
|
||||
-keep class com.squareup.wire.** { *; }
|
||||
-dontwarn com.squareup.wire.**
|
||||
|
||||
# All generated proto message classes
|
||||
-keep class org.meshtastic.proto.** { *; }
|
||||
-keep class meshtastic.** { *; }
|
||||
|
||||
# Suppress warnings about missing Android Parcelable (Wire cross-platform stubs)
|
||||
-dontwarn android.os.Parcel**
|
||||
-dontwarn android.os.Parcelable**
|
||||
|
||||
# ---- Room KMP ---------------------------------------------------------------
|
||||
|
||||
# Preserve generated database constructors (required for Room's reflective init)
|
||||
-keep class * extends androidx.room3.RoomDatabase { <init>(); }
|
||||
-keep class * implements androidx.room3.RoomDatabaseConstructor { *; }
|
||||
|
||||
# Keep the expect/actual MeshtasticDatabaseConstructor
|
||||
-keep class org.meshtastic.core.database.MeshtasticDatabaseConstructor { *; }
|
||||
-keep class org.meshtastic.core.database.MeshtasticDatabase { *; }
|
||||
|
||||
# Room DAOs — Room generates implementations at compile time; keep interfaces
|
||||
-keep class org.meshtastic.core.database.dao.** { *; }
|
||||
|
||||
# Room Entities — accessed via reflection for column mapping
|
||||
-keep class org.meshtastic.core.database.entity.** { *; }
|
||||
|
||||
# Room TypeConverters — invoked reflectively
|
||||
-keep class org.meshtastic.core.database.Converters { *; }
|
||||
|
||||
# Room generated _Impl classes
|
||||
-keep class **_Impl { *; }
|
||||
|
||||
# ---- SQLite bundled (JNI) ---------------------------------------------------
|
||||
|
||||
-keep class androidx.sqlite.** { *; }
|
||||
-dontwarn androidx.sqlite.**
|
||||
|
||||
# ---- Ktor (Java engine + ServiceLoader + content negotiation) ---------------
|
||||
|
||||
# Ktor uses ServiceLoader and reflection for engine/plugin discovery
|
||||
-keep class io.ktor.** { *; }
|
||||
-dontwarn io.ktor.**
|
||||
|
||||
# Keep ServiceLoader metadata files
|
||||
-keepclassmembers class * implements io.ktor.client.HttpClientEngineFactory { *; }
|
||||
|
||||
# Java HTTP client engine
|
||||
-keep class io.ktor.client.engine.java.** { *; }
|
||||
|
||||
# ---- Coil (image loading) ---------------------------------------------------
|
||||
|
||||
-keep class coil3.** { *; }
|
||||
-dontwarn coil3.**
|
||||
|
||||
# ---- Kable BLE --------------------------------------------------------------
|
||||
|
||||
-keep class com.juul.kable.** { *; }
|
||||
-dontwarn com.juul.kable.**
|
||||
|
||||
# ---- Compose Multiplatform resources ----------------------------------------
|
||||
|
||||
# Generated resource accessor classes (Res.string.*, Res.drawable.*, etc.)
|
||||
-keep class org.jetbrains.compose.resources.** { *; }
|
||||
-keep class org.meshtastic.core.resources.** { *; }
|
||||
|
||||
|
||||
# ---- AboutLibraries ---------------------------------------------------------
|
||||
|
||||
-keep class com.mikepenz.aboutlibraries.** { *; }
|
||||
-dontwarn com.mikepenz.aboutlibraries.**
|
||||
|
||||
# ---- Multiplatform Markdown Renderer ----------------------------------------
|
||||
|
||||
-keep class com.mikepenz.markdown.** { *; }
|
||||
-dontwarn com.mikepenz.markdown.**
|
||||
|
||||
# ---- QR Code Kotlin ---------------------------------------------------------
|
||||
|
||||
-keep class io.github.g0dkar.qrcode.** { *; }
|
||||
-dontwarn io.github.g0dkar.qrcode.**
|
||||
-keep class qrcode.** { *; }
|
||||
-dontwarn qrcode.**
|
||||
|
||||
# ---- Kermit logging ----------------------------------------------------------
|
||||
|
||||
-keep class co.touchlab.kermit.** { *; }
|
||||
-dontwarn co.touchlab.kermit.**
|
||||
|
||||
# ---- Okio -------------------------------------------------------------------
|
||||
|
||||
-dontwarn okio.**
|
||||
-keep class okio.** { *; }
|
||||
|
||||
# ---- DataStore --------------------------------------------------------------
|
||||
|
||||
-keep class androidx.datastore.** { *; }
|
||||
-dontwarn androidx.datastore.**
|
||||
|
||||
# ---- Paging -----------------------------------------------------------------
|
||||
|
||||
-keep class androidx.paging.** { *; }
|
||||
-dontwarn androidx.paging.**
|
||||
|
||||
# ---- Lifecycle / Navigation / ViewModel (JetBrains forks) -------------------
|
||||
|
||||
-keep class androidx.lifecycle.** { *; }
|
||||
-keep class androidx.navigation3.** { *; }
|
||||
-dontwarn androidx.lifecycle.**
|
||||
-dontwarn androidx.navigation3.**
|
||||
|
||||
# ---- Meshtastic application code --------------------------------------------
|
||||
# ---- Meshtastic desktop host shell ------------------------------------------
|
||||
|
||||
# Keep all desktop module classes (thin host shell — not worth tree-shaking)
|
||||
-keep class org.meshtastic.desktop.** { *; }
|
||||
|
||||
# Core model classes (used in serialization, Room, and Koin injection)
|
||||
-keep class org.meshtastic.core.model.** { *; }
|
||||
|
||||
# ---- JVM runtime suppression ------------------------------------------------
|
||||
|
||||
-dontwarn java.lang.reflect.**
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ import io.ktor.client.HttpClient
|
|||
import kotlinx.coroutines.flow.first
|
||||
import okio.Path.Companion.toPath
|
||||
import org.jetbrains.compose.resources.decodeToSvgPainter
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.koin.compose.koinInject
|
||||
import org.koin.core.context.startKoin
|
||||
import org.meshtastic.core.common.BuildConfigProvider
|
||||
|
|
@ -70,6 +71,10 @@ import org.meshtastic.core.navigation.SettingsRoute
|
|||
import org.meshtastic.core.navigation.TopLevelDestination
|
||||
import org.meshtastic.core.navigation.rememberMultiBackstack
|
||||
import org.meshtastic.core.repository.UiPrefs
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.desktop_tray_quit
|
||||
import org.meshtastic.core.resources.desktop_tray_show
|
||||
import org.meshtastic.core.resources.desktop_tray_tooltip
|
||||
import org.meshtastic.core.service.MeshServiceOrchestrator
|
||||
import org.meshtastic.core.ui.theme.AppTheme
|
||||
import org.meshtastic.core.ui.viewmodel.UIViewModel
|
||||
|
|
@ -216,11 +221,11 @@ private fun ApplicationScope.MeshtasticDesktopApp(
|
|||
Tray(
|
||||
state = trayState,
|
||||
icon = trayIcon,
|
||||
tooltip = "Meshtastic Desktop",
|
||||
tooltip = stringResource(Res.string.desktop_tray_tooltip),
|
||||
onAction = { isAppVisible = true },
|
||||
menu = {
|
||||
Item("Show Meshtastic", onClick = { isAppVisible = true })
|
||||
Item("Quit", onClick = ::exitApplication)
|
||||
Item(stringResource(Res.string.desktop_tray_show), onClick = { isAppVisible = true })
|
||||
Item(stringResource(Res.string.desktop_tray_quit), onClick = ::exitApplication)
|
||||
},
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import org.meshtastic.core.repository.MeshServiceNotifications
|
|||
import org.meshtastic.core.repository.Notification
|
||||
import org.meshtastic.core.repository.NotificationManager
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.desktop_notification_title
|
||||
import org.meshtastic.core.resources.getString
|
||||
import org.meshtastic.core.resources.low_battery_message
|
||||
import org.meshtastic.core.resources.low_battery_title
|
||||
|
|
@ -141,7 +142,7 @@ class DesktopMeshServiceNotifications(private val notificationManager: Notificat
|
|||
override fun showClientNotification(clientNotification: ClientNotification) {
|
||||
notificationManager.dispatch(
|
||||
Notification(
|
||||
title = "Meshtastic",
|
||||
title = getString(Res.string.desktop_notification_title),
|
||||
message = clientNotification.message,
|
||||
category = Notification.Category.Alert,
|
||||
id = clientNotification.toString().hashCode(),
|
||||
|
|
|
|||
|
|
@ -80,6 +80,10 @@ class NoopRadioInterfaceService : RadioInterfaceService {
|
|||
logWarn("NoopRadioInterfaceService.sendToRadio(${bytes.size} bytes)")
|
||||
}
|
||||
|
||||
override fun resetReceivedBuffer() {
|
||||
// No-op: this stub never buffers bytes.
|
||||
}
|
||||
|
||||
override fun connect() {
|
||||
logWarn("NoopRadioInterfaceService.connect()")
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue