Skip to content

Commit

Permalink
WIP: Sets up navigation to BT and WF details fragments supporting arg…
Browse files Browse the repository at this point in the history
…uments
  • Loading branch information
christianrowlands committed Oct 25, 2024
1 parent e39efbb commit 2b8efb8
Show file tree
Hide file tree
Showing 12 changed files with 169 additions and 53 deletions.
2 changes: 1 addition & 1 deletion networksurvey/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ dependencies {
implementation("com.craxiom:network-survey-messaging:${networkSurveyMessagingVersion}") {
exclude group: 'com.google.api.grpc', module: 'proto-google-common-protos'
}
implementation "com.google.protobuf:protobuf-java-util:4.28.2"
implementation "com.google.protobuf:protobuf-java-util:4.27.3"

implementation "mil.nga.geopackage:geopackage-android:6.7.3"
implementation 'org.apache.commons:commons-csv:1.10.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import androidx.preference.PreferenceManager
import com.craxiom.messaging.BluetoothRecord
import com.craxiom.messaging.BluetoothRecordData
Expand All @@ -24,6 +23,8 @@ import com.craxiom.networksurvey.util.NsTheme
import com.craxiom.networksurvey.util.PreferenceUtils
import timber.log.Timber

const val BLUETOOTH_DATA_KEY = "bluetoothData"

/**
* The fragment that displays the details of a single Bluetooth device from the scan results.
*/
Expand All @@ -49,9 +50,6 @@ class BluetoothDetailsFragment : AServiceDataFragment(), IBluetoothSurveyRecordL
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val args: BluetoothDetailsFragmentArgs by navArgs()
bluetoothData = args.bluetoothData

val composeView = ComposeView(requireContext())

composeView.apply {
Expand Down Expand Up @@ -145,6 +143,18 @@ class BluetoothDetailsFragment : AServiceDataFragment(), IBluetoothSurveyRecordL
}
}

/**
* Sets the BluetoothRecordData that this fragment should display. This needs to be called
* right after the fragment is created.
*
* @param bluetoothRecordData The BluetoothRecordData to display.
*/
fun setBluetoothData(bluetoothRecordData: BluetoothRecordData) {
this.bluetoothData = bluetoothRecordData
// TODO We might need to update the ViewModel with the new BluetoothRecordData if it has already
// been initialized
}

/**
* Navigates to the Settings UI (primarily for the user to change the scan rate)
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.Navigation;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.DividerItemDecoration;

Expand All @@ -39,6 +38,7 @@
import com.craxiom.networksurvey.listeners.IBluetoothSurveyRecordListener;
import com.craxiom.networksurvey.model.SortedSet;
import com.craxiom.networksurvey.services.NetworkSurveyService;
import com.craxiom.networksurvey.ui.main.SharedViewModel;
import com.craxiom.networksurvey.util.NsUtils;
import com.craxiom.networksurvey.util.PreferenceUtils;

Expand Down Expand Up @@ -256,9 +256,16 @@ public void navigateToBluetoothDetails(BluetoothRecordData bluetoothData)
FragmentActivity activity = getActivity();
if (activity == null) return;

Navigation.findNavController(activity, getId())
.navigate(BluetoothFragmentDirections.actionBtListFragmentToBtDetailsFragment(
bluetoothData));
try
{
SharedViewModel viewModel = new ViewModelProvider(activity).get(SharedViewModel.class);
viewModel.triggerNavigationToBluetooth(bluetoothData);
} catch (Exception e)
{
// An IllegalArgumentException can occur when the user switches to a new fragment (e.g. cellular details)
// before the navigation is complete. This is an edge case that we can ignore.
Timber.e(e, "Could not navigate to the Bluetooth Details Fragment");
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,6 @@ public class MqttFragment extends AConnectionFragment<NetworkSurveyService.Surve
{
SharedViewModel viewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
viewModel.triggerNavigationToQrCodeScanner();
/* TODO Delete me Navigation.findNavController(requireActivity(), getId())
.navigate(MqttFragmentDirections.actionMqttConnectionFragmentToScannerFragment()
.setMqttConnectionSettings(getCurrentMqttConnectionSettings()));*/
} else
{
Toast.makeText(getContext(), getString(R.string.grant_camera_permission), Toast.LENGTH_LONG).show();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,

ImageView imageView = view.findViewById(R.id.ivQrCode);

// FIXME Update this code with the new route approach
MqttConnectionSettings mqttConnectionSettings =
QrCodeShareFragmentArgs.fromBundle(getArguments()).getMqttConnectionSettings();
if (mqttConnectionSettings == null) return view;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import androidx.preference.PreferenceManager
import com.craxiom.networksurvey.constants.NetworkSurveyConstants
import com.craxiom.networksurvey.listeners.IWifiSurveyRecordListener
Expand All @@ -27,7 +26,7 @@ import timber.log.Timber
* The fragment that displays the details of a single Wifi network from the scan results.
*/
class WifiDetailsFragment : AServiceDataFragment(), IWifiSurveyRecordListener {
private lateinit var wifiNetwork: WifiNetwork
private var wifiNetwork: WifiNetwork? = null
private lateinit var viewModel: WifiDetailsViewModel

private lateinit var sharedPreferences: SharedPreferences
Expand Down Expand Up @@ -56,20 +55,19 @@ class WifiDetailsFragment : AServiceDataFragment(), IWifiSurveyRecordListener {
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val args: WifiDetailsFragmentArgs by navArgs()
wifiNetwork = args.wifiNetwork

val composeView = ComposeView(requireContext())

composeView.apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
viewModel = viewModel()
viewModel.wifiNetwork = wifiNetwork
if (wifiNetwork.signalStrength == null) {
viewModel.addInitialRssi(UNKNOWN_RSSI)
} else {
viewModel.addInitialRssi(wifiNetwork.signalStrength!!)
if (wifiNetwork != null) {
viewModel.wifiNetwork = wifiNetwork!!
if (wifiNetwork!!.signalStrength == null) {
viewModel.addInitialRssi(UNKNOWN_RSSI)
} else {
viewModel.addInitialRssi(wifiNetwork!!.signalStrength!!)
}
}

sharedPreferences.registerOnSharedPreferenceChangeListener(
Expand Down Expand Up @@ -124,23 +122,33 @@ class WifiDetailsFragment : AServiceDataFragment(), IWifiSurveyRecordListener {

override fun onWifiBeaconSurveyRecords(wifiBeaconRecords: MutableList<WifiRecordWrapper>?) {
val matchedWifiRecordWrapper =
wifiBeaconRecords?.find { it.wifiBeaconRecord.data.bssid.equals(wifiNetwork.bssid) }
wifiBeaconRecords?.find { it.wifiBeaconRecord.data.bssid.equals(wifiNetwork?.bssid) }

if (matchedWifiRecordWrapper == null) {
Timber.i("No wifi record found for ${wifiNetwork.bssid} in the wifi scan results")
Timber.i("No wifi record found for ${wifiNetwork?.bssid} in the wifi scan results")
viewModel.addNewRssi(UNKNOWN_RSSI)
return
}

if (matchedWifiRecordWrapper.wifiBeaconRecord.data.hasSignalStrength()) {
viewModel.addNewRssi(matchedWifiRecordWrapper.wifiBeaconRecord.data.signalStrength.value)
} else {
Timber.i("No signal strength present for ${wifiNetwork.bssid} in the wifi beacon record")
Timber.i("No signal strength present for ${wifiNetwork?.bssid} in the wifi beacon record")
viewModel.addNewRssi(UNKNOWN_RSSI)

}
}

/**
* Sets the WifiNetwork that this fragment should display the details for. This needs to be
* called right after the fragment is created.
*/
fun setWifiNetwork(wifiNetwork: WifiNetwork) {
this.wifiNetwork = wifiNetwork
// TODO We might need to update the ViewModel with the new WifiNetwork if it has already
// been initialized
}

/**
* Navigates to the Settings UI (primarily for the user to change the scan rate)
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import com.craxiom.networksurvey.model.WifiNetwork;
import com.craxiom.networksurvey.model.WifiRecordWrapper;
import com.craxiom.networksurvey.services.NetworkSurveyService;
import com.craxiom.networksurvey.ui.main.SharedViewModel;
import com.craxiom.networksurvey.ui.wifi.model.WifiNetworkInfoList;
import com.craxiom.networksurvey.util.PreferenceUtils;
import com.google.android.material.snackbar.Snackbar;
Expand Down Expand Up @@ -260,9 +261,8 @@ public void navigateToWifiDetails(WifiNetwork wifiNetwork)

try
{
Navigation.findNavController(activity, getId())
.navigate(WifiNetworksFragmentDirections.actionWifiListFragmentToWifiDetailsFragment(
wifiNetwork));
SharedViewModel viewModel = new ViewModelProvider(activity).get(SharedViewModel.class);
viewModel.triggerNavigationToWifiDetails(wifiNetwork);
} catch (Exception e)
{
// An IllegalArgumentException can occur when the user switches to a new fragment (e.g. cellular details)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.craxiom.networksurvey.model

import android.os.Parcel
import android.os.Parcelable
import com.craxiom.messaging.wifi.Standard
import com.craxiom.messaging.wifi.WifiBandwidth
import java.io.Serializable
Expand All @@ -15,4 +17,48 @@ data class WifiNetwork(
val passpoint: Boolean?,
val capabilities: String,
val standard: Standard?,
) : Serializable
) : Serializable, Parcelable {
constructor(parcel: Parcel) : this(
parcel.readString() ?: "",
parcel.readValue(Float::class.java.classLoader) as? Float,
parcel.readString() ?: "",
parcel.readValue(Int::class.java.classLoader) as? Int,
parcel.readValue(Int::class.java.classLoader) as? Int,
WifiBandwidth.forNumber(parcel.readValue(Int::class.java.classLoader) as? Int ?: 0),
parcel.readString() ?: "",
parcel.readValue(Boolean::class.java.classLoader) as? Boolean,
parcel.readString() ?: "",
Standard.forNumber(parcel.readValue(Int::class.java.classLoader) as? Int ?: 0),

)

override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(bssid)
parcel.writeValue(signalStrength)
parcel.writeString(ssid)
parcel.writeValue(frequency)
parcel.writeValue(channel)
parcel.writeValue(bandwidth ?: WifiBandwidth.UNKNOWN)
parcel.writeString(encryptionType)
parcel.writeValue(passpoint)
parcel.writeString(capabilities)
parcel.writeValue(standard ?: Standard.UNKNOWN)
}

override fun describeContents(): Int {
return 0
}

companion object CREATOR : Parcelable.Creator<WifiNetwork> {

const val KEY: String = "wifiNetwork"

override fun createFromParcel(parcel: Parcel): WifiNetwork {
return WifiNetwork(parcel)
}

override fun newArray(size: Int): Array<WifiNetwork?> {
return arrayOfNulls(size)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ fun getAppBarActions(currentScreen: MainScreens, navController: NavController):
icon = R.drawable.ic_spectrum_chart,
description = R.string.open_wifi_spectrum,
onClick = {
// TODO Navigate to WiFi Spectrum Fragment
navController.navigate(NavOption.WifiSpectrum.name)
}
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.rememberNavController
import com.craxiom.networksurvey.R
import com.craxiom.networksurvey.fragments.BLUETOOTH_DATA_KEY
import com.craxiom.networksurvey.model.WifiNetwork
import com.craxiom.networksurvey.ui.main.appdrawer.AppDrawerContent
import com.craxiom.networksurvey.ui.main.appdrawer.AppDrawerItemInfo
import com.craxiom.networksurvey.ui.main.appdrawer.NavDrawerOption
Expand Down Expand Up @@ -77,15 +79,23 @@ fun MainCompose(
LaunchedEffect(viewModel.navigateToWifiDetails) {
viewModel.navigateToWifiDetails.observe(lifecycleOwner) { shouldNavigate ->
if (shouldNavigate) {
mainNavController.currentBackStackEntry?.savedStateHandle?.set(
WifiNetwork.KEY,
viewModel.wifiNetwork
)
mainNavController.navigate(NavOption.WifiDetails.name)
viewModel.resetNavigationFlag()
}
}
}

LaunchedEffect(viewModel.navigateToBluetooth) {
viewModel.navigateToBluetooth.observe(lifecycleOwner) { shouldNavigate ->
LaunchedEffect(viewModel.navigateToBluetoothDetails) {
viewModel.navigateToBluetoothDetails.observe(lifecycleOwner) { shouldNavigate ->
if (shouldNavigate) {
mainNavController.currentBackStackEntry?.savedStateHandle?.set(
BLUETOOTH_DATA_KEY,
viewModel.bluetoothData
)
mainNavController.navigate(NavOption.BluetoothDetails.name)
viewModel.resetNavigationFlag()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.craxiom.messaging.BluetoothRecordData
import com.craxiom.networksurvey.model.WifiNetwork
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject

Expand All @@ -24,9 +26,15 @@ class SharedViewModel @Inject constructor(application: Application) :

private val _navigateToWifiDetails = MutableLiveData(false)
val navigateToWifiDetails: LiveData<Boolean> = _navigateToWifiDetails
private var _wifiNetwork: WifiNetwork? = null
val wifiNetwork: WifiNetwork?
get() = _wifiNetwork

private val _navigateToBluetooth = MutableLiveData(false)
val navigateToBluetooth: LiveData<Boolean> = _navigateToBluetooth
private val _navigateToBluetoothDetails = MutableLiveData(false)
val navigateToBluetoothDetails: LiveData<Boolean> = _navigateToBluetoothDetails
private var _bluetoothData: BluetoothRecordData? = null
val bluetoothData: BluetoothRecordData?
get() = _bluetoothData

fun triggerNavigationToQrCodeScanner() {
_navigateToQrCodeScanner.value = true
Expand All @@ -44,12 +52,14 @@ class SharedViewModel @Inject constructor(application: Application) :
_navigateToWifiSpectrum.value = true
}

fun triggerNavigationToWifiDetails() {
fun triggerNavigationToWifiDetails(wifiNetwork: WifiNetwork) {
_wifiNetwork = wifiNetwork
_navigateToWifiDetails.value = true
}

fun triggerNavigationToBluetooth() {
_navigateToBluetooth.value = true
fun triggerNavigationToBluetooth(bluetoothRecordData: BluetoothRecordData) {
_bluetoothData = bluetoothRecordData
_navigateToBluetoothDetails.value = true
}

fun resetNavigationFlag() {
Expand All @@ -59,6 +69,6 @@ class SharedViewModel @Inject constructor(application: Application) :
_navigateToTowerMap.value = false
_navigateToWifiSpectrum.value = false
_navigateToWifiDetails.value = false
_navigateToBluetooth.value = false
_navigateToBluetoothDetails.value = false
}
}
Loading

0 comments on commit 2b8efb8

Please sign in to comment.