mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
refactor: migrate core modules to Kotlin Multiplatform and consolidat… (#4735)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
parent
f3775a601c
commit
cffbd08806
265 changed files with 1383 additions and 1340 deletions
|
|
@ -43,12 +43,12 @@ import javax.net.ssl.SSLContext
|
|||
import javax.net.ssl.TrustManager
|
||||
|
||||
@Singleton
|
||||
class MQTTRepository
|
||||
class MQTTRepositoryImpl
|
||||
@Inject
|
||||
constructor(
|
||||
private val radioConfigRepository: RadioConfigRepository,
|
||||
private val nodeRepository: NodeRepository,
|
||||
) {
|
||||
) : MQTTRepository {
|
||||
|
||||
companion object {
|
||||
/**
|
||||
|
|
@ -67,7 +67,7 @@ constructor(
|
|||
|
||||
private var mqttClient: MqttAsyncClient? = null
|
||||
|
||||
fun disconnect() {
|
||||
override fun disconnect() {
|
||||
Logger.i { "MQTT Disconnected" }
|
||||
mqttClient?.apply {
|
||||
if (isConnected) {
|
||||
|
|
@ -78,7 +78,7 @@ constructor(
|
|||
mqttClient = null
|
||||
}
|
||||
|
||||
val proxyMessageFlow: Flow<MqttClientProxyMessage> = callbackFlow {
|
||||
override val proxyMessageFlow: Flow<MqttClientProxyMessage> = callbackFlow {
|
||||
val ownerId = "MeshtasticAndroidMqttProxy-${nodeRepository.myId.value ?: generateClientId()}"
|
||||
val channelSet = radioConfigRepository.channelSetFlow.first()
|
||||
val mqttConfig = radioConfigRepository.moduleConfigFlow.first().mqtt
|
||||
|
|
@ -165,7 +165,7 @@ constructor(
|
|||
}
|
||||
|
||||
@Suppress("TooGenericExceptionCaught")
|
||||
fun publish(topic: String, data: ByteArray, retained: Boolean) {
|
||||
override fun publish(topic: String, data: ByteArray, retained: Boolean) {
|
||||
try {
|
||||
val token = mqttClient?.publish(topic, data, DEFAULT_QOS, retained)
|
||||
Logger.i { "MQTT Publish messageId: ${token?.messageId}" }
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2025-2026 Meshtastic LLC
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.meshtastic.core.network.repository
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import org.meshtastic.proto.MqttClientProxyMessage
|
||||
|
||||
/** Interface defining the MQTT interactions used for proxying messages to and from the mesh. */
|
||||
interface MQTTRepository {
|
||||
/** Disconnects the MQTT client and cleans up resources. */
|
||||
fun disconnect()
|
||||
|
||||
/**
|
||||
* A flow of incoming messages from the subscribed MQTT topics. Connecting/subscribing is initiated when this flow
|
||||
* is collected.
|
||||
*/
|
||||
val proxyMessageFlow: Flow<MqttClientProxyMessage>
|
||||
|
||||
/**
|
||||
* Publishes a message to the given MQTT topic.
|
||||
*
|
||||
* @param topic The MQTT topic to publish to.
|
||||
* @param data The binary payload.
|
||||
* @param retained Whether the message should be retained by the broker.
|
||||
*/
|
||||
fun publish(topic: String, data: ByteArray, retained: Boolean)
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2025 Meshtastic LLC
|
||||
* Copyright (c) 2025-2026 Meshtastic LLC
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -14,7 +14,6 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.meshtastic.core.network.service
|
||||
|
||||
import io.ktor.client.HttpClient
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2025 Meshtastic LLC
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.meshtastic.core.network.di
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import org.meshtastic.core.model.NetworkDeviceHardware
|
||||
import org.meshtastic.core.model.NetworkFirmwareReleases
|
||||
import org.meshtastic.core.network.BuildConfig
|
||||
import org.meshtastic.core.network.service.ApiService
|
||||
import javax.inject.Singleton
|
||||
|
||||
@InstallIn(SingletonComponent::class)
|
||||
@Module
|
||||
class FDroidNetworkModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideOkHttpClient(): OkHttpClient = OkHttpClient.Builder()
|
||||
.addInterceptor(
|
||||
interceptor =
|
||||
HttpLoggingInterceptor().apply {
|
||||
if (BuildConfig.DEBUG) {
|
||||
setLevel(HttpLoggingInterceptor.Level.BODY)
|
||||
}
|
||||
},
|
||||
)
|
||||
.build()
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideApiService(): ApiService = object : ApiService {
|
||||
override suspend fun getDeviceHardware(): List<NetworkDeviceHardware> =
|
||||
throw NotImplementedError("API calls to getDeviceHardware are not supported on Fdroid builds.")
|
||||
|
||||
override suspend fun getFirmwareReleases(): NetworkFirmwareReleases =
|
||||
throw NotImplementedError("API calls to getFirmwareReleases are not supported on Fdroid builds.")
|
||||
}
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2025-2026 Meshtastic LLC
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.meshtastic.core.network.di
|
||||
|
||||
import android.content.Context
|
||||
import com.datadog.android.okhttp.DatadogEventListener
|
||||
import com.datadog.android.okhttp.DatadogInterceptor
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import okhttp3.Cache
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import org.meshtastic.core.network.BuildConfig
|
||||
import org.meshtastic.core.network.service.ApiService
|
||||
import org.meshtastic.core.network.service.ApiServiceImpl
|
||||
import java.io.File
|
||||
import javax.inject.Singleton
|
||||
|
||||
@InstallIn(SingletonComponent::class)
|
||||
@Module
|
||||
interface GoogleNetworkModule {
|
||||
|
||||
@Binds @Singleton
|
||||
fun bindApiService(apiServiceImpl: ApiServiceImpl): ApiService
|
||||
|
||||
companion object {
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideOkHttpClient(@ApplicationContext context: Context): OkHttpClient = OkHttpClient.Builder()
|
||||
.cache(
|
||||
cache =
|
||||
Cache(
|
||||
directory = File(context.applicationContext.cacheDir, "http_cache"),
|
||||
maxSize = 50L * 1024L * 1024L, // 50 MiB
|
||||
),
|
||||
)
|
||||
.addInterceptor(
|
||||
interceptor =
|
||||
HttpLoggingInterceptor().apply {
|
||||
if (BuildConfig.DEBUG) {
|
||||
setLevel(HttpLoggingInterceptor.Level.BODY)
|
||||
}
|
||||
},
|
||||
)
|
||||
.addInterceptor(
|
||||
interceptor = DatadogInterceptor.Builder(tracedHosts = listOf("meshtastic.org")).build(),
|
||||
)
|
||||
.eventListenerFactory(eventListenerFactory = DatadogEventListener.Factory())
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
</manifest>
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2025-2026 Meshtastic LLC
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.meshtastic.core.network.di
|
||||
|
||||
import android.content.Context
|
||||
import coil3.ImageLoader
|
||||
import coil3.disk.DiskCache
|
||||
import coil3.memory.MemoryCache
|
||||
import coil3.network.okhttp.OkHttpNetworkFetcherFactory
|
||||
import coil3.request.crossfade
|
||||
import coil3.svg.SvgDecoder
|
||||
import coil3.util.DebugLogger
|
||||
import coil3.util.Logger
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.engine.okhttp.OkHttp
|
||||
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
|
||||
import io.ktor.serialization.kotlinx.json.json
|
||||
import kotlinx.serialization.json.Json
|
||||
import okhttp3.OkHttpClient
|
||||
import org.meshtastic.core.network.BuildConfig
|
||||
import javax.inject.Singleton
|
||||
|
||||
private const val DISK_CACHE_PERCENT = 0.02
|
||||
private const val MEMORY_CACHE_PERCENT = 0.25
|
||||
|
||||
@InstallIn(SingletonComponent::class)
|
||||
@Module
|
||||
class NetworkModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideImageLoader(okHttpClient: OkHttpClient, @ApplicationContext application: Context): ImageLoader {
|
||||
val sharedOkHttp = okHttpClient.newBuilder().build()
|
||||
return ImageLoader.Builder(context = application)
|
||||
.components {
|
||||
add(OkHttpNetworkFetcherFactory(callFactory = { sharedOkHttp }))
|
||||
add(SvgDecoder.Factory(scaleToDensity = true))
|
||||
}
|
||||
.memoryCache {
|
||||
MemoryCache.Builder().maxSizePercent(context = application, percent = MEMORY_CACHE_PERCENT).build()
|
||||
}
|
||||
.diskCache { DiskCache.Builder().maxSizePercent(percent = DISK_CACHE_PERCENT).build() }
|
||||
.logger(logger = if (BuildConfig.DEBUG) DebugLogger(minLevel = Logger.Level.Verbose) else null)
|
||||
.crossfade(enable = true)
|
||||
.build()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideHttpClient(okHttpClient: OkHttpClient): HttpClient = HttpClient(engineFactory = OkHttp) {
|
||||
engine { preconfigured = okHttpClient }
|
||||
|
||||
install(plugin = ContentNegotiation) {
|
||||
json(
|
||||
Json {
|
||||
isLenient = true
|
||||
ignoreUnknownKeys = true
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue