Refine channel error checking and allow multi-channel auto
This commit is contained in:
@@ -226,7 +226,7 @@ class RepeaterManager(private val parent: TetheringFragment) : Manager(), Servic
|
||||
return null
|
||||
}
|
||||
private suspend fun updateConfiguration(config: SoftApConfigurationCompat) {
|
||||
val (band, channel) = config.requireSingleBand()
|
||||
val (band, channel) = SoftApConfigurationCompat.requireSingleBand(config.channels)
|
||||
if (RepeaterService.safeMode) {
|
||||
RepeaterService.networkName = config.ssid
|
||||
RepeaterService.deviceAddress = config.bssid
|
||||
|
||||
@@ -333,6 +333,33 @@ data class SoftApConfigurationCompat(
|
||||
Build.VERSION.SDK_INT < 31 || isUserConfiguration(this) as Boolean,
|
||||
this,
|
||||
)
|
||||
|
||||
/**
|
||||
* Only single band/channel can be supplied on API 23-30
|
||||
*/
|
||||
fun requireSingleBand(channels: SparseIntArray): Pair<Int, Int> {
|
||||
require(channels.size() == 1) { "Unsupported number of bands configured" }
|
||||
return channels.keyAt(0) to channels.valueAt(0)
|
||||
}
|
||||
fun optimizeChannels(channels: SparseIntArray) = SparseIntArray(channels.size()).apply {
|
||||
var setBand = 0
|
||||
repeat(channels.size()) { i -> if (channels.valueAt(i) == 0) setBand = setBand or channels.keyAt(i) }
|
||||
if (setBand != 0) append(setBand, 0) // merge all bands into one
|
||||
repeat(channels.size()) { i ->
|
||||
val band = channels.keyAt(i)
|
||||
if (band and setBand == 0) put(band, channels.valueAt(i))
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(30)
|
||||
private fun setChannelsCompat(builder: Any, channels: SparseIntArray) = if (Build.VERSION.SDK_INT < 31) {
|
||||
val (band, channel) = requireSingleBand(channels)
|
||||
if (channel == 0) setBand(builder, band) else setChannel(builder, channel, band)
|
||||
} else setChannels(builder, channels)
|
||||
@get:RequiresApi(30)
|
||||
private val staticBuilder by lazy { classBuilder.newInstance() }
|
||||
@RequiresApi(30)
|
||||
fun testPlatformValidity(channels: SparseIntArray) = setChannels(staticBuilder, channels)
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
@@ -342,13 +369,6 @@ data class SoftApConfigurationCompat(
|
||||
bssidAddr = value?.addr
|
||||
}
|
||||
|
||||
/**
|
||||
* Only single band/channel can be supplied on API 23-30
|
||||
*/
|
||||
fun requireSingleBand(): Pair<Int, Int> {
|
||||
require(channels.size() == 1) { "Unsupported number of bands configured" }
|
||||
return channels.keyAt(0) to channels.valueAt(0)
|
||||
}
|
||||
fun getChannel(band: Int): Int {
|
||||
var result = -1
|
||||
repeat(channels.size()) { i ->
|
||||
@@ -367,17 +387,6 @@ data class SoftApConfigurationCompat(
|
||||
}, channel)
|
||||
}
|
||||
}
|
||||
fun optimizeChannels(channels: SparseIntArray = this.channels) {
|
||||
this.channels = SparseIntArray(channels.size()).apply {
|
||||
var setBand = 0
|
||||
repeat(channels.size()) { i -> if (channels.valueAt(i) == 0) setBand = setBand or channels.keyAt(i) }
|
||||
if (setBand != 0) append(setBand, 0) // merge all bands into one
|
||||
repeat(channels.size()) { i ->
|
||||
val band = channels.keyAt(i)
|
||||
if (band and setBand == 0) put(band, channels.valueAt(i))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setMacRandomizationEnabled(enabled: Boolean) {
|
||||
macRandomizationSetting = if (enabled) RANDOMIZATION_PERSISTENT else RANDOMIZATION_NONE
|
||||
@@ -393,7 +402,7 @@ data class SoftApConfigurationCompat(
|
||||
@Deprecated("Class deprecated in framework, use toPlatform().toWifiConfiguration()")
|
||||
@Suppress("DEPRECATION")
|
||||
fun toWifiConfiguration(): android.net.wifi.WifiConfiguration {
|
||||
val (band, channel) = requireSingleBand()
|
||||
val (band, channel) = requireSingleBand(channels)
|
||||
val wc = underlying as? android.net.wifi.WifiConfiguration
|
||||
val result = if (wc == null) android.net.wifi.WifiConfiguration() else android.net.wifi.WifiConfiguration(wc)
|
||||
val original = wc?.toCompat()
|
||||
@@ -438,10 +447,7 @@ data class SoftApConfigurationCompat(
|
||||
setSsid(builder, ssid)
|
||||
setPassphrase(builder, if (securityType == SoftApConfiguration.SECURITY_TYPE_OPEN) null else passphrase,
|
||||
securityType)
|
||||
if (Build.VERSION.SDK_INT >= 31) setChannels(builder, channels) else {
|
||||
val (band, channel) = requireSingleBand()
|
||||
if (channel == 0) setBand(builder, band) else setChannel(builder, channel, band)
|
||||
}
|
||||
setChannelsCompat(builder, channels)
|
||||
setBssid(builder, bssid?.toPlatform())
|
||||
setMaxNumberOfClients(builder, maxNumberOfClients)
|
||||
setShutdownTimeoutMillis(builder, shutdownTimeoutMillis)
|
||||
|
||||
@@ -95,6 +95,19 @@ class WifiApDialogFragment : AlertDialogFragment<WifiApDialogFragment.Arg, WifiA
|
||||
private val currentChannels5G get() = if (arg.p2pMode && !RepeaterService.safeMode) p2pChannels else channels5G
|
||||
override val ret get() = Arg(generateConfig())
|
||||
|
||||
private fun generateChannels() = SparseIntArray(4).apply {
|
||||
for ((band, spinner) in arrayOf(SoftApConfigurationCompat.BAND_2GHZ to dialogView.band2G,
|
||||
SoftApConfigurationCompat.BAND_5GHZ to dialogView.band5G,
|
||||
SoftApConfigurationCompat.BAND_6GHZ to dialogView.band6G,
|
||||
SoftApConfigurationCompat.BAND_60GHZ to dialogView.band60G)) {
|
||||
val channel = (spinner.selectedItem as ChannelOption?)?.channel
|
||||
if (channel != null && channel >= 0) append(band, channel)
|
||||
}
|
||||
}.let {
|
||||
if (arg.p2pMode || Build.VERSION.SDK_INT < 31 || !dialogView.bridgedMode.isChecked || it.size() > 2) {
|
||||
SoftApConfigurationCompat.optimizeChannels(it)
|
||||
} else it
|
||||
}
|
||||
private fun generateConfig(full: Boolean = true) = base.copy(
|
||||
ssid = dialogView.ssid.text.toString(),
|
||||
passphrase = if (dialogView.password.length() != 0) dialogView.password.text.toString() else null).apply {
|
||||
@@ -107,19 +120,7 @@ class WifiApDialogFragment : AlertDialogFragment<WifiApDialogFragment.Arg, WifiA
|
||||
shutdownTimeoutMillis = dialogView.timeout.text.let { text ->
|
||||
if (text.isNullOrEmpty()) 0 else text.toString().toLong()
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= 23 || arg.p2pMode) {
|
||||
val channels = SparseIntArray(4)
|
||||
for ((band, spinner) in arrayOf(SoftApConfigurationCompat.BAND_2GHZ to dialogView.band2G,
|
||||
SoftApConfigurationCompat.BAND_5GHZ to dialogView.band5G,
|
||||
SoftApConfigurationCompat.BAND_6GHZ to dialogView.band6G,
|
||||
SoftApConfigurationCompat.BAND_60GHZ to dialogView.band60G)) {
|
||||
val channel = (spinner.selectedItem as ChannelOption?)?.channel
|
||||
if (channel != null && channel >= 0) channels.append(band, channel)
|
||||
}
|
||||
if (!arg.p2pMode && Build.VERSION.SDK_INT >= 31 && dialogView.bridgedMode.isChecked) {
|
||||
this.channels = channels
|
||||
} else optimizeChannels(channels)
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= 23 || arg.p2pMode) channels = generateChannels()
|
||||
bssid = if (dialogView.bssid.length() != 0) {
|
||||
MacAddressCompat.fromString(dialogView.bssid.text.toString())
|
||||
} else null
|
||||
@@ -291,10 +292,9 @@ class WifiApDialogFragment : AlertDialogFragment<WifiApDialogFragment.Arg, WifiA
|
||||
}
|
||||
}
|
||||
dialogView.timeoutWrapper.error = timeoutError
|
||||
val isBandValid = when {
|
||||
arg.p2pMode || Build.VERSION.SDK_INT in 23 until 30 -> {
|
||||
val bandError = if (arg.p2pMode || Build.VERSION.SDK_INT <= 30) {
|
||||
val option5G = dialogView.band5G.selectedItem
|
||||
when (dialogView.band2G.selectedItem) {
|
||||
val valid = when (dialogView.band2G.selectedItem) {
|
||||
is ChannelOption.Disabled -> option5G !is ChannelOption.Disabled &&
|
||||
(!arg.p2pMode || RepeaterService.safeMode || option5G !is ChannelOption.Auto)
|
||||
is ChannelOption.Auto ->
|
||||
@@ -302,18 +302,18 @@ class WifiApDialogFragment : AlertDialogFragment<WifiApDialogFragment.Arg, WifiA
|
||||
(!arg.p2pMode || RepeaterService.safeMode) && option5G is ChannelOption.Disabled
|
||||
else -> option5G is ChannelOption.Disabled
|
||||
}
|
||||
if (valid) null else ""
|
||||
} else {
|
||||
if (Build.VERSION.SDK_INT >= 31) setBridgedMode()
|
||||
try {
|
||||
SoftApConfigurationCompat.testPlatformValidity(generateChannels())
|
||||
null
|
||||
} catch (e: Exception) {
|
||||
e.readableMessage
|
||||
}
|
||||
Build.VERSION.SDK_INT == 30 -> {
|
||||
var expected = 1
|
||||
var set = 0
|
||||
for (s in arrayOf(dialogView.band2G, dialogView.band5G, dialogView.band6G)) when (s.selectedItem) {
|
||||
is ChannelOption.Auto -> expected = 0
|
||||
!is ChannelOption.Disabled -> ++set
|
||||
}
|
||||
set == expected
|
||||
}
|
||||
else -> setBridgedMode()
|
||||
}
|
||||
dialogView.bandError.isGone = bandError.isNullOrEmpty()
|
||||
dialogView.bandError.text = bandError
|
||||
dialogView.bssidWrapper.error = null
|
||||
val bssidValid = dialogView.bssid.length() == 0 || try {
|
||||
MacAddressCompat.fromString(dialogView.bssid.text.toString())
|
||||
@@ -353,7 +353,7 @@ class WifiApDialogFragment : AlertDialogFragment<WifiApDialogFragment.Arg, WifiA
|
||||
} else true
|
||||
val canCopy = timeoutError == null && bssidValid && maxClientError == null && listsNoError
|
||||
(dialog as? AlertDialog)?.getButton(DialogInterface.BUTTON_POSITIVE)?.isEnabled =
|
||||
ssidLength in 1..32 && passwordValid && isBandValid && canCopy
|
||||
ssidLength in 1..32 && passwordValid && bandError == null && canCopy
|
||||
dialogView.toolbar.menu.findItem(android.R.id.copy).isEnabled = canCopy
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="300sp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
@@ -208,6 +210,16 @@
|
||||
android:layout_marginTop="8dip"
|
||||
android:minHeight="@dimen/touch_target_min"
|
||||
android:text="@string/wifi_bridged_mode" />
|
||||
<TextView
|
||||
android:id="@+id/band_error"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dip"
|
||||
android:paddingStart="8dp"
|
||||
android:textAppearance="@style/TextAppearance.Design.Error"
|
||||
android:visibility="gone"
|
||||
tools:text="error text placeholder"
|
||||
tools:visibility="visible"/>
|
||||
<Switch
|
||||
android:id="@+id/bridged_mode_opportunistic_shutdown"
|
||||
style="@style/wifi_item_label"
|
||||
|
||||
Reference in New Issue
Block a user