Merge "[AAPM] UX for disabling WEP" into main
This commit is contained in:
@@ -18,6 +18,9 @@ package com.android.settings.wifi
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.wifi.WifiManager
|
import android.net.wifi.WifiManager
|
||||||
|
import android.security.advancedprotection.AdvancedProtectionManager
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
@@ -27,6 +30,7 @@ import androidx.compose.runtime.saveable.rememberSaveable
|
|||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.semantics.Role
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.android.settings.R
|
import com.android.settings.R
|
||||||
@@ -50,6 +54,9 @@ class WepNetworksPreferenceController(context: Context, preferenceKey: String) :
|
|||||||
ComposePreferenceController(context, preferenceKey) {
|
ComposePreferenceController(context, preferenceKey) {
|
||||||
|
|
||||||
var wifiManager = context.getSystemService(WifiManager::class.java)!!
|
var wifiManager = context.getSystemService(WifiManager::class.java)!!
|
||||||
|
var aapmManager = if (android.security.Flags.aapmApi() && Flags.wepDisabledInApm())
|
||||||
|
context.getSystemService(AdvancedProtectionManager::class.java)!!
|
||||||
|
else null
|
||||||
|
|
||||||
override fun getAvailabilityStatus() =
|
override fun getAvailabilityStatus() =
|
||||||
if (Flags.androidVWifiApi()) AVAILABLE else UNSUPPORTED_ON_DEVICE
|
if (Flags.androidVWifiApi()) AVAILABLE else UNSUPPORTED_ON_DEVICE
|
||||||
@@ -60,27 +67,49 @@ class WepNetworksPreferenceController(context: Context, preferenceKey: String) :
|
|||||||
isWepSupportedFlow.collectAsStateWithLifecycle(initialValue = null).value
|
isWepSupportedFlow.collectAsStateWithLifecycle(initialValue = null).value
|
||||||
val isWepAllowed: Boolean? =
|
val isWepAllowed: Boolean? =
|
||||||
wepAllowedFlow.flow.collectAsStateWithLifecycle(initialValue = null).value
|
wepAllowedFlow.flow.collectAsStateWithLifecycle(initialValue = null).value
|
||||||
var openDialog by rememberSaveable { mutableStateOf(false) }
|
val isAapmEnabled: Boolean? = if (android.security.Flags.aapmApi()
|
||||||
SwitchPreference(
|
&& Flags.wepDisabledInApm())
|
||||||
object : SwitchPreferenceModel {
|
isAapmEnabledFlow.collectAsStateWithLifecycle(initialValue = null).value
|
||||||
override val title = stringResource(R.string.wifi_allow_wep_networks)
|
else false
|
||||||
override val summary = { getSummary(isWepSupported) }
|
|
||||||
override val checked = {
|
|
||||||
if (isWepSupported == true) isWepAllowed else isWepSupported
|
|
||||||
}
|
|
||||||
override val changeable: () -> Boolean
|
|
||||||
get() = { isWepSupported == true }
|
|
||||||
|
|
||||||
override val onCheckedChange: (Boolean) -> Unit = { newChecked ->
|
var openDialog by rememberSaveable { mutableStateOf(false) }
|
||||||
val wifiInfo = wifiManager.connectionInfo
|
|
||||||
if (!newChecked && wifiInfo.currentSecurityType == WifiEntry.SECURITY_WEP) {
|
RestrictionWrapper(
|
||||||
openDialog = true
|
restricted = isAapmEnabled == true
|
||||||
} else {
|
) {
|
||||||
wifiManager.setWepAllowed(newChecked)
|
SwitchPreference(
|
||||||
wepAllowedFlow.override(newChecked)
|
object : SwitchPreferenceModel {
|
||||||
|
override val title = stringResource(R.string.wifi_allow_wep_networks)
|
||||||
|
override val summary = { getSummary(isWepSupported) }
|
||||||
|
override val checked = {
|
||||||
|
when {
|
||||||
|
isWepSupported == false -> false
|
||||||
|
isAapmEnabled == true -> false
|
||||||
|
else -> isWepAllowed
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
override val changeable: () -> Boolean
|
||||||
|
get() = { isWepSupported == true && isAapmEnabled == false }
|
||||||
|
|
||||||
|
override val onCheckedChange: ((Boolean) -> Unit)? =
|
||||||
|
if (isAapmEnabled == true) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
{ newChecked ->
|
||||||
|
val wifiInfo = wifiManager.connectionInfo
|
||||||
|
if (!newChecked &&
|
||||||
|
wifiInfo.currentSecurityType == WifiEntry.SECURITY_WEP
|
||||||
|
) {
|
||||||
|
openDialog = true
|
||||||
|
} else {
|
||||||
|
wifiManager.setWepAllowed(newChecked)
|
||||||
|
wepAllowedFlow.override(newChecked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
)
|
||||||
|
}
|
||||||
if (openDialog) {
|
if (openDialog) {
|
||||||
SettingsAlertDialogWithIcon(
|
SettingsAlertDialogWithIcon(
|
||||||
onDismissRequest = { openDialog = false },
|
onDismissRequest = { openDialog = false },
|
||||||
@@ -103,6 +132,21 @@ class WepNetworksPreferenceController(context: Context, preferenceKey: String) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun RestrictionWrapper(restricted: Boolean, content: @Composable () -> Unit) {
|
||||||
|
if (restricted) {
|
||||||
|
Box(
|
||||||
|
Modifier.clickable(
|
||||||
|
enabled = true,
|
||||||
|
role = Role.Switch,
|
||||||
|
onClick = ::startSupportIntent
|
||||||
|
)
|
||||||
|
) { content() }
|
||||||
|
} else {
|
||||||
|
content()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun getSummary(isWepSupported: Boolean?): String =
|
private fun getSummary(isWepSupported: Boolean?): String =
|
||||||
mContext.getString(
|
mContext.getString(
|
||||||
when (isWepSupported) {
|
when (isWepSupported) {
|
||||||
@@ -114,6 +158,16 @@ class WepNetworksPreferenceController(context: Context, preferenceKey: String) :
|
|||||||
private val isWepSupportedFlow =
|
private val isWepSupportedFlow =
|
||||||
flow { emit(wifiManager.isWepSupported) }.flowOn(Dispatchers.Default)
|
flow { emit(wifiManager.isWepSupported) }.flowOn(Dispatchers.Default)
|
||||||
|
|
||||||
|
private val isAapmEnabledFlow = flow {
|
||||||
|
emit(aapmManager?.isAdvancedProtectionEnabled ?: false) }.flowOn(Dispatchers.Default)
|
||||||
|
|
||||||
|
private fun startSupportIntent() {
|
||||||
|
aapmManager?.createSupportIntent(
|
||||||
|
AdvancedProtectionManager.FEATURE_ID_DISALLOW_WEP,
|
||||||
|
AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_DISABLED_SETTING
|
||||||
|
)?.let { mContext.startActivity(it) }
|
||||||
|
}
|
||||||
|
|
||||||
val wepAllowedFlow =
|
val wepAllowedFlow =
|
||||||
OverridableFlow(
|
OverridableFlow(
|
||||||
callbackFlow {
|
callbackFlow {
|
||||||
|
@@ -17,8 +17,10 @@
|
|||||||
package com.android.settings.wifi
|
package com.android.settings.wifi
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
import android.net.wifi.WifiInfo
|
import android.net.wifi.WifiInfo
|
||||||
import android.net.wifi.WifiManager
|
import android.net.wifi.WifiManager
|
||||||
|
import android.security.advancedprotection.AdvancedProtectionManager
|
||||||
import androidx.compose.ui.test.assertIsOff
|
import androidx.compose.ui.test.assertIsOff
|
||||||
import androidx.compose.ui.test.assertIsOn
|
import androidx.compose.ui.test.assertIsOn
|
||||||
import androidx.compose.ui.test.isDisplayed
|
import androidx.compose.ui.test.isDisplayed
|
||||||
@@ -43,9 +45,12 @@ import org.mockito.Mockito
|
|||||||
import org.mockito.kotlin.any
|
import org.mockito.kotlin.any
|
||||||
import org.mockito.kotlin.doAnswer
|
import org.mockito.kotlin.doAnswer
|
||||||
import org.mockito.kotlin.doReturn
|
import org.mockito.kotlin.doReturn
|
||||||
|
import org.mockito.kotlin.doNothing
|
||||||
import org.mockito.kotlin.mock
|
import org.mockito.kotlin.mock
|
||||||
import org.mockito.kotlin.spy
|
import org.mockito.kotlin.spy
|
||||||
import org.mockito.kotlin.stub
|
import org.mockito.kotlin.stub
|
||||||
|
import org.mockito.kotlin.verify
|
||||||
|
import org.mockito.kotlin.whenever
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
@RunWith(AndroidJUnit4::class)
|
||||||
class WepNetworksPreferenceControllerTest {
|
class WepNetworksPreferenceControllerTest {
|
||||||
@@ -71,9 +76,15 @@ class WepNetworksPreferenceControllerTest {
|
|||||||
on { connectionInfo } doReturn mockWifiInfo
|
on { connectionInfo } doReturn mockWifiInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var mockAapmManager =
|
||||||
|
mock<AdvancedProtectionManager> {
|
||||||
|
on { isAdvancedProtectionEnabled } doReturn false
|
||||||
|
}
|
||||||
|
|
||||||
private var context: Context =
|
private var context: Context =
|
||||||
spy(ApplicationProvider.getApplicationContext()) {
|
spy(ApplicationProvider.getApplicationContext()) {
|
||||||
on { getSystemService(WifiManager::class.java) } doReturn mockWifiManager
|
on { getSystemService(WifiManager::class.java) } doReturn mockWifiManager
|
||||||
|
on { getSystemService(AdvancedProtectionManager::class.java) } doReturn mockAapmManager
|
||||||
}
|
}
|
||||||
|
|
||||||
private var controller = WepNetworksPreferenceController(context, TEST_KEY)
|
private var controller = WepNetworksPreferenceController(context, TEST_KEY)
|
||||||
@@ -185,6 +196,23 @@ class WepNetworksPreferenceControllerTest {
|
|||||||
.isNotDisplayed()
|
.isNotDisplayed()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenClick_aapmEnabled_openDialog() {
|
||||||
|
mockAapmManager.stub {
|
||||||
|
on { isAdvancedProtectionEnabled } doReturn true
|
||||||
|
on { createSupportIntent(any(), any()) } doReturn Intent()
|
||||||
|
}
|
||||||
|
doNothing().whenever(context).startActivity(any())
|
||||||
|
composeTestRule.setContent { controller.Content() }
|
||||||
|
|
||||||
|
composeTestRule.onRoot().performClick()
|
||||||
|
|
||||||
|
composeTestRule
|
||||||
|
.onDialogText(context.getString(R.string.wifi_disconnect_button_text))
|
||||||
|
.isNotDisplayed()
|
||||||
|
verify(context).startActivity(any())
|
||||||
|
}
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
const val TEST_KEY = "test_key"
|
const val TEST_KEY = "test_key"
|
||||||
const val SSID = "ssid"
|
const val SSID = "ssid"
|
||||||
|
Reference in New Issue
Block a user