diff --git a/app/src/main/java/com/geeksville/mesh/MainActivity.kt b/app/src/main/java/com/geeksville/mesh/MainActivity.kt index b79a26156..f87fb87cb 100644 --- a/app/src/main/java/com/geeksville/mesh/MainActivity.kt +++ b/app/src/main/java/com/geeksville/mesh/MainActivity.kt @@ -41,6 +41,7 @@ import com.geeksville.android.ServiceClient import com.geeksville.concurrent.handledLaunch import com.geeksville.mesh.databinding.ActivityMainBinding import com.geeksville.mesh.model.Channel +import com.geeksville.mesh.model.ChannelSet import com.geeksville.mesh.model.UIViewModel import com.geeksville.mesh.service.* import com.geeksville.mesh.ui.* @@ -620,7 +621,7 @@ class MainActivity : AppCompatActivity(), Logging, debug("Getting latest radioconfig from service") try { model.radioConfig.value = - MeshProtos.RadioConfig.parseFrom(service.radioConfig) + RadioConfigProtos.RadioConfig.parseFrom(service.radioConfig) val info = service.myNodeInfo model.myNodeInfo.value = info @@ -654,19 +655,20 @@ class MainActivity : AppCompatActivity(), Logging, // If the is opening a channel URL, handle it now requestedChannelUrl?.let { url -> try { - val channel = Channel(url) + val channels = ChannelSet(url) + val primary = channels.primaryChannel requestedChannelUrl = null MaterialAlertDialogBuilder(this) .setTitle(R.string.new_channel_rcvd) - .setMessage(getString(R.string.do_you_want_switch).format(channel.name)) + .setMessage(getString(R.string.do_you_want_switch).format(primary.name)) .setNeutralButton(R.string.cancel) { _, _ -> // Do nothing } .setPositiveButton(R.string.accept) { _, _ -> debug("Setting channel from URL") try { - model.setChannel(channel.settings) + model.setChannels(channels) } catch (ex: RemoteException) { errormsg("Couldn't change channel ${ex.message}") Toast.makeText( 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 d19faed8e..5686bb209 100644 --- a/app/src/main/java/com/geeksville/mesh/model/Channel.kt +++ b/app/src/main/java/com/geeksville/mesh/model/Channel.kt @@ -3,6 +3,7 @@ package com.geeksville.mesh.model import android.graphics.Bitmap import android.net.Uri import android.util.Base64 +import com.geeksville.mesh.ChannelProtos import com.geeksville.mesh.MeshProtos import com.google.protobuf.ByteString import com.google.zxing.BarcodeFormat @@ -15,7 +16,7 @@ fun byteArrayOfInts(vararg ints: Int) = ByteArray(ints.size) { pos -> ints[pos]. data class Channel( - val settings: MeshProtos.ChannelSettings = MeshProtos.ChannelSettings.getDefaultInstance() + val settings: ChannelProtos.ChannelSettings = ChannelProtos.ChannelSettings.getDefaultInstance() ) { companion object { // Note: this string _SHOULD NOT BE LOCALIZED_ because it directly hashes to values used on the device for the default channel name. @@ -30,8 +31,8 @@ data class Channel( // Placeholder when emulating val emulated = Channel( - MeshProtos.ChannelSettings.newBuilder().setName(defaultChannelName) - .setModemConfig(MeshProtos.ChannelSettings.ModemConfig.Bw125Cr45Sf128).build() + ChannelProtos.ChannelSettings.newBuilder().setName(defaultChannelName) + .setModemConfig(ChannelProtos.ChannelSettings.ModemConfig.Bw125Cr45Sf128).build() ) } @@ -42,16 +43,16 @@ data class Channel( if (settings.bandwidth != 0) "Unset" else when (settings.modemConfig) { - MeshProtos.ChannelSettings.ModemConfig.Bw125Cr45Sf128 -> "Medium" - MeshProtos.ChannelSettings.ModemConfig.Bw500Cr45Sf128 -> "ShortFast" - MeshProtos.ChannelSettings.ModemConfig.Bw31_25Cr48Sf512 -> "LongAlt" - MeshProtos.ChannelSettings.ModemConfig.Bw125Cr48Sf4096 -> "LongSlow" + ChannelProtos.ChannelSettings.ModemConfig.Bw125Cr45Sf128 -> "Medium" + ChannelProtos.ChannelSettings.ModemConfig.Bw500Cr45Sf128 -> "ShortFast" + ChannelProtos.ChannelSettings.ModemConfig.Bw31_25Cr48Sf512 -> "LongAlt" + ChannelProtos.ChannelSettings.ModemConfig.Bw125Cr48Sf4096 -> "LongSlow" else -> "Invalid" } } else settings.name - val modemConfig: MeshProtos.ChannelSettings.ModemConfig get() = settings.modemConfig + val modemConfig: ChannelProtos.ChannelSettings.ModemConfig get() = settings.modemConfig val psk get() = if (settings.psk.size() != 1) 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 827624cd5..62409f4ff 100644 --- a/app/src/main/java/com/geeksville/mesh/model/ChannelOption.kt +++ b/app/src/main/java/com/geeksville/mesh/model/ChannelOption.kt @@ -1,22 +1,23 @@ -package com.geeksville.mesh.model - -import com.geeksville.mesh.MeshProtos -import com.geeksville.mesh.R - -enum class ChannelOption(val modemConfig: MeshProtos.ChannelSettings.ModemConfig, val configRes: Int, val minBroadcastPeriodSecs: Int) { - SHORT(MeshProtos.ChannelSettings.ModemConfig.Bw500Cr45Sf128, R.string.modem_config_short, 3), - MEDIUM(MeshProtos.ChannelSettings.ModemConfig.Bw125Cr45Sf128, R.string.modem_config_medium, 12), - LONG(MeshProtos.ChannelSettings.ModemConfig.Bw31_25Cr48Sf512, R.string.modem_config_long, 240), - VERY_LONG(MeshProtos.ChannelSettings.ModemConfig.Bw125Cr48Sf4096, R.string.modem_config_very_long, 375); - - companion object { - fun fromConfig(modemConfig: MeshProtos.ChannelSettings.ModemConfig?): ChannelOption? { - for (option in values()) { - if (option.modemConfig == modemConfig) - return option - } - return null - } - val defaultMinBroadcastPeriod = VERY_LONG.minBroadcastPeriodSecs - } +package com.geeksville.mesh.model + +import com.geeksville.mesh.ChannelProtos +import com.geeksville.mesh.MeshProtos +import com.geeksville.mesh.R + +enum class ChannelOption(val modemConfig: ChannelProtos.ChannelSettings.ModemConfig, val configRes: Int, val minBroadcastPeriodSecs: Int) { + SHORT(ChannelProtos.ChannelSettings.ModemConfig.Bw500Cr45Sf128, R.string.modem_config_short, 3), + MEDIUM(ChannelProtos.ChannelSettings.ModemConfig.Bw125Cr45Sf128, R.string.modem_config_medium, 12), + LONG(ChannelProtos.ChannelSettings.ModemConfig.Bw31_25Cr48Sf512, R.string.modem_config_long, 240), + VERY_LONG(ChannelProtos.ChannelSettings.ModemConfig.Bw125Cr48Sf4096, R.string.modem_config_very_long, 375); + + companion object { + fun fromConfig(modemConfig: ChannelProtos.ChannelSettings.ModemConfig?): ChannelOption? { + for (option in values()) { + if (option.modemConfig == modemConfig) + return option + } + return null + } + val defaultMinBroadcastPeriod = VERY_LONG.minBroadcastPeriodSecs + } } \ No newline at end of file diff --git a/app/src/main/java/com/geeksville/mesh/model/ChannelSet.kt b/app/src/main/java/com/geeksville/mesh/model/ChannelSet.kt index 1206af6e7..d6b0bcf5e 100644 --- a/app/src/main/java/com/geeksville/mesh/model/ChannelSet.kt +++ b/app/src/main/java/com/geeksville/mesh/model/ChannelSet.kt @@ -11,10 +11,6 @@ import com.google.zxing.MultiFormatWriter import com.journeyapps.barcodescanner.BarcodeEncoder import java.net.MalformedURLException -/** Utility function to make it easy to declare byte arrays - FIXME move someplace better */ -fun byteArrayOfInts(vararg ints: Int) = ByteArray(ints.size) { pos -> ints[pos].toByte() } - - data class ChannelSet( val protobuf: AppOnlyProtos.ChannelSet = AppOnlyProtos.ChannelSet.getDefaultInstance() ) { @@ -48,6 +44,13 @@ data class ChannelSet( /// Can this channel be changed right now? var editable = false + /** + * Return the primary channel info + */ + val primaryChannel: Channel get() { + return Channel(protobuf.getSettings(0)) + } + /// Return an URL that represents the current channel values /// @param upperCasePrefix - portions of the URL can be upper case to make for more efficient QR codes fun getChannelUrl(upperCasePrefix: Boolean = false): Uri { 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 bc4f3a0b5..91d78a4bd 100644 --- a/app/src/main/java/com/geeksville/mesh/model/UIState.kt +++ b/app/src/main/java/com/geeksville/mesh/model/UIState.kt @@ -12,10 +12,7 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope import com.geeksville.android.Logging -import com.geeksville.mesh.AppOnlyProtos -import com.geeksville.mesh.IMeshService -import com.geeksville.mesh.MeshProtos -import com.geeksville.mesh.MyNodeInfo +import com.geeksville.mesh.* import com.geeksville.mesh.database.MeshtasticDatabase import com.geeksville.mesh.database.PacketRepository import com.geeksville.mesh.database.entity.Packet @@ -90,16 +87,16 @@ class UIViewModel(private val app: Application) : AndroidViewModel(app), Logging } /// various radio settings (including the channel) - val radioConfig = object : MutableLiveData(null) { + val radioConfig = object : MutableLiveData(null) { } - val channels = object : MutableLiveData(null) { + val channels = object : MutableLiveData(null) { } var positionBroadcastSecs: Int? get() { radioConfig.value?.preferences?.let { - if (it.locationShare == MeshProtos.LocationSharing.LocDisabled) return 0 + if (it.locationShare == RadioConfigProtos.LocationSharing.LocDisabled) return 0 if (it.positionBroadcastSecs > 0) return it.positionBroadcastSecs // These default values are borrowed from the device code. if (it.isRouter) return 60 * 60 @@ -116,11 +113,11 @@ class UIViewModel(private val app: Application) : AndroidViewModel(app), Logging builder.preferencesBuilder.gpsUpdateInterval = value builder.preferencesBuilder.sendOwnerInterval = max(1, 3600 / value).toInt() builder.preferencesBuilder.locationShare = - MeshProtos.LocationSharing.LocEnabled + RadioConfigProtos.LocationSharing.LocEnabled } else { builder.preferencesBuilder.positionBroadcastSecs = Int.MAX_VALUE builder.preferencesBuilder.locationShare = - MeshProtos.LocationSharing.LocDisabled + RadioConfigProtos.LocationSharing.LocDisabled } setRadioConfig(builder.build()) } @@ -153,13 +150,11 @@ class UIViewModel(private val app: Application) : AndroidViewModel(app), Logging /** * Return the primary channel info */ - val primaryChannel: ChannelSet? get() { - return channels.value?.let { it -> - Channel(it.getSettings(0)) - } - } - /// Set the radio config (also updates our saved copy in preferences) - private fun setRadioConfig(c: MeshProtos.RadioConfig) { + val primaryChannel: Channel? get() = channels.value?.primaryChannel + + /// + // Set the radio config (also updates our saved copy in preferences) + private fun setRadioConfig(c: RadioConfigProtos.RadioConfig) { debug("Setting new radio config!") meshService?.radioConfig = c.toByteArray() radioConfig.value = @@ -167,23 +162,14 @@ class UIViewModel(private val app: Application) : AndroidViewModel(app), Logging } /// Set the radio config (also updates our saved copy in preferences) - private fun setChannels(c: AppOnlyProtos.ChannelSet) { + fun setChannels(c: ChannelSet) { debug("Setting new channels!") - meshService?.channels = c.toByteArray() + meshService?.channels = c.protobuf.toByteArray() channels.value = c // Must be done after calling the service, so we will will properly throw if the service failed (and therefore not cache invalid new settings) getPreferences(context).edit(commit = true) { - this.putString("channel-url", primaryChannel!!.getChannelUrl().toString()) - } - } - - /** Update just the channel settings portion of our config (both in the device and in saved preferences) */ - fun setChannel(c: MeshProtos.ChannelSettings) { - // When running on the emulator, radio config might not really be available, in that case, just ignore attempts to change the config - radioConfig.value?.toBuilder()?.let { config -> - config.channelSettings = c - setRadioConfig(config.build()) + this.putString("channel-url", c.getChannelUrl().toString()) } } 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 861a2f295..8aef6d463 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -111,7 +111,7 @@ class MeshService : Service(), Logging { private var fusedLocationClient: FusedLocationProviderClient? = null // If we've ever read a valid region code from our device it will be here - var curRegionValue = MeshProtos.RegionCode.Unset_VALUE + var curRegionValue = RadioConfigProtos.RegionCode.Unset_VALUE val radio = ServiceClient { IRadioInterfaceService.Stub.asInterface(it).apply { @@ -417,7 +417,7 @@ class MeshService : Service(), Logging { var myNodeInfo: MyNodeInfo? = null - private var radioConfig: MeshProtos.RadioConfig? = null + private var radioConfig: RadioConfigProtos.RadioConfig? = null /// True after we've done our initial node db init @Volatile @@ -1029,7 +1029,7 @@ class MeshService : Service(), Logging { MeshProtos.FromRadio.NODE_INFO_FIELD_NUMBER -> handleNodeInfo(proto.nodeInfo) - MeshProtos.FromRadio.RADIO_FIELD_NUMBER -> handleRadioConfig(proto.radio) + // MeshProtos.FromRadio.RADIO_FIELD_NUMBER -> handleRadioConfig(proto.radio) else -> errormsg("Unexpected FromRadio variant") } @@ -1053,7 +1053,7 @@ class MeshService : Service(), Logging { private var configNonce = 1 - private fun handleRadioConfig(radio: MeshProtos.RadioConfig) { + private fun handleRadioConfig(radio: RadioConfigProtos.RadioConfig) { val packetToSave = Packet( UUID.randomUUID().toString(), "RadioConfig", @@ -1174,20 +1174,20 @@ class MeshService : Service(), Logging { ignoreException { // Try to pull our region code from the new preferences field // FIXME - do not check net - figuring out why board is rebooting - val curConfigRegion = radioConfig?.preferences?.region ?: MeshProtos.RegionCode.Unset - if (curConfigRegion != MeshProtos.RegionCode.Unset) { + val curConfigRegion = radioConfig?.preferences?.region ?: RadioConfigProtos.RegionCode.Unset + if (curConfigRegion != RadioConfigProtos.RegionCode.Unset) { info("Using device region $curConfigRegion (code ${curConfigRegion.number})") curRegionValue = curConfigRegion.number } - if (curRegionValue == MeshProtos.RegionCode.Unset_VALUE) { + if (curRegionValue == RadioConfigProtos.RegionCode.Unset_VALUE) { // look for a legacy region val legacyRegex = Regex(".+-(.+)") myNodeInfo?.region?.let { legacyRegion -> val matches = legacyRegex.find(legacyRegion) if (matches != null) { val (region) = matches.destructured - val newRegion = MeshProtos.RegionCode.valueOf(region) + val newRegion = RadioConfigProtos.RegionCode.valueOf(region) info("Upgrading legacy region $newRegion (code ${newRegion.number})") curRegionValue = newRegion.number } @@ -1195,7 +1195,7 @@ class MeshService : Service(), Logging { } // If nothing was set in our (new style radio preferences, but we now have a valid setting - slam it in) - if (curConfigRegion == MeshProtos.RegionCode.Unset && curRegionValue != MeshProtos.RegionCode.Unset_VALUE) { + if (curConfigRegion == RadioConfigProtos.RegionCode.Unset && curRegionValue != RadioConfigProtos.RegionCode.Unset_VALUE) { info("Telling device to upgrade region") // Tell the device to set the new region field (old devices will simply ignore this) @@ -1321,7 +1321,7 @@ class MeshService : Service(), Logging { /** Send our current radio config to the device */ - private fun sendRadioConfig(c: MeshProtos.RadioConfig) { + private fun sendRadioConfig(c: RadioConfigProtos.RadioConfig) { // Update our device val payload = AdminProtos.AdminMessage.newBuilder().also { it.setRadio = c @@ -1347,7 +1347,7 @@ class MeshService : Service(), Logging { /** Set our radio config */ private fun setRadioConfig(payload: ByteArray) { - val parsed = MeshProtos.RadioConfig.parseFrom(payload) + val parsed = RadioConfigProtos.RadioConfig.parseFrom(payload) sendRadioConfig(parsed) } @@ -1608,6 +1608,10 @@ class MeshService : Service(), Logging { TODO("Not yet implemented") } + override fun setChannels(payload: ByteArray?) { + TODO("Not yet implemented") + } + override fun getNodes(): MutableList = toRemoteExceptions { val r = nodeDBbyID.values.toMutableList() info("in getOnline, count=${r.size}") diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshServiceSettingsData.kt b/app/src/main/java/com/geeksville/mesh/service/MeshServiceSettingsData.kt index 2b6e455a4..c1477b718 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshServiceSettingsData.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshServiceSettingsData.kt @@ -1,9 +1,6 @@ package com.geeksville.mesh.service -import com.geeksville.mesh.DataPacket -import com.geeksville.mesh.MeshProtos -import com.geeksville.mesh.MyNodeInfo -import com.geeksville.mesh.NodeInfo +import com.geeksville.mesh.* import kotlinx.serialization.Serializable /// Our saved preferences as stored on disk @@ -12,7 +9,7 @@ data class MeshServiceSettingsData( val nodeDB: Array, val myInfo: MyNodeInfo, val messages: Array, - val regionCode: Int = MeshProtos.RegionCode.Unset_VALUE + val regionCode: Int = RadioConfigProtos.RegionCode.Unset_VALUE ) { override fun equals(other: Any?): Boolean { if (this === other) return true diff --git a/app/src/main/java/com/geeksville/mesh/service/MockInterface.kt b/app/src/main/java/com/geeksville/mesh/service/MockInterface.kt index 5eaf012c6..06ed39603 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MockInterface.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MockInterface.kt @@ -46,11 +46,9 @@ class MockInterface(private val service: RadioInterfaceService) : Logging, IRadi to = 0xffffffff.toInt() // ugly way of saying broadcast rxTime = (System.currentTimeMillis() / 1000).toInt() rxSnr = 1.5f - decoded = MeshProtos.SubPacket.newBuilder().apply { - data = MeshProtos.Data.newBuilder().apply { - portnum = Portnums.PortNum.TEXT_MESSAGE_APP - payload = ByteString.copyFromUtf8("This simulated node sends Hi!") - }.build() + decoded = MeshProtos.Data.newBuilder().apply { + portnum = Portnums.PortNum.TEXT_MESSAGE_APP + payload = ByteString.copyFromUtf8("This simulated node sends Hi!") }.build() }.build() } @@ -64,17 +62,20 @@ class MockInterface(private val service: RadioInterfaceService) : Logging, IRadi to = toIn rxTime = (System.currentTimeMillis() / 1000).toInt() rxSnr = 1.5f - decoded = MeshProtos.SubPacket.newBuilder().apply { - data = MeshProtos.Data.newBuilder().apply { - successId = msgId - }.build() + decoded = MeshProtos.Data.newBuilder().apply { + portnum = Portnums.PortNum.ROUTING_APP + payload = MeshProtos.Routing.newBuilder().apply { + }.build().toByteString() + requestId = msgId }.build() }.build() } /// Send a fake ack packet back if the sender asked for want_ack private fun sendFakeAck(pr: MeshProtos.ToRadio) { - service.handleFromRadio(makeAck(pr.packet.to, pr.packet.from, pr.packet.id).build().toByteArray()) + service.handleFromRadio( + makeAck(pr.packet.to, pr.packet.from, pr.packet.id).build().toByteArray() + ) } private fun sendConfigResponse(configId: Int) { @@ -101,37 +102,33 @@ class MockInterface(private val service: RadioInterfaceService) : Logging, IRadi } // Simulated network data to feed to our app - val MY_NODE = 0x42424242 + val MY_NODE = 0x42424242 val packets = arrayOf( // MyNodeInfo MeshProtos.FromRadio.newBuilder().apply { myInfo = MeshProtos.MyNodeInfo.newBuilder().apply { myNodeNum = MY_NODE region = "TW" - numChannels = 7 hwModel = "Sim" - packetIdBits = 32 - nodeNumBits = 32 - currentPacketId = 1 messageTimeoutMsec = 5 * 60 * 1000 firmwareVersion = service.getString(R.string.cur_firmware_version) }.build() }, // RadioConfig - MeshProtos.FromRadio.newBuilder().apply { - radio = MeshProtos.RadioConfig.newBuilder().apply { + /* MeshProtos.FromRadio.newBuilder().apply { + radio = RadioConfigProtos.RadioConfig.newBuilder().apply { - preferences = MeshProtos.RadioConfig.UserPreferences.newBuilder().apply { - region = MeshProtos.RegionCode.TW + preferences = RadioConfigProtos.RadioConfig.UserPreferences.newBuilder().apply { + region = RadioConfigProtos.RegionCode.TW // FIXME set critical times? }.build() - channel = MeshProtos.ChannelSettings.newBuilder().apply { + /* channel = ChannelProtos.ChannelSettings.newBuilder().apply { // we just have an empty listing so that the default channel works - }.build() + }.build() */ }.build() - }, + }, */ // Fake NodeDB makeNodeInfo(MY_NODE, 32.776665, -96.796989), // dallas diff --git a/app/src/main/java/com/geeksville/mesh/ui/AdvancedSettingsFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/AdvancedSettingsFragment.kt index 75175a14e..6b22b7e6a 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/AdvancedSettingsFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/AdvancedSettingsFragment.kt @@ -51,7 +51,7 @@ class AdvancedSettingsFragment : ScreenFragment("Advanced Settings"), Logging { val textEdit = binding.positionBroadcastPeriodEditText val n = textEdit.text.toString().toIntOrNull() val minBroadcastPeriodSecs = - ChannelOption.fromConfig(model.radioConfig.value?.channelSettings?.modemConfig)?.minBroadcastPeriodSecs + ChannelOption.fromConfig(model.primaryChannel?.modemConfig)?.minBroadcastPeriodSecs ?: ChannelOption.defaultMinBroadcastPeriod if (n != null && n < MAX_INT_DEVICE && (n == 0 || n >= minBroadcastPeriodSecs)) { 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 ecc3cfe76..d7e1743ea 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/ChannelFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/ChannelFragment.kt @@ -16,6 +16,7 @@ import com.geeksville.analytics.DataPair import com.geeksville.android.GeeksvilleApplication import com.geeksville.android.Logging import com.geeksville.android.hideKeyboard +import com.geeksville.mesh.ChannelProtos import com.geeksville.mesh.MeshProtos import com.geeksville.mesh.R import com.geeksville.mesh.databinding.ChannelFragmentBinding @@ -76,10 +77,12 @@ class ChannelFragment : ScreenFragment("Channel"), Logging { /// Pull the latest data from the model (discarding any user edits) private fun setGUIfromModel() { val radioConfig = model.radioConfig.value - val channel = UIViewModel.getChannel(radioConfig) + val channels = model.channels.value binding.editableCheckbox.isChecked = false // start locked - if (channel != null) { + if (channels != null) { + val channel = channels.primaryChannel + binding.qrView.visibility = View.VISIBLE binding.channelNameEdit.visibility = View.VISIBLE binding.channelNameEdit.setText(channel.humanName) @@ -89,9 +92,9 @@ class ChannelFragment : ScreenFragment("Channel"), Logging { val connected = model.isConnected.value == MeshService.ConnectionState.CONNECTED binding.editableCheckbox.isEnabled = connected - binding.qrView.setImageBitmap(channel.getChannelQR()) + binding.qrView.setImageBitmap(channels.getChannelQR()) - val modemConfig = radioConfig?.channelSettings?.modemConfig + val modemConfig = channel.modemConfig val channelOption = ChannelOption.fromConfig(modemConfig) binding.filledExposedDropdown.setText( getString( @@ -118,7 +121,7 @@ class ChannelFragment : ScreenFragment("Channel"), Logging { } private fun shareChannel() { - UIViewModel.getChannel(model.radioConfig.value)?.let { channel -> + model.channels.value?.let { channels -> GeeksvilleApplication.analytics.track( "share", @@ -127,7 +130,7 @@ class ChannelFragment : ScreenFragment("Channel"), Logging { val sendIntent: Intent = Intent().apply { action = Intent.ACTION_SEND - putExtra(Intent.EXTRA_TEXT, channel.getChannelUrl().toString()) + putExtra(Intent.EXTRA_TEXT, channels.getChannelUrl().toString()) putExtra( Intent.EXTRA_TITLE, getString(R.string.url_for_join) @@ -152,8 +155,8 @@ class ChannelFragment : ScreenFragment("Channel"), Logging { val checked = binding.editableCheckbox.isChecked if (checked) { // User just unlocked for editing - remove the # goo around the channel name - UIViewModel.getChannel(model.radioConfig.value)?.let { channel -> - binding.channelNameEdit.setText(channel.name) + model.channels.value?.let { channels -> + binding.channelNameEdit.setText(channels.primaryChannel.name) } } else { // User just locked it, we should warn and then apply changes to radio @@ -165,8 +168,9 @@ class ChannelFragment : ScreenFragment("Channel"), Logging { } .setPositiveButton(getString(R.string.accept)) { _, _ -> // Generate a new channel with only the changes the user can change in the GUI - UIViewModel.getChannel(model.radioConfig.value)?.let { old -> - val newSettings = old.settings.toBuilder() + model.channels.value?.let { old -> + val oldPrimary = old.primaryChannel + val newSettings = oldPrimary.settings.toBuilder() newSettings.name = binding.channelNameEdit.text.toString().trim() // Generate a new AES256 key (for any channel not named Default) @@ -191,7 +195,7 @@ class ChannelFragment : ScreenFragment("Channel"), Logging { binding.filledExposedDropdown.editableText.toString() val modemConfig = getModemConfig(selectedChannelOptionString) - if (modemConfig != MeshProtos.ChannelSettings.ModemConfig.UNRECOGNIZED) + if (modemConfig != ChannelProtos.ChannelSettings.ModemConfig.UNRECOGNIZED) newSettings.modemConfig = modemConfig // Try to change the radio, if it fails, tell the user why and throw away their redits try { @@ -232,12 +236,12 @@ class ChannelFragment : ScreenFragment("Channel"), Logging { }) } - private fun getModemConfig(selectedChannelOptionString: String): MeshProtos.ChannelSettings.ModemConfig { + private fun getModemConfig(selectedChannelOptionString: String): ChannelProtos.ChannelSettings.ModemConfig { for (item in ChannelOption.values()) { if (getString(item.configRes) == selectedChannelOptionString) return item.modemConfig } - return MeshProtos.ChannelSettings.ModemConfig.UNRECOGNIZED + return ChannelProtos.ChannelSettings.ModemConfig.UNRECOGNIZED } } diff --git a/app/src/main/proto b/app/src/main/proto index 564b48869..39c41e0ef 160000 --- a/app/src/main/proto +++ b/app/src/main/proto @@ -1 +1 @@ -Subproject commit 564b488695da6bee7bb9c4553872268595a0f77d +Subproject commit 39c41e0ef130e7239eed916f7609aad1aa7f6db8