diff --git a/app/src/main/java/com/geeksville/mesh/DataPacket.kt b/app/src/main/java/com/geeksville/mesh/DataPacket.kt index b4a90780..2cc10d29 100644 --- a/app/src/main/java/com/geeksville/mesh/DataPacket.kt +++ b/app/src/main/java/com/geeksville/mesh/DataPacket.kt @@ -62,10 +62,11 @@ data class DataPacket( * If this is a text message, return the string, otherwise null */ val text: String? - get() = if (dataType == Portnums.PortNum.TEXT_MESSAGE_APP_VALUE) + get() = if (dataType == Portnums.PortNum.TEXT_MESSAGE_APP_VALUE) { bytes?.decodeToString() - else + } else { null + } constructor(to: String?, channel: Int, waypoint: MeshProtos.Waypoint) : this( to = to, @@ -75,10 +76,11 @@ data class DataPacket( ) val waypoint: MeshProtos.Waypoint? - get() = if (dataType == Portnums.PortNum.WAYPOINT_APP_VALUE) + get() = if (dataType == Portnums.PortNum.WAYPOINT_APP_VALUE) { MeshProtos.Waypoint.parseFrom(bytes) - else + } else { null + } // Autogenerated comparision, because we have a byte array @@ -142,7 +144,7 @@ data class DataPacket( return 0 } - /// Update our object from our parcel (used for inout parameters + // Update our object from our parcel (used for inout parameters fun readFromParcel(parcel: Parcel) { to = parcel.readString() parcel.createByteArray() @@ -164,7 +166,7 @@ data class DataPacket( /** The Node ID for the local node - used for from when sender doesn't know our local node ID */ const val ID_LOCAL = "^local" - /// special broadcast address + // special broadcast address const val NODENUM_BROADCAST = (0xffffffff).toInt() // Public-key cryptography (PKC) channel index @@ -181,4 +183,4 @@ data class DataPacket( return arrayOfNulls(size) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/geeksville/mesh/MainActivity.kt b/app/src/main/java/com/geeksville/mesh/MainActivity.kt index c9779772..b5f62c0b 100644 --- a/app/src/main/java/com/geeksville/mesh/MainActivity.kt +++ b/app/src/main/java/com/geeksville/mesh/MainActivity.kt @@ -212,7 +212,7 @@ class MainActivity : AppCompatActivity(), Logging { tab.icon = ContextCompat.getDrawable(this, tabInfos[position].icon) }.attach() - binding.tabLayout.addOnTabSelectedListener(object: TabLayout.OnTabSelectedListener { + binding.tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener { override fun onTabSelected(tab: TabLayout.Tab?) { val mainTab = tab?.position ?: 0 model.setCurrentTab(mainTab) @@ -254,7 +254,7 @@ class MainActivity : AppCompatActivity(), Logging { private var requestedChannelUrl: Uri? = null - /// Handle any itents that were passed into us + // Handle any intents that were passed into us private fun handleIntent(intent: Intent) { val appLinkAction = intent.action val appLinkData: Uri? = intent.data @@ -327,7 +327,7 @@ class MainActivity : AppCompatActivity(), Logging { showSettingsPage() // Default to the settings page in this case } - /// Called when we gain/lose a connection to our mesh radio + // Called when we gain/lose a connection to our mesh radio private fun onMeshConnectionChanged(newConnection: MeshService.ConnectionState) { if (newConnection == MeshService.ConnectionState.CONNECTED) { serviceRepository.meshService?.let { service -> @@ -336,17 +336,17 @@ class MainActivity : AppCompatActivity(), Logging { if (info != null) { val isOld = info.minAppVersion > BuildConfig.VERSION_CODE - if (isOld) + if (isOld) { showAlert(R.string.app_too_old, R.string.must_update) - else { + } else { // If we are already doing an update don't put up a dialog or try to get device info val isUpdating = service.updateStatus >= 0 if (!isUpdating) { val curVer = DeviceVersion(info.firmwareVersion ?: "0.0.0") - if (curVer < MeshService.minDeviceVersion) + if (curVer < MeshService.minDeviceVersion) { showAlert(R.string.firmware_too_old, R.string.firmware_old) - else { + } else { // If our app is too old/new, we probably don't understand the new DeviceConfig messages, so we don't read them until here // we have a connection to our device now, do the channel change @@ -359,8 +359,9 @@ class MainActivity : AppCompatActivity(), Logging { warn("Abandoning connect $ex, because we probably just lost device connection") } // if provideLocation enabled: Start providing location (from phone GPS) to mesh - if (model.provideLocation.value == true) + if (model.provideLocation.value == true) { service.startProvideLocation() + } } if (!hasNotificationPermission()) { @@ -406,9 +407,9 @@ class MainActivity : AppCompatActivity(), Logging { val channels = url.toChannelSet() val shouldAdd = url.shouldAddChannels() val primary = channels.primaryChannel - if (primary == null) + if (primary == null) { showSnackbar(R.string.channel_invalid) - else { + } else { val dialogMessage = if (!shouldAdd) { getString(R.string.do_you_want_switch).format(primary.name) } else { @@ -651,10 +652,11 @@ class MainActivity : AppCompatActivity(), Logging { handler.postDelayed({ postPing() }, 30000) } item.isChecked = !item.isChecked // toggle ping test - if (item.isChecked) + if (item.isChecked) { postPing() - else + } else { handler.removeCallbacksAndMessages(null) + } return true } R.id.radio_config -> { @@ -705,11 +707,11 @@ class MainActivity : AppCompatActivity(), Logging { } } - /// Theme functions + // Theme functions private fun chooseThemeDialog() { - /// Prepare dialog and its items + // Prepare dialog and its items val builder = MaterialAlertDialogBuilder(this) builder.setTitle(getString(R.string.choose_theme)) @@ -719,7 +721,7 @@ class MainActivity : AppCompatActivity(), Logging { getString(R.string.theme_system) to AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM ) - /// Load preferences and its value + // Load preferences and its value val prefs = UIViewModel.getPreferences(this) val theme = prefs.getInt("theme", AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) debug("Theme from prefs: $theme") @@ -740,13 +742,13 @@ class MainActivity : AppCompatActivity(), Logging { } private fun chooseLangDialog() { - /// Prepare dialog and its items + // Prepare dialog and its items val builder = MaterialAlertDialogBuilder(this) builder.setTitle(getString(R.string.preferences_language)) val languageTags = LanguageUtils.getLanguageTags(this) - /// Load preferences and its value + // Load preferences and its value val lang = LanguageUtils.getLocale() debug("Lang from prefs: $lang") diff --git a/app/src/main/java/com/geeksville/mesh/android/ContextServices.kt b/app/src/main/java/com/geeksville/mesh/android/ContextServices.kt index 9232bfba..551195ec 100644 --- a/app/src/main/java/com/geeksville/mesh/android/ContextServices.kt +++ b/app/src/main/java/com/geeksville/mesh/android/ContextServices.kt @@ -150,8 +150,9 @@ fun Context.hasLocationPermission() = getLocationPermissions().isEmpty() */ fun Context.getNotificationPermissions(): Array { val perms = mutableListOf() - if (android.os.Build.VERSION.SDK_INT >= 33) + if (android.os.Build.VERSION.SDK_INT >= 33) { perms.add(Manifest.permission.POST_NOTIFICATIONS) + } return getMissingPermissions(perms) } diff --git a/app/src/main/java/com/geeksville/mesh/android/ServiceClient.kt b/app/src/main/java/com/geeksville/mesh/android/ServiceClient.kt index daebfd5b..92370ccf 100644 --- a/app/src/main/java/com/geeksville/mesh/android/ServiceClient.kt +++ b/app/src/main/java/com/geeksville/mesh/android/ServiceClient.kt @@ -22,7 +22,7 @@ open class ServiceClient(private val stubFactory: (IBinder) -> T var serviceP: T? = null - /// A getter that returns the bound service or throws if not bound + // A getter that returns the bound service or throws if not bound val service: T get() { waitConnect() // Wait for at least the initial connection to happen @@ -40,11 +40,13 @@ open class ServiceClient(private val stubFactory: (IBinder) -> T fun waitConnect() { // Wait until this service is connected lock.withLock { - if (context == null) + if (context == null) { throw Exception("Haven't called connect") + } - if (serviceP == null) + if (serviceP == null) { condition.await() + } } } @@ -71,8 +73,7 @@ open class ServiceClient(private val stubFactory: (IBinder) -> T isClosed = true try { context?.unbindService(connection) - } - catch(ex: IllegalArgumentException) { + } catch (ex: IllegalArgumentException) { // Autobugs show this can generate an illegal arg exception for "service not registered" during reinstall? warn("Ignoring error in ServiceClient.close, probably harmless") } @@ -80,11 +81,11 @@ open class ServiceClient(private val stubFactory: (IBinder) -> T context = null } - /// Called when we become connected + // Called when we become connected open fun onConnected(service: T) { } - /// called on loss of connection + // called on loss of connection open fun onDisconnected() { } @@ -111,4 +112,4 @@ open class ServiceClient(private val stubFactory: (IBinder) -> T onDisconnected() } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/geeksville/mesh/concurrent/SyncContinuation.kt b/app/src/main/java/com/geeksville/mesh/concurrent/SyncContinuation.kt index 3e270a5f..f1f6d149 100644 --- a/app/src/main/java/com/geeksville/mesh/concurrent/SyncContinuation.kt +++ b/app/src/main/java/com/geeksville/mesh/concurrent/SyncContinuation.kt @@ -2,7 +2,6 @@ package com.geeksville.mesh.concurrent import com.geeksville.mesh.android.Logging - /** * A deferred execution object (with various possible implementations) */ @@ -52,15 +51,17 @@ class SyncContinuation : Continuation { while (result == null) { mbox.wait(timeoutMsecs) - if (timeoutMsecs > 0 && ((System.currentTimeMillis() - startT) >= timeoutMsecs)) + if (timeoutMsecs > 0 && ((System.currentTimeMillis() - startT) >= timeoutMsecs)) { throw Exception("SyncContinuation timeout") + } } val r = result - if (r != null) + if (r != null) { return r.getOrThrow() - else + } else { throw Exception("This shouldn't happen") + } } } } diff --git a/app/src/main/java/com/geeksville/mesh/database/MeshtasticDatabase.kt b/app/src/main/java/com/geeksville/mesh/database/MeshtasticDatabase.kt index fd7d8546..6a1542b2 100644 --- a/app/src/main/java/com/geeksville/mesh/database/MeshtasticDatabase.kt +++ b/app/src/main/java/com/geeksville/mesh/database/MeshtasticDatabase.kt @@ -29,15 +29,15 @@ import com.geeksville.mesh.database.entity.QuickChatAction QuickChatAction::class ], autoMigrations = [ - AutoMigration (from = 3, to = 4), - AutoMigration (from = 4, to = 5), - AutoMigration (from = 5, to = 6), - AutoMigration (from = 6, to = 7), - AutoMigration (from = 7, to = 8), - AutoMigration (from = 8, to = 9), - AutoMigration (from = 9, to = 10), - AutoMigration (from = 10, to = 11), - AutoMigration (from = 11, to = 12), + AutoMigration(from = 3, to = 4), + AutoMigration(from = 4, to = 5), + AutoMigration(from = 5, to = 6), + AutoMigration(from = 6, to = 7), + AutoMigration(from = 7, to = 8), + AutoMigration(from = 8, to = 9), + AutoMigration(from = 9, to = 10), + AutoMigration(from = 10, to = 11), + AutoMigration(from = 11, to = 12), AutoMigration(from = 12, to = 13, spec = AutoMigration12to13::class), ], version = 13, diff --git a/app/src/main/java/com/geeksville/mesh/database/dao/MeshLogDao.kt b/app/src/main/java/com/geeksville/mesh/database/dao/MeshLogDao.kt index ad82aca4..2ad412e7 100644 --- a/app/src/main/java/com/geeksville/mesh/database/dao/MeshLogDao.kt +++ b/app/src/main/java/com/geeksville/mesh/database/dao/MeshLogDao.kt @@ -29,5 +29,4 @@ interface MeshLogDao { @Query("DELETE FROM log") fun deleteAll() - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/geeksville/mesh/database/dao/PacketDao.kt b/app/src/main/java/com/geeksville/mesh/database/dao/PacketDao.kt index 50c79023..8b0ef8fc 100644 --- a/app/src/main/java/com/geeksville/mesh/database/dao/PacketDao.kt +++ b/app/src/main/java/com/geeksville/mesh/database/dao/PacketDao.kt @@ -164,7 +164,7 @@ interface PacketDao { fun getContactSettings(): Flow> @Query("SELECT * FROM contact_settings WHERE contact_key = :contact") - suspend fun getContactSettings(contact:String): ContactSettings? + suspend fun getContactSettings(contact: String): ContactSettings? @Upsert fun upsertContactSettings(contacts: List) diff --git a/app/src/main/java/com/geeksville/mesh/database/entity/NodeEntity.kt b/app/src/main/java/com/geeksville/mesh/database/entity/NodeEntity.kt index 1a11d890..70f08044 100644 --- a/app/src/main/java/com/geeksville/mesh/database/entity/NodeEntity.kt +++ b/app/src/main/java/com/geeksville/mesh/database/entity/NodeEntity.kt @@ -107,9 +107,9 @@ data class NodeEntity( val validPosition: MeshProtos.Position? get() = position.takeIf { hasValidPosition() } // @return distance in meters to some other node (or null if unknown) - fun distance(o: NodeEntity): Int? { - return if (validPosition == null || o.validPosition == null) null - else latLongToMeter(latitude, longitude, o.latitude, o.longitude).toInt() + fun distance(o: NodeEntity): Int? = when { + validPosition == null || o.validPosition == null -> null + else -> latLongToMeter(latitude, longitude, o.latitude, o.longitude).toInt() } // @return a nice human readable string for the distance, or null for unknown @@ -119,9 +119,9 @@ data class NodeEntity( } // @return bearing to the other position in degrees - fun bearing(o: NodeEntity?): Int? { - return if (validPosition == null || o?.validPosition == null) null - else bearing(latitude, longitude, o.latitude, o.longitude).toInt() + fun bearing(o: NodeEntity?): Int? = when { + validPosition == null || o?.validPosition == null -> null + else -> bearing(latitude, longitude, o.latitude, o.longitude).toInt() } fun gpsString(gpsFormat: Int): String = when (gpsFormat) { @@ -140,7 +140,9 @@ data class NodeEntity( } else { "%.1f°C".format(temperature) } - } else null + } else { + null + } val humidity = if (relativeHumidity != 0f) "%.0f%%".format(relativeHumidity) else null val pressure = if (barometricPressure != 0f) "%.1fhPa".format(barometricPressure) else null val gas = if (gasResistance != 0f) "%.0fMΩ".format(gasResistance) else null @@ -188,7 +190,7 @@ data class NodeEntity( } companion object { - /// Convert to a double representation of degrees + // Convert to a double representation of degrees fun degD(i: Int) = i * 1e-7 fun degI(d: Double) = (d * 1e7).toInt() diff --git a/app/src/main/java/com/geeksville/mesh/database/entity/QuickChatAction.kt b/app/src/main/java/com/geeksville/mesh/database/entity/QuickChatAction.kt index 8ca16ff7..5f88ae77 100644 --- a/app/src/main/java/com/geeksville/mesh/database/entity/QuickChatAction.kt +++ b/app/src/main/java/com/geeksville/mesh/database/entity/QuickChatAction.kt @@ -7,12 +7,13 @@ import androidx.room.PrimaryKey @Entity(tableName = "quick_chat") data class QuickChatAction( @PrimaryKey(autoGenerate = true) val uuid: Long, - @ColumnInfo(name="name") val name: String, - @ColumnInfo(name="message") val message: String, - @ColumnInfo(name="mode") val mode: Mode, - @ColumnInfo(name="position") val position: Int) { + @ColumnInfo(name = "name") val name: String, + @ColumnInfo(name = "message") val message: String, + @ColumnInfo(name = "mode") val mode: Mode, + @ColumnInfo(name = "position") val position: Int +) { enum class Mode { Append, Instant, } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/geeksville/mesh/model/Channel.kt b/app/src/main/java/com/geeksville/mesh/model/Channel.kt index 99bd6b7a..71407471 100644 --- a/app/src/main/java/com/geeksville/mesh/model/Channel.kt +++ b/app/src/main/java/com/geeksville/mesh/model/Channel.kt @@ -47,7 +47,7 @@ data class Channel( } } - /// Return the name of our channel as a human readable string. If empty string, assume "Default" per mesh.proto spec + // Return the name of our channel as a human readable string. If empty string, assume "Default" per mesh.proto spec val name: String get() = settings.name.ifEmpty { // We have a new style 'empty' channel name. Use the same logic from the device to convert that to a human readable name @@ -66,15 +66,15 @@ data class Channel( } val psk: ByteString - get() = if (settings.psk.size() != 1) + get() = if (settings.psk.size() != 1) { settings.psk // A standard PSK - else { + } else { // One of our special 1 byte PSKs, see mesh.proto for docs. val pskIndex = settings.psk.byteAt(0).toInt() - if (pskIndex == 0) + if (pskIndex == 0) { cleartextPSK - else { + } else { // Treat an index of 1 as the old channelDefaultKey and work up from there val bytes = channelDefaultKey.clone() bytes[bytes.size - 1] = (0xff and (bytes[bytes.size - 1] + pskIndex - 1)).toByte() diff --git a/app/src/main/java/com/geeksville/mesh/model/ChannelOption.kt b/app/src/main/java/com/geeksville/mesh/model/ChannelOption.kt index 9d277303..4802b666 100644 --- a/app/src/main/java/com/geeksville/mesh/model/ChannelOption.kt +++ b/app/src/main/java/com/geeksville/mesh/model/ChannelOption.kt @@ -40,8 +40,9 @@ private fun LoRaConfig.bandwidth() = if (usePreset) { val LoRaConfig.numChannels: Int get() { for (option in RegionInfo.entries) { - if (option.regionCode == region) + if (option.regionCode == region) { return ((option.freqEnd - option.freqStart) / bandwidth()).toInt() + } } return 0 } @@ -55,8 +56,9 @@ internal fun LoRaConfig.channelNum(primaryName: String): Int = when { internal fun LoRaConfig.radioFreq(channelNum: Int): Float { if (overrideFrequency != 0f) return overrideFrequency + frequencyOffset for (option in RegionInfo.entries) { - if (option.regionCode == region) + if (option.regionCode == region) { return (option.freqStart + bandwidth() / 2) + (channelNum - 1) * bandwidth() + } } return 0f } @@ -103,5 +105,4 @@ enum class ChannelOption( LONG_MODERATE(ModemPreset.LONG_MODERATE, R.string.modem_config_mod_long, .125f), LONG_SLOW(ModemPreset.LONG_SLOW, R.string.modem_config_slow_long, .125f), VERY_LONG_SLOW(ModemPreset.VERY_LONG_SLOW, R.string.modem_config_very_long, .0625f), - ; } diff --git a/app/src/main/java/com/geeksville/mesh/model/RadioConfigViewModel.kt b/app/src/main/java/com/geeksville/mesh/model/RadioConfigViewModel.kt index 64e1b83c..112d0940 100644 --- a/app/src/main/java/com/geeksville/mesh/model/RadioConfigViewModel.kt +++ b/app/src/main/java/com/geeksville/mesh/model/RadioConfigViewModel.kt @@ -469,8 +469,11 @@ class RadioConfigViewModel @Inject constructor( setResponseStateError(app.getString(parsed.errorReason.stringRes)) } else if (packet.from == destNum && route.isEmpty()) { requestIds.update { it.apply { remove(data.requestId) } } - if (requestIds.value.isEmpty()) setResponseStateSuccess() - else incrementCompleted() + if (requestIds.value.isEmpty()) { + setResponseStateSuccess() + } else { + incrementCompleted() + } } } if (data?.portnumValue == Portnums.PortNum.ADMIN_APP_VALUE) { diff --git a/app/src/main/java/com/geeksville/mesh/model/UIState.kt b/app/src/main/java/com/geeksville/mesh/model/UIState.kt index b15f9103..67cc3ef7 100644 --- a/app/src/main/java/com/geeksville/mesh/model/UIState.kt +++ b/app/src/main/java/com/geeksville/mesh/model/UIState.kt @@ -58,10 +58,10 @@ import java.util.concurrent.TimeUnit import javax.inject.Inject import kotlin.math.roundToInt -// / Given a human name, strip out the first letter of the first three words and return that as the initials for -// / that user. If the original name is only one word, strip vowels from the original name and if the result is -// / 3 or more characters, use the first three characters. If not, just take the first 3 characters of the -// / original name. +// Given a human name, strip out the first letter of the first three words and return that as the initials for +// that user. If the original name is only one word, strip vowels from the original name and if the result is +// 3 or more characters, use the first three characters. If not, just take the first 3 characters of the +// original name. fun getInitials(nameIn: String): String { val nchars = 4 val minchars = 2 @@ -70,10 +70,11 @@ fun getInitials(nameIn: String): String { val initials = when (words.size) { in 0 until minchars -> { - val nm = if (name.isNotEmpty()) + val nm = if (name.isNotEmpty()) { name.first() + name.drop(1).filterNot { c -> c.lowercase() in "aeiou" } - else + } else { "" + } if (nm.length >= nchars) nm else name } else -> words.map { it.first() }.joinToString("") @@ -414,7 +415,7 @@ class UIViewModel @Inject constructor( fun requestUserInfo(destNum: Int) { info("Requesting UserInfo for '$destNum'") try { - meshService?.requestUserInfo( destNum ) + meshService?.requestUserInfo(destNum) } catch (ex: RemoteException) { errormsg("Request NodeInfo error: ${ex.message}") } @@ -545,7 +546,7 @@ class UIViewModel @Inject constructor( fun setChannels(channelSet: AppOnlyProtos.ChannelSet, overwrite: Boolean = true) = viewModelScope.launch { val newRadioSettings: List = if (overwrite) { channelSet.settingsList - } else { + } else { // To guarantee consistent ordering, using a LinkedHashSet which iterates through it's // entries according to the order an item was *first* inserted. // https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-linked-hash-set/ diff --git a/app/src/main/java/com/geeksville/mesh/model/map/MarkerWithLabel.kt b/app/src/main/java/com/geeksville/mesh/model/map/MarkerWithLabel.kt index bf779a48..33b2ba00 100644 --- a/app/src/main/java/com/geeksville/mesh/model/map/MarkerWithLabel.kt +++ b/app/src/main/java/com/geeksville/mesh/model/map/MarkerWithLabel.kt @@ -43,7 +43,6 @@ class MarkerWithLabel(mapView: MapView?, label: String, emoji: String? = null) : } } - private var onLongClickListener: (() -> Boolean)? = null fun setOnLongClickListener(listener: () -> Boolean) { @@ -93,7 +92,7 @@ class MarkerWithLabel(mapView: MapView?, label: String, emoji: String? = null) : val bgRect = getTextBackgroundSize(mLabel, (p.x - 0F), (p.y - LABEL_Y_OFFSET)) bgRect.inset(-8F, -2F) - if(mLabel.isNotEmpty()) { + if (mLabel.isNotEmpty()) { c.drawRoundRect(bgRect, LABEL_CORNER_RADIUS, LABEL_CORNER_RADIUS, bgPaint) c.drawText(mLabel, (p.x - 0F), (p.y - LABEL_Y_OFFSET), textPaint) } diff --git a/app/src/main/java/com/geeksville/mesh/repository/radio/BluetoothInterfaceSpec.kt b/app/src/main/java/com/geeksville/mesh/repository/radio/BluetoothInterfaceSpec.kt index e055820c..1ed16ddb 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/radio/BluetoothInterfaceSpec.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/radio/BluetoothInterfaceSpec.kt @@ -11,7 +11,7 @@ import javax.inject.Inject class BluetoothInterfaceSpec @Inject constructor( private val factory: BluetoothInterfaceFactory, private val bluetoothRepository: BluetoothRepository, -): InterfaceSpec, Logging { +) : InterfaceSpec, Logging { override fun createInterface(rest: String): BluetoothInterface { return factory.create(rest) } @@ -23,7 +23,8 @@ class BluetoothInterfaceSpec @Inject constructor( return if (!allPaired.contains(rest)) { warn("Ignoring stale bond to ${rest.anonymize}") false - } else + } else { true + } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/geeksville/mesh/repository/radio/InterfaceFactory.kt b/app/src/main/java/com/geeksville/mesh/repository/radio/InterfaceFactory.kt index 9faf8e07..2845675e 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/radio/InterfaceFactory.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/radio/InterfaceFactory.kt @@ -12,7 +12,7 @@ import javax.inject.Provider class InterfaceFactory @Inject constructor( private val nopInterfaceFactory: NopInterfaceFactory, private val specMap: Map>> -) { +) { internal val nopInterface by lazy { nopInterfaceFactory.create("") } @@ -38,4 +38,4 @@ class InterfaceFactory @Inject constructor( val rest = address.substring(1) return Pair(c, rest) } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/geeksville/mesh/repository/radio/InterfaceFactorySpi.kt b/app/src/main/java/com/geeksville/mesh/repository/radio/InterfaceFactorySpi.kt index 69e673b8..320b06c1 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/radio/InterfaceFactorySpi.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/radio/InterfaceFactorySpi.kt @@ -9,6 +9,6 @@ package com.geeksville.mesh.repository.radio * This is primarily used in conjunction with Dagger assisted injection for each backend * interface type. */ -interface InterfaceFactorySpi { +interface InterfaceFactorySpi { fun create(rest: String): T -} \ No newline at end of file +} diff --git a/app/src/main/java/com/geeksville/mesh/repository/radio/MockInterfaceSpec.kt b/app/src/main/java/com/geeksville/mesh/repository/radio/MockInterfaceSpec.kt index 726911ce..e726464f 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/radio/MockInterfaceSpec.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/radio/MockInterfaceSpec.kt @@ -7,7 +7,7 @@ import javax.inject.Inject */ class MockInterfaceSpec @Inject constructor( private val factory: MockInterfaceFactory -): InterfaceSpec { +) : InterfaceSpec { override fun createInterface(rest: String): MockInterface { return factory.create(rest) } diff --git a/app/src/main/java/com/geeksville/mesh/repository/radio/NopInterfaceSpec.kt b/app/src/main/java/com/geeksville/mesh/repository/radio/NopInterfaceSpec.kt index 50de0f61..e711e884 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/radio/NopInterfaceSpec.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/radio/NopInterfaceSpec.kt @@ -7,8 +7,8 @@ import javax.inject.Inject */ class NopInterfaceSpec @Inject constructor( private val factory: NopInterfaceFactory -): InterfaceSpec { +) : InterfaceSpec { override fun createInterface(rest: String): NopInterface { return factory.create(rest) } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/geeksville/mesh/repository/radio/RadioInterfaceService.kt b/app/src/main/java/com/geeksville/mesh/repository/radio/RadioInterfaceService.kt index 03df22c2..3f36f614 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/radio/RadioInterfaceService.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/radio/RadioInterfaceService.kt @@ -30,7 +30,6 @@ import kotlinx.coroutines.launch import javax.inject.Inject import javax.inject.Singleton - /** * Handles the bluetooth link with a mesh radio device. Does not cache any device state, * just does bluetooth comms etc... @@ -79,7 +78,7 @@ class RadioInterfaceService @Inject constructor( */ private var isStarted = false - /// true if our interface is currently connected to a device + // true if our interface is currently connected to a device private var isConnected = false private fun initStateListeners() { @@ -156,7 +155,7 @@ class RadioInterfaceService @Inject constructor( } } - /// Send a packet/command out the radio link, this routine can block if it needs to + // Send a packet/command out the radio link, this routine can block if it needs to private fun handleSendToRadio(p: ByteArray) { radioIf.handleSendToRadio(p) } @@ -191,20 +190,22 @@ class RadioInterfaceService @Inject constructor( /** Start our configured interface (if it isn't already running) */ private fun startInterface() { - if (radioIf !is NopInterface) + if (radioIf !is NopInterface) { warn("Can't start interface - $radioIf is already running") - else { + } else { val address = getBondedDeviceAddress() - if (address == null) + if (address == null) { warn("No bonded mesh radio, can't start interface") - else { + } else { info("Starting radio ${address.anonymize}") isStarted = true - if (logSends) + if (logSends) { sentPacketsLog = BinaryLogFile(context, "sent_log.pb") - if (logReceives) + } + if (logReceives) { receivedPacketsLog = BinaryLogFile(context, "receive_log.pb") + } radioIf = interfaceFactory.createInterface(address) } @@ -222,17 +223,19 @@ class RadioInterfaceService @Inject constructor( serviceScope.cancel("stopping interface") serviceScope = CoroutineScope(Dispatchers.IO + Job()) - if (logSends) + if (logSends) { sentPacketsLog.close() - if (logReceives) + } + if (logReceives) { receivedPacketsLog.close() + } // Don't broadcast disconnects if we were just using the nop device - if (r !is NopInterface) + if (r !is NopInterface) { onDisconnect(isPermanent = true) // Tell any clients we are now offline + } } - /** * Change to a new device * @@ -258,10 +261,11 @@ class RadioInterfaceService @Inject constructor( debug("Setting bonded device to ${address.anonymize}") prefs.edit { - if (address == null) + if (address == null) { this.remove(DEVADDR_KEY) - else + } else { putString(DEVADDR_KEY, address) + } } // Force the service to reconnect diff --git a/app/src/main/java/com/geeksville/mesh/repository/radio/SerialInterfaceSpec.kt b/app/src/main/java/com/geeksville/mesh/repository/radio/SerialInterfaceSpec.kt index 170694ef..620b6012 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/radio/SerialInterfaceSpec.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/radio/SerialInterfaceSpec.kt @@ -12,7 +12,7 @@ class SerialInterfaceSpec @Inject constructor( private val factory: SerialInterfaceFactory, private val usbManager: dagger.Lazy, private val usbRepository: UsbRepository, -): InterfaceSpec { +) : InterfaceSpec { override fun createInterface(rest: String): SerialInterface { return factory.create(rest) } @@ -37,4 +37,4 @@ class SerialInterfaceSpec @Inject constructor( deviceMap.map { (_, driver) -> driver }.firstOrNull() } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/geeksville/mesh/repository/radio/StreamInterface.kt b/app/src/main/java/com/geeksville/mesh/repository/radio/StreamInterface.kt index bbe862db..9e947ddc 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/radio/StreamInterface.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/radio/StreamInterface.kt @@ -2,7 +2,6 @@ package com.geeksville.mesh.repository.radio import com.geeksville.mesh.android.Logging - /** * An interface that assumes we are talking to a meshtastic device over some sort of stream connection (serial or TCP probably) */ @@ -49,7 +48,7 @@ abstract class StreamInterface(protected val service: RadioInterfaceService) : abstract fun sendBytes(p: ByteArray) - /// If subclasses need to flash at the end of a packet they can implement + // If subclasses need to flash at the end of a packet they can implement open fun flushBytes() {} override fun handleSendToRadio(p: ByteArray) { @@ -66,7 +65,6 @@ abstract class StreamInterface(protected val service: RadioInterfaceService) : flushBytes() } - /** Print device serial debug output somewhere */ private fun debugOut(b: Byte) { when (val c = b.toChar()) { @@ -92,7 +90,7 @@ abstract class StreamInterface(protected val service: RadioInterfaceService) : nextPtr = 0 } - /// Deliver our current packet and restart our reader + // Deliver our current packet and restart our reader fun deliverPacket() { val buf = rxPacket.copyOf(packetLen) service.handleFromRadio(buf) @@ -107,8 +105,9 @@ abstract class StreamInterface(protected val service: RadioInterfaceService) : nextPtr = 0 // Restart from scratch } 1 -> // Looking for START2 - if (c != START2) + if (c != START2) { lostSync() // Restart from scratch + } 2 -> // Looking for MSB of our 16 bit length msb = c.toInt() and 0xff 3 -> { // Looking for LSB of our 16 bit length @@ -116,10 +115,11 @@ abstract class StreamInterface(protected val service: RadioInterfaceService) : // We've read our header, do one big read for the packet itself packetLen = (msb shl 8) or lsb - if (packetLen > MAX_TO_FROM_RADIO_SIZE) - lostSync() // If packet len is too long, the bytes must have been corrupted, start looking for START1 again - else if (packetLen == 0) + if (packetLen > MAX_TO_FROM_RADIO_SIZE) { + lostSync() // If packet len is too long, the bytes must have been corrupted, start looking for START1 again + } else if (packetLen == 0) { deliverPacket() // zero length packets are valid and should be delivered immediately (because there won't be a next byte of payload) + } } else -> { // We are looking at the packet bytes now @@ -133,4 +133,4 @@ abstract class StreamInterface(protected val service: RadioInterfaceService) : } ptr = nextPtr } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/geeksville/mesh/repository/radio/TCPInterfaceSpec.kt b/app/src/main/java/com/geeksville/mesh/repository/radio/TCPInterfaceSpec.kt index f92e3def..651699b6 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/radio/TCPInterfaceSpec.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/radio/TCPInterfaceSpec.kt @@ -7,8 +7,8 @@ import javax.inject.Inject */ class TCPInterfaceSpec @Inject constructor( private val factory: TCPInterfaceFactory -): InterfaceSpec { +) : InterfaceSpec { override fun createInterface(rest: String): TCPInterface { return factory.create(rest) } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/geeksville/mesh/repository/usb/SerialConnectionImpl.kt b/app/src/main/java/com/geeksville/mesh/repository/usb/SerialConnectionImpl.kt index 271a5ff2..70641934 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/usb/SerialConnectionImpl.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/usb/SerialConnectionImpl.kt @@ -16,7 +16,7 @@ internal class SerialConnectionImpl( private val device: UsbSerialDriver, private val listener: SerialConnectionListener ) : SerialConnection, Logging { - private val port = device.ports[0] // Most devices have just one port (port 0) + private val port = device.ports[0] // Most devices have just one port (port 0) private val closedLatch = CountDownLatch(1) private val closed = AtomicBoolean(false) private val ioRef = AtomicReference() @@ -80,7 +80,7 @@ internal class SerialConnectionImpl( listener.onDisconnected(e) } }).apply { - readTimeout = 200 // To save battery we only timeout ever so often + readTimeout = 200 // To save battery we only timeout ever so often ioRef.set(this) } @@ -92,4 +92,4 @@ internal class SerialConnectionImpl( listener.onConnected() } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/geeksville/mesh/repository/usb/UsbRepository.kt b/app/src/main/java/com/geeksville/mesh/repository/usb/UsbRepository.kt index 9040b6f4..0d3b863d 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/usb/UsbRepository.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/usb/UsbRepository.kt @@ -38,7 +38,7 @@ class UsbRepository @Inject constructor( @Suppress("unused") // Retained as public API val serialDevicesWithDrivers = _serialDevices - .mapLatest { serialDevices -> + .mapLatest { serialDevices -> val serialProber = usbSerialProberLazy.get() buildMap { serialDevices.forEach { (k, v) -> @@ -72,7 +72,7 @@ class UsbRepository @Inject constructor( * Creates a USB serial connection to the specified USB device. State changes and data arrival * result in async callbacks on the supplied listener. */ - fun createSerialConnection(device: UsbSerialDriver, listener: SerialConnectionListener) : SerialConnection { + fun createSerialConnection(device: UsbSerialDriver, listener: SerialConnectionListener): SerialConnection { return SerialConnectionImpl(usbManagerLazy, device, listener) } @@ -88,4 +88,4 @@ class UsbRepository @Inject constructor( private suspend fun refreshStateInternal() = withContext(dispatchers.default) { _serialDevices.emit(usbManagerLazy.get()?.deviceList ?: emptyMap()) } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt index c255986c..fb758839 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -88,11 +88,11 @@ class MeshService : Service(), Logging { companion object : Logging { - /// Intents broadcast by MeshService + // Intents broadcast by MeshService private fun actionReceived(portNum: String) = "$prefix.RECEIVED.$portNum" - /// generate a RECEIVED action filter string that includes either the portnumber as an int, or preferably a symbolic name from portnums.proto + // generate a RECEIVED action filter string that includes either the portnumber as an int, or preferably a symbolic name from portnums.proto fun actionReceived(portNum: Int): String { val portType = Portnums.PortNum.forNumber(portNum) val portStr = portType?.toString() ?: portNum.toString() @@ -141,7 +141,7 @@ class MeshService : Service(), Logging { private var previousSummary: String? = null private var previousStats: LocalStats? = null - /// A mapping of receiver class name to package name - used for explicit broadcasts + // A mapping of receiver class name to package name - used for explicit broadcasts private val clientPackages = mutableMapOf() private val serviceNotifications = MeshServiceNotifications(this) private val serviceBroadcasts = MeshServiceBroadcasts(this, clientPackages) { @@ -337,9 +337,9 @@ class MeshService : Service(), Logging { serviceJob.cancel() } - /// - /// BEGINNING OF MODEL - FIXME, move elsewhere - /// + // + // BEGINNING OF MODEL - FIXME, move elsewhere + // private fun loadSettings() { discardNodeDB() // Get rid of any old state @@ -368,7 +368,7 @@ class MeshService : Service(), Logging { private var moduleConfig: LocalModuleConfig = LocalModuleConfig.getDefaultInstance() private var channelSet: AppOnlyProtos.ChannelSet = AppOnlyProtos.ChannelSet.getDefaultInstance() - /// True after we've done our initial node db init + // True after we've done our initial node db init @Volatile private var haveNodeDB = false @@ -379,15 +379,15 @@ class MeshService : Service(), Logging { // NOTE: some NodeInfos might be in only nodeDBbyNodeNum (because we don't yet know an ID). private val nodeDBbyID get() = nodeDBbyNodeNum.mapKeys { it.value.user.id } - /// - /// END OF MODEL - /// + // + // END OF MODEL + // private val deviceVersion get() = DeviceVersion(myNodeInfo?.firmwareVersion ?: "") private val appVersion get() = BuildConfig.VERSION_CODE private val minAppVersion get() = myNodeInfo?.minAppVersion ?: 0 - /// Map a nodenum to a node, or throw an exception if not found + // Map a nodenum to a node, or throw an exception if not found private fun toNodeInfo(n: Int) = nodeDBbyNodeNum[n] ?: throw NodeNumNotFoundException(n) /** Map a nodeNum to the nodeId string @@ -395,8 +395,11 @@ class MeshService : Service(), Logging { but some nodes might not have a user record at all (because not yet received), in that case, we return a hex version of the ID just based on the number */ private fun toNodeID(n: Int): String = - if (n == DataPacket.NODENUM_BROADCAST) DataPacket.ID_BROADCAST - else nodeDBbyNodeNum[n]?.user?.id ?: DataPacket.nodeNumToDefaultId(n) + if (n == DataPacket.NODENUM_BROADCAST) { + DataPacket.ID_BROADCAST + } else { + nodeDBbyNodeNum[n]?.user?.id ?: DataPacket.nodeNumToDefaultId(n) + } // given a nodeNum, return a db entry - creating if necessary private fun getOrCreateNodeInfo(n: Int) = nodeDBbyNodeNum.getOrPut(n) { @@ -418,8 +421,8 @@ class MeshService : Service(), Logging { private val hexIdRegex = """\!([0-9A-Fa-f]+)""".toRegex() private val rangeTestRegex = Regex("seq (\\d{1,10})") - /// Map a userid to a node/ node num, or throw an exception if not found - /// We prefer to find nodes based on their assigned IDs, but if no ID has been assigned to a node, we can also find it based on node number + // Map a userid to a node/ node num, or throw an exception if not found + // We prefer to find nodes based on their assigned IDs, but if no ID has been assigned to a node, we can also find it based on node number private fun toNodeInfo(id: String): NodeEntity { // If this is a valid hexaddr will be !null val hexStr = hexIdRegex.matchEntire(id)?.groups?.get(1)?.value @@ -454,7 +457,7 @@ class MeshService : Service(), Logging { else -> toNodeInfo(id).num } - /// A helper function that makes it easy to update node info objects + // A helper function that makes it easy to update node info objects private inline fun updateNodeInfo( nodeNum: Int, withBroadcast: Boolean = true, @@ -463,25 +466,26 @@ class MeshService : Service(), Logging { val info = getOrCreateNodeInfo(nodeNum) updateFn(info) - if (info.user.id.isNotEmpty()) { - if (haveNodeDB) serviceScope.handledLaunch { + if (info.user.id.isNotEmpty() && haveNodeDB) { + serviceScope.handledLaunch { radioConfigRepository.upsert(info) } } - if (withBroadcast) + if (withBroadcast) { serviceBroadcasts.broadcastNodeChange(info.toNodeInfo()) + } } - /// My node num + // My node num private val myNodeNum get() = myNodeInfo?.myNodeNum ?: throw RadioNotConnectedException("We don't yet have our myNodeInfo") - /// My node ID string + // My node ID string private val myNodeID get() = toNodeID(myNodeNum) - /// Admin channel index + // Admin channel index private val MeshPacket.Builder.adminChannelIndex: Int get() = when { myNodeNum == to -> 0 @@ -493,10 +497,11 @@ class MeshService : Service(), Logging { .coerceAtLeast(0) } - /// Generate a new mesh packet builder with our node as the sender, and the specified node num + // Generate a new mesh packet builder with our node as the sender, and the specified node num private fun newMeshPacketTo(idNum: Int) = MeshPacket.newBuilder().apply { - if (myNodeInfo == null) + if (myNodeInfo == null) { throw RadioNotConnectedException() + } from = 0 // don't add myNodeNum @@ -540,7 +545,6 @@ class MeshService : Service(), Logging { return build() } - /** * Helper to make it easy to build a subpacket in the proper protobufs */ @@ -562,7 +566,7 @@ class MeshService : Service(), Logging { }.build().toByteString() } - /// Generate a DataPacket from a MeshPacket, or null if we didn't have enough data to do so + // Generate a DataPacket from a MeshPacket, or null if we didn't have enough data to do so private fun toDataPacket(packet: MeshPacket): DataPacket? { return if (!packet.hasDecoded()) { // We never convert packets that are not DataPackets @@ -631,7 +635,7 @@ class MeshService : Service(), Logging { } } - /// Update our model and resend as needed for a MeshPacket we just received from the radio + // Update our model and resend as needed for a MeshPacket we just received from the radio private fun handleReceivedData(packet: MeshPacket) { myNodeInfo?.let { myInfo -> val data = packet.decoded @@ -650,7 +654,7 @@ class MeshService : Service(), Logging { // if (p.hasUser()) handleReceivedUser(fromNum, p.user) - /// We tell other apps about most message types, but some may have sensitve data, so that is not shared' + // We tell other apps about most message types, but some may have sensitive data, so that is not shared' var shouldBroadcast = !fromUs when (data.portnumValue) { @@ -747,8 +751,9 @@ class MeshService : Service(), Logging { } // We always tell other apps when new data packets arrive - if (shouldBroadcast) + if (shouldBroadcast) { serviceBroadcasts.broadcastReceivedData(dataPacket) + } GeeksvilleApplication.analytics.track( "num_data_receive", @@ -784,9 +789,7 @@ class MeshService : Service(), Logging { } } } - else -> - warn("No special processing needed for ${a.payloadVariantCase}") - + else -> warn("No special processing needed for ${a.payloadVariantCase}") } } else { debug("Admin: Received session_passkey from $fromNodeNum") @@ -794,7 +797,7 @@ class MeshService : Service(), Logging { } } - /// Update our DB of users based on someone sending out a User subpacket + // Update our DB of users based on someone sending out a User subpacket private fun handleReceivedUser(fromNum: Int, p: MeshProtos.User, channel: Int = 0) { updateNodeInfo(fromNum) { val keyMatch = !it.hasPKC || it.user.publicKey == p.publicKey @@ -829,20 +832,14 @@ class MeshService : Service(), Logging { } } - - private fun handleLocalStats(stats: TelemetryProtos.Telemetry) { - localStatsTelemetry = stats - maybeUpdateServiceStatusNotification() - } - - - /// Update our DB of users based on someone sending out a Telemetry subpacket + // Update our DB of users based on someone sending out a Telemetry subpacket private fun handleReceivedTelemetry( fromNum: Int, t: TelemetryProtos.Telemetry, ) { if (t.hasLocalStats()) { - handleLocalStats(t) + localStatsTelemetry = t + maybeUpdateServiceStatusNotification() } updateNodeInfo(fromNum) { when { @@ -903,7 +900,9 @@ class MeshService : Service(), Logging { private fun formatTraceroutePath(nodesList: List, snrList: List): String { // nodesList should include both origin and destination nodes // origin will not have an SNR value, but destination should - val snrStr = if (snrList.size == nodesList.size - 1) snrList else { + val snrStr = if (snrList.size == nodesList.size - 1) { + snrList + } else { // use unknown SNR for entire route if snrList has invalid size List(nodesList.size - 1) { -128 } }.map { snr -> @@ -914,7 +913,7 @@ class MeshService : Service(), Logging { return nodesList.map { nodeId -> "■ ${getUserName(nodeId)}" }.flatMapIndexed { i, nodeStr -> - if (i == 0) listOf(nodeStr) else listOf(snrStr[i-1], nodeStr) + if (i == 0) listOf(nodeStr) else listOf(snrStr[i - 1], nodeStr) }.joinToString("\n") } @@ -945,15 +944,15 @@ class MeshService : Service(), Logging { // If apps try to send packets when our radio is sleeping, we queue them here instead private val offlineSentPackets = mutableListOf() - /// Update our model and resend as needed for a MeshPacket we just received from the radio + // Update our model and resend as needed for a MeshPacket we just received from the radio private fun handleReceivedMeshPacket(packet: MeshPacket) { if (haveNodeDB) { processReceivedMeshPacket(packet) onNodeDBChanged() } else { warn("Ignoring early received packet: ${packet.toOneLineString()}") - //earlyReceivedPackets.add(packet) - //logAssert(earlyReceivedPackets.size < 128) // The max should normally be about 32, but if the device is messed up it might try to send forever + // earlyReceivedPackets.add(packet) + // logAssert(earlyReceivedPackets.size < 128) // The max should normally be about 32, but if the device is messed up it might try to send forever } } @@ -1072,13 +1071,13 @@ class MeshService : Service(), Logging { } } - /// Update our model and resend as needed for a MeshPacket we just received from the radio + // Update our model and resend as needed for a MeshPacket we just received from the radio private fun processReceivedMeshPacket(packet: MeshPacket) { val fromNum = packet.from // FIXME, perhaps we could learn our node ID by looking at any to packets the radio // decided to pass through to us (except for broadcast packets) - //val toNum = packet.to + // val toNum = packet.to // debug("Recieved: $packet") if (packet.hasDecoded()) { @@ -1160,8 +1159,7 @@ class MeshService : Service(), Logging { private fun currentSecond() = (System.currentTimeMillis() / 1000).toInt() - - /// If we just changed our nodedb, we might want to do somethings + // If we just changed our nodedb, we might want to do somethings private fun onNodeDBChanged() { maybeUpdateServiceStatusNotification() } @@ -1189,14 +1187,14 @@ class MeshService : Service(), Logging { private var sleepTimeout: Job? = null - /// msecs since 1970 we started this connection + // msecs since 1970 we started this connection private var connectTimeMsec = 0L - /// Called when we gain/lose connection to our radio + // Called when we gain/lose connection to our radio private fun onConnectionChanged(c: ConnectionState) { debug("onConnectionChanged: $connectionState -> $c") - /// Perform all the steps needed once we start waiting for device sleep to complete + // Perform all the steps needed once we start waiting for device sleep to complete fun startDeviceSleep() { stopPacketQueue() stopLocationRequests() @@ -1355,13 +1353,13 @@ class MeshService : Service(), Logging { } } - /// A provisional MyNodeInfo that we will install if all of our node config downloads go okay + // A provisional MyNodeInfo that we will install if all of our node config downloads go okay private var newMyNodeInfo: MyNodeEntity? = null - /// provisional NodeInfos we will install if all goes well + // provisional NodeInfos we will install if all goes well private val newNodes = mutableListOf() - /// Used to make sure we never get foold by old BLE packets + // Used to make sure we never get foold by old BLE packets private var configNonce = 1 private fun handleDeviceConfig(config: ConfigProtos.Config) { @@ -1400,8 +1398,11 @@ class MeshService : Service(), Logging { Triple(res == 0, free == 0, meshPacketId) } if (success && isFull) return // Queue is full, wait for free != 0 - if (requestId != 0) queueResponse.remove(requestId)?.complete(success) - else queueResponse.entries.lastOrNull { !it.value.isDone }?.value?.complete(success) + if (requestId != 0) { + queueResponse.remove(requestId)?.complete(success) + } else { + queueResponse.entries.lastOrNull { !it.value.isDone }?.value?.complete(success) + } } private fun handleChannel(ch: ChannelProtos.Channel) { @@ -1484,9 +1485,9 @@ class MeshService : Service(), Logging { val mi = with(myInfo) { MyNodeEntity( myNodeNum = myNodeNum, - model = rawDeviceMetadata?.hwModel?.let { hwModel -> - if (hwModel == MeshProtos.HardwareModel.UNSET) null - else hwModel.name.replace('_', '-').replace('p', '.').lowercase() + model = when (val hwModel = rawDeviceMetadata?.hwModel) { + null, MeshProtos.HardwareModel.UNSET -> null + else -> hwModel.name.replace('_', '-').replace('p', '.').lowercase() }, firmwareVersion = rawDeviceMetadata?.firmwareVersion, couldUpdate = false, @@ -1506,7 +1507,7 @@ class MeshService : Service(), Logging { val myInfo = rawMyNodeInfo val mi = myNodeInfo if (myInfo != null && mi != null) { - /// Track types of devices and firmware versions in use + // Track types of devices and firmware versions in use GeeksvilleApplication.analytics.setUserInfo( DataPair("firmware", mi.firmwareVersion), DataPair("hw_model", mi.model), @@ -1603,7 +1604,7 @@ class MeshService : Service(), Logging { } } - /// If we've received our initial config, our radio settings and all of our channels, send any queued packets and broadcast connected to clients + // If we've received our initial config, our radio settings and all of our channels, send any queued packets and broadcast connected to clients private fun onHasSettings() { processQueuedPackets() // send any packets that were queued up @@ -1731,8 +1732,7 @@ class MeshService : Service(), Logging { } } - - /// Do not use directly, instead call generatePacketId() + // Do not use directly, instead call generatePacketId() private var currentPacketId = Random(System.currentTimeMillis()).nextLong().absoluteValue /** @@ -1816,13 +1816,16 @@ class MeshService : Service(), Logging { info("sendData dest=${p.to}, id=${p.id} <- ${p.bytes!!.size} bytes (connectionState=$connectionState)") - if (p.dataType == 0) + if (p.dataType == 0) { throw Exception("Port numbers must be non-zero!") // we are now more strict + } if (p.bytes.size >= MeshProtos.Constants.DATA_PAYLOAD_LEN.number) { p.status = MessageStatus.ERROR throw RemoteException("Message too long") - } else p.status = MessageStatus.QUEUED + } else { + p.status = MessageStatus.QUEUED + } if (connectionState == ConnectionState.CONNECTED) try { sendNow(p) @@ -1974,7 +1977,7 @@ class MeshService : Service(), Logging { removeByNodenum = nodeNum }) } - override fun requestUserInfo( destNum: Int ) = toRemoteExceptions { + override fun requestUserInfo(destNum: Int) = toRemoteExceptions { if (destNum != myNodeNum) { sendToRadio(newMeshPacketTo(destNum ).buildMeshPacket( diff --git a/app/src/main/java/com/geeksville/mesh/ui/ChannelFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/ChannelFragment.kt index cd5cd728..09656a25 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/ChannelFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/ChannelFragment.kt @@ -223,7 +223,7 @@ fun ChannelScreen( .show() } - /// Send new channel settings to the device + // Send new channel settings to the device fun installSettings( newChannelSet: ChannelSet ) { @@ -420,8 +420,11 @@ fun ChannelScreen( !isUrlEqual -> stringResource(R.string.send) else -> "Copy" }, - tint = if (isError) MaterialTheme.colors.error - else LocalContentColor.current.copy(alpha = LocalContentAlpha.current) + tint = if (isError) { + MaterialTheme.colors.error + } else { + LocalContentColor.current.copy(alpha = LocalContentAlpha.current) + } ) } }, diff --git a/app/src/main/java/com/geeksville/mesh/ui/DebugFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/DebugFragment.kt index 3597fe74..c14a31e7 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/DebugFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/DebugFragment.kt @@ -60,7 +60,8 @@ class DebugFragment : Fragment() { private val model: DebugViewModel by viewModels() override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, + inflater: LayoutInflater, + container: ViewGroup?, savedInstanceState: Bundle? ): View { _binding = FragmentDebugBinding.inflate(inflater, container, false) diff --git a/app/src/main/java/com/geeksville/mesh/ui/DeviceSettingsFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/DeviceSettingsFragment.kt index a6ed83a1..1e2f3a87 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/DeviceSettingsFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/DeviceSettingsFragment.kt @@ -170,7 +170,6 @@ enum class AdminRoute(@StringRes val title: Int) { SHUTDOWN(R.string.shutdown), FACTORY_RESET(R.string.factory_reset), NODEDB_RESET(R.string.nodedb_reset), - ; } // Config (configType = AdminProtos.AdminMessage.ConfigType) @@ -185,7 +184,6 @@ enum class ConfigRoute(val title: String, val configType: Int = 0) { LORA("LoRa", 5), BLUETOOTH("Bluetooth", 6), SECURITY("Security", configType = 7), - ; } // ModuleConfig (configType = AdminProtos.AdminMessage.ModuleConfigType) @@ -203,7 +201,6 @@ enum class ModuleRoute(val title: String, val configType: Int = 0) { AMBIENT_LIGHTING("Ambient Lighting", 10), DETECTION_SENSOR("Detection Sensor", 11), PAXCOUNTER("Paxcounter", 12), - ; } private fun getName(route: Any): String = when (route) { @@ -655,8 +652,11 @@ private fun NavCard( enabled: Boolean, onClick: () -> Unit ) { - val color = if (enabled) MaterialTheme.colors.onSurface - else MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.disabled) + val color = if (enabled) { + MaterialTheme.colors.onSurface + } else { + MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.disabled) + } Card( modifier = Modifier diff --git a/app/src/main/java/com/geeksville/mesh/ui/LinkedCoordinates.kt b/app/src/main/java/com/geeksville/mesh/ui/LinkedCoordinates.kt index ce078190..4b6250fa 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/LinkedCoordinates.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/LinkedCoordinates.kt @@ -44,7 +44,7 @@ fun LinkedCoordinates( tag = "gps", // URI scheme is defined at: // https://developer.android.com/guide/components/intents-common#Maps - annotation = "geo:0,0?q=${latitude},${longitude}&z=17&label=${ + annotation = "geo:0,0?q=$latitude,$longitude&z=17&label=${ URLEncoder.encode(nodeName, "utf-8") }" ) diff --git a/app/src/main/java/com/geeksville/mesh/ui/MessageItem.kt b/app/src/main/java/com/geeksville/mesh/ui/MessageItem.kt index b759e60e..001455a3 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/MessageItem.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/MessageItem.kt @@ -60,7 +60,7 @@ internal fun MessageItem( ) { val fromLocal = shortName == null val messageColor = if (fromLocal) R.color.colorMyMsg else R.color.colorMsg - val (topStart, topEnd) = if (fromLocal) 12.dp to 4.dp else 4.dp to 12.dp + val (topStart, topEnd) = if (fromLocal) 12.dp to 4.dp else 4.dp to 12.dp val messageModifier = if (fromLocal) { Modifier.padding(start = 48.dp, top = 8.dp, end = 8.dp, bottom = 6.dp) } else { diff --git a/app/src/main/java/com/geeksville/mesh/ui/MessagesFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/MessagesFragment.kt index c6e4d484..38d14b38 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/MessagesFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/MessagesFragment.kt @@ -104,7 +104,8 @@ class MessagesFragment : Fragment(), Logging { } override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, + inflater: LayoutInflater, + container: ViewGroup?, savedInstanceState: Bundle? ): View { _binding = MessagesFragmentBinding.inflate(inflater, container, false) @@ -278,8 +279,9 @@ class MessagesFragment : Fragment(), Logging { selectedList.forEach { resendText = resendText + it.text + System.lineSeparator() } - if (resendText != "") + if (resendText != "") { resendText = resendText.substring(0, resendText.length - 1) + } binding.messageInputText.setText(resendText) mode.finish() } diff --git a/app/src/main/java/com/geeksville/mesh/ui/NodeItem.kt b/app/src/main/java/com/geeksville/mesh/ui/NodeItem.kt index 110ff2c1..9c2315ce 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/NodeItem.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/NodeItem.kt @@ -90,9 +90,9 @@ fun NodeItem( } val (textColor, nodeColor) = thatNode.colors - val hwInfoString = thatNode.user.hwModel.let { hwModel -> - if (hwModel == MeshProtos.HardwareModel.UNSET) MeshProtos.HardwareModel.UNSET.name - else hwModel.name.replace('_', '-').replace('p', '.').lowercase() + val hwInfoString = when (val hwModel = thatNode.user.hwModel) { + MeshProtos.HardwareModel.UNSET -> MeshProtos.HardwareModel.UNSET.name + else -> hwModel.name.replace('_', '-').replace('p', '.').lowercase() } val roleName = if (isUnknownUser) { DeviceConfig.Role.UNRECOGNIZED.name diff --git a/app/src/main/java/com/geeksville/mesh/ui/QuickChatSettingsFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/QuickChatSettingsFragment.kt index 99e162e4..e7ca39af 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/QuickChatSettingsFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/QuickChatSettingsFragment.kt @@ -60,7 +60,8 @@ class QuickChatSettingsFragment : ScreenFragment("Quick Chat Settings"), Logging private val model: UIViewModel by activityViewModels() override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, + inflater: LayoutInflater, + container: ViewGroup?, savedInstanceState: Bundle? ): View { _binding = QuickChatSettingsFragmentBinding.inflate(inflater, container, false) @@ -81,11 +82,12 @@ class QuickChatSettingsFragment : ScreenFragment("Quick Chat Settings"), Logging val name = builder.nameInput.text.toString().trim() val message = builder.messageInput.text.toString() - if (builder.isNotEmpty()) + if (builder.isNotEmpty()) { model.addQuickChatAction( name, message, if (builder.modeSwitch.isChecked) QuickChatAction.Mode.Instant else QuickChatAction.Mode.Append ) + } } val dialog = builder.builder.create() diff --git a/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt index 26440994..07f800fb 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt @@ -53,7 +53,8 @@ class SettingsFragment : ScreenFragment("Settings"), Logging { private val hasGps by lazy { requireContext().hasGps() } override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, + inflater: LayoutInflater, + container: ViewGroup?, savedInstanceState: Bundle? ): View { _binding = SettingsFragmentBinding.inflate(inflater, container, false) @@ -86,8 +87,9 @@ class SettingsFragment : ScreenFragment("Settings"), Logging { debug("current region is $region") var regionIndex = regions.indexOfFirst { it.regionCode == region } - if (regionIndex == -1) // Not found, probably because the device has a region our app doesn't yet understand. Punt and say Unset + if (regionIndex == -1) { // Not found, probably because the device has a region our app doesn't yet understand. Punt and say Unset regionIndex = ConfigProtos.Config.LoRaConfig.RegionCode.UNSET_VALUE + } // We don't want to be notified of our own changes, so turn off listener while making them spinner.setSelection(regionIndex, false) @@ -125,7 +127,7 @@ class SettingsFragment : ScreenFragment("Settings"), Logging { } override fun onNothingSelected(parent: AdapterView<*>) { - //TODO("Not yet implemented") + // TODO("Not yet implemented") } } @@ -248,7 +250,7 @@ class SettingsFragment : ScreenFragment("Settings"), Logging { if (view.isPressed) { // We want to ignore changes caused by code (as opposed to the user) debug("User changed location tracking to $isChecked") model.provideLocation.value = isChecked - if (isChecked && !view.isChecked) + if (isChecked && !view.isChecked) { MaterialAlertDialogBuilder(requireContext()) .setTitle(R.string.background_required) .setMessage(R.string.why_background_required) @@ -262,6 +264,7 @@ class SettingsFragment : ScreenFragment("Settings"), Logging { } } .show() + } } if (view.isChecked) { checkLocationEnabled(getString(R.string.location_disabled)) @@ -330,8 +333,9 @@ class SettingsFragment : ScreenFragment("Settings"), Logging { scanModel.showMockInterface() } } - if (!device.bonded) // If user just clicked on us, try to bond + if (!device.bonded) { // If user just clicked on us, try to bond binding.scanStatusText.setText(R.string.starting_pairing) + } b.isChecked = scanModel.onSelected(device) } } @@ -363,10 +367,11 @@ class SettingsFragment : ScreenFragment("Settings"), Logging { devices.values // Display the device list in alphabetical order while keeping the "None (Disabled)" // device (fullAddress == n) at the top - .sortedBy { dle -> if (dle.fullAddress == "n") "0" else dle.name } + .sortedBy { dle -> if (dle.fullAddress == "n") "0" else dle.name } .forEach { device -> - if (device.fullAddress == scanModel.selectedNotNull) + if (device.fullAddress == scanModel.selectedNotNull) { hasShownOurDevice = true + } addDeviceButton(device, true) } @@ -473,8 +478,9 @@ class SettingsFragment : ScreenFragment("Settings"), Logging { if (scanModel.selectedBluetooth) checkBTEnabled() // Warn user if provide location is selected but location disabled - if (binding.provideLocationCheckbox.isChecked) + if (binding.provideLocationCheckbox.isChecked) { checkLocationEnabled(getString(R.string.location_disabled)) + } } override fun onDestroyView() { @@ -486,7 +492,6 @@ class SettingsFragment : ScreenFragment("Settings"), Logging { const val SCAN_PERIOD: Long = 10000 // Stops scanning after 10 seconds private const val TAP_TRIGGER: Int = 7 private const val TAP_THRESHOLD: Long = 500 // max 500 ms between taps - } private fun Editable.isIPAddress(): Boolean { @@ -497,5 +502,4 @@ class SettingsFragment : ScreenFragment("Settings"), Logging { Patterns.IP_ADDRESS.matcher(this).matches() } } - } diff --git a/app/src/main/java/com/geeksville/mesh/ui/UsersFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/UsersFragment.kt index db613894..9ddd9d9f 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/UsersFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/UsersFragment.kt @@ -110,7 +110,6 @@ class UsersFragment : ScreenFragment("Users"), Logging { parentFragmentManager.navigateToMetrics(nodeNum) } - override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/BitwisePreference.kt b/app/src/main/java/com/geeksville/mesh/ui/components/BitwisePreference.kt index aec3b214..fc32204f 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/BitwisePreference.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/components/BitwisePreference.kt @@ -37,8 +37,11 @@ fun BitwisePreference( subtitle = value.toString(), onClick = { dropDownExpanded = !dropDownExpanded }, enabled = enabled, - trailingIcon = if (dropDownExpanded) Icons.TwoTone.KeyboardArrowUp - else Icons.TwoTone.KeyboardArrowDown, + trailingIcon = if (dropDownExpanded) { + Icons.TwoTone.KeyboardArrowUp + } else { + Icons.TwoTone.KeyboardArrowDown + }, ) Box { diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/DeviceMetrics.kt b/app/src/main/java/com/geeksville/mesh/ui/components/DeviceMetrics.kt index ea886d1a..fdcb0c59 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/DeviceMetrics.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/components/DeviceMetrics.kt @@ -53,7 +53,6 @@ import com.geeksville.mesh.ui.components.CommonCharts.MS_PER_SEC import com.geeksville.mesh.ui.components.CommonCharts.TIME_FORMAT import com.geeksville.mesh.ui.theme.Orange - private val DEVICE_METRICS_COLORS = listOf(Color.Green, Color.Magenta, Color.Cyan) private const val MAX_PERCENT_VALUE = 100f @@ -64,8 +63,9 @@ fun DeviceMetricsScreen(telemetries: List) { Column { - if (displayInfoDialog) + if (displayInfoDialog) { DeviceInfoDialog { displayInfoDialog = false } + } DeviceMetricsChart( modifier = Modifier @@ -92,8 +92,7 @@ private fun DeviceMetricsChart( ) { ChartHeader(amount = telemetries.size) - if (telemetries.isEmpty()) - return + if (telemetries.isEmpty()) return Spacer(modifier = Modifier.height(16.dp)) @@ -153,8 +152,9 @@ private fun DeviceMetricsChart( val x2 = spacing + (i + 1) * spacePerEntry val y2 = height - spacing - (rightRatio * height) - if (i == 0) + if (i == 0) { moveTo(x1, y1) + } lastX = (x1 + x2) / 2f diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/DropDownPreference.kt b/app/src/main/java/com/geeksville/mesh/ui/components/DropDownPreference.kt index 7dcc1195..fceec24f 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/DropDownPreference.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/components/DropDownPreference.kt @@ -56,8 +56,11 @@ fun DropDownPreference( dropDownExpanded = true }, enabled = enabled, - trailingIcon = if (dropDownExpanded) Icons.TwoTone.KeyboardArrowUp - else Icons.TwoTone.KeyboardArrowDown, + trailingIcon = if (dropDownExpanded) { + Icons.TwoTone.KeyboardArrowUp + } else { + Icons.TwoTone.KeyboardArrowDown + }, summary = summary, ) @@ -74,15 +77,17 @@ fun DropDownPreference( }, modifier = modifier .background( - color = if (selectedItem == item.first) + color = if (selectedItem == item.first) { MaterialTheme.colors.primary.copy(alpha = 0.3f) - else - Color.Unspecified, + } else { + Color.Unspecified + }, ), content = { Text( text = item.second, overflow = TextOverflow.Ellipsis, + maxLines = 1, ) } ) diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/EditTextPreference.kt b/app/src/main/java/com/geeksville/mesh/ui/components/EditTextPreference.kt index 20bb61b8..b95de81e 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/EditTextPreference.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/components/EditTextPreference.kt @@ -21,11 +21,13 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusState import androidx.compose.ui.focus.onFocusEvent +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import com.geeksville.mesh.R @Composable fun EditTextPreference( @@ -167,8 +169,12 @@ fun EditTextPreference( trailingIcon = { if (trailingIcon != null) { trailingIcon() - } else { - if (isError) Icon(Icons.TwoTone.Info, "Error", tint = MaterialTheme.colors.error) + } else if (isError) { + Icon( + imageVector = Icons.TwoTone.Info, + contentDescription = stringResource(id = R.string.error), + tint = MaterialTheme.colors.error + ) } }, ) diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/IndoorAirQuality.kt b/app/src/main/java/com/geeksville/mesh/ui/components/IndoorAirQuality.kt index 0766ca96..78cbc8a7 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/IndoorAirQuality.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/components/IndoorAirQuality.kt @@ -54,8 +54,6 @@ enum class Iaq(val color: Color, val description: String, val range: IntRange) { DangerouslyPolluted(Color(0xFF663300), "Dangerously Polluted", 501..Int.MAX_VALUE) } - - fun getIaq(iaq: Int): Iaq { return when { iaq in Iaq.Excellent.range -> Iaq.Excellent @@ -70,7 +68,7 @@ fun getIaq(iaq: Int): Iaq { } private fun getIaqDescriptionWithRange(iaqEnum: Iaq): String { - return if (iaqEnum.range.last == Int.MAX_VALUE){ + return if (iaqEnum.range.last == Int.MAX_VALUE) { "${iaqEnum.description} (${iaqEnum.range.first}+)" } else { "${iaqEnum.description} (${iaqEnum.range.first}-${iaqEnum.range.last})" diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/SimpleAlertDialog.kt b/app/src/main/java/com/geeksville/mesh/ui/components/SimpleAlertDialog.kt index 4b9c9370..0c8f53d5 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/SimpleAlertDialog.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/components/SimpleAlertDialog.kt @@ -31,7 +31,7 @@ fun SimpleAlertDialog( onClick = onDismiss, modifier = Modifier .padding(horizontal = 16.dp), - colors = ButtonDefaults.textButtonColors( + colors = ButtonDefaults.textButtonColors( contentColor = MaterialTheme.colors.onSurface, ), ) { Text(text = stringResource(id = R.string.close)) } diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/SwitchPreference.kt b/app/src/main/java/com/geeksville/mesh/ui/components/SwitchPreference.kt index 007c5987..d5b99dee 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/SwitchPreference.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/components/SwitchPreference.kt @@ -39,7 +39,11 @@ fun SwitchPreference( Text( text = title, style = MaterialTheme.typography.body1, - color = if (!enabled) MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.disabled) else Color.Unspecified, + color = if (enabled) { + Color.Unspecified + } else { + MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.disabled) + }, ) Switch( modifier = modifier diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/BluetoothConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/components/config/BluetoothConfigItemList.kt index 04eec1f8..c4a51155 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/BluetoothConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/components/config/BluetoothConfigItemList.kt @@ -59,8 +59,9 @@ fun BluetoothConfigItemList( enabled = enabled, keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }), onValueChanged = { - if (it.toString().length == 6) // ensure 6 digits + if (it.toString().length == 6) { // ensure 6 digits bluetoothInput = bluetoothInput.copy { fixedPin = it } + } }) } diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/CannedMessageConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/components/config/CannedMessageConfigItemList.kt index e60034bd..651e6fbc 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/CannedMessageConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/components/config/CannedMessageConfigItemList.kt @@ -187,7 +187,7 @@ fun CannedMessageConfigItemList( }, onSaveClicked = { focusManager.clearFocus() - onSaveClicked(messagesInput,cannedMessageInput) + onSaveClicked(messagesInput, cannedMessageInput) } ) } diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/ChannelSettingsItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/components/config/ChannelSettingsItemList.kt index 7fd4f035..0ee0f8bb 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/ChannelSettingsItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/components/config/ChannelSettingsItemList.kt @@ -78,8 +78,11 @@ private fun ChannelItem( verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(vertical = 4.dp, horizontal = 4.dp) ) { - val textColor = if (enabled) Color.Unspecified - else MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.disabled) + val textColor = if (enabled) { + Color.Unspecified + } else { + MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.disabled) + } Chip(onClick = onClick) { Text( @@ -165,8 +168,8 @@ fun ChannelSettingsItemList( } } - val isEditing: Boolean = settingsList.size != settingsListInput.size - || settingsList.zip(settingsListInput).any { (item1, item2) -> item1 != item2 } + val isEditing: Boolean = settingsList.size != settingsListInput.size || + settingsList.zip(settingsListInput).any { (item1, item2) -> item1 != item2 } var showEditChannelDialog: Int? by rememberSaveable { mutableStateOf(null) } @@ -178,8 +181,11 @@ fun ChannelSettingsItemList( }, modemPresetName = modemPresetName, onAddClick = { - if (settingsListInput.size > index) settingsListInput[index] = it - else settingsListInput.add(it) + if (settingsListInput.size > index) { + settingsListInput[index] = it + } else { + settingsListInput.add(it) + } showEditChannelDialog = null }, onDismissRequest = { showEditChannelDialog = null } diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/DeviceConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/components/config/DeviceConfigItemList.kt index 233766ca..9222bb4b 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/DeviceConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/components/config/DeviceConfigItemList.kt @@ -25,7 +25,7 @@ import com.geeksville.mesh.ui.components.PreferenceCategory import com.geeksville.mesh.ui.components.PreferenceFooter import com.geeksville.mesh.ui.components.SwitchPreference -private val DeviceConfig.Role.stringRes: Int +private val DeviceConfig.Role.stringRes: Int get() = when (this) { DeviceConfig.Role.CLIENT -> R.string.role_client DeviceConfig.Role.CLIENT_MUTE -> R.string.role_client_mute diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/DisplayConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/components/config/DisplayConfigItemList.kt index d73957fa..e21d2580 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/DisplayConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/components/config/DisplayConfigItemList.kt @@ -153,7 +153,6 @@ fun DisplayConfigItemList( ) } } - } @Preview(showBackground = true) diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/EditDeviceProfileDialog.kt b/app/src/main/java/com/geeksville/mesh/ui/components/config/EditDeviceProfileDialog.kt index d75b4871..1994b107 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/EditDeviceProfileDialog.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/components/config/EditDeviceProfileDialog.kt @@ -68,7 +68,7 @@ fun EditDeviceProfileDialog( SwitchPreference( title = field.name, checked = state[field] == true, - enabled = deviceProfile.hasField(field), + enabled = deviceProfile.hasField(field), onCheckedChange = { state[field] = it }, padding = PaddingValues(0.dp) ) diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/LoRaConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/components/config/LoRaConfigItemList.kt index e63ffa6f..a870e39f 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/LoRaConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/components/config/LoRaConfigItemList.kt @@ -140,8 +140,9 @@ fun LoRaConfigItemList( keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }), onFocusChanged = { isFocused = it.isFocused }, onValueChanged = { - if (it <= loraInput.numChannels) // total num of LoRa channels + if (it <= loraInput.numChannels) { // total num of LoRa channels loraInput = loraInput.copy { channelNum = it } + } }) } diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/PositionConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/components/config/PositionConfigItemList.kt index e4d9c64a..b3dd2868 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/PositionConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/components/config/PositionConfigItemList.kt @@ -97,8 +97,9 @@ fun PositionConfigItemList( enabled = enabled, keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }), onValueChanged = { value -> - if (value >= -90 && value <= 90.0) + if (value >= -90 && value <= 90.0) { locationInput = locationInput.copy(latitude = value) + } }) } item { @@ -107,8 +108,9 @@ fun PositionConfigItemList( enabled = enabled, keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }), onValueChanged = { value -> - if (value >= -180 && value <= 180.0) + if (value >= -180 && value <= 180.0) { locationInput = locationInput.copy(longitude = value) + } }) } item { diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/config/UserConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/components/config/UserConfigItemList.kt index 3b51ede0..3b7077b5 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/config/UserConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/components/config/UserConfigItemList.kt @@ -58,8 +58,9 @@ fun UserConfigItemList( keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }), onValueChanged = { userInput = userInput.copy { longName = it } - if (getInitials(it).toByteArray().size <= 4) // short_name max_size:5 + if (getInitials(it).toByteArray().size <= 4) { // short_name max_size:5 userInput = userInput.copy { shortName = getInitials(it) } + } }) } diff --git a/app/src/main/java/com/geeksville/mesh/ui/map/MapFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/map/MapFragment.kt index 12b861e5..17138122 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/map/MapFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/map/MapFragment.kt @@ -224,7 +224,6 @@ private fun Context.purgeTileSource(onResult: (String) -> Unit) { } else { selectedList.remove(i) } - } builder.setPositiveButton(R.string.clear) { _, _ -> for (x in selectedList) { @@ -382,12 +381,13 @@ fun MapView( debug("User deleted waypoint ${waypoint.id} for me") model.deleteWaypoint(waypoint.id) } - if (waypoint.lockedTo in setOf(0, model.myNodeNum ?: 0) && model.isConnected()) + if (waypoint.lockedTo in setOf(0, model.myNodeNum ?: 0) && model.isConnected()) { builder.setPositiveButton(R.string.delete_for_everyone) { _, _ -> debug("User deleted waypoint ${waypoint.id} for everyone") model.sendWaypoint(waypoint.copy { expire = 1 }) model.deleteWaypoint(waypoint.id) } + } val dialog = builder.show() for (button in setOf( androidx.appcompat.app.AlertDialog.BUTTON_NEUTRAL, @@ -398,7 +398,7 @@ fun MapView( fun showMarkerLongPressDialog(id: Int) { performHapticFeedback() - debug("marker long pressed id=${id}") + debug("marker long pressed id=$id") val waypoint = waypoints[id]?.data?.waypoint ?: return // edit only when unlocked or lockedTo myNodeNum if (waypoint.lockedTo in setOf(0, model.myNodeNum ?: 0) && model.isConnected()) { @@ -488,7 +488,7 @@ fun MapView( overlays.add(nodeClusterer) } - addCopyright() // Copyright is required for certain map sources + addCopyright() // Copyright is required for certain map sources createLatLongGrid(false) invalidate() @@ -697,12 +697,18 @@ fun MapView( ) MapButton( onClick = { - if (context.hasLocationPermission()) map.toggleMyLocation() - else requestPermissionAndToggleLauncher.launch(context.getLocationPermissions()) + if (context.hasLocationPermission()) { + map.toggleMyLocation() + } else { + requestPermissionAndToggleLauncher.launch(context.getLocationPermissions()) + } }, enabled = hasGps, - drawableRes = if (myLocationOverlay == null) R.drawable.ic_twotone_my_location_24 - else R.drawable.ic_twotone_location_disabled_24, + drawableRes = if (myLocationOverlay == null) { + R.drawable.ic_twotone_my_location_24 + } else { + R.drawable.ic_twotone_location_disabled_24 + }, contentDescription = null, ) } @@ -720,7 +726,6 @@ fun MapView( expire = Int.MAX_VALUE // TODO add expire picker lockedTo = if (waypoint.lockedTo != 0) model.myNodeNum ?: 0 else 0 }) - }, onDeleteClicked = { waypoint -> debug("User clicked delete waypoint ${waypoint.id}") diff --git a/app/src/main/java/com/geeksville/mesh/util/Extensions.kt b/app/src/main/java/com/geeksville/mesh/util/Extensions.kt index cd4d55be..997b27de 100644 --- a/app/src/main/java/com/geeksville/mesh/util/Extensions.kt +++ b/app/src/main/java/com/geeksville/mesh/util/Extensions.kt @@ -20,7 +20,7 @@ val Any?.anonymize: String fun Any?.anonymize(maxLen: Int = 3) = if (this != null) ("..." + this.toString().takeLast(maxLen)) else "null" -/// A toString that makes sure all newlines are removed (for nice logging). +// A toString that makes sure all newlines are removed (for nice logging). fun Any.toOneLineString() = this.toString().replace('\n', ' ') fun ConfigProtos.Config.toOneLineString(): String { @@ -30,12 +30,13 @@ fun ConfigProtos.Config.toOneLineString(): String { .replace('\n', ' ') } -/// Return a one line string version of an object (but if a release build, just say 'might be PII) +// Return a one line string version of an object (but if a release build, just say 'might be PII) fun Any.toPIIString() = - if (!BuildConfig.DEBUG) + if (!BuildConfig.DEBUG) { "" - else + } else { this.toOneLineString() + } fun ByteArray.toHexString() = joinToString("") { "%02x".format(it) } @@ -51,7 +52,7 @@ fun formatAgo(lastSeenUnix: Int, currentTimeMillis: Long = System.currentTimeMil } } -/// Allows usage like email.onEditorAction(EditorInfo.IME_ACTION_NEXT, { confirm() }) +// Allows usage like email.onEditorAction(EditorInfo.IME_ACTION_NEXT, { confirm() }) fun EditText.onEditorAction(actionId: Int, func: () -> Unit) { setOnEditorActionListener { _, receivedActionId, _ -> diff --git a/app/src/main/java/com/geeksville/mesh/util/LanguageUtils.kt b/app/src/main/java/com/geeksville/mesh/util/LanguageUtils.kt index 8481488e..8157b67a 100644 --- a/app/src/main/java/com/geeksville/mesh/util/LanguageUtils.kt +++ b/app/src/main/java/com/geeksville/mesh/util/LanguageUtils.kt @@ -21,8 +21,11 @@ object LanguageUtils : Logging { fun setLocale(lang: String) { AppCompatDelegate.setApplicationLocales( - if (lang == SYSTEM_DEFAULT) LocaleListCompat.getEmptyLocaleList() - else LocaleListCompat.forLanguageTags(lang) + if (lang == SYSTEM_DEFAULT) { + LocaleListCompat.getEmptyLocaleList() + } else { + LocaleListCompat.forLanguageTags(lang) + } ) } @@ -64,4 +67,4 @@ object LanguageUtils : Logging { } } } -} \ No newline at end of file +} diff --git a/config/detekt/detekt-baseline.xml b/config/detekt/detekt-baseline.xml index 56c7ccae..5848f922 100644 --- a/config/detekt/detekt-baseline.xml +++ b/config/detekt/detekt-baseline.xml @@ -2,6 +2,68 @@ + ChainWrapping:Channel.kt$Channel$&& + ChainWrapping:CustomTileSource.kt$CustomTileSource.Companion.<no name provided>$+ + ChainWrapping:SqlTileWriterExt.kt$SqlTileWriterExt$+ + CommentSpacing:AppIntroduction.kt$AppIntroduction$//addSlide(SlideTwoFragment()) + CommentSpacing:BLEException.kt$BLEConnectionClosing$/// Our interface is being shut down + CommentSpacing:BTScanModel.kt$BTScanModel$/// Use the string for the NopInterface + CommentSpacing:BluetoothInterface.kt$BluetoothInterface$/// Attempt to read from the fromRadio mailbox, if data is found broadcast it to android apps + CommentSpacing:BluetoothInterface.kt$BluetoothInterface$/// For testing + CommentSpacing:BluetoothInterface.kt$BluetoothInterface$/// Our BLE device + CommentSpacing:BluetoothInterface.kt$BluetoothInterface$/// Our service - note - it is possible to get back a null response for getService if the device services haven't yet been found + CommentSpacing:BluetoothInterface.kt$BluetoothInterface$/// Send a packet/command out the radio link + CommentSpacing:BluetoothInterface.kt$BluetoothInterface$/// Start a connection attempt + CommentSpacing:BluetoothInterface.kt$BluetoothInterface$/// We gracefully handle safe being null because this can occur if someone has unpaired from our device - just abandon the reconnect attempt + CommentSpacing:BluetoothInterface.kt$BluetoothInterface$/// We only force service refresh the _first_ time we connect to the device. Thereafter it is assumed the firmware didn't change + CommentSpacing:BluetoothInterface.kt$BluetoothInterface$/// We only try to set MTU once, because some buggy implementations fail + CommentSpacing:BluetoothInterface.kt$BluetoothInterface$//needForceRefresh = false // In fact, because of tearing down BLE in sleep on the ESP32, our handle # assignments are not stable across sleep - so we much refetch every time + CommentSpacing:BluetoothInterface.kt$BluetoothInterface.Companion$/// this service UUID is publicly visible for scanning + CommentSpacing:Constants.kt$/// a bool true means we expect this condition to continue until, false means device might come back + CommentSpacing:ContextExtensions.kt$/// Utility function to hide the soft keyboard per stack overflow + CommentSpacing:ContextExtensions.kt$/// show a toast + CommentSpacing:Coroutines.kt$/// Wrap launch with an exception handler, FIXME, move into a utility lib + CommentSpacing:DeferredExecution.kt$DeferredExecution$/// Queue some new work + CommentSpacing:DeferredExecution.kt$DeferredExecution$/// run all work in the queue and clear it to be ready to accept new work + CommentSpacing:DownloadButton.kt$//@Composable + CommentSpacing:DownloadButton.kt$//@Preview(showBackground = true) + CommentSpacing:DownloadButton.kt$//private fun DownloadButtonPreview() { + CommentSpacing:DownloadButton.kt$//} + CommentSpacing:Exceptions.kt$/// Convert any exceptions in this service call into a RemoteException that the client can + CommentSpacing:Exceptions.kt$/// then handle + CommentSpacing:Exceptions.kt$Exceptions$/// Set in Application.onCreate + CommentSpacing:Logging.kt$Logging$/// Kotlin assertions are disabled on android, so instead we use this assert helper + CommentSpacing:Logging.kt$Logging$/// Report an error (including messaging our crash reporter service if allowed + CommentSpacing:Logging.kt$Logging.Companion$/// If false debug logs will not be shown (but others might) + CommentSpacing:Logging.kt$Logging.Companion$/// if false NO logs will be shown, set this in the application based on BuildConfig.DEBUG + CommentSpacing:MeshServiceStarter.kt$/// Helper function to start running our service + CommentSpacing:MockInterface.kt$MockInterface$/// Generate a fake node info entry + CommentSpacing:MockInterface.kt$MockInterface$/// Generate a fake text message from a node + CommentSpacing:MockInterface.kt$MockInterface$/// Send a fake ack packet back if the sender asked for want_ack + CommentSpacing:NOAAWmsTileSource.kt$NOAAWmsTileSource$//array indexes for that data + CommentSpacing:NOAAWmsTileSource.kt$NOAAWmsTileSource$//used by geo server + CommentSpacing:NodeInfo.kt$NodeInfo$/// @return a nice human readable string for the distance, or null for unknown + CommentSpacing:NodeInfo.kt$NodeInfo$/// @return bearing to the other position in degrees + CommentSpacing:NodeInfo.kt$NodeInfo$/// @return distance in meters to some other node (or null if unknown) + CommentSpacing:NodeInfo.kt$NodeInfo$/// return the position if it is valid, else null + CommentSpacing:NodeInfo.kt$Position$/// @return bearing to the other position in degrees + CommentSpacing:NodeInfo.kt$Position$/// @return distance in meters to some other node (or null if unknown) + CommentSpacing:NodeInfo.kt$Position.Companion$/// Convert to a double representation of degrees + CommentSpacing:SafeBluetooth.kt$/// Return a standard BLE 128 bit UUID from the short 16 bit versions + CommentSpacing:SafeBluetooth.kt$SafeBluetooth$/// Drop our current connection and then requeue a connect as needed + CommentSpacing:SafeBluetooth.kt$SafeBluetooth$/// If we have work we can do, start doing it. + CommentSpacing:SafeBluetooth.kt$SafeBluetooth$/// Restart any previous connect attempts + CommentSpacing:SafeBluetooth.kt$SafeBluetooth$/// Timeout before we declare a bluetooth operation failed (used for synchronous API operations only) + CommentSpacing:SafeBluetooth.kt$SafeBluetooth$/// True if the current active connection is auto (possible for this to be false but autoConnect to be true + CommentSpacing:SafeBluetooth.kt$SafeBluetooth$/// Users can access the GATT directly as needed + CommentSpacing:SafeBluetooth.kt$SafeBluetooth$/// asyncronously turn notification on/off for a characteristic + CommentSpacing:SafeBluetooth.kt$SafeBluetooth$/// from characteristic UUIDs to the handler function for notfies + CommentSpacing:SafeBluetooth.kt$SafeBluetooth$/// helper glue to make sync continuations and then wait for the result + CommentSpacing:SafeBluetooth.kt$SafeBluetooth$/// if we are in the first non-automated lowLevel connect. + CommentSpacing:SafeBluetooth.kt$SafeBluetooth$//com.geeksville.mesh.service.SafeBluetooth.closeGatt + CommentSpacing:SafeBluetooth.kt$SafeBluetooth.<no name provided>$//throw Exception("Mystery bluetooth failure - debug me") + CommentSpacing:SafeBluetooth.kt$SafeBluetooth.BluetoothContinuation$/// Connection work items are treated specially + CommentSpacing:SafeBluetooth.kt$SafeBluetooth.BluetoothContinuation$/// Start running a queued bit of work, return true for success or false for fatal bluetooth error ConstructorParameterNaming:MeshLog.kt$MeshLog$@ColumnInfo(name = "message") val raw_message: String ConstructorParameterNaming:MeshLog.kt$MeshLog$@ColumnInfo(name = "received_date") val received_date: Long ConstructorParameterNaming:MeshLog.kt$MeshLog$@ColumnInfo(name = "type") val message_type: String @@ -10,15 +72,11 @@ ConstructorParameterNaming:Packet.kt$Packet$@ColumnInfo(name = "port_num") val port_num: Int ConstructorParameterNaming:Packet.kt$Packet$@ColumnInfo(name = "received_time") val received_time: Long CyclomaticComplexMethod:ChannelFragment.kt$@Composable fun ChannelScreen( viewModel: UIViewModel = viewModel(), showSnackbar: (String) -> Unit = {}, ) - CyclomaticComplexMethod:DeviceSettingsFragment.kt$@Composable fun RadioConfigNavHost( node: NodeInfo?, viewModel: RadioConfigViewModel = hiltViewModel(), navController: NavHostController = rememberNavController(), modifier: Modifier, ) CyclomaticComplexMethod:MainActivity.kt$MainActivity$override fun onOptionsItemSelected(item: MenuItem): Boolean CyclomaticComplexMethod:MapFragment.kt$@Composable fun MapView( model: UIViewModel = viewModel(), ) CyclomaticComplexMethod:MeshService.kt$MeshService$private fun handleReceivedData(packet: MeshPacket) - CyclomaticComplexMethod:PositionConfigItemList.kt$@Composable fun PositionConfigItemList( isLocal: Boolean = false, location: Position?, positionConfig: PositionConfig, enabled: Boolean, onSaveClicked: (position: Position?, config: PositionConfig) -> Unit, ) CyclomaticComplexMethod:RadioConfigViewModel.kt$RadioConfigViewModel$private fun processPacketResponse(packet: MeshProtos.MeshPacket) - CyclomaticComplexMethod:SettingsFragment.kt$SettingsFragment$private fun initCommonUI() CyclomaticComplexMethod:UIState.kt$UIViewModel$fun saveMessagesCSV(uri: Uri) - DestructuringDeclarationWithTooManyEntries:NodeInfo.kt$val (chip, dist, name, hw, pos, alt, sats, batt, heard, sig, env) = createRefs() EmptyCatchBlock:MeshLog.kt$MeshLog${ } EmptyClassBlock:DebugLogFile.kt$BinaryLogFile${ } EmptyDefaultConstructor:SqlTileWriterExt.kt$SqlTileWriterExt$() @@ -27,7 +85,54 @@ EmptyFunctionBlock:NopInterface.kt$NopInterface${ } EmptyFunctionBlock:NsdManager.kt$<no name provided>${ } EmptyFunctionBlock:TrustAllX509TrustManager.kt$TrustAllX509TrustManager${} - ExceptionRaisedInUnexpectedLocation:DistanceExtensions.kt$fun Float.toString( system: ConfigProtos.Config.DisplayConfig.DisplayUnits ): String + FinalNewline:AppIntroduction.kt$com.geeksville.mesh.AppIntroduction.kt + FinalNewline:AppPrefs.kt$com.geeksville.mesh.android.AppPrefs.kt + FinalNewline:ApplicationModule.kt$com.geeksville.mesh.ApplicationModule.kt + FinalNewline:BLEException.kt$com.geeksville.mesh.service.BLEException.kt + FinalNewline:BluetoothInterfaceFactory.kt$com.geeksville.mesh.repository.radio.BluetoothInterfaceFactory.kt + FinalNewline:BluetoothRepositoryModule.kt$com.geeksville.mesh.repository.bluetooth.BluetoothRepositoryModule.kt + FinalNewline:BluetoothViewModel.kt$com.geeksville.mesh.model.BluetoothViewModel.kt + FinalNewline:BootCompleteReceiver.kt$com.geeksville.mesh.service.BootCompleteReceiver.kt + FinalNewline:Color.kt$com.geeksville.mesh.ui.theme.Color.kt + FinalNewline:CoroutineDispatchers.kt$com.geeksville.mesh.CoroutineDispatchers.kt + FinalNewline:Coroutines.kt$com.geeksville.mesh.concurrent.Coroutines.kt + FinalNewline:CustomTileSource.kt$com.geeksville.mesh.model.map.CustomTileSource.kt + FinalNewline:DatabaseModule.kt$com.geeksville.mesh.database.DatabaseModule.kt + FinalNewline:DateUtils.kt$com.geeksville.mesh.android.DateUtils.kt + FinalNewline:DebugLogFile.kt$com.geeksville.mesh.android.DebugLogFile.kt + FinalNewline:DeferredExecution.kt$com.geeksville.mesh.concurrent.DeferredExecution.kt + FinalNewline:DeviceVersion.kt$com.geeksville.mesh.model.DeviceVersion.kt + FinalNewline:DeviceVersionTest.kt$com.geeksville.mesh.model.DeviceVersionTest.kt + FinalNewline:ElevationInfo.kt$com.geeksville.mesh.ui.compose.ElevationInfo.kt + FinalNewline:ExpireChecker.kt$com.geeksville.mesh.android.ExpireChecker.kt + FinalNewline:InterfaceId.kt$com.geeksville.mesh.repository.radio.InterfaceId.kt + FinalNewline:InterfaceSpec.kt$com.geeksville.mesh.repository.radio.InterfaceSpec.kt + FinalNewline:Logging.kt$com.geeksville.mesh.android.Logging.kt + FinalNewline:MockInterfaceFactory.kt$com.geeksville.mesh.repository.radio.MockInterfaceFactory.kt + FinalNewline:NOAAWmsTileSource.kt$com.geeksville.mesh.model.map.NOAAWmsTileSource.kt + FinalNewline:NopInterface.kt$com.geeksville.mesh.repository.radio.NopInterface.kt + FinalNewline:NopInterfaceFactory.kt$com.geeksville.mesh.repository.radio.NopInterfaceFactory.kt + FinalNewline:OnlineTileSourceAuth.kt$com.geeksville.mesh.model.map.OnlineTileSourceAuth.kt + FinalNewline:PreferenceCategory.kt$com.geeksville.mesh.ui.components.PreferenceCategory.kt + FinalNewline:PreviewParameterProviders.kt$com.geeksville.mesh.ui.preview.PreviewParameterProviders.kt + FinalNewline:ProbeTableProvider.kt$com.geeksville.mesh.repository.usb.ProbeTableProvider.kt + FinalNewline:QuickChatActionDao.kt$com.geeksville.mesh.database.dao.QuickChatActionDao.kt + FinalNewline:QuickChatActionRepository.kt$com.geeksville.mesh.database.QuickChatActionRepository.kt + FinalNewline:RadioNotConnectedException.kt$com.geeksville.mesh.service.RadioNotConnectedException.kt + FinalNewline:RadioRepositoryModule.kt$com.geeksville.mesh.repository.radio.RadioRepositoryModule.kt + FinalNewline:RegularPreference.kt$com.geeksville.mesh.ui.components.RegularPreference.kt + FinalNewline:SafeBluetooth.kt$com.geeksville.mesh.service.SafeBluetooth.kt + FinalNewline:SatelliteCountInfo.kt$com.geeksville.mesh.ui.compose.SatelliteCountInfo.kt + FinalNewline:SerialConnection.kt$com.geeksville.mesh.repository.usb.SerialConnection.kt + FinalNewline:SerialConnectionListener.kt$com.geeksville.mesh.repository.usb.SerialConnectionListener.kt + FinalNewline:SerialInterface.kt$com.geeksville.mesh.repository.radio.SerialInterface.kt + FinalNewline:SerialInterfaceFactory.kt$com.geeksville.mesh.repository.radio.SerialInterfaceFactory.kt + FinalNewline:SoftwareUpdateService.kt$com.geeksville.mesh.service.SoftwareUpdateService.kt + FinalNewline:SqlTileWriterExt.kt$com.geeksville.mesh.util.SqlTileWriterExt.kt + FinalNewline:TCPInterfaceFactory.kt$com.geeksville.mesh.repository.radio.TCPInterfaceFactory.kt + FinalNewline:Theme.kt$com.geeksville.mesh.ui.theme.Theme.kt + FinalNewline:UsbBroadcastReceiver.kt$com.geeksville.mesh.repository.usb.UsbBroadcastReceiver.kt + FinalNewline:UsbRepositoryModule.kt$com.geeksville.mesh.repository.usb.UsbRepositoryModule.kt ForbiddenComment:MapFragment.kt$// TODO: Accept filename input param from user ForbiddenComment:SafeBluetooth.kt$SafeBluetooth$// TODO: display some kind of UI about restarting BLE FunctionNaming:PacketDao.kt$PacketDao$@Query("DELETE FROM packet WHERE uuid=:uuid") fun _delete(uuid: Long) @@ -41,13 +146,6 @@ ImplicitDefaultLocale:LocationUtils.kt$GPSFormat$String.format( "%s%s %s%s %05d %05d", MGRS.zone, MGRS.band, MGRS.column, MGRS.row, MGRS.easting, MGRS.northing ) ImplicitDefaultLocale:LocationUtils.kt$GPSFormat$String.format("%.5f %.5f", p.latitude, p.longitude) ImplicitDefaultLocale:LocationUtils.kt$GPSFormat$String.format("%s°%s'%.5s\"%s", a[0], a[1], a[2], a[3]) - ImplicitDefaultLocale:NodeInfo.kt$EnvironmentMetrics$String.format("%.0f%%", relativeHumidity) - ImplicitDefaultLocale:NodeInfo.kt$EnvironmentMetrics$String.format("%.0fMΩ", gasResistance) - ImplicitDefaultLocale:NodeInfo.kt$EnvironmentMetrics$String.format("%.1fhPa", barometricPressure) - ImplicitDefaultLocale:NodeInfo.kt$EnvironmentMetrics$String.format("%.1fmA", current) - ImplicitDefaultLocale:NodeInfo.kt$EnvironmentMetrics$String.format("%.1f°C", temperature) - ImplicitDefaultLocale:NodeInfo.kt$EnvironmentMetrics$String.format("%.1f°F", fahrenheit) - ImplicitDefaultLocale:NodeInfo.kt$EnvironmentMetrics$String.format("%.2fV", voltage) ImplicitDefaultLocale:NodeInfo.kt$NodeInfo$String.format("%d%%", batteryLevel) LargeClass:MeshService.kt$MeshService : ServiceLogging LongMethod:AmbientLightingConfigItemList.kt$@Composable fun AmbientLightingConfigItemList( ambientLightingConfig: ModuleConfigProtos.ModuleConfig.AmbientLightingConfig, enabled: Boolean, onSaveClicked: (ModuleConfigProtos.ModuleConfig.AmbientLightingConfig) -> Unit, ) @@ -55,27 +153,17 @@ LongMethod:CannedMessageConfigItemList.kt$@Composable fun CannedMessageConfigItemList( messages: String, cannedMessageConfig: CannedMessageConfig, enabled: Boolean, onSaveClicked: (messages: String, config: CannedMessageConfig) -> Unit, ) LongMethod:ChannelFragment.kt$@Composable fun ChannelScreen( viewModel: UIViewModel = viewModel(), showSnackbar: (String) -> Unit = {}, ) LongMethod:ChannelSettingsItemList.kt$@Composable fun ChannelSettingsItemList( settingsList: List<ChannelSettings>, modemPresetName: String = "Default", maxChannels: Int = 8, enabled: Boolean, onNegativeClicked: () -> Unit = { }, onPositiveClicked: (List<ChannelSettings>) -> Unit, ) - LongMethod:ContactItem.kt$@OptIn(ExperimentalMaterialApi::class) @Composable fun ContactItem( contact: Contact, modifier: Modifier = Modifier, ) LongMethod:ContactsFragment.kt$ContactsFragment.ActionModeCallback$override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean - LongMethod:DetectionSensorConfigItemList.kt$@Composable fun DetectionSensorConfigItemList( detectionSensorConfig: ModuleConfigProtos.ModuleConfig.DetectionSensorConfig, enabled: Boolean, onSaveClicked: (ModuleConfigProtos.ModuleConfig.DetectionSensorConfig) -> Unit, ) LongMethod:DeviceConfigItemList.kt$@Composable fun DeviceConfigItemList( deviceConfig: DeviceConfig, enabled: Boolean, onSaveClicked: (DeviceConfig) -> Unit, ) - LongMethod:DeviceSettingsFragment.kt$@Composable fun RadioConfigNavHost( node: NodeInfo?, viewModel: RadioConfigViewModel = hiltViewModel(), navController: NavHostController = rememberNavController(), modifier: Modifier, ) LongMethod:DisplayConfigItemList.kt$@Composable fun DisplayConfigItemList( displayConfig: DisplayConfig, enabled: Boolean, onSaveClicked: (DisplayConfig) -> Unit, ) - LongMethod:EditChannelDialog.kt$@Composable fun EditChannelDialog( channelSettings: ChannelProtos.ChannelSettings, onAddClick: (ChannelProtos.ChannelSettings) -> Unit, onDismissRequest: () -> Unit, modifier: Modifier = Modifier, modemPresetName: String = "Default", ) - LongMethod:EditDeviceProfileDialog.kt$@Composable fun EditDeviceProfileDialog( title: String, deviceProfile: ClientOnlyProtos.DeviceProfile, onAddClick: (ClientOnlyProtos.DeviceProfile) -> Unit, onDismissRequest: () -> Unit, modifier: Modifier = Modifier, ) + LongMethod:DropDownPreference.kt$@Composable fun <T> DropDownPreference( title: String, enabled: Boolean, items: List<Pair<T, String>>, selectedItem: T, onItemSelected: (T) -> Unit, modifier: Modifier = Modifier, summary: String? = null, ) LongMethod:EditListPreference.kt$@Composable inline fun <reified T> EditListPreference( title: String, list: List<T>, maxCount: Int, enabled: Boolean, keyboardActions: KeyboardActions, crossinline onValuesChanged: (List<T>) -> Unit, modifier: Modifier = Modifier, ) - LongMethod:EditWaypointDialog.kt$@Composable internal fun EditWaypointDialog( waypoint: Waypoint, onSendClicked: (Waypoint) -> Unit, onDeleteClicked: (Waypoint) -> Unit, onDismissRequest: () -> Unit, modifier: Modifier = Modifier, ) LongMethod:ExternalNotificationConfigItemList.kt$@Composable fun ExternalNotificationConfigItemList( ringtone: String, extNotificationConfig: ExternalNotificationConfig, enabled: Boolean, onSaveClicked: (ringtone: String, config: ExternalNotificationConfig) -> Unit, ) - LongMethod:LoRaConfigItemList.kt$@Composable fun LoRaConfigItemList( loraConfig: LoRaConfig, primarySettings: ChannelSettings, enabled: Boolean, onSaveClicked: (LoRaConfig) -> Unit, ) LongMethod:MQTTConfigItemList.kt$@Composable fun MQTTConfigItemList( mqttConfig: MQTTConfig, enabled: Boolean, onSaveClicked: (MQTTConfig) -> Unit, ) LongMethod:MainActivity.kt$MainActivity$override fun onOptionsItemSelected(item: MenuItem): Boolean LongMethod:MapFragment.kt$@Composable fun MapView( model: UIViewModel = viewModel(), ) LongMethod:MeshService.kt$MeshService$private fun handleReceivedData(packet: MeshPacket) - LongMethod:MessagesFragment.kt$MessagesFragment$override fun onViewCreated(view: View, savedInstanceState: Bundle?) - LongMethod:MessagesFragment.kt$MessagesFragment.<no name provided>$override fun onBindViewHolder(holder: ViewHolder, position: Int) LongMethod:NetworkConfigItemList.kt$@Composable fun NetworkConfigItemList( networkConfig: NetworkConfig, enabled: Boolean, onSaveClicked: (NetworkConfig) -> Unit, ) - LongMethod:NodeInfo.kt$@OptIn(ExperimentalMaterialApi::class) @Composable fun NodeInfo( thisNodeInfo: NodeInfo?, thatNodeInfo: NodeInfo, gpsFormat: Int, distanceUnits: Int, tempInFahrenheit: Boolean, isIgnored: Boolean = false, onClicked: () -> Unit = {}, blinking: Boolean = false, ) - LongMethod:PositionConfigItemList.kt$@Composable fun PositionConfigItemList( isLocal: Boolean = false, location: Position?, positionConfig: PositionConfig, enabled: Boolean, onSaveClicked: (position: Position?, config: PositionConfig) -> Unit, ) LongMethod:PowerConfigItemList.kt$@Composable fun PowerConfigItemList( powerConfig: PowerConfig, enabled: Boolean, onSaveClicked: (PowerConfig) -> Unit, ) LongMethod:RadioConfigViewModel.kt$RadioConfigViewModel$private fun processPacketResponse(packet: MeshProtos.MeshPacket) LongMethod:SerialConfigItemList.kt$@Composable fun SerialConfigItemList( serialConfig: SerialConfig, enabled: Boolean, onSaveClicked: (SerialConfig) -> Unit, ) @@ -88,7 +176,6 @@ LongParameterList:NOAAWmsTileSource.kt$NOAAWmsTileSource$( aName: String, aBaseUrl: Array<String>, layername: String, version: String, time: String?, srs: String, style: String?, format: String, ) LongParameterList:OnlineTileSourceAuth.kt$OnlineTileSourceAuth$( aName: String, aZoomLevel: Int, aZoomMaxLevel: Int, aTileSizePixels: Int, aImageFileNameEnding: String, aBaseUrl: Array<String>, pCopyright: String, tileSourcePolicy: TileSourcePolicy, layerName: String?, apiKey: String ) LongParameterList:RadioInterfaceService.kt$RadioInterfaceService$( private val context: Application, private val dispatchers: CoroutineDispatchers, private val bluetoothRepository: BluetoothRepository, private val networkRepository: NetworkRepository, private val processLifecycle: Lifecycle, @RadioRepositoryQualifier private val prefs: SharedPreferences, private val interfaceFactory: InterfaceFactory, ) - LongParameterList:UIState.kt$UIViewModel$( private val app: Application, val nodeDB: NodeDB, private val radioConfigRepository: RadioConfigRepository, private val radioInterfaceService: RadioInterfaceService, private val meshLogRepository: MeshLogRepository, private val packetRepository: PacketRepository, private val quickChatActionRepository: QuickChatActionRepository, private val preferences: SharedPreferences ) MagicNumber:BatteryInfo.kt$100 MagicNumber:BatteryInfo.kt$101 MagicNumber:BatteryInfo.kt$14 @@ -128,52 +215,10 @@ MagicNumber:ChannelOption.kt$ChannelOption.SHORT_FAST$.250f MagicNumber:ChannelOption.kt$ChannelOption.SHORT_SLOW$.250f MagicNumber:ChannelOption.kt$ChannelOption.VERY_LONG_SLOW$.0625f - MagicNumber:ChannelOption.kt$RegionInfo.ANZ$915.0f - MagicNumber:ChannelOption.kt$RegionInfo.ANZ$928.0f - MagicNumber:ChannelOption.kt$RegionInfo.CN$470.0f - MagicNumber:ChannelOption.kt$RegionInfo.CN$510.0f - MagicNumber:ChannelOption.kt$RegionInfo.EU_433$433.0f - MagicNumber:ChannelOption.kt$RegionInfo.EU_433$434.0f - MagicNumber:ChannelOption.kt$RegionInfo.EU_868$869.4f - MagicNumber:ChannelOption.kt$RegionInfo.EU_868$869.65f - MagicNumber:ChannelOption.kt$RegionInfo.IN$865.0f - MagicNumber:ChannelOption.kt$RegionInfo.IN$867.0f - MagicNumber:ChannelOption.kt$RegionInfo.JP$920.8f - MagicNumber:ChannelOption.kt$RegionInfo.JP$927.8f - MagicNumber:ChannelOption.kt$RegionInfo.KR$920.0f - MagicNumber:ChannelOption.kt$RegionInfo.KR$923.0f - MagicNumber:ChannelOption.kt$RegionInfo.LORA_24$2400.0f - MagicNumber:ChannelOption.kt$RegionInfo.LORA_24$2483.5f - MagicNumber:ChannelOption.kt$RegionInfo.MY_433$433.0f - MagicNumber:ChannelOption.kt$RegionInfo.MY_433$435.0f - MagicNumber:ChannelOption.kt$RegionInfo.MY_919$919.0f - MagicNumber:ChannelOption.kt$RegionInfo.MY_919$924.0f - MagicNumber:ChannelOption.kt$RegionInfo.NZ_865$864.0f - MagicNumber:ChannelOption.kt$RegionInfo.NZ_865$868.0f - MagicNumber:ChannelOption.kt$RegionInfo.RU$868.7f - MagicNumber:ChannelOption.kt$RegionInfo.RU$869.2f - MagicNumber:ChannelOption.kt$RegionInfo.SG_923$917.0f - MagicNumber:ChannelOption.kt$RegionInfo.SG_923$925.0f - MagicNumber:ChannelOption.kt$RegionInfo.TH$920.0f - MagicNumber:ChannelOption.kt$RegionInfo.TH$925.0f - MagicNumber:ChannelOption.kt$RegionInfo.TW$920.0f - MagicNumber:ChannelOption.kt$RegionInfo.TW$925.0f - MagicNumber:ChannelOption.kt$RegionInfo.UA_433$433.0f - MagicNumber:ChannelOption.kt$RegionInfo.UA_433$434.7f - MagicNumber:ChannelOption.kt$RegionInfo.UA_868$868.0f - MagicNumber:ChannelOption.kt$RegionInfo.UA_868$868.6f - MagicNumber:ChannelOption.kt$RegionInfo.UNSET$902.0f - MagicNumber:ChannelOption.kt$RegionInfo.UNSET$928.0f - MagicNumber:ChannelOption.kt$RegionInfo.US$902.0f - MagicNumber:ChannelOption.kt$RegionInfo.US$928.0f MagicNumber:ChannelSet.kt$40 MagicNumber:ChannelSet.kt$960 MagicNumber:ContactsFragment.kt$ContactsFragment.ActionModeCallback$7 MagicNumber:ContactsFragment.kt$ContactsFragment.ActionModeCallback$8 - MagicNumber:ContactsViewModel.kt$1000L - MagicNumber:ContactsViewModel.kt$24 - MagicNumber:ContactsViewModel.kt$60 - MagicNumber:ContextServices.kt$29 MagicNumber:ContextServices.kt$33 MagicNumber:DataPacket.kt$DataPacket.CREATOR$16 MagicNumber:DebugFragment.kt$DebugFragment$3 @@ -193,9 +238,6 @@ MagicNumber:DeviceSettingsFragment.kt$ModuleRoute.TELEMETRY$5 MagicNumber:DeviceVersion.kt$DeviceVersion$100 MagicNumber:DeviceVersion.kt$DeviceVersion$10000 - MagicNumber:DistanceExtensions.kt$DistanceUnit.FEET$3.28084F - MagicNumber:DistanceExtensions.kt$DistanceUnit.KILOMETERS$0.001F - MagicNumber:DistanceExtensions.kt$DistanceUnit.MILES$0.000621371F MagicNumber:DownloadButton.kt$1.25f MagicNumber:EditChannelDialog.kt$16 MagicNumber:EditChannelDialog.kt$32 @@ -215,10 +257,7 @@ MagicNumber:Extensions.kt$24 MagicNumber:Extensions.kt$2880 MagicNumber:Extensions.kt$60 - MagicNumber:IconButton.kt$1.5f MagicNumber:LazyColumnDragAndDropDemo.kt$50 - MagicNumber:LinkedCoordinates.kt$122.4194 - MagicNumber:LinkedCoordinates.kt$37.7749 MagicNumber:LocationRepository.kt$LocationRepository$1000L MagicNumber:LocationRepository.kt$LocationRepository$30 MagicNumber:LocationRepository.kt$LocationRepository$31 @@ -226,7 +265,6 @@ MagicNumber:LocationUtils.kt$111320 MagicNumber:LocationUtils.kt$180 MagicNumber:LocationUtils.kt$1e-7 - MagicNumber:LocationUtils.kt$3.14169 MagicNumber:LocationUtils.kt$360 MagicNumber:LocationUtils.kt$360.0 MagicNumber:LocationUtils.kt$3600.0 @@ -249,12 +287,8 @@ MagicNumber:MapFragment.kt$3.0f MagicNumber:MapFragment.kt$40f MagicNumber:MapFragment.kt$<no name provided>$1e7 - MagicNumber:MarkerWithLabel.kt$MarkerWithLabel$2F MagicNumber:MarkerWithLabel.kt$MarkerWithLabel$3 - MagicNumber:MarkerWithLabel.kt$MarkerWithLabel$30f - MagicNumber:MarkerWithLabel.kt$MarkerWithLabel$8F MagicNumber:MeshService.kt$MeshService$0xffffffff - MagicNumber:MeshService.kt$MeshService$0xffffffffL MagicNumber:MeshService.kt$MeshService$100 MagicNumber:MeshService.kt$MeshService$1000 MagicNumber:MeshService.kt$MeshService$1000.0 @@ -262,8 +296,6 @@ MagicNumber:MeshService.kt$MeshService$16 MagicNumber:MeshService.kt$MeshService$30 MagicNumber:MeshService.kt$MeshService$32 - MagicNumber:MeshService.kt$MeshService$5 - MagicNumber:MeshService.kt$MeshService$60 MagicNumber:MeshService.kt$MeshService$60000 MagicNumber:MeshService.kt$MeshService$8 MagicNumber:MessagesFragment.kt$1000L @@ -276,7 +308,6 @@ MagicNumber:MockInterface.kt$MockInterface$2000 MagicNumber:MockInterface.kt$MockInterface$32.776665 MagicNumber:MockInterface.kt$MockInterface$32.960758 - MagicNumber:MockInterface.kt$MockInterface$35 MagicNumber:MockInterface.kt$MockInterface$96.733521 MagicNumber:MockInterface.kt$MockInterface$96.796989 MagicNumber:NOAAWmsTileSource.kt$NOAAWmsTileSource$180 @@ -284,10 +315,7 @@ MagicNumber:NOAAWmsTileSource.kt$NOAAWmsTileSource$360.0 MagicNumber:NOAAWmsTileSource.kt$NOAAWmsTileSource$4 MagicNumber:NOAAWmsTileSource.kt$NOAAWmsTileSource$5 - MagicNumber:NodeInfo.kt$0x33FFFFFF MagicNumber:NodeInfo.kt$DeviceMetrics.Companion$1000 - MagicNumber:NodeInfo.kt$EnvironmentMetrics$1.8F - MagicNumber:NodeInfo.kt$EnvironmentMetrics$32 MagicNumber:NodeInfo.kt$EnvironmentMetrics.Companion$1000 MagicNumber:NodeInfo.kt$NodeInfo$0.114 MagicNumber:NodeInfo.kt$NodeInfo$0.299 @@ -314,9 +342,6 @@ MagicNumber:NodeMenu.kt$3 MagicNumber:PacketRepository.kt$PacketRepository$500 MagicNumber:PacketResponseStateDialog.kt$100 - MagicNumber:PositionPrecisionPreference.kt$PositionPrecision.HIGH_PRECISION$32 - MagicNumber:PositionPrecisionPreference.kt$PositionPrecision.LOW_PRECISION$11 - MagicNumber:PositionPrecisionPreference.kt$PositionPrecision.MED_PRECISION$16 MagicNumber:ProbeTableProvider.kt$ProbeTableProvider$21972 MagicNumber:ProbeTableProvider.kt$ProbeTableProvider$32809 MagicNumber:ProbeTableProvider.kt$ProbeTableProvider$6790 @@ -330,7 +355,6 @@ MagicNumber:SerialConnectionImpl.kt$SerialConnectionImpl$115200 MagicNumber:SerialConnectionImpl.kt$SerialConnectionImpl$200 MagicNumber:ServiceClient.kt$ServiceClient$500 - MagicNumber:SignalInfo.kt$100F MagicNumber:SoftwareUpdateService.kt$0xFF MagicNumber:SoftwareUpdateService.kt$16 MagicNumber:SoftwareUpdateService.kt$24 @@ -369,15 +393,10 @@ MaxLineLength:BluetoothInterface.kt$BluetoothInterface$null MaxLineLength:BluetoothState.kt$BluetoothState$"BluetoothState(hasPermissions=$hasPermissions, enabled=$enabled, bondedDevices=${bondedDevices.map { it.anonymize }})" MaxLineLength:Channel.kt$Channel$// We have a new style 'empty' channel name. Use the same logic from the device to convert that to a human readable name - MaxLineLength:Channel.kt$Channel$/// Return the name of our channel as a human readable string. If empty string, assume "Default" per mesh.proto spec - MaxLineLength:ChannelFragment.kt$color = if (!enabled) MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.disabled) else Color.Unspecified - MaxLineLength:ChannelSettingsItemList.kt$color = if (!enabled) MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.disabled) else Color.Unspecified - MaxLineLength:ContextServices.kt$get MaxLineLength:ContextServices.kt$val Context.locationManager: LocationManager get() = requireNotNull(getSystemService(Context.LOCATION_SERVICE) as? LocationManager?) MaxLineLength:ContextServices.kt$val Context.notificationManager: NotificationManager get() = requireNotNull(getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager?) MaxLineLength:CustomTileSource.kt$CustomTileSource.Companion$arrayOf("https://new.nowcoast.noaa.gov/arcgis/services/nowcoast/radar_meteo_imagery_nexrad_time/MapServer/WmsServer?") MaxLineLength:DataPacket.kt$DataPacket$val dataType: Int - MaxLineLength:EditListPreference.kt$color = if (!enabled) MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.disabled) else Color.Unspecified MaxLineLength:LoRaConfigItemList.kt$value = if (isFocused || loraInput.overrideFrequency != 0f) loraInput.overrideFrequency else primaryChannel.radioFreq MaxLineLength:LocationRepository.kt$LocationRepository$info("Starting location updates with $providerList intervalMs=${intervalMs}ms and minDistanceM=${minDistanceM}m") MaxLineLength:MQTTRepository.kt$MQTTRepository.Companion$* @@ -391,40 +410,32 @@ MaxLineLength:MainActivity.kt$MainActivity$debug("Asked to open a channel URL - ask user if they want to switch to that channel. If so send the config to the radio") MaxLineLength:MeshService.kt$MeshService$* MaxLineLength:MeshService.kt$MeshService$* Send a mesh packet to the radio, if the radio is not currently connected this function will throw NotConnectedException - MaxLineLength:MeshService.kt$MeshService$// For the local node, it might not be able to update its times because it doesn't have a valid GPS reading yet + MaxLineLength:MeshService.kt$MeshService$// If we've received our initial config, our radio settings and all of our channels, send any queued packets and broadcast connected to clients MaxLineLength:MeshService.kt$MeshService$// Nodes periodically send out position updates, but those updates might not contain a lat & lon (because no GPS lock) MaxLineLength:MeshService.kt$MeshService$// Note: we do not haveNodeDB = true because that means we've got a valid db from a real device (rather than this possibly stale hint) MaxLineLength:MeshService.kt$MeshService$// Update last seen for the node that sent the packet, but also for _our node_ because anytime a packet passes MaxLineLength:MeshService.kt$MeshService$// Update our last seen based on any valid timestamps. If the device didn't provide a timestamp make one MaxLineLength:MeshService.kt$MeshService$// We always start foreground because that's how our service is always started (if we didn't then android would kill us) MaxLineLength:MeshService.kt$MeshService$// We like to look at the local node to see if it has been sending out valid lat/lon, so for the LOCAL node (only) + MaxLineLength:MeshService.kt$MeshService$// We prefer to find nodes based on their assigned IDs, but if no ID has been assigned to a node, we can also find it based on node number MaxLineLength:MeshService.kt$MeshService$// because apps really only care about important updates of node state - which handledReceivedData will give them MaxLineLength:MeshService.kt$MeshService$// causes the phone to try and reconnect. If we fail downloading our initial radio state we don't want to + MaxLineLength:MeshService.kt$MeshService$// logAssert(earlyReceivedPackets.size < 128) // The max should normally be about 32, but if the device is messed up it might try to send forever MaxLineLength:MeshService.kt$MeshService$// note: no need to call startDeviceSleep(), because this exception could only have reached us if it was already called - MaxLineLength:MeshService.kt$MeshService$/// If we've received our initial config, our radio settings and all of our channels, send any queued packets and broadcast connected to clients - MaxLineLength:MeshService.kt$MeshService$/// We prefer to find nodes based on their assigned IDs, but if no ID has been assigned to a node, we can also find it based on node number - MaxLineLength:MeshService.kt$MeshService$//logAssert(earlyReceivedPackets.size < 128) // The max should normally be about 32, but if the device is messed up it might try to send forever MaxLineLength:MeshService.kt$MeshService$MeshProtos.FromRadio.MQTTCLIENTPROXYMESSAGE_FIELD_NUMBER -> handleMqttProxyMessage(proto.mqttClientProxyMessage) MaxLineLength:MeshService.kt$MeshService$debug("Received nodeinfo num=${info.num}, hasUser=${info.hasUser()}, hasPosition=${info.hasPosition()}, hasDeviceMetrics=${info.hasDeviceMetrics()}") - MaxLineLength:MeshService.kt$MeshService.Companion$/// generate a RECEIVED action filter string that includes either the portnumber as an int, or preferably a symbolic name from portnums.proto - MaxLineLength:MeshService.kt$MeshService.Companion.IsUpdatingException$/** We treat software update as similar to loss of comms to the regular bluetooth service (so things like sendPosition for background GPS ignores the problem */ + MaxLineLength:MeshService.kt$MeshService.Companion$// generate a RECEIVED action filter string that includes either the portnumber as an int, or preferably a symbolic name from portnums.proto MaxLineLength:MeshServiceBroadcasts.kt$MeshServiceBroadcasts$context.sendBroadcast(intent) MaxLineLength:MeshServiceNotifications.kt$MeshServiceNotifications$// If running on really old versions of android (<= 5.1.1) (possibly only cyanogen) we might encounter a bug with setting application specific icons - MaxLineLength:MessagesFragment.kt$MessagesFragment$button.backgroundTintList = ContextCompat.getColorStateList(requireActivity(), R.color.colorMyMsg) - MaxLineLength:NodeInfo.kt$MeshUser$return "MeshUser(id=${id.anonymize}, longName=${longName.anonymize}, shortName=${shortName.anonymize}, hwModel=${hwModelString}, isLicensed=${isLicensed})" MaxLineLength:NodeInfo.kt$NodeInfo$prefUnits == ConfigProtos.Config.DisplayConfig.DisplayUnits.IMPERIAL_VALUE && dist < 1609 -> "%.0f ft".format(dist.toDouble()*3.281) MaxLineLength:NodeInfo.kt$NodeInfo$prefUnits == ConfigProtos.Config.DisplayConfig.DisplayUnits.IMPERIAL_VALUE && dist >= 1609 -> "%.1f mi".format(dist / 1609.34) MaxLineLength:NodeInfo.kt$NodeInfo$prefUnits == ConfigProtos.Config.DisplayConfig.DisplayUnits.METRIC_VALUE && dist < 1000 -> "%.0f m".format(dist.toDouble()) MaxLineLength:NodeInfo.kt$NodeInfo$prefUnits == ConfigProtos.Config.DisplayConfig.DisplayUnits.METRIC_VALUE && dist >= 1000 -> "%.1f km".format(dist / 1000.0) MaxLineLength:NodeInfo.kt$Position$/** MaxLineLength:NodeInfo.kt$Position$return "Position(lat=${latitude.anonymize}, lon=${longitude.anonymize}, alt=${altitude.anonymize}, time=${time})" - MaxLineLength:NodeInfoDao.kt$NodeInfoDao$@Query("SELECT * FROM NodeInfo ORDER BY CASE WHEN num = (SELECT myNodeNum FROM MyNodeInfo LIMIT 1) THEN 0 ELSE 1 END, lastHeard DESC") MaxLineLength:PositionConfigItemList.kt$. - MaxLineLength:QuickChatSettingsFragment.kt$QuickChatSettingsFragment$if (builder.modeSwitch.isChecked) QuickChatAction.Mode.Instant else QuickChatAction.Mode.Append MaxLineLength:RadioInterfaceService.kt$RadioInterfaceService$/** MaxLineLength:RadioInterfaceService.kt$RadioInterfaceService$// If we are running on the emulator we default to the mock interface, so we can have some data to show to the user - MaxLineLength:RegularPreference.kt$color - MaxLineLength:RegularPreference.kt$color = if (!enabled) MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.disabled) else Color.Unspecified MaxLineLength:SafeBluetooth.kt$SafeBluetooth$* MaxLineLength:SafeBluetooth.kt$SafeBluetooth$* mtu operations seem to hang sometimes. To cope with this we have a 5 second timeout before throwing an exception and cancelling the work MaxLineLength:SafeBluetooth.kt$SafeBluetooth$// Attempt to invoke virtual method 'com.android.bluetooth.gatt.AdvertiseClient com.android.bluetooth.gatt.AdvertiseManager.getAdvertiseClient(int)' on a null object reference @@ -452,102 +463,211 @@ MaxLineLength:StreamInterface.kt$StreamInterface$deliverPacket() MaxLineLength:StreamInterface.kt$StreamInterface$lostSync() MaxLineLength:StreamInterface.kt$StreamInterface$service.onDisconnect(isPermanent = true) - MaxLineLength:SwitchPreference.kt$color = if (!enabled) MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.disabled) else Color.Unspecified MaxLineLength:TextDividerPreference.kt$color = if (!enabled) MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.disabled) else Color.Unspecified MaxLineLength:UIState.kt$UIViewModel$// date,time,from,sender name,sender lat,sender long,rx lat,rx long,rx elevation,rx snr,distance,hop limit,payload MaxLineLength:UIState.kt$UIViewModel$writer.appendLine("$rxDateTime,\"$rxFrom\",\"$senderName\",\"$senderLat\",\"$senderLong\",\"$rxLat\",\"$rxLong\",\"$rxAlt\",\"$rxSnr\",\"$dist\",\"$hopLimit\",\"$payload\"") MaxLineLength:UIState.kt$UIViewModel$writer.appendLine("\"date\",\"time\",\"from\",\"sender name\",\"sender lat\",\"sender long\",\"rx lat\",\"rx long\",\"rx elevation\",\"rx snr\",\"distance\",\"hop limit\",\"payload\"") MayBeConst:AppPrefs.kt$AppPrefs.Companion$private val baseName = "appPrefs_" + MultiLineIfElse:BluetoothInterface.kt$BluetoothInterface$doDiscoverServicesAndInit() + MultiLineIfElse:BluetoothInterface.kt$BluetoothInterface$s.asyncDiscoverServices { discRes -> try { discRes.getOrThrow() service.serviceScope.handledLaunch { try { debug("Discovered services!") delay(1000) // android BLE is buggy and needs a 500ms sleep before calling getChracteristic, or you might get back null /* if (isFirstTime) { isFirstTime = false throw BLEException("Faking a BLE failure") } */ fromNum = getCharacteristic(BTM_FROMNUM_CHARACTER) // We treat the first send by a client as special isFirstSend = true // Now tell clients they can (finally use the api) service.onConnect() // Immediately broadcast any queued packets sitting on the device doReadFromRadio(true) } catch (ex: BLEException) { scheduleReconnect( "Unexpected error in initial device enumeration, forcing disconnect $ex" ) } } } catch (ex: BLEException) { if (s.gatt == null) warn("GATT was closed while discovering, assume we are shutting down") else scheduleReconnect( "Unexpected error discovering services, forcing disconnect $ex" ) } } + MultiLineIfElse:BluetoothInterface.kt$BluetoothInterface$safe?.asyncRequestMtu(512) { mtuRes -> try { mtuRes.getOrThrow() debug("MTU change attempted") // throw BLEException("Test MTU set failed") doDiscoverServicesAndInit() } catch (ex: BLEException) { shouldSetMtu = false scheduleReconnect( "Giving up on setting MTUs, forcing disconnect $ex" ) } } + MultiLineIfElse:BluetoothInterface.kt$BluetoothInterface$scheduleReconnect( "Unexpected error discovering services, forcing disconnect $ex" ) + MultiLineIfElse:BluetoothInterface.kt$BluetoothInterface$startConnect() + MultiLineIfElse:BluetoothInterface.kt$BluetoothInterface$startWatchingFromNum() + MultiLineIfElse:BluetoothInterface.kt$BluetoothInterface$warn("GATT was closed while discovering, assume we are shutting down") + MultiLineIfElse:BluetoothInterface.kt$BluetoothInterface$warn("Interface is shutting down, so skipping discover") + MultiLineIfElse:BluetoothInterface.kt$BluetoothInterface$warn("Not connecting, because safe==null, someone must have closed us") + MultiLineIfElse:BluetoothRepository.kt$BluetoothRepository$bondedDevices.filter { it.name?.matches(Regex(BLE_NAME_PATTERN)) == true } + MultiLineIfElse:BluetoothRepository.kt$BluetoothRepository$emptyList() + MultiLineIfElse:BuildUtils.kt$BuildUtils$return Build.SUPPORTED_64_BIT_ABIS.size > 0 + MultiLineIfElse:BuildUtils.kt$BuildUtils$return false + MultiLineIfElse:Channel.kt$Channel$"Custom" + MultiLineIfElse:Channel.kt$Channel$when (loraConfig.modemPreset) { ModemPreset.SHORT_TURBO -> "ShortTurbo" ModemPreset.SHORT_FAST -> "ShortFast" ModemPreset.SHORT_SLOW -> "ShortSlow" ModemPreset.MEDIUM_FAST -> "MediumFast" ModemPreset.MEDIUM_SLOW -> "MediumSlow" ModemPreset.LONG_FAST -> "LongFast" ModemPreset.LONG_SLOW -> "LongSlow" ModemPreset.LONG_MODERATE -> "LongMod" ModemPreset.VERY_LONG_SLOW -> "VLongSlow" else -> "Invalid" } + MultiLineIfElse:ChannelFragment.kt$channelSet = copy { settings.add(it) } + MultiLineIfElse:ChannelFragment.kt$channelSet = copy { settings[index] = it } + MultiLineIfElse:ChannelFragment.kt$item { PreferenceFooter( enabled = enabled, onCancelClicked = { focusManager.clearFocus() showChannelEditor = false channelSet = channels }, onSaveClicked = { focusManager.clearFocus() // viewModel.setRequestChannelUrl(channelUrl) sendButton() }) } + MultiLineIfElse:ChannelOption.kt$when (bandwidth) { 31 -> .03125f 62 -> .0625f 200 -> .203125f 400 -> .40625f 800 -> .8125f 1600 -> 1.6250f else -> bandwidth / 1000f } + MultiLineIfElse:ContextServices.kt$MaterialAlertDialogBuilder(this) .setTitle(title) .setMessage(rationale) .setNeutralButton(R.string.cancel) { _, _ -> } .setPositiveButton(R.string.accept) { _, _ -> invokeFun() } .show() + MultiLineIfElse:ContextServices.kt$invokeFun() + MultiLineIfElse:DeviceSettingsFragment.kt$AlertDialog( onDismissRequest = {}, shape = RoundedCornerShape(16.dp), backgroundColor = MaterialTheme.colors.background, title = { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center, ) { Icon( imageVector = Icons.TwoTone.Warning, contentDescription = "warning", modifier = Modifier.padding(end = 8.dp) ) Text( text = "${stringResource(title)}?\n") Icon( imageVector = Icons.TwoTone.Warning, contentDescription = "warning", modifier = Modifier.padding(start = 8.dp) ) } }, buttons = { Row( modifier = Modifier .fillMaxWidth() .padding(start = 16.dp, end = 16.dp, bottom = 16.dp), horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically, ) { TextButton( modifier = Modifier.weight(1f), onClick = { showDialog = false }, ) { Text(stringResource(R.string.cancel)) } Button( modifier = Modifier.weight(1f), onClick = { showDialog = false onClick() }, ) { Text(stringResource(R.string.send)) } } } ) + MultiLineIfElse:DeviceSettingsFragment.kt$EditDeviceProfileDialog( title = if (deviceProfile != null) "Import configuration" else "Export configuration", deviceProfile = deviceProfile ?: viewModel.currentDeviceProfile, onConfirm = { showEditDeviceProfileDialog = false if (deviceProfile != null) { viewModel.installProfile(it) } else { viewModel.setDeviceProfile(it) val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply { addCategory(Intent.CATEGORY_OPENABLE) type = "application/*" putExtra(Intent.EXTRA_TITLE, "${destNum.toUInt()}.cfg") } exportConfigLauncher.launch(intent) } }, onDismiss = { showEditDeviceProfileDialog = false viewModel.setDeviceProfile(null) } ) + MultiLineIfElse:DeviceSettingsFragment.kt$PacketResponseStateDialog( radioConfigState.responseState, onDismiss = { showEditDeviceProfileDialog = false viewModel.clearPacketResponse() }, onComplete = { val route = radioConfigState.route if (ConfigRoute.entries.any { it.name == route } || ModuleRoute.entries.any { it.name == route }) { navController.navigate(route) viewModel.clearPacketResponse() } } ) + MultiLineIfElse:EditListPreference.kt$EditBase64Preference( title = "${index + 1}/$maxCount", value = value, enabled = enabled, keyboardActions = keyboardActions, onValueChange = { listState[index] = it as T onValuesChanged(listState) }, modifier = modifier.fillMaxWidth(), trailingIcon = trailingIcon, ) + MultiLineIfElse:EditListPreference.kt$EditTextPreference( title = "${index + 1}/$maxCount", value = value, enabled = enabled, keyboardActions = keyboardActions, onValueChanged = { listState[index] = it as T onValuesChanged(listState) }, modifier = modifier.fillMaxWidth(), trailingIcon = trailingIcon, ) + MultiLineIfElse:EditPasswordPreference.kt$painterResource(R.drawable.ic_twotone_visibility_24) + MultiLineIfElse:EditPasswordPreference.kt$painterResource(R.drawable.ic_twotone_visibility_off_24) + MultiLineIfElse:EditTextPreference.kt$it.toDoubleOrNull()?.let { double -> valueState = it onValueChanged(double) } + MultiLineIfElse:EditTextPreference.kt$it.toFloatOrNull()?.let { float -> valueState = it onValueChanged(float) } + MultiLineIfElse:EditTextPreference.kt$it.toUIntOrNull()?.toInt()?.let { int -> valueState = it onValueChanged(int) } + MultiLineIfElse:EditTextPreference.kt$onValueChanged(it) + MultiLineIfElse:EditTextPreference.kt$valueState = it + MultiLineIfElse:EditWaypointDialog.kt$AlertDialog( onDismissRequest = onDismissRequest, shape = RoundedCornerShape(16.dp), backgroundColor = MaterialTheme.colors.background, text = { Column(modifier = modifier.fillMaxWidth()) { Text( text = stringResource(title), style = MaterialTheme.typography.h6.copy( fontWeight = FontWeight.Bold, textAlign = TextAlign.Center, ), modifier = Modifier .fillMaxWidth() .padding(bottom = 16.dp), ) EditTextPreference( title = stringResource(R.string.name), value = waypointInput.name, maxSize = 29, // name max_size:30 enabled = true, isError = false, keyboardOptions = KeyboardOptions.Default.copy( keyboardType = KeyboardType.Text, imeAction = ImeAction.Done ), keyboardActions = KeyboardActions(onDone = { /*TODO*/ }), onValueChanged = { waypointInput = waypointInput.copy { name = it } }, trailingIcon = { IconButton(onClick = { showEmojiPickerView = true }) { Text( text = String(Character.toChars(emoji)), modifier = Modifier .background(MaterialTheme.colors.background, CircleShape) .padding(4.dp), fontSize = 24.sp, color = Color.Unspecified.copy(alpha = 1f), ) } }, ) EditTextPreference(title = stringResource(R.string.description), value = waypointInput.description, maxSize = 99, // description max_size:100 enabled = true, isError = false, keyboardOptions = KeyboardOptions.Default.copy( keyboardType = KeyboardType.Text, imeAction = ImeAction.Done ), keyboardActions = KeyboardActions(onDone = { /*TODO*/ }), onValueChanged = { waypointInput = waypointInput.copy { description = it } } ) Row( modifier = Modifier .fillMaxWidth() .size(48.dp), verticalAlignment = Alignment.CenterVertically ) { Image( painter = painterResource(R.drawable.ic_twotone_lock_24), contentDescription = stringResource(R.string.locked), ) Text(stringResource(R.string.locked)) Switch( modifier = Modifier .fillMaxWidth() .wrapContentWidth(Alignment.End), checked = waypointInput.lockedTo != 0, onCheckedChange = { waypointInput = waypointInput.copy { lockedTo = if (it) 1 else 0 } } ) } } }, buttons = { FlowRow( modifier = modifier.padding(start = 20.dp, end = 20.dp, bottom = 16.dp), horizontalArrangement = Arrangement.spacedBy(8.dp), verticalArrangement = Arrangement.Center, ) { TextButton( modifier = modifier.weight(1f), onClick = onDismissRequest ) { Text(stringResource(R.string.cancel)) } if (waypoint.id != 0) { Button( modifier = modifier.weight(1f), onClick = { onDeleteClicked(waypointInput) }, enabled = waypointInput.name.isNotEmpty(), ) { Text(stringResource(R.string.delete)) } } Button( modifier = modifier.weight(1f), onClick = { onSendClicked(waypointInput) }, enabled = waypointInput.name.isNotEmpty(), ) { Text(stringResource(R.string.send)) } } }, ) + MultiLineIfElse:Exceptions.kt$Exceptions.errormsg("ignoring exception", ex) + MultiLineIfElse:ExpireChecker.kt$ExpireChecker$doExpire() + MultiLineIfElse:ExternalNotificationConfigItemList.kt$item { SwitchPreference(title = "Output LED active high", checked = externalNotificationInput.active, enabled = enabled, onCheckedChange = { externalNotificationInput = externalNotificationInput.copy { active = it } }) } + MultiLineIfElse:ExternalNotificationConfigItemList.kt$item { SwitchPreference(title = "Use PWM buzzer", checked = externalNotificationInput.usePwm, enabled = enabled, onCheckedChange = { externalNotificationInput = externalNotificationInput.copy { usePwm = it } }) } + MultiLineIfElse:Logging.kt$Logging$printlog(Log.ERROR, tag(), "$msg (exception ${ex.message})") + MultiLineIfElse:Logging.kt$Logging$printlog(Log.ERROR, tag(), "$msg") + MultiLineIfElse:MapFragment.kt$<no name provided>$showEditWaypointDialog = waypoint { latitudeI = (p.latitude * 1e7).toInt() longitudeI = (p.longitude * 1e7).toInt() } + MultiLineIfElse:MapFragment.kt$CacheLayout( cacheEstimate = cacheEstimate, onExecuteJob = { startDownload() }, onCancelDownload = { downloadRegionBoundingBox = null map.overlays.removeAll { it is Polygon } map.invalidate() }, modifier = Modifier.align(Alignment.BottomCenter) ) + MultiLineIfElse:MapFragment.kt$Column( modifier = Modifier .padding(top = 16.dp, end = 16.dp) .align(Alignment.TopEnd), verticalArrangement = Arrangement.spacedBy(8.dp), ) { MapButton( onClick = { showMapStyleDialog() }, drawableRes = R.drawable.ic_twotone_layers_24, contentDescription = R.string.map_style_selection, ) MapButton( onClick = { if (context.hasLocationPermission()) { map.toggleMyLocation() } else { requestPermissionAndToggleLauncher.launch(context.getLocationPermissions()) } }, enabled = hasGps, drawableRes = if (myLocationOverlay == null) { R.drawable.ic_twotone_my_location_24 } else { R.drawable.ic_twotone_location_disabled_24 }, contentDescription = null, ) } + MultiLineIfElse:MapViewWithLifecycle.kt$try { acquire() } catch (e: SecurityException) { errormsg("WakeLock permission exception: ${e.message}") } catch (e: IllegalStateException) { errormsg("WakeLock acquire() exception: ${e.message}") } + MultiLineIfElse:MapViewWithLifecycle.kt$try { release() } catch (e: IllegalStateException) { errormsg("WakeLock release() exception: ${e.message}") } + MultiLineIfElse:MeshService.kt$MeshService$getDataPacketById(packetId)?.let { p -> if (p.status == m) return@handledLaunch packetRepository.get().updateMessageStatus(p, m) serviceBroadcasts.broadcastMessageStatus(packetId, m) } + MultiLineIfElse:MeshService.kt$MeshService$p + MultiLineIfElse:MeshService.kt$MeshService$p.copy { warn("Public key mismatch from $longName ($shortName)") publicKey = it.errorByteString } + MultiLineIfElse:MeshService.kt$MeshService.<no name provided>$try { sendNow(p) } catch (ex: Exception) { errormsg("Error sending message, so enqueueing", ex) enqueueForSending(p) } + MultiLineIfElse:NOAAWmsTileSource.kt$NOAAWmsTileSource$sb.append("service=WMS") + MultiLineIfElse:NodeInfo.kt$MeshUser$hwModel.name.replace('_', '-').replace('p', '.').lowercase() + MultiLineIfElse:NodeInfo.kt$MeshUser$null + MultiLineIfElse:RadioConfigViewModel.kt$RadioConfigViewModel$destNode.value?.user?.let { val user = MeshProtos.User.newBuilder() .setLongName(if (hasLongName()) longName else it.longName) .setShortName(if (hasShortName()) shortName else it.shortName) .setIsLicensed(it.isLicensed) .build() setOwner(user) } + MultiLineIfElse:RadioConfigViewModel.kt$RadioConfigViewModel$try { setChannels(channelUrl) } catch (ex: Exception) { errormsg("DeviceProfile channel import error", ex) setResponseStateError(ex.customMessage) } + MultiLineIfElse:RadioConfigViewModel.kt$RadioConfigViewModel$viewModelScope.launch { radioConfigRepository.replaceAllSettings(new) } + MultiLineIfElse:RadioInterfaceService.kt$RadioInterfaceService$startInterface() + MultiLineIfElse:SafeBluetooth.kt$SafeBluetooth$cb + MultiLineIfElse:SafeBluetooth.kt$SafeBluetooth$null + MultiLineIfElse:SafeBluetooth.kt$SafeBluetooth$startNewWork() + MultiLineIfElse:SafeBluetooth.kt$SafeBluetooth$throw AssertionError("currentWork was not null: $currentWork") + MultiLineIfElse:SafeBluetooth.kt$SafeBluetooth$warn("wor completed, but we already killed it via failsafetimer? status=$status, res=$res") + MultiLineIfElse:SafeBluetooth.kt$SafeBluetooth$work.completion.resume(Result.success(res) as Result<Nothing>) + MultiLineIfElse:SafeBluetooth.kt$SafeBluetooth$work.completion.resumeWithException( BLEStatusException( status, "Bluetooth status=$status while doing ${work.tag}" ) ) + MultiLineIfElse:SafeBluetooth.kt$SafeBluetooth.<no name provided>$completeWork(status, Unit) + MultiLineIfElse:SafeBluetooth.kt$SafeBluetooth.<no name provided>$completeWork(status, characteristic) + MultiLineIfElse:SafeBluetooth.kt$SafeBluetooth.<no name provided>$dropAndReconnect() + MultiLineIfElse:SafeBluetooth.kt$SafeBluetooth.<no name provided>$errormsg("Ignoring bogus onMtuChanged") + MultiLineIfElse:SafeBluetooth.kt$SafeBluetooth.<no name provided>$if (!characteristic.value.contentEquals(reliable)) { errormsg("A reliable write failed!") gatt.abortReliableWrite() completeWork( STATUS_RELIABLE_WRITE_FAILED, characteristic ) // skanky code to indicate failure } else { logAssert(gatt.executeReliableWrite()) // After this execute reliable completes - we can continue with normal operations (see onReliableWriteCompleted) } + MultiLineIfElse:SafeBluetooth.kt$SafeBluetooth.<no name provided>$lostConnection("lost connection") + MultiLineIfElse:SafeBluetooth.kt$SafeBluetooth.<no name provided>$warn("Received notification from $characteristic, but no handler registered") + MultiLineIfElse:TextDividerPreference.kt$Icon( trailingIcon, "trailingIcon", modifier = modifier .fillMaxWidth() .wrapContentWidth(Alignment.End), ) + MultiLineIfElse:UIState.kt$add(channel { role = when (i) { 0 -> ChannelProtos.Channel.Role.PRIMARY in 1..new.lastIndex -> ChannelProtos.Channel.Role.SECONDARY else -> ChannelProtos.Channel.Role.DISABLED } index = i settings = new.getOrNull(i) ?: channelSettings { } }) NestedBlockDepth:LanguageUtils.kt$LanguageUtils$fun getLanguageTags(context: Context): Map<String, String> NestedBlockDepth:MainActivity.kt$MainActivity$private fun onMeshConnectionChanged(newConnection: MeshService.ConnectionState) NestedBlockDepth:MeshService.kt$MeshService$private fun handleReceivedAdmin(fromNodeNum: Int, a: AdminProtos.AdminMessage) NestedBlockDepth:MeshService.kt$MeshService$private fun handleReceivedData(packet: MeshPacket) - NestedBlockDepth:RadioConfigViewModel.kt$RadioConfigViewModel$fun installProfile(protobuf: DeviceProfile) NestedBlockDepth:RadioConfigViewModel.kt$RadioConfigViewModel$private fun processPacketResponse(packet: MeshProtos.MeshPacket) NewLineAtEndOfFile:AppIntroduction.kt$com.geeksville.mesh.AppIntroduction.kt NewLineAtEndOfFile:AppPrefs.kt$com.geeksville.mesh.android.AppPrefs.kt NewLineAtEndOfFile:ApplicationModule.kt$com.geeksville.mesh.ApplicationModule.kt NewLineAtEndOfFile:BLEException.kt$com.geeksville.mesh.service.BLEException.kt NewLineAtEndOfFile:BluetoothInterfaceFactory.kt$com.geeksville.mesh.repository.radio.BluetoothInterfaceFactory.kt - NewLineAtEndOfFile:BluetoothInterfaceSpec.kt$com.geeksville.mesh.repository.radio.BluetoothInterfaceSpec.kt NewLineAtEndOfFile:BluetoothRepositoryModule.kt$com.geeksville.mesh.repository.bluetooth.BluetoothRepositoryModule.kt NewLineAtEndOfFile:BluetoothViewModel.kt$com.geeksville.mesh.model.BluetoothViewModel.kt NewLineAtEndOfFile:BootCompleteReceiver.kt$com.geeksville.mesh.service.BootCompleteReceiver.kt NewLineAtEndOfFile:Color.kt$com.geeksville.mesh.ui.theme.Color.kt - NewLineAtEndOfFile:ContactsViewModel.kt$com.geeksville.mesh.model.ContactsViewModel.kt NewLineAtEndOfFile:CoroutineDispatchers.kt$com.geeksville.mesh.CoroutineDispatchers.kt NewLineAtEndOfFile:Coroutines.kt$com.geeksville.mesh.concurrent.Coroutines.kt NewLineAtEndOfFile:CustomTileSource.kt$com.geeksville.mesh.model.map.CustomTileSource.kt - NewLineAtEndOfFile:DataPacket.kt$com.geeksville.mesh.DataPacket.kt NewLineAtEndOfFile:DatabaseModule.kt$com.geeksville.mesh.database.DatabaseModule.kt NewLineAtEndOfFile:DateUtils.kt$com.geeksville.mesh.android.DateUtils.kt NewLineAtEndOfFile:DebugLogFile.kt$com.geeksville.mesh.android.DebugLogFile.kt NewLineAtEndOfFile:DeferredExecution.kt$com.geeksville.mesh.concurrent.DeferredExecution.kt NewLineAtEndOfFile:DeviceVersion.kt$com.geeksville.mesh.model.DeviceVersion.kt NewLineAtEndOfFile:DeviceVersionTest.kt$com.geeksville.mesh.model.DeviceVersionTest.kt - NewLineAtEndOfFile:DistanceExtensions.kt$com.geeksville.mesh.util.DistanceExtensions.kt - NewLineAtEndOfFile:DragManageAdapter.kt$com.geeksville.mesh.ui.DragManageAdapter.kt NewLineAtEndOfFile:ElevationInfo.kt$com.geeksville.mesh.ui.compose.ElevationInfo.kt NewLineAtEndOfFile:ExpireChecker.kt$com.geeksville.mesh.android.ExpireChecker.kt - NewLineAtEndOfFile:InterfaceFactory.kt$com.geeksville.mesh.repository.radio.InterfaceFactory.kt - NewLineAtEndOfFile:InterfaceFactorySpi.kt$com.geeksville.mesh.repository.radio.InterfaceFactorySpi.kt NewLineAtEndOfFile:InterfaceId.kt$com.geeksville.mesh.repository.radio.InterfaceId.kt NewLineAtEndOfFile:InterfaceSpec.kt$com.geeksville.mesh.repository.radio.InterfaceSpec.kt - NewLineAtEndOfFile:LanguageUtils.kt$com.geeksville.mesh.util.LanguageUtils.kt - NewLineAtEndOfFile:LastHeardInfo.kt$com.geeksville.mesh.ui.LastHeardInfo.kt - NewLineAtEndOfFile:LinkedCoordinates.kt$com.geeksville.mesh.ui.LinkedCoordinates.kt NewLineAtEndOfFile:Logging.kt$com.geeksville.mesh.android.Logging.kt - NewLineAtEndOfFile:MeshLogDao.kt$com.geeksville.mesh.database.dao.MeshLogDao.kt - NewLineAtEndOfFile:MeshLogRepository.kt$com.geeksville.mesh.database.MeshLogRepository.kt NewLineAtEndOfFile:MockInterfaceFactory.kt$com.geeksville.mesh.repository.radio.MockInterfaceFactory.kt - NewLineAtEndOfFile:MockInterfaceSpec.kt$com.geeksville.mesh.repository.radio.MockInterfaceSpec.kt NewLineAtEndOfFile:NOAAWmsTileSource.kt$com.geeksville.mesh.model.map.NOAAWmsTileSource.kt - NewLineAtEndOfFile:NodeFilterTextField.kt$com.geeksville.mesh.ui.components.NodeFilterTextField.kt NewLineAtEndOfFile:NopInterface.kt$com.geeksville.mesh.repository.radio.NopInterface.kt NewLineAtEndOfFile:NopInterfaceFactory.kt$com.geeksville.mesh.repository.radio.NopInterfaceFactory.kt - NewLineAtEndOfFile:NopInterfaceSpec.kt$com.geeksville.mesh.repository.radio.NopInterfaceSpec.kt NewLineAtEndOfFile:OnlineTileSourceAuth.kt$com.geeksville.mesh.model.map.OnlineTileSourceAuth.kt NewLineAtEndOfFile:PreferenceCategory.kt$com.geeksville.mesh.ui.components.PreferenceCategory.kt NewLineAtEndOfFile:PreviewParameterProviders.kt$com.geeksville.mesh.ui.preview.PreviewParameterProviders.kt NewLineAtEndOfFile:ProbeTableProvider.kt$com.geeksville.mesh.repository.usb.ProbeTableProvider.kt - NewLineAtEndOfFile:QuickChatAction.kt$com.geeksville.mesh.database.entity.QuickChatAction.kt - NewLineAtEndOfFile:QuickChatActionAdapter.kt$com.geeksville.mesh.ui.QuickChatActionAdapter.kt NewLineAtEndOfFile:QuickChatActionDao.kt$com.geeksville.mesh.database.dao.QuickChatActionDao.kt NewLineAtEndOfFile:QuickChatActionRepository.kt$com.geeksville.mesh.database.QuickChatActionRepository.kt - NewLineAtEndOfFile:QuickChatSettingsFragment.kt$com.geeksville.mesh.ui.QuickChatSettingsFragment.kt NewLineAtEndOfFile:RadioNotConnectedException.kt$com.geeksville.mesh.service.RadioNotConnectedException.kt NewLineAtEndOfFile:RadioRepositoryModule.kt$com.geeksville.mesh.repository.radio.RadioRepositoryModule.kt NewLineAtEndOfFile:RegularPreference.kt$com.geeksville.mesh.ui.components.RegularPreference.kt NewLineAtEndOfFile:SafeBluetooth.kt$com.geeksville.mesh.service.SafeBluetooth.kt NewLineAtEndOfFile:SatelliteCountInfo.kt$com.geeksville.mesh.ui.compose.SatelliteCountInfo.kt NewLineAtEndOfFile:SerialConnection.kt$com.geeksville.mesh.repository.usb.SerialConnection.kt - NewLineAtEndOfFile:SerialConnectionImpl.kt$com.geeksville.mesh.repository.usb.SerialConnectionImpl.kt NewLineAtEndOfFile:SerialConnectionListener.kt$com.geeksville.mesh.repository.usb.SerialConnectionListener.kt NewLineAtEndOfFile:SerialInterface.kt$com.geeksville.mesh.repository.radio.SerialInterface.kt NewLineAtEndOfFile:SerialInterfaceFactory.kt$com.geeksville.mesh.repository.radio.SerialInterfaceFactory.kt - NewLineAtEndOfFile:SerialInterfaceSpec.kt$com.geeksville.mesh.repository.radio.SerialInterfaceSpec.kt - NewLineAtEndOfFile:ServiceClient.kt$com.geeksville.mesh.android.ServiceClient.kt NewLineAtEndOfFile:SoftwareUpdateService.kt$com.geeksville.mesh.service.SoftwareUpdateService.kt NewLineAtEndOfFile:SqlTileWriterExt.kt$com.geeksville.mesh.util.SqlTileWriterExt.kt - NewLineAtEndOfFile:StreamInterface.kt$com.geeksville.mesh.repository.radio.StreamInterface.kt NewLineAtEndOfFile:TCPInterfaceFactory.kt$com.geeksville.mesh.repository.radio.TCPInterfaceFactory.kt - NewLineAtEndOfFile:TCPInterfaceSpec.kt$com.geeksville.mesh.repository.radio.TCPInterfaceSpec.kt NewLineAtEndOfFile:Theme.kt$com.geeksville.mesh.ui.theme.Theme.kt NewLineAtEndOfFile:UsbBroadcastReceiver.kt$com.geeksville.mesh.repository.usb.UsbBroadcastReceiver.kt - NewLineAtEndOfFile:UsbRepository.kt$com.geeksville.mesh.repository.usb.UsbRepository.kt NewLineAtEndOfFile:UsbRepositoryModule.kt$com.geeksville.mesh.repository.usb.UsbRepositoryModule.kt + NoBlankLineBeforeRbrace:BluetoothInterface.kt$BluetoothInterface$ + NoBlankLineBeforeRbrace:CustomTileSource.kt$CustomTileSource$ + NoBlankLineBeforeRbrace:DebugLogFile.kt$BinaryLogFile$ + NoBlankLineBeforeRbrace:NOAAWmsTileSource.kt$NOAAWmsTileSource$ + NoBlankLineBeforeRbrace:NopInterface.kt$NopInterface$ + NoBlankLineBeforeRbrace:OnlineTileSourceAuth.kt$OnlineTileSourceAuth$ + NoBlankLineBeforeRbrace:PositionTest.kt$PositionTest$ + NoBlankLineBeforeRbrace:PreviewParameterProviders.kt$NodeInfoPreviewParameterProvider$ + NoBlankLineBeforeRbrace:QuickChatActionDao.kt$QuickChatActionDao$ + NoConsecutiveBlankLines:AppIntroduction.kt$AppIntroduction$ + NoConsecutiveBlankLines:AppPrefs.kt$ + NoConsecutiveBlankLines:BluetoothInterface.kt$ + NoConsecutiveBlankLines:BluetoothInterface.kt$BluetoothInterface$ + NoConsecutiveBlankLines:BootCompleteReceiver.kt$ + NoConsecutiveBlankLines:CommonCharts.kt$ + NoConsecutiveBlankLines:Constants.kt$ + NoConsecutiveBlankLines:CustomTileSource.kt$ + NoConsecutiveBlankLines:CustomTileSource.kt$CustomTileSource.Companion$ + NoConsecutiveBlankLines:DebugLogFile.kt$ + NoConsecutiveBlankLines:DeferredExecution.kt$ + NoConsecutiveBlankLines:EnvironmentMetrics.kt$ + NoConsecutiveBlankLines:Exceptions.kt$ + NoConsecutiveBlankLines:IRadioInterface.kt$ + NoConsecutiveBlankLines:NOAAWmsTileSource.kt$NOAAWmsTileSource$ + NoConsecutiveBlankLines:NodeInfo.kt$ + NoConsecutiveBlankLines:PositionTest.kt$ + NoConsecutiveBlankLines:PreviewParameterProviders.kt$ + NoConsecutiveBlankLines:SafeBluetooth.kt$ + NoConsecutiveBlankLines:SafeBluetooth.kt$SafeBluetooth$ + NoConsecutiveBlankLines:SqlTileWriterExt.kt$ + NoEmptyClassBody:DebugLogFile.kt$BinaryLogFile${ } + NoSemicolons:DateUtils.kt$DateUtils$; + NoTrailingSpaces:ExpireChecker.kt$ExpireChecker$ + NoWildcardImports:BluetoothInterface.kt$import com.geeksville.mesh.service.* + NoWildcardImports:DeviceVersionTest.kt$import org.junit.Assert.* + NoWildcardImports:ExampleUnitTest.kt$import org.junit.Assert.* + NoWildcardImports:MainActivity.kt$import android.content.* + NoWildcardImports:MainActivity.kt$import com.geeksville.mesh.android.* + NoWildcardImports:MainActivity.kt$import com.geeksville.mesh.service.* + NoWildcardImports:MainActivity.kt$import com.geeksville.mesh.ui.* + NoWildcardImports:MeshService.kt$import com.geeksville.mesh.* + NoWildcardImports:MeshService.kt$import com.geeksville.mesh.util.* + NoWildcardImports:MockInterface.kt$import com.geeksville.mesh.* + NoWildcardImports:PreferenceFooter.kt$import androidx.compose.foundation.layout.* + NoWildcardImports:PreferenceFooter.kt$import androidx.compose.material.* + NoWildcardImports:QuickChatActionDao.kt$import androidx.room.* + NoWildcardImports:SafeBluetooth.kt$import android.bluetooth.* + NoWildcardImports:SafeBluetooth.kt$import kotlinx.coroutines.* + NoWildcardImports:SettingsFragment.kt$import com.geeksville.mesh.android.* + NoWildcardImports:UIState.kt$import com.geeksville.mesh.* + NoWildcardImports:UsbRepository.kt$import kotlinx.coroutines.flow.* OptionalAbstractKeyword:SyncContinuation.kt$Continuation$abstract + ParameterListWrapping:AppPrefs.kt$FloatPref$(thisRef: AppPrefs, prop: KProperty<Float>) + ParameterListWrapping:AppPrefs.kt$StringPref$(thisRef: AppPrefs, prop: KProperty<String>) + ParameterListWrapping:SafeBluetooth.kt$SafeBluetooth$( c: BluetoothGattCharacteristic, cont: Continuation<BluetoothGattCharacteristic>, timeout: Long = 0 ) + ParameterListWrapping:SafeBluetooth.kt$SafeBluetooth$( c: BluetoothGattCharacteristic, cont: Continuation<Unit>, timeout: Long = 0 ) + ParameterListWrapping:SafeBluetooth.kt$SafeBluetooth$( c: BluetoothGattCharacteristic, v: ByteArray, cont: Continuation<BluetoothGattCharacteristic>, timeout: Long = 0 ) + ParameterListWrapping:SafeBluetooth.kt$SafeBluetooth$( c: BluetoothGattDescriptor, cont: Continuation<BluetoothGattDescriptor>, timeout: Long = 0 ) RethrowCaughtException:SyncContinuation.kt$Continuation$throw ex ReturnCount:ChannelOption.kt$internal fun LoRaConfig.radioFreq(channelNum: Int): Float - ReturnCount:Extensions.kt$fun formatAgo(lastSeenUnix: Int): String ReturnCount:MainActivity.kt$MainActivity$override fun onOptionsItemSelected(item: MenuItem): Boolean ReturnCount:MeshService.kt$MeshService$private fun handleReceivedData(packet: MeshPacket) ReturnCount:RadioConfigViewModel.kt$RadioConfigViewModel$private fun processPacketResponse(packet: MeshProtos.MeshPacket) + SpacingAroundColon:PreviewParameterProviders.kt$NodeInfoPreviewParameterProvider$: + SpacingAroundCurly:AppPrefs.kt$FloatPref$} + SpacingAroundKeyword:AppPrefs.kt$AppPrefs$if + SpacingAroundKeyword:Exceptions.kt$if + SpacingAroundKeyword:Exceptions.kt$when + SpacingAroundOperators:NodeInfo.kt$NodeInfo$* + SpacingAroundRangeOperator:BatteryInfo.kt$.. + StringTemplate:NodeInfo.kt$Position$${time} SwallowedException:BluetoothInterface.kt$BluetoothInterface$ex: CancellationException SwallowedException:ChannelFragment.kt$ex: Throwable SwallowedException:ChannelSet.kt$ex: Throwable SwallowedException:DeviceVersion.kt$DeviceVersion$e: Exception - SwallowedException:EditChannelDialog.kt$ex: Throwable SwallowedException:Exceptions.kt$ex: Throwable SwallowedException:MainActivity.kt$MainActivity$ex: BindFailedException SwallowedException:MainActivity.kt$MainActivity$ex: IllegalStateException @@ -562,14 +682,12 @@ SwallowedException:SafeBluetooth.kt$SafeBluetooth$ex: NullPointerException SwallowedException:ServiceClient.kt$ServiceClient$ex: IllegalArgumentException SwallowedException:TCPInterface.kt$TCPInterface$ex: SocketTimeoutException - ThrowsCount:MeshService.kt$MeshService$private fun doFirmwareUpdate() TooGenericExceptionCaught:BTScanModel.kt$BTScanModel$ex: Throwable TooGenericExceptionCaught:BluetoothInterface.kt$BluetoothInterface$ex: Exception TooGenericExceptionCaught:ChannelFragment.kt$ex: Exception TooGenericExceptionCaught:ChannelFragment.kt$ex: Throwable TooGenericExceptionCaught:ChannelSet.kt$ex: Throwable TooGenericExceptionCaught:DeviceVersion.kt$DeviceVersion$e: Exception - TooGenericExceptionCaught:EditChannelDialog.kt$ex: Throwable TooGenericExceptionCaught:Exceptions.kt$ex: Throwable TooGenericExceptionCaught:LanguageUtils.kt$LanguageUtils$e: Exception TooGenericExceptionCaught:LocationRepository.kt$LocationRepository$e: Exception @@ -589,23 +707,18 @@ TooGenericExceptionCaught:TCPInterface.kt$TCPInterface$ex: Throwable TooGenericExceptionThrown:DeviceVersion.kt$DeviceVersion$throw Exception("Can't parse version $s") TooGenericExceptionThrown:MeshService.kt$MeshService$throw Exception("Can't set user without a NodeInfo") - TooGenericExceptionThrown:MeshService.kt$MeshService$throw Exception("Can't update - no bluetooth connected") - TooGenericExceptionThrown:MeshService.kt$MeshService$throw Exception("Firmware update already running") - TooGenericExceptionThrown:MeshService.kt$MeshService$throw Exception("No update filename") TooGenericExceptionThrown:MeshService.kt$MeshService.<no name provided>$throw Exception("Port numbers must be non-zero!") TooGenericExceptionThrown:ServiceClient.kt$ServiceClient$throw Exception("Haven't called connect") TooGenericExceptionThrown:ServiceClient.kt$ServiceClient$throw Exception("Service not bound") TooGenericExceptionThrown:SyncContinuation.kt$SyncContinuation$throw Exception("SyncContinuation timeout") TooGenericExceptionThrown:SyncContinuation.kt$SyncContinuation$throw Exception("This shouldn't happen") TooManyFunctions:AppPrefs.kt$AppPrefs - TooManyFunctions:BTScanModel.kt$BTScanModel : ViewModelLogging TooManyFunctions:BluetoothInterface.kt$BluetoothInterface : IRadioInterfaceLogging TooManyFunctions:ContextServices.kt$com.geeksville.mesh.android.ContextServices.kt TooManyFunctions:LocationUtils.kt$com.geeksville.mesh.util.LocationUtils.kt TooManyFunctions:MainActivity.kt$MainActivity : AppCompatActivityLogging TooManyFunctions:MeshService.kt$MeshService : ServiceLogging TooManyFunctions:MeshService.kt$MeshService$<no name provided> : Stub - TooManyFunctions:ModuleConfigRepository.kt$ModuleConfigRepository : Logging TooManyFunctions:PacketDao.kt$PacketDao TooManyFunctions:PacketRepository.kt$PacketRepository TooManyFunctions:RadioConfigRepository.kt$RadioConfigRepository @@ -614,19 +727,7 @@ TooManyFunctions:SafeBluetooth.kt$SafeBluetooth : LoggingCloseable TooManyFunctions:SettingsFragment.kt$SettingsFragment : ScreenFragmentLogging TooManyFunctions:UIState.kt$UIViewModel : ViewModelLogging - TopLevelPropertyNaming:ChannelSet.kt$internal const val URL_PREFIX = "https://meshtastic.org/e/#" - TopLevelPropertyNaming:Constants.kt$// a bool true means now connected, false means not const val EXTRA_CONNECTED = "$prefix.Connected" - TopLevelPropertyNaming:Constants.kt$/// a bool true means we expect this condition to continue until, false means device might come back const val EXTRA_PERMANENT = "$prefix.Permanent" - TopLevelPropertyNaming:Constants.kt$const val EXTRA_NODEINFO = "$prefix.NodeInfo" - TopLevelPropertyNaming:Constants.kt$const val EXTRA_PACKET_ID = "$prefix.PacketId" - TopLevelPropertyNaming:Constants.kt$const val EXTRA_PAYLOAD = "$prefix.Payload" - TopLevelPropertyNaming:Constants.kt$const val EXTRA_PROGRESS = "$prefix.Progress" - TopLevelPropertyNaming:Constants.kt$const val EXTRA_STATUS = "$prefix.Status" TopLevelPropertyNaming:Constants.kt$const val prefix = "com.geeksville.mesh" - TopLevelPropertyNaming:UsbManager.kt$private const val ACTION_USB_PERMISSION = "com.geeksville.mesh.USB_PERMISSION" - UnusedParameter:PositionPrecisionPreference.kt$modifier: Modifier = Modifier - UnusedPrivateMember:MeshService.kt$MeshService$private fun processQueuedPackets() - UnusedPrivateMember:MeshService.kt$MeshService$private fun requestAllConfig() UnusedPrivateMember:NOAAWmsTileSource.kt$NOAAWmsTileSource$private fun tile2lat(y: Int, z: Int): Double UnusedPrivateMember:NOAAWmsTileSource.kt$NOAAWmsTileSource$private fun tile2lon(x: Int, z: Int): Double UnusedPrivateMember:SafeBluetooth.kt$SafeBluetooth$private fun reconnect() @@ -635,8 +736,6 @@ UnusedPrivateProperty:CustomTileSource.kt$CustomTileSource.Companion$private val SEAMAP: OnlineTileSourceBase = TileSourceFactory.OPEN_SEAMAP UnusedPrivateProperty:CustomTileSource.kt$CustomTileSource.Companion$private val USGS_HYDRO_CACHE = object : OnlineTileSourceBase( "USGS Hydro Cache", 0, 18, 256, "", arrayOf( "https://basemap.nationalmap.gov/arcgis/rest/services/USGSHydroCached/MapServer/tile/" ), "USGS", TileSourcePolicy( 2, TileSourcePolicy.FLAG_NO_PREVENTIVE or TileSourcePolicy.FLAG_USER_AGENT_MEANINGFUL or TileSourcePolicy.FLAG_USER_AGENT_NORMALIZED ) ) { override fun getTileURLString(pMapTileIndex: Long): String { return baseUrl + (MapTileIndex.getZoom(pMapTileIndex) .toString() + "/" + MapTileIndex.getY(pMapTileIndex) + "/" + MapTileIndex.getX(pMapTileIndex) + mImageFilenameEnding) } } UnusedPrivateProperty:CustomTileSource.kt$CustomTileSource.Companion$private val USGS_SHADED_RELIEF = object : OnlineTileSourceBase( "USGS Shaded Relief Only", 0, 18, 256, "", arrayOf( "https://basemap.nationalmap.gov/arcgis/rest/services/USGSShadedReliefOnly/MapServer/tile/" ), "USGS", TileSourcePolicy( 2, TileSourcePolicy.FLAG_NO_PREVENTIVE or TileSourcePolicy.FLAG_USER_AGENT_MEANINGFUL or TileSourcePolicy.FLAG_USER_AGENT_NORMALIZED ) ) { override fun getTileURLString(pMapTileIndex: Long): String { return baseUrl + (MapTileIndex.getZoom(pMapTileIndex) .toString() + "/" + MapTileIndex.getY(pMapTileIndex) + "/" + MapTileIndex.getX(pMapTileIndex) + mImageFilenameEnding) } } - UnusedPrivateProperty:MeshService.kt$MeshService$val filename = firmwareUpdateFilename ?: throw Exception("No update filename") - UnusedPrivateProperty:MeshService.kt$MeshService$val isBluetoothInterface = a != null && a.startsWith("x") UtilityClassWithPublicConstructor:CustomTileSource.kt$CustomTileSource UtilityClassWithPublicConstructor:NetworkRepositoryModule.kt$NetworkRepositoryModule VariableNaming:NOAAWmsTileSource.kt$NOAAWmsTileSource$// Size of square world map in meters, using WebMerc projection. private val MAP_SIZE = 20037508.34789244 * 2 @@ -651,8 +750,6 @@ VariableNaming:SafeBluetooth.kt$SafeBluetooth$private val STATUS_NOSTART = 4405 VariableNaming:SafeBluetooth.kt$SafeBluetooth$private val STATUS_SIMFAILURE = 4406 VariableNaming:SafeBluetooth.kt$SafeBluetooth$private val STATUS_TIMEOUT = 4404 - WildcardImport:BTScanModel.kt$import android.content.* - WildcardImport:BTScanModel.kt$import com.geeksville.mesh.android.* WildcardImport:BluetoothInterface.kt$import com.geeksville.mesh.service.* WildcardImport:DeviceVersionTest.kt$import org.junit.Assert.* WildcardImport:ExampleUnitTest.kt$import org.junit.Assert.* @@ -662,8 +759,6 @@ WildcardImport:MainActivity.kt$import com.geeksville.mesh.ui.* WildcardImport:MeshService.kt$import com.geeksville.mesh.* WildcardImport:MeshService.kt$import com.geeksville.mesh.util.* - WildcardImport:MessagesFragment.kt$import android.view.* - WildcardImport:MessagesFragment.kt$import android.widget.* WildcardImport:MockInterface.kt$import com.geeksville.mesh.* WildcardImport:PreferenceFooter.kt$import androidx.compose.foundation.layout.* WildcardImport:PreferenceFooter.kt$import androidx.compose.material.* diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index 0a3cff99..eb528e77 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -304,6 +304,137 @@ exceptions: - 'RuntimeException' - 'Throwable' +formatting: + active: true + android: false + autoCorrect: true + AnnotationOnSeparateLine: + active: false + autoCorrect: true + AnnotationSpacing: + active: false + autoCorrect: true + ArgumentListWrapping: + active: false + autoCorrect: true + ChainWrapping: + active: true + autoCorrect: true + CommentSpacing: + active: true + autoCorrect: true + EnumEntryNameCase: + active: false + autoCorrect: true + Filename: + active: false + FinalNewline: + active: true + autoCorrect: true + insertFinalNewLine: true + ImportOrdering: + active: false + autoCorrect: true + layout: 'idea' + Indentation: + active: false + autoCorrect: true + indentSize: 4 + MaximumLineLength: + active: false # Use default detekt rule + maxLineLength: 120 + ModifierOrdering: + active: true + autoCorrect: true + MultiLineIfElse: + active: true + autoCorrect: true + NoBlankLineBeforeRbrace: + active: true + autoCorrect: true + NoConsecutiveBlankLines: + active: true + autoCorrect: true + NoEmptyClassBody: + active: true + autoCorrect: true + NoEmptyFirstLineInMethodBlock: + active: false + autoCorrect: true + NoLineBreakAfterElse: + active: true + autoCorrect: true + NoLineBreakBeforeAssignment: + active: true + autoCorrect: true + NoMultipleSpaces: + active: true + autoCorrect: true + NoSemicolons: + active: true + autoCorrect: true + NoTrailingSpaces: + active: true + autoCorrect: true + NoUnitReturn: + active: true + autoCorrect: true + NoUnusedImports: + active: true + autoCorrect: true + NoWildcardImports: + active: true + PackageName: + active: true + autoCorrect: true + ParameterListWrapping: + active: true + autoCorrect: true + SpacingAroundColon: + active: true + autoCorrect: true + SpacingAroundComma: + active: true + autoCorrect: true + SpacingAroundCurly: + active: true + autoCorrect: true + SpacingAroundDot: + active: true + autoCorrect: true + SpacingAroundDoubleColon: + active: false + autoCorrect: true + SpacingAroundKeyword: + active: true + autoCorrect: true + SpacingAroundOperators: + active: true + autoCorrect: true + SpacingAroundParens: + active: true + autoCorrect: true + SpacingAroundRangeOperator: + active: true + autoCorrect: true + SpacingBetweenDeclarationsWithAnnotations: + active: false + autoCorrect: true + SpacingBetweenDeclarationsWithComments: + active: false + autoCorrect: true + StringTemplate: + active: true + autoCorrect: true + TrailingCommaOnCallSite: + active: false + autoCorrect: true + useTrailingCommaOnCallSite: true + TrailingCommaOnDeclarationSite: + active: false + autoCorrect: true + useTrailingCommaOnDeclarationSite: true + naming: active: true BooleanPropertyNaming: