From da7d318f60ce78f55584ef3ae04c4239f6bf67b1 Mon Sep 17 00:00:00 2001 From: Mygod Date: Fri, 8 Oct 2021 14:17:34 -0400 Subject: [PATCH] Correctly implement bridged AP, third attempt --- .../net/wifi/SoftApConfigurationCompat.kt | 26 +--- .../net/wifi/WifiApDialogFragment.kt | 141 +++++++----------- mobile/src/main/res/layout/dialog_wifi_ap.xml | 89 ++--------- mobile/src/main/res/values-it/strings.xml | 4 +- mobile/src/main/res/values-ru/strings.xml | 6 +- mobile/src/main/res/values-zh-rCN/strings.xml | 7 +- mobile/src/main/res/values-zh-rTW/strings.xml | 6 +- mobile/src/main/res/values/strings.xml | 7 +- 8 files changed, 79 insertions(+), 207 deletions(-) diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/SoftApConfigurationCompat.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/SoftApConfigurationCompat.kt index 29af489c..ab1fb8e8 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/SoftApConfigurationCompat.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/SoftApConfigurationCompat.kt @@ -24,11 +24,9 @@ data class SoftApConfigurationCompat( var passphrase: String? = null, var isHiddenSsid: Boolean = false, /** - * To read legacy band/channel pair, use [requireSingleBand]. For easy access, see [getChannel]. - * * You should probably set or modify this field directly only when you want to use bridged AP, * see also [android.net.wifi.WifiManager.isBridgedApConcurrencySupported]. - * Otherwise, use [optimizeChannels] or [setChannel]. + * Otherwise, use [requireSingleBand] and [setChannel]. */ @TargetApi(23) var channels: SparseIntArray = SparseIntArray(1).apply { append(BAND_2GHZ, 0) }, @@ -62,6 +60,10 @@ data class SoftApConfigurationCompat( @TargetApi(31) const val BAND_60GHZ = 8 const val BAND_LEGACY = BAND_2GHZ or BAND_5GHZ + @TargetApi(30) + const val BAND_ANY_30 = BAND_LEGACY or BAND_6GHZ + @TargetApi(31) + const val BAND_ANY_31 = BAND_ANY_30 or BAND_60GHZ val BAND_TYPES by lazy { if (Build.VERSION.SDK_INT >= 31) try { return@lazy UnblockCentral.SoftApConfiguration_BAND_TYPES @@ -341,15 +343,6 @@ data class SoftApConfigurationCompat( 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) { @@ -369,15 +362,6 @@ data class SoftApConfigurationCompat( bssidAddr = value?.addr } - fun getChannel(band: Int): Int { - var result = -1 - repeat(channels.size()) { i -> - if (band and channels.keyAt(i) != band) return@repeat - require(result == -1) { "Duplicate band found" } - result = channels.valueAt(i) - } - return result - } fun setChannel(channel: Int, band: Int = BAND_LEGACY) { channels = SparseIntArray(1).apply { append(when { diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiApDialogFragment.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiApDialogFragment.kt index e7f1516a..b62f2903 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiApDialogFragment.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiApDialogFragment.kt @@ -36,6 +36,8 @@ import be.mygod.vpnhotspot.util.readableMessage import be.mygod.vpnhotspot.util.showAllowingStateLoss import kotlinx.parcelize.Parcelize import timber.log.Timber +import java.text.DecimalFormat +import java.text.DecimalFormatSymbols /** * Based on: https://android.googlesource.com/platform/packages/apps/Settings/+/39b4674/src/com/android/settings/wifi/WifiApDialog.java @@ -48,26 +50,30 @@ class WifiApDialogFragment : AlertDialogFragment= 31) { + genAutoOptions(SoftApConfigurationCompat.BAND_ANY_31) + + channels6G + (1..6).map { ChannelOption(SoftApConfigurationCompat.BAND_60GHZ, it) } + } else genAutoOptions(SoftApConfigurationCompat.BAND_ANY_30) + channels6G } } @@ -80,34 +86,36 @@ class WifiApDialogFragment : AlertDialogFragment band and mask == mask }.joinToString("/") { (_, name) -> format.format(name) }) + } else "${SoftApConfigurationCompat.channelToFrequency(band, channel)} MHz ($channel)" } private lateinit var dialogView: DialogWifiApBinding private lateinit var base: SoftApConfigurationCompat private var started = false - private val currentChannels5G get() = if (arg.p2pMode && !RepeaterService.safeMode) p2pChannels else channels5G + private val currentChannels get() = when { + arg.p2pMode && !RepeaterService.safeMode -> p2pUnsafeOptions + arg.p2pMode || Build.VERSION.SDK_INT < 30 -> p2pSafeOptions + else -> softApOptions + } 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) + private fun generateChannels() = SparseIntArray(2).apply { + if (!arg.p2pMode && Build.VERSION.SDK_INT >= 31) { + (dialogView.bandSecondary.selectedItem as ChannelOption?)?.apply { if (band >= 0) put(band, channel) } } - }.let { - if (arg.p2pMode || Build.VERSION.SDK_INT < 31 || !dialogView.bridgedMode.isChecked || it.size() > 2) { - SoftApConfigurationCompat.optimizeChannels(it) - } else it + (dialogView.bandPrimary.selectedItem as ChannelOption).apply { put(band, channel) } } private fun generateConfig(full: Boolean = true) = base.copy( ssid = dialogView.ssid.text.toString(), @@ -188,15 +196,10 @@ class WifiApDialogFragment : AlertDialogFragment= 23 || arg.p2pMode) { - dialogView.band2G.configure(channels2G) - dialogView.band5G.configure(currentChannels5G) - if (Build.VERSION.SDK_INT >= 30 && !arg.p2pMode) dialogView.band6G.configure(channels6G) - else dialogView.bandWrapper6G.isGone = true - if (Build.VERSION.SDK_INT >= 31 && !arg.p2pMode) dialogView.band60G.configure(channels60G) else { - dialogView.bandWrapper60G.isGone = true - dialogView.bridgedMode.isGone = true - dialogView.bridgedModeOpportunisticShutdown.isGone = true - } + dialogView.bandPrimary.configure(currentChannels) + if (Build.VERSION.SDK_INT >= 31 && !arg.p2pMode) { + dialogView.bandSecondary.configure(listOf(ChannelOption.Disabled) + currentChannels) + } else dialogView.bandSecondary.isGone = true } else dialogView.bandGroup.isGone = true if (arg.p2pMode || Build.VERSION.SDK_INT < 30) dialogView.accessControlGroup.isGone = true else if (!arg.readOnly) { @@ -210,41 +213,22 @@ class WifiApDialogFragment : AlertDialogFragment): Int { - val channel = base.getChannel(band) - val selection = channels.indexOfFirst { it.channel == channel } + private fun locate(i: Int): Int { + val band = base.channels.keyAt(i) + val channel = base.channels.valueAt(i) + val selection = currentChannels.indexOfFirst { it.band == band && it.channel == channel } return if (selection == -1) { Timber.w(Exception("Unable to locate $band, $channel, ${arg.p2pMode && !RepeaterService.safeMode}")) 0 } else selection } - private var userBridgedMode = false - private fun setBridgedMode(): Boolean { - var auto = 0 - var set = 0 - for (s in arrayOf(dialogView.band2G, dialogView.band5G, dialogView.band6G, - dialogView.band60G)) when (s.selectedItem) { - is ChannelOption.Auto -> auto = 1 - !is ChannelOption.Disabled -> ++set - } - if (auto + set > 1) { - if (dialogView.bridgedMode.isEnabled) { - userBridgedMode = dialogView.bridgedMode.isChecked - dialogView.bridgedMode.isEnabled = false - dialogView.bridgedMode.isChecked = true - } - } else if (!dialogView.bridgedMode.isEnabled) { - dialogView.bridgedMode.isEnabled = true - dialogView.bridgedMode.isChecked = userBridgedMode - } - return auto + set > 0 - } private fun populateFromConfiguration() { dialogView.ssid.setText(base.ssid) if (!arg.p2pMode) dialogView.security.setSelection(base.securityType) @@ -252,13 +236,10 @@ class WifiApDialogFragment : AlertDialogFragment= 23 || arg.p2pMode) { - dialogView.band2G.setSelection(locate(SoftApConfigurationCompat.BAND_2GHZ, channels2G)) - dialogView.band5G.setSelection(locate(SoftApConfigurationCompat.BAND_5GHZ, currentChannels5G)) - dialogView.band6G.setSelection(locate(SoftApConfigurationCompat.BAND_6GHZ, channels6G)) - dialogView.band60G.setSelection(locate(SoftApConfigurationCompat.BAND_60GHZ, channels60G)) - userBridgedMode = base.channels.size() > 1 - dialogView.bridgedMode.isChecked = userBridgedMode - setBridgedMode() + dialogView.bandPrimary.setSelection(locate(0)) + if (Build.VERSION.SDK_INT >= 31 && !arg.p2pMode) { + dialogView.bandSecondary.setSelection(if (base.channels.size() > 1) locate(1) + 1 else 0) + } } dialogView.bssid.setText(base.bssid?.toString()) dialogView.hiddenSsid.isChecked = base.isHiddenSsid @@ -308,26 +289,14 @@ class WifiApDialogFragment : AlertDialogFragment option5G !is ChannelOption.Disabled && - (!arg.p2pMode || RepeaterService.safeMode || option5G !is ChannelOption.Auto) - is ChannelOption.Auto -> - (arg.p2pMode || Build.VERSION.SDK_INT >= 28) && option5G is ChannelOption.Auto || - (!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() + val bandError = if (!arg.p2pMode && Build.VERSION.SDK_INT >= 30) { try { SoftApConfigurationCompat.testPlatformValidity(generateChannels()) null } catch (e: Exception) { e.readableMessage } - } + } else null dialogView.bandError.isGone = bandError.isNullOrEmpty() dialogView.bandError.text = bandError dialogView.bssidWrapper.error = null diff --git a/mobile/src/main/res/layout/dialog_wifi_ap.xml b/mobile/src/main/res/layout/dialog_wifi_ap.xml index 952d3cb0..dd5f96d0 100644 --- a/mobile/src/main/res/layout/dialog_wifi_ap.xml +++ b/mobile/src/main/res/layout/dialog_wifi_ap.xml @@ -128,88 +128,27 @@ android:id="@+id/band_group" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_marginTop="8dip" android:orientation="vertical"> - - - + android:prompt="@string/wifi_hotspot_ap_band_title" /> - - - - - - - - - + android:prompt="@string/wifi_hotspot_ap_band_title" /> - + Password "L\'hotspot Wi‑Fi viene disattivato se non ci sono dispositivi collegati" Banda AP - "Automatica" - "Banda a 2,4 GHz" - "Banda a 5 GHz" + "Banda a %s GHz" "Indirizzo MAC" "Rete nascosta" Salva diff --git a/mobile/src/main/res/values-ru/strings.xml b/mobile/src/main/res/values-ru/strings.xml index c74ace52..ccf26072 100644 --- a/mobile/src/main/res/values-ru/strings.xml +++ b/mobile/src/main/res/values-ru/strings.xml @@ -59,11 +59,7 @@ "Пароль" "Выключать точку доступа Wi‑Fi автоматически, если к ней не подключено ни одного устройства" "Диапазон частот Wi-Fi" - "Авто" - "2,4 ГГц" - "5 ГГц" - "6 ГГц" - "60 ГГц" + "%s ГГц" "MAC-адрес" "Скрытая сеть" "Сохранить" diff --git a/mobile/src/main/res/values-zh-rCN/strings.xml b/mobile/src/main/res/values-zh-rCN/strings.xml index 1e7be6c6..1230ea94 100644 --- a/mobile/src/main/res/values-zh-rCN/strings.xml +++ b/mobile/src/main/res/values-zh-rCN/strings.xml @@ -180,11 +180,7 @@ 默认延迟:%d 毫秒 "AP 频段" Disabled - "自动" - "2.4 GHz 频段" - "5 GHz 频段" - 6 GHz 频段 - 60 GHz 频段 + "%s GHz 频段" 访问控制 高级接入点设置 "MAC 地址" @@ -194,7 +190,6 @@ 设备黑名单 设备白名单 随机生成 MAC 地址 - 启用无线接入点桥接模式 启用桥接模式伺机关闭 启用 Wi\u2011Fi 6 用户提供配置 diff --git a/mobile/src/main/res/values-zh-rTW/strings.xml b/mobile/src/main/res/values-zh-rTW/strings.xml index 615d40be..93eed8f7 100644 --- a/mobile/src/main/res/values-zh-rTW/strings.xml +++ b/mobile/src/main/res/values-zh-rTW/strings.xml @@ -177,11 +177,7 @@ 默認延遲:%d 毫秒 AP 頻帶 停用 - 自動 - 2.4 GHz 頻帶 - 5 GHz 頻帶 - 6 GHz 頻帶 - 60 GHz 頻帶 + %s GHz 頻帶 "MAC 地址" "隱藏的網路" 允許的連接裝置數量 diff --git a/mobile/src/main/res/values/strings.xml b/mobile/src/main/res/values/strings.xml index 0fbfb5fc..25492cfb 100644 --- a/mobile/src/main/res/values/strings.xml +++ b/mobile/src/main/res/values/strings.xml @@ -203,11 +203,7 @@ Default timeout: %dms AP Band Disabled - Auto - 2.4 GHz Band - 5 GHz Band - 6 GHz Band - 60 GHz Band + %s GHz Band Access Control Advanced AP Options MAC address @@ -217,7 +213,6 @@ Blocked list of clients Allowed list of clients Use randomized MAC - Enable Bridged Access point (AP) concurrency Enable Bridged mode opportunistic shutdown Enable Wi\u2011Fi 6 User Supplied Configuration