Add :core:service (#3253)

This commit is contained in:
Phil Oliver 2025-09-30 16:55:56 -04:00 committed by GitHub
parent cf59033c49
commit db2ef75e08
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
46 changed files with 125 additions and 1077 deletions

View file

@ -19,7 +19,6 @@ package com.geeksville.mesh.ui.map
import androidx.lifecycle.viewModelScope
import com.geeksville.mesh.LocalOnlyProtos.LocalConfig
import com.geeksville.mesh.service.ServiceRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.stateIn
@ -28,6 +27,7 @@ import org.meshtastic.core.data.repository.PacketRepository
import org.meshtastic.core.data.repository.RadioConfigRepository
import org.meshtastic.core.model.DataPacket
import org.meshtastic.core.prefs.map.MapPrefs
import org.meshtastic.core.service.ServiceRepository
import javax.inject.Inject
@HiltViewModel

View file

@ -23,7 +23,6 @@ import androidx.core.net.toFile
import androidx.lifecycle.viewModelScope
import com.geeksville.mesh.ConfigProtos
import com.geeksville.mesh.android.BuildUtils.debug
import com.geeksville.mesh.service.ServiceRepository
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.model.TileProvider
import com.google.android.gms.maps.model.UrlTileProvider
@ -55,6 +54,7 @@ import org.meshtastic.core.data.repository.RadioConfigRepository
import org.meshtastic.core.datastore.UiPreferencesDataSource
import org.meshtastic.core.prefs.map.GoogleMapsPrefs
import org.meshtastic.core.prefs.map.MapPrefs
import org.meshtastic.core.service.ServiceRepository
import timber.log.Timber
import java.io.File
import java.io.FileOutputStream

View file

@ -1,174 +0,0 @@
// com.geeksville.mesh.IMeshService.aidl
package com.geeksville.mesh;
// Declare any non-default types here with import statements
import org.meshtastic.core.model.DataPacket;
import org.meshtastic.core.model.NodeInfo;
import org.meshtastic.core.model.MeshUser;
import org.meshtastic.core.model.Position;
import org.meshtastic.core.model.MyNodeInfo;
/**
This is the public android API for talking to meshtastic radios.
To connect to meshtastic you should bind to it per https://developer.android.com/guide/components/bound-services
The intent you use to reach the service should look like this:
val intent = Intent().apply {
setClassName(
"com.geeksville.mesh",
"com.geeksville.mesh.service.MeshService"
)
}
In Android 11+ you *may* need to add the following to the client app's manifest to allow binding of the mesh service:
<queries>
<package android:name="com.geeksville.mesh" />
</queries>
For additional information, see https://developer.android.com/guide/topics/manifest/queries-element
Once you have bound to the service you should register your broadcast receivers per https://developer.android.com/guide/components/broadcasts#context-registered-receivers
// com.geeksville.mesh.x broadcast intents, where x is:
// RECEIVED.<portnumm> - will **only** deliver packets for the specified port number. If a wellknown portnums.proto name for portnum is known it will be used
// (i.e. com.geeksville.mesh.RECEIVED.TEXT_MESSAGE_APP) else the numeric portnum will be included as a base 10 integer (com.geeksville.mesh.RECEIVED.4403 etc...)
// NODE_CHANGE for new IDs appearing or disappearing
// CONNECTION_CHANGED for losing/gaining connection to the packet radio
// MESSAGE_STATUS_CHANGED for any message status changes (for sent messages only, payload will contain a message ID and a MessageStatus)
Note - these calls might throw RemoteException to indicate mesh error states
*/
interface IMeshService {
/// Tell the service where to send its broadcasts of received packets
/// This call is only required for manifest declared receivers. If your receiver is context-registered
/// you don't need this.
void subscribeReceiver(String packageName, String receiverName);
/**
* Set the user info for this node
*/
void setOwner(in MeshUser user);
void setRemoteOwner(in int requestId, in byte []payload);
void getRemoteOwner(in int requestId, in int destNum);
/// Return my unique user ID string
String getMyId();
/// Return a unique packet ID
int getPacketId();
/*
Send a packet to a specified node name
typ is defined in mesh.proto Data.Type. For now juse use 0 to mean opaque bytes.
destId can be null to indicate "broadcast message"
messageStatus and id of the provided message will be updated by this routine to indicate
message send status and the ID that can be used to locate the message in the future
*/
void send(inout DataPacket packet);
/**
Get the IDs of everyone on the mesh. You should also subscribe for NODE_CHANGE broadcasts.
*/
List<NodeInfo> getNodes();
/// This method is only intended for use in our GUI, so the user can set radio options
/// It returns a DeviceConfig protobuf.
byte []getConfig();
/// It sets a Config protobuf via admin packet
void setConfig(in byte []payload);
/// Set and get a Config protobuf via admin packet
void setRemoteConfig(in int requestId, in int destNum, in byte []payload);
void getRemoteConfig(in int requestId, in int destNum, in int configTypeValue);
/// Set and get a ModuleConfig protobuf via admin packet
void setModuleConfig(in int requestId, in int destNum, in byte []payload);
void getModuleConfig(in int requestId, in int destNum, in int moduleConfigTypeValue);
/// Set and get the Ext Notification Ringtone string via admin packet
void setRingtone(in int destNum, in String ringtone);
void getRingtone(in int requestId, in int destNum);
/// Set and get the Canned Message Messages string via admin packet
void setCannedMessages(in int destNum, in String messages);
void getCannedMessages(in int requestId, in int destNum);
/// This method is only intended for use in our GUI, so the user can set radio options
/// It sets a Channel protobuf via admin packet
void setChannel(in byte []payload);
/// Set and get a Channel protobuf via admin packet
void setRemoteChannel(in int requestId, in int destNum, in byte []payload);
void getRemoteChannel(in int requestId, in int destNum, in int channelIndex);
/// Send beginEditSettings admin packet to nodeNum
void beginEditSettings();
/// Send commitEditSettings admin packet to nodeNum
void commitEditSettings();
/// delete a specific nodeNum from nodeDB
void removeByNodenum(in int requestID, in int nodeNum);
/// Send position packet with wantResponse to nodeNum
void requestPosition(in int destNum, in Position position);
/// Send setFixedPosition admin packet (or removeFixedPosition if Position is empty)
void setFixedPosition(in int destNum, in Position position);
/// Send traceroute packet with wantResponse to nodeNum
void requestTraceroute(in int requestId, in int destNum);
/// Send Shutdown admin packet to nodeNum
void requestShutdown(in int requestId, in int destNum);
/// Send Reboot admin packet to nodeNum
void requestReboot(in int requestId, in int destNum);
/// Send FactoryReset admin packet to nodeNum
void requestFactoryReset(in int requestId, in int destNum);
/// Send NodedbReset admin packet to nodeNum
void requestNodedbReset(in int requestId, in int destNum);
/// Returns a ChannelSet protobuf
byte []getChannelSet();
/**
Is the packet radio currently connected to the phone? Returns a ConnectionState string.
*/
String connectionState();
/// If a macaddress we will try to talk to our device, if null we will be idle.
/// Any current connection will be dropped (even if the device address is the same) before reconnecting.
/// Users should not call this directly, only used internally by the MeshUtil activity
/// Returns true if the device address actually changed, or false if no change was needed
boolean setDeviceAddress(String deviceAddr);
/// Get basic device hardware info about our connected radio. Will never return NULL. Will return NULL
/// if no my node info is available (i.e. it will not throw an exception)
MyNodeInfo getMyNodeInfo();
/// Start updating the radios firmware
void startFirmwareUpdate();
/// Return a number 0-100 for firmware update progress. -1 for completed and success, -2 for failure
int getUpdateStatus();
/// Start providing location (from phone GPS) to mesh
void startProvideLocation();
/// Stop providing location (from phone GPS) to mesh
void stopProvideLocation();
/// Send request for node UserInfo
void requestUserInfo(in int destNum);
}

View file

@ -27,10 +27,11 @@ import com.geeksville.mesh.android.BindFailedException
import com.geeksville.mesh.android.ServiceClient
import com.geeksville.mesh.concurrent.handledLaunch
import com.geeksville.mesh.service.MeshService
import com.geeksville.mesh.service.ServiceRepository
import com.geeksville.mesh.service.startService
import dagger.hilt.android.scopes.ActivityScoped
import kotlinx.coroutines.Job
import org.meshtastic.core.service.IMeshService
import org.meshtastic.core.service.ServiceRepository
import javax.inject.Inject
/** A Activity-lifecycle-aware [ServiceClient] that binds [MeshService] once the Activity is started. */

View file

@ -34,7 +34,6 @@ import com.geeksville.mesh.repository.radio.InterfaceId
import com.geeksville.mesh.repository.radio.RadioInterfaceService
import com.geeksville.mesh.repository.usb.UsbRepository
import com.geeksville.mesh.service.MeshService
import com.geeksville.mesh.service.ServiceRepository
import com.hoho.android.usbserial.driver.UsbSerialDriver
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Job
@ -52,6 +51,7 @@ import kotlinx.coroutines.launch
import org.meshtastic.core.datastore.RecentAddressesDataSource
import org.meshtastic.core.datastore.model.RecentAddress
import org.meshtastic.core.model.util.anonymize
import org.meshtastic.core.service.ServiceRepository
import org.meshtastic.core.strings.R
import javax.inject.Inject

View file

@ -35,8 +35,6 @@ import com.geeksville.mesh.Portnums
import com.geeksville.mesh.Portnums.PortNum
import com.geeksville.mesh.TelemetryProtos.Telemetry
import com.geeksville.mesh.android.Logging
import com.geeksville.mesh.service.ServiceAction
import com.geeksville.mesh.service.ServiceRepository
import com.geeksville.mesh.util.safeNumber
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
@ -65,6 +63,8 @@ import org.meshtastic.core.model.DataPacket
import org.meshtastic.core.model.DeviceHardware
import org.meshtastic.core.navigation.NodesRoutes
import org.meshtastic.core.prefs.map.MapPrefs
import org.meshtastic.core.service.ServiceAction
import org.meshtastic.core.service.ServiceRepository
import org.meshtastic.core.strings.R
import org.meshtastic.feature.map.model.CustomTileSource
import java.io.BufferedWriter

View file

@ -32,7 +32,6 @@ import com.geeksville.mesh.AppOnlyProtos
import com.geeksville.mesh.ChannelProtos
import com.geeksville.mesh.ChannelProtos.ChannelSettings
import com.geeksville.mesh.ConfigProtos.Config
import com.geeksville.mesh.IMeshService
import com.geeksville.mesh.LocalOnlyProtos.LocalConfig
import com.geeksville.mesh.LocalOnlyProtos.LocalModuleConfig
import com.geeksville.mesh.MeshProtos
@ -45,7 +44,6 @@ import com.geeksville.mesh.copy
import com.geeksville.mesh.repository.radio.MeshActivity
import com.geeksville.mesh.repository.radio.RadioInterfaceService
import com.geeksville.mesh.service.MeshServiceNotifications
import com.geeksville.mesh.service.ServiceRepository
import com.geeksville.mesh.util.safeNumber
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
@ -75,6 +73,8 @@ import org.meshtastic.core.database.model.Node
import org.meshtastic.core.datastore.UiPreferencesDataSource
import org.meshtastic.core.model.DeviceHardware
import org.meshtastic.core.model.util.toChannelSet
import org.meshtastic.core.service.IMeshService
import org.meshtastic.core.service.ServiceRepository
import org.meshtastic.core.strings.R
import javax.inject.Inject

View file

@ -30,7 +30,6 @@ import com.geeksville.mesh.android.Logging
import com.geeksville.mesh.concurrent.handledLaunch
import com.geeksville.mesh.repository.bluetooth.BluetoothRepository
import com.geeksville.mesh.repository.network.NetworkRepository
import com.geeksville.mesh.service.ConnectionState
import com.geeksville.mesh.util.ignoreException
import com.geeksville.mesh.util.toRemoteExceptions
import kotlinx.coroutines.CoroutineScope
@ -49,6 +48,7 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import org.meshtastic.core.model.util.anonymize
import org.meshtastic.core.prefs.radio.RadioPrefs
import org.meshtastic.core.service.ConnectionState
import javax.inject.Inject
import javax.inject.Singleton

View file

@ -1,33 +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 com.geeksville.mesh.service
enum class ConnectionState {
/** We are disconnected from the device, and we should be trying to reconnect. */
DISCONNECTED,
/** We are connected to the device and communicating normally. */
CONNECTED,
/** The device is in a light sleep state, and we are waiting for it to wake up and reconnect to us. */
DEVICE_SLEEP,
;
fun isConnected() = this != DISCONNECTED
}

View file

@ -34,7 +34,6 @@ import com.geeksville.mesh.ChannelProtos
import com.geeksville.mesh.ConfigProtos
import com.geeksville.mesh.CoroutineDispatchers
import com.geeksville.mesh.DeviceUIProtos
import com.geeksville.mesh.IMeshService
import com.geeksville.mesh.LocalOnlyProtos.LocalConfig
import com.geeksville.mesh.LocalOnlyProtos.LocalModuleConfig
import com.geeksville.mesh.MeshProtos
@ -103,6 +102,10 @@ import org.meshtastic.core.model.util.toOneLineString
import org.meshtastic.core.model.util.toPIIString
import org.meshtastic.core.prefs.mesh.MeshPrefs
import org.meshtastic.core.prefs.ui.UiPrefs
import org.meshtastic.core.service.ConnectionState
import org.meshtastic.core.service.IMeshService
import org.meshtastic.core.service.ServiceAction
import org.meshtastic.core.service.ServiceRepository
import org.meshtastic.core.strings.R
import timber.log.Timber
import java.util.Random
@ -111,18 +114,6 @@ import java.util.concurrent.ConcurrentHashMap
import javax.inject.Inject
import kotlin.math.absoluteValue
sealed class ServiceAction {
data class GetDeviceMetadata(val destNum: Int) : ServiceAction()
data class Favorite(val node: Node) : ServiceAction()
data class Ignore(val node: Node) : ServiceAction()
data class Reaction(val emoji: String, val replyId: Int, val contactKey: String) : ServiceAction()
data class AddSharedContact(val contact: AdminProtos.SharedContact) : ServiceAction()
}
/**
* Handles all the communication with android apps. Also keeps an internal model of the network state.
*

View file

@ -24,6 +24,7 @@ import dagger.hilt.android.qualifiers.ApplicationContext
import org.meshtastic.core.model.DataPacket
import org.meshtastic.core.model.MessageStatus
import org.meshtastic.core.model.NodeInfo
import org.meshtastic.core.service.ServiceRepository
import javax.inject.Inject
import javax.inject.Singleton

View file

@ -17,6 +17,7 @@
package com.geeksville.mesh.service
import org.meshtastic.core.service.ConnectionState
import javax.inject.Inject
import javax.inject.Singleton

View file

@ -40,6 +40,7 @@ import org.meshtastic.core.model.DataPacket
import org.meshtastic.core.model.MessageStatus
import org.meshtastic.core.model.util.toOneLineString
import org.meshtastic.core.model.util.toPIIString
import org.meshtastic.core.service.ConnectionState
import java.util.UUID
import java.util.concurrent.ConcurrentLinkedQueue
import java.util.concurrent.TimeUnit

View file

@ -22,6 +22,7 @@ import androidx.core.app.RemoteInput
import dagger.hilt.android.AndroidEntryPoint
import jakarta.inject.Inject
import org.meshtastic.core.model.DataPacket
import org.meshtastic.core.service.ServiceRepository
/**
* A [BroadcastReceiver] that handles inline replies from notifications.

View file

@ -1,125 +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 com.geeksville.mesh.service
import com.geeksville.mesh.IMeshService
import com.geeksville.mesh.MeshProtos
import com.geeksville.mesh.MeshProtos.MeshPacket
import com.geeksville.mesh.android.Logging
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.receiveAsFlow
import javax.inject.Inject
import javax.inject.Singleton
/** Repository class for managing the [IMeshService] instance and connection state */
@Suppress("TooManyFunctions")
@Singleton
class ServiceRepository @Inject constructor() : Logging {
var meshService: IMeshService? = null
private set
fun setMeshService(service: IMeshService?) {
meshService = service
}
// Connection state to our radio device
private val _connectionState = MutableStateFlow(ConnectionState.DISCONNECTED)
val connectionState: StateFlow<ConnectionState>
get() = _connectionState
fun setConnectionState(connectionState: ConnectionState) {
_connectionState.value = connectionState
}
// Current bluetooth link RSSI (dBm). Null if not connected or not a bluetooth interface.
private val _bluetoothRssi = MutableStateFlow<Int?>(null)
val bluetoothRssi: StateFlow<Int?>
get() = _bluetoothRssi
fun setBluetoothRssi(rssi: Int?) {
_bluetoothRssi.value = rssi
}
private val _clientNotification = MutableStateFlow<MeshProtos.ClientNotification?>(null)
val clientNotification: StateFlow<MeshProtos.ClientNotification?>
get() = _clientNotification
fun setClientNotification(notification: MeshProtos.ClientNotification?) {
errormsg(notification?.message.orEmpty())
_clientNotification.value = notification
}
fun clearClientNotification() {
_clientNotification.value = null
}
private val _errorMessage = MutableStateFlow<String?>(null)
val errorMessage: StateFlow<String?>
get() = _errorMessage
fun setErrorMessage(text: String) {
errormsg(text)
_errorMessage.value = text
}
fun clearErrorMessage() {
_errorMessage.value = null
}
private val _statusMessage = MutableStateFlow<String?>(null)
val statusMessage: StateFlow<String?>
get() = _statusMessage
fun setStatusMessage(text: String) {
if (connectionState.value != ConnectionState.CONNECTED) {
_statusMessage.value = text
}
}
private val _meshPacketFlow = MutableSharedFlow<MeshPacket>()
val meshPacketFlow: SharedFlow<MeshPacket>
get() = _meshPacketFlow
suspend fun emitMeshPacket(packet: MeshPacket) {
_meshPacketFlow.emit(packet)
}
private val _tracerouteResponse = MutableStateFlow<String?>(null)
val tracerouteResponse: StateFlow<String?>
get() = _tracerouteResponse
fun setTracerouteResponse(value: String?) {
_tracerouteResponse.value = value
}
fun clearTracerouteResponse() {
setTracerouteResponse(null)
}
private val _serviceAction = Channel<ServiceAction>()
val serviceAction = _serviceAction.receiveAsFlow()
suspend fun onServiceAction(action: ServiceAction) {
_serviceAction.send(action)
}
}

View file

@ -88,7 +88,6 @@ import com.geeksville.mesh.navigation.mapGraph
import com.geeksville.mesh.navigation.nodesGraph
import com.geeksville.mesh.navigation.settingsGraph
import com.geeksville.mesh.repository.radio.MeshActivity
import com.geeksville.mesh.service.ConnectionState
import com.geeksville.mesh.service.MeshService
import com.geeksville.mesh.ui.common.components.MainAppBar
import com.geeksville.mesh.ui.common.components.ScannedQrCodeDialog
@ -108,6 +107,7 @@ import org.meshtastic.core.navigation.NodeDetailRoutes
import org.meshtastic.core.navigation.NodesRoutes
import org.meshtastic.core.navigation.Route
import org.meshtastic.core.navigation.SettingsRoutes
import org.meshtastic.core.service.ConnectionState
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.MultipleChoiceAlertDialog
import org.meshtastic.core.ui.component.SimpleAlertDialog

View file

@ -64,7 +64,6 @@ import com.geeksville.mesh.model.BTScanModel
import com.geeksville.mesh.model.DeviceListEntry
import com.geeksville.mesh.navigation.ConfigRoute
import com.geeksville.mesh.navigation.getNavRouteFrom
import com.geeksville.mesh.service.ConnectionState
import com.geeksville.mesh.ui.common.components.MainAppBar
import com.geeksville.mesh.ui.connections.components.BLEDevices
import com.geeksville.mesh.ui.connections.components.ConnectionsSegmentedBar
@ -78,6 +77,7 @@ import com.google.accompanist.permissions.ExperimentalPermissionsApi
import kotlinx.coroutines.delay
import org.meshtastic.core.navigation.Route
import org.meshtastic.core.navigation.SettingsRoutes
import org.meshtastic.core.service.ConnectionState
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.TitledCard

View file

@ -21,7 +21,6 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.geeksville.mesh.LocalOnlyProtos.LocalConfig
import com.geeksville.mesh.repository.bluetooth.BluetoothRepository
import com.geeksville.mesh.service.ServiceRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
@ -33,6 +32,7 @@ import org.meshtastic.core.data.repository.RadioConfigRepository
import org.meshtastic.core.database.entity.MyNodeEntity
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.prefs.ui.UiPrefs
import org.meshtastic.core.service.ServiceRepository
import javax.inject.Inject
@HiltViewModel

View file

@ -48,10 +48,10 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.geeksville.mesh.model.BTScanModel
import com.geeksville.mesh.model.DeviceListEntry
import com.geeksville.mesh.service.ConnectionState
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.MultiplePermissionsState
import com.google.accompanist.permissions.rememberMultiplePermissionsState
import org.meshtastic.core.service.ConnectionState
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.TitledCard

View file

@ -54,9 +54,9 @@ import androidx.compose.ui.unit.dp
import com.geeksville.mesh.model.BTScanModel
import com.geeksville.mesh.model.DeviceListEntry
import com.geeksville.mesh.repository.network.NetworkRepository
import com.geeksville.mesh.service.ConnectionState
import com.geeksville.mesh.ui.connections.isIPAddress
import kotlinx.coroutines.launch
import org.meshtastic.core.service.ConnectionState
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.TitledCard
import org.meshtastic.core.ui.theme.AppTheme

View file

@ -36,9 +36,9 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import com.geeksville.mesh.service.ConnectionState
import com.geeksville.mesh.ui.TopLevelDestination
import com.geeksville.mesh.ui.connections.DeviceType
import org.meshtastic.core.service.ConnectionState
import org.meshtastic.core.ui.icon.Device
import org.meshtastic.core.ui.icon.MeshtasticIcons
import org.meshtastic.core.ui.icon.NoDevice

View file

@ -25,7 +25,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewLightDark
import com.geeksville.mesh.model.BTScanModel
import com.geeksville.mesh.model.DeviceListEntry
import com.geeksville.mesh.service.ConnectionState
import org.meshtastic.core.service.ConnectionState
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.TitledCard
import org.meshtastic.core.ui.theme.AppTheme

View file

@ -22,7 +22,6 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.geeksville.mesh.channelSet
import com.geeksville.mesh.model.Contact
import com.geeksville.mesh.service.ServiceRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
@ -37,6 +36,7 @@ import org.meshtastic.core.database.entity.Packet
import org.meshtastic.core.model.DataPacket
import org.meshtastic.core.model.util.getChannel
import org.meshtastic.core.model.util.getShortDate
import org.meshtastic.core.service.ServiceRepository
import org.meshtastic.core.strings.R
import javax.inject.Inject
import kotlin.collections.map

View file

@ -22,7 +22,6 @@ import androidx.annotation.StringRes
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.geeksville.mesh.MeshProtos
import com.geeksville.mesh.service.ServiceRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
@ -38,6 +37,7 @@ import org.meshtastic.core.database.entity.Packet
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.model.DataPacket
import org.meshtastic.core.prefs.map.MapPrefs
import org.meshtastic.core.service.ServiceRepository
import org.meshtastic.core.strings.R
import timber.log.Timber
import java.util.concurrent.TimeUnit

View file

@ -22,8 +22,6 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.geeksville.mesh.channelSet
import com.geeksville.mesh.service.MeshServiceNotifications
import com.geeksville.mesh.service.ServiceAction
import com.geeksville.mesh.service.ServiceRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
@ -43,6 +41,8 @@ import org.meshtastic.core.database.model.Message
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.model.DataPacket
import org.meshtastic.core.prefs.ui.UiPrefs
import org.meshtastic.core.service.ServiceAction
import org.meshtastic.core.service.ServiceRepository
import timber.log.Timber
import javax.inject.Inject

View file

@ -133,7 +133,6 @@ import com.geeksville.mesh.ConfigProtos
import com.geeksville.mesh.MeshProtos
import com.geeksville.mesh.model.MetricsState
import com.geeksville.mesh.model.MetricsViewModel
import com.geeksville.mesh.service.ServiceAction
import com.geeksville.mesh.ui.common.components.MainAppBar
import com.geeksville.mesh.ui.common.preview.NodePreviewParameterProvider
import com.geeksville.mesh.ui.node.components.NodeActionDialogs
@ -162,6 +161,7 @@ import org.meshtastic.core.model.util.toSpeedString
import org.meshtastic.core.navigation.NodeDetailRoutes
import org.meshtastic.core.navigation.Route
import org.meshtastic.core.navigation.SettingsRoutes
import org.meshtastic.core.service.ServiceAction
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.TitledCard
import org.meshtastic.core.ui.theme.AppTheme

View file

@ -20,8 +20,6 @@ package com.geeksville.mesh.ui.node
import android.os.RemoteException
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.geeksville.mesh.service.ServiceAction
import com.geeksville.mesh.service.ServiceRepository
import com.geeksville.mesh.ui.node.components.NodeMenuAction
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
@ -32,6 +30,8 @@ import kotlinx.coroutines.launch
import org.meshtastic.core.data.repository.NodeRepository
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.model.Position
import org.meshtastic.core.service.ServiceAction
import org.meshtastic.core.service.ServiceRepository
import timber.log.Timber
import javax.inject.Inject

View file

@ -60,7 +60,6 @@ import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.geeksville.mesh.AdminProtos
import com.geeksville.mesh.service.ConnectionState
import com.geeksville.mesh.ui.common.components.MainAppBar
import com.geeksville.mesh.ui.node.components.NodeActionDialogs
import com.geeksville.mesh.ui.node.components.NodeFilterTextField
@ -69,6 +68,7 @@ import com.geeksville.mesh.ui.sharing.AddContactFAB
import com.geeksville.mesh.ui.sharing.supportsQrCodeSharing
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.model.DeviceVersion
import org.meshtastic.core.service.ConnectionState
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.rememberTimeTickWithLifecycle
import org.meshtastic.core.ui.theme.StatusColors.StatusRed

View file

@ -21,8 +21,6 @@ import android.os.RemoteException
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.geeksville.mesh.AdminProtos
import com.geeksville.mesh.service.ServiceAction
import com.geeksville.mesh.service.ServiceRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
@ -40,6 +38,8 @@ import org.meshtastic.core.data.repository.RadioConfigRepository
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.database.model.NodeSortOption
import org.meshtastic.core.datastore.UiPreferencesDataSource
import org.meshtastic.core.service.ServiceAction
import org.meshtastic.core.service.ServiceRepository
import timber.log.Timber
import javax.inject.Inject

View file

@ -21,12 +21,10 @@ import android.app.Application
import android.net.Uri
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.geeksville.mesh.IMeshService
import com.geeksville.mesh.LocalOnlyProtos.LocalConfig
import com.geeksville.mesh.MeshProtos
import com.geeksville.mesh.Portnums
import com.geeksville.mesh.android.Logging
import com.geeksville.mesh.service.ServiceRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
@ -50,6 +48,8 @@ import org.meshtastic.core.datastore.UiPreferencesDataSource
import org.meshtastic.core.model.Position
import org.meshtastic.core.model.util.positionToMeter
import org.meshtastic.core.prefs.ui.UiPrefs
import org.meshtastic.core.service.IMeshService
import org.meshtastic.core.service.ServiceRepository
import java.io.BufferedWriter
import java.io.FileNotFoundException
import java.io.FileWriter

View file

@ -19,13 +19,13 @@ package com.geeksville.mesh.ui.settings.radio
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.geeksville.mesh.service.ServiceRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import org.meshtastic.core.data.repository.NodeRepository
import org.meshtastic.core.database.entity.NodeEntity
import org.meshtastic.core.service.ServiceRepository
import javax.inject.Inject
import kotlin.time.Duration.Companion.days
import kotlin.time.Duration.Companion.milliseconds

View file

@ -37,7 +37,6 @@ import com.geeksville.mesh.ChannelProtos
import com.geeksville.mesh.ClientOnlyProtos.DeviceProfile
import com.geeksville.mesh.ConfigProtos
import com.geeksville.mesh.ConfigProtos.Config.SecurityConfig
import com.geeksville.mesh.IMeshService
import com.geeksville.mesh.MeshProtos
import com.geeksville.mesh.ModuleConfigProtos
import com.geeksville.mesh.Portnums
@ -51,8 +50,6 @@ import com.geeksville.mesh.moduleConfig
import com.geeksville.mesh.navigation.ConfigRoute
import com.geeksville.mesh.navigation.ModuleRoute
import com.geeksville.mesh.repository.location.LocationRepository
import com.geeksville.mesh.service.ConnectionState
import com.geeksville.mesh.service.ServiceRepository
import com.geeksville.mesh.util.UiText
import com.google.protobuf.MessageLite
import dagger.hilt.android.lifecycle.HiltViewModel
@ -79,6 +76,9 @@ import org.meshtastic.core.model.util.toChannelSet
import org.meshtastic.core.navigation.SettingsRoutes
import org.meshtastic.core.prefs.analytics.AnalyticsPrefs
import org.meshtastic.core.prefs.map.MapConsentPrefs
import org.meshtastic.core.service.ConnectionState
import org.meshtastic.core.service.IMeshService
import org.meshtastic.core.service.ServiceRepository
import org.meshtastic.core.strings.R
import java.io.FileOutputStream
import javax.inject.Inject

View file

@ -98,7 +98,6 @@ import com.geeksville.mesh.copy
import com.geeksville.mesh.model.UIViewModel
import com.geeksville.mesh.navigation.ConfigRoute
import com.geeksville.mesh.navigation.getNavRouteFrom
import com.geeksville.mesh.service.ConnectionState
import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
import com.geeksville.mesh.ui.settings.radio.components.ChannelSelection
import com.geeksville.mesh.ui.settings.radio.components.PacketResponseStateDialog
@ -113,6 +112,7 @@ import org.meshtastic.core.model.util.getChannelUrl
import org.meshtastic.core.model.util.qrCode
import org.meshtastic.core.model.util.toChannelSet
import org.meshtastic.core.navigation.Route
import org.meshtastic.core.service.ConnectionState
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.AdaptiveTwoPane
import org.meshtastic.core.ui.component.PreferenceFooter