Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2ccbf1db authored by Hani Kazmi's avatar Hani Kazmi Committed by Android (Google) Code Review
Browse files

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

parents 15ca2ddd 4efa8adf
Loading
Loading
Loading
Loading
+72 −18
Original line number Diff line number Diff line
@@ -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
        val isAapmEnabled: Boolean? = if (android.security.Flags.aapmApi()
            && Flags.wepDisabledInApm())
                isAapmEnabledFlow.collectAsStateWithLifecycle(initialValue = null).value
        else false

        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 = {
                    if (isWepSupported == true) isWepAllowed else isWepSupported
                        when {
                            isWepSupported == false -> false
                            isAapmEnabled == true -> false
                            else -> isWepAllowed
                        }
                    }
                    override val changeable: () -> Boolean
                    get() = { isWepSupported == true }
                        get() = { isWepSupported == true && isAapmEnabled == false }

                override val onCheckedChange: (Boolean) -> Unit = { newChecked ->
                    override val onCheckedChange: ((Boolean) -> Unit)? =
                        if (isAapmEnabled == true) {
                            null
                        } else {
                            { newChecked ->
                                val wifiInfo = wifiManager.connectionInfo
                    if (!newChecked && wifiInfo.currentSecurityType == WifiEntry.SECURITY_WEP) {
                                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 {
+28 −0
Original line number Diff line number Diff line
@@ -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"