Merge "[AAPM] UX for disabling WEP" into main

This commit is contained in:
Hani Kazmi
2024-12-11 09:05:58 -08:00
committed by Android (Google) Code Review
2 changed files with 100 additions and 18 deletions

View File

@@ -18,6 +18,9 @@ package com.android.settings.wifi
import android.content.Context
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.material3.Text
import androidx.compose.runtime.Composable
@@ -27,6 +30,7 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.text.style.TextAlign
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.settings.R
@@ -50,6 +54,9 @@ class WepNetworksPreferenceController(context: Context, preferenceKey: String) :
ComposePreferenceController(context, preferenceKey) {
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() =
if (Flags.androidVWifiApi()) AVAILABLE else UNSUPPORTED_ON_DEVICE
@@ -60,27 +67,49 @@ class WepNetworksPreferenceController(context: Context, preferenceKey: String) :
isWepSupportedFlow.collectAsStateWithLifecycle(initialValue = null).value
val isWepAllowed: Boolean? =
wepAllowedFlow.flow.collectAsStateWithLifecycle(initialValue = null).value
var openDialog by rememberSaveable { mutableStateOf(false) }
SwitchPreference(
object : SwitchPreferenceModel {
override val title = stringResource(R.string.wifi_allow_wep_networks)
override val summary = { getSummary(isWepSupported) }
override val checked = {
if (isWepSupported == true) isWepAllowed else isWepSupported
}
override val changeable: () -> Boolean
get() = { isWepSupported == true }
val isAapmEnabled: Boolean? = if (android.security.Flags.aapmApi()
&& Flags.wepDisabledInApm())
isAapmEnabledFlow.collectAsStateWithLifecycle(initialValue = null).value
else false
override val onCheckedChange: (Boolean) -> Unit = { newChecked ->
val wifiInfo = wifiManager.connectionInfo
if (!newChecked && wifiInfo.currentSecurityType == WifiEntry.SECURITY_WEP) {
openDialog = true
} else {
wifiManager.setWepAllowed(newChecked)
wepAllowedFlow.override(newChecked)
var openDialog by rememberSaveable { mutableStateOf(false) }
RestrictionWrapper(
restricted = isAapmEnabled == true
) {
SwitchPreference(
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) {
SettingsAlertDialogWithIcon(
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 =
mContext.getString(
when (isWepSupported) {
@@ -114,6 +158,16 @@ class WepNetworksPreferenceController(context: Context, preferenceKey: String) :
private val isWepSupportedFlow =
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 =
OverridableFlow(
callbackFlow {

View File

@@ -17,8 +17,10 @@
package com.android.settings.wifi
import android.content.Context
import android.content.Intent
import android.net.wifi.WifiInfo
import android.net.wifi.WifiManager
import android.security.advancedprotection.AdvancedProtectionManager
import androidx.compose.ui.test.assertIsOff
import androidx.compose.ui.test.assertIsOn
import androidx.compose.ui.test.isDisplayed
@@ -43,9 +45,12 @@ import org.mockito.Mockito
import org.mockito.kotlin.any
import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.doNothing
import org.mockito.kotlin.mock
import org.mockito.kotlin.spy
import org.mockito.kotlin.stub
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
@RunWith(AndroidJUnit4::class)
class WepNetworksPreferenceControllerTest {
@@ -71,9 +76,15 @@ class WepNetworksPreferenceControllerTest {
on { connectionInfo } doReturn mockWifiInfo
}
private var mockAapmManager =
mock<AdvancedProtectionManager> {
on { isAdvancedProtectionEnabled } doReturn false
}
private var context: Context =
spy(ApplicationProvider.getApplicationContext()) {
on { getSystemService(WifiManager::class.java) } doReturn mockWifiManager
on { getSystemService(AdvancedProtectionManager::class.java) } doReturn mockAapmManager
}
private var controller = WepNetworksPreferenceController(context, TEST_KEY)
@@ -185,6 +196,23 @@ class WepNetworksPreferenceControllerTest {
.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 {
const val TEST_KEY = "test_key"
const val SSID = "ssid"