Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 173 additions & 0 deletions core/src/main/java/com/featuremodule/core/util/WifiUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
package com.featuremodule.core.util;

/**
* Copy of ScanResult utility functions unavailable on earlier SDKs
*/
public class WifiUtils {
/**
* The unspecified value.
*/
public final static int UNSPECIFIED = -1;

/**
* 2.4 GHz band first channel number
*/
public static final int BAND_24_GHZ_FIRST_CH_NUM = 1;
/**
* 2.4 GHz band last channel number
*/
public static final int BAND_24_GHZ_LAST_CH_NUM = 14;
/**
* 2.4 GHz band frequency of first channel in MHz
*/
public static final int BAND_24_GHZ_START_FREQ_MHZ = 2412;
/**
* 2.4 GHz band frequency of last channel in MHz
*/
public static final int BAND_24_GHZ_END_FREQ_MHZ = 2484;

/**
* 5 GHz band first channel number
*/
public static final int BAND_5_GHZ_FIRST_CH_NUM = 32;
/**
* 5 GHz band last channel number
*/
public static final int BAND_5_GHZ_LAST_CH_NUM = 177;
/**
* 5 GHz band frequency of first channel in MHz
*/
public static final int BAND_5_GHZ_START_FREQ_MHZ = 5160;
/**
* 5 GHz band frequency of last channel in MHz
*/
public static final int BAND_5_GHZ_END_FREQ_MHZ = 5885;

/**
* 6 GHz band first channel number
*/
public static final int BAND_6_GHZ_FIRST_CH_NUM = 1;
/**
* 6 GHz band last channel number
*/
public static final int BAND_6_GHZ_LAST_CH_NUM = 233;
/**
* 6 GHz band frequency of first channel in MHz
*/
public static final int BAND_6_GHZ_START_FREQ_MHZ = 5955;
/**
* 6 GHz band frequency of last channel in MHz
*/
public static final int BAND_6_GHZ_END_FREQ_MHZ = 7115;
/**
* The center frequency of the first 6Ghz preferred scanning channel, as defined by
* IEEE802.11ax draft 7.0 section 26.17.2.3.3.
*/
public static final int BAND_6_GHZ_PSC_START_MHZ = 5975;
/**
* The number of MHz to increment in order to get the next 6Ghz preferred scanning channel
* as defined by IEEE802.11ax draft 7.0 section 26.17.2.3.3.
*/
public static final int BAND_6_GHZ_PSC_STEP_SIZE_MHZ = 80;

/**
* 6 GHz band operating class 136 channel 2 center frequency in MHz
*/
public static final int BAND_6_GHZ_OP_CLASS_136_CH_2_FREQ_MHZ = 5935;

/**
* 60 GHz band first channel number
*/
public static final int BAND_60_GHZ_FIRST_CH_NUM = 1;
/**
* 60 GHz band last channel number
*/
public static final int BAND_60_GHZ_LAST_CH_NUM = 6;
/**
* 60 GHz band frequency of first channel in MHz
*/
public static final int BAND_60_GHZ_START_FREQ_MHZ = 58320;
/**
* 60 GHz band frequency of last channel in MHz
*/
public static final int BAND_60_GHZ_END_FREQ_MHZ = 70200;

/**
* Utility function to check if a frequency within 2.4 GHz band
*
* @param freqMhz frequency in MHz
* @return true if within 2.4GHz, false otherwise
*/
public static boolean is24GHz(int freqMhz) {
return freqMhz >= BAND_24_GHZ_START_FREQ_MHZ && freqMhz <= BAND_24_GHZ_END_FREQ_MHZ;
}

/**
* Utility function to check if a frequency within 5 GHz band
*
* @param freqMhz frequency in MHz
* @return true if within 5GHz, false otherwise
*/
public static boolean is5GHz(int freqMhz) {
return freqMhz >= BAND_5_GHZ_START_FREQ_MHZ && freqMhz <= BAND_5_GHZ_END_FREQ_MHZ;
}

/**
* Utility function to check if a frequency within 6 GHz band
*
* @return true if within 6GHz, false otherwise
*/
public static boolean is6GHz(int freqMhz) {
if (freqMhz == BAND_6_GHZ_OP_CLASS_136_CH_2_FREQ_MHZ) {
return true;
}
return (freqMhz >= BAND_6_GHZ_START_FREQ_MHZ && freqMhz <= BAND_6_GHZ_END_FREQ_MHZ);
}

/**
* Utility function to check if a frequency is 6Ghz PSC channel.
*
* @return true if the frequency is 6GHz PSC, false otherwise
*/
public static boolean is6GHzPsc(int freqMhz) {
if (!is6GHz(freqMhz)) {
return false;
}
return (freqMhz - BAND_6_GHZ_PSC_START_MHZ) % BAND_6_GHZ_PSC_STEP_SIZE_MHZ == 0;
}

/**
* Utility function to check if a frequency within 60 GHz band
*
* @return true if within 60GHz, false otherwise
*/
public static boolean is60GHz(int freqMhz) {
return freqMhz >= BAND_60_GHZ_START_FREQ_MHZ && freqMhz <= BAND_60_GHZ_END_FREQ_MHZ;
}

/**
* Utility function to convert frequency in MHz to channel number.
*
* @param freqMhz frequency in MHz
* @return channel number associated with given frequency, {@link #UNSPECIFIED} if no match
*/
public static int convertFrequencyMhzToChannelIfSupported(int freqMhz) {
// Special case
if (freqMhz == 2484) {
return 14;
} else if (is24GHz(freqMhz)) {
return (freqMhz - BAND_24_GHZ_START_FREQ_MHZ) / 5 + BAND_24_GHZ_FIRST_CH_NUM;
} else if (is5GHz(freqMhz)) {
return ((freqMhz - BAND_5_GHZ_START_FREQ_MHZ) / 5) + BAND_5_GHZ_FIRST_CH_NUM;
} else if (is6GHz(freqMhz)) {
if (freqMhz == BAND_6_GHZ_OP_CLASS_136_CH_2_FREQ_MHZ) {
return 2;
}
return ((freqMhz - BAND_6_GHZ_START_FREQ_MHZ) / 5) + BAND_6_GHZ_FIRST_CH_NUM;
} else if (is60GHz(freqMhz)) {
return ((freqMhz - BAND_60_GHZ_START_FREQ_MHZ) / 2160) + BAND_60_GHZ_FIRST_CH_NUM;
}

return UNSPECIFIED;
}
}
4 changes: 4 additions & 0 deletions feature/homeImpl/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
android:name="android.hardware.camera"
android:required="false" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />

<application>
<meta-data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import com.featuremodule.homeImpl.camera.TakePhotoScreen
import com.featuremodule.homeImpl.exoplayer.ExoplayerScreen
import com.featuremodule.homeImpl.imageUpload.ImageUploadScreen
import com.featuremodule.homeImpl.ui.HomeScreen
import com.featuremodule.homeImpl.wifi.WifiScreen

fun NavGraphBuilder.registerHome() {
composable(HomeDestination.ROUTE) { backStackEntry ->
Expand Down Expand Up @@ -49,6 +50,10 @@ fun NavGraphBuilder.registerHome() {
?: "NONE"
BarcodeResultScreen(barcode)
}

composable(InternalRoutes.WifiDestination.ROUTE) {
WifiScreen()
}
}

internal class InternalRoutes {
Expand Down Expand Up @@ -87,4 +92,10 @@ internal class InternalRoutes {

fun constructRoute(barcodeValue: String) = "barcode_result/$barcodeValue"
}

object WifiDestination {
const val ROUTE = "wifi"

fun constructRoute() = ROUTE
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ internal sealed interface Event : UiEvent {
data object NavigateToExoplayer : Event
data object NavigateToCamera : Event
data object NavigateToBarcode : Event
data object NavigateToWifi : Event
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ internal fun HomeScreen(route: String?, viewModel: HomeVM = hiltViewModel()) {
GenericButton(text = "Exoplayer") { viewModel.postEvent(Event.NavigateToExoplayer) }
GenericButton(text = "Camera") { viewModel.postEvent(Event.NavigateToCamera) }
GenericButton(text = "Barcode") { viewModel.postEvent(Event.NavigateToBarcode) }
GenericButton(text = "Wifi") { viewModel.postEvent(Event.NavigateToWifi) }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,33 @@ internal class HomeVM @Inject constructor(
override fun initialState() = State

override fun handleEvent(event: Event) {
when (event) {
Event.NavigateToFeatureA -> launch {
val randomInt = Random.nextInt(until = 10)
// Using `saveState = false` causes return to Feature A on Home item click
navManager.navigate(NavCommand.OpenNavBarRoute(NavBarItems.FeatureA.graphRoute))

navManager.navigate(
NavCommand.Forward(FeatureADestination.constructRoute(randomInt)),
)
}
launch {
when (event) {
Event.NavigateToFeatureA -> {
val randomInt = Random.nextInt(until = 10)
// Using `saveState = false` causes return to Feature A on Home item click
navManager.navigate(NavCommand.OpenNavBarRoute(NavBarItems.FeatureA.graphRoute))

Event.NavigateToExoplayer -> launch {
navManager.navigate(
navManager.navigate(
NavCommand.Forward(FeatureADestination.constructRoute(randomInt)),
)
}

Event.NavigateToExoplayer -> navManager.navigate(
NavCommand.Forward(InternalRoutes.ExoplayerDestination.constructRoute()),
)
}

Event.NavigateToCamera -> launch {
navManager.navigate(
Event.NavigateToCamera -> navManager.navigate(
NavCommand.Forward(InternalRoutes.ImageUploadDestination.constructRoute()),
)
}

Event.NavigateToBarcode -> launch {
navManager.navigate(
Event.NavigateToBarcode -> navManager.navigate(
NavCommand.Forward(InternalRoutes.BarcodeCameraDestination.constructRoute()),
)

Event.NavigateToWifi -> navManager.navigate(
NavCommand.Forward(InternalRoutes.WifiDestination.constructRoute()),
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.featuremodule.homeImpl.wifi

import android.net.NetworkRequest
import android.net.wifi.ScanResult
import android.net.wifi.WifiNetworkSuggestion
import com.featuremodule.core.ui.UiEvent
import com.featuremodule.core.ui.UiState

internal data class State(
val wifiNetworks: List<NetworkState> = emptyList(),
val wifiToConnect: NetworkRequest? = null,
val wifiSuggestions: ArrayList<WifiNetworkSuggestion>? = null,
val isLocationEnabled: Boolean = true,
val isWifiEnabled: Boolean = true,
) : UiState

internal data class NetworkState(
val ssid: String,
val bssid: String,
val bandGhz: String,
val channel: Int,
val channelWidthMhz: Int,
val level: Int,
)

internal sealed interface Event : UiEvent {
data class WifiResultsScanned(val result: List<ScanResult>) : Event
data class SaveWifi(val network: NetworkState) : Event
data class ConnectWifi(val network: NetworkState) : Event
data object ClearWifiEvents : Event
data class UpdateLocationEnabled(val enabled: Boolean) : Event
data class UpdateWifiEnabled(val enabled: Boolean) : Event
data object PopBack : Event
}
Loading
Loading