[WIFI-Enterprise] Change the summary for Certificate Details.
Test: Visual Test Fix: 333850992 Change-Id: If2d8743f788a0732267ac6576f77bea41b4e2e84
This commit is contained in:
@@ -37,6 +37,9 @@ import com.android.settingslib.spa.widget.preference.Preference
|
|||||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||||
import com.android.wifi.flags.Flags
|
import com.android.wifi.flags.Flags
|
||||||
import com.android.wifitrackerlib.WifiEntry
|
import com.android.wifitrackerlib.WifiEntry
|
||||||
|
import com.android.wifitrackerlib.WifiEntry.CertificateInfo.CERTIFICATE_VALIDATION_METHOD_USING_CERTIFICATE_PINNING
|
||||||
|
import com.android.wifitrackerlib.WifiEntry.CertificateInfo.CERTIFICATE_VALIDATION_METHOD_USING_INSTALLED_ROOTCA
|
||||||
|
import com.android.wifitrackerlib.WifiEntry.CertificateInfo.CERTIFICATE_VALIDATION_METHOD_USING_SYSTEM_CERTIFICATE
|
||||||
import java.security.KeyStore
|
import java.security.KeyStore
|
||||||
import java.security.cert.X509Certificate
|
import java.security.cert.X509Certificate
|
||||||
|
|
||||||
@@ -44,15 +47,13 @@ class CertificateDetailsPreferenceController(context: Context, preferenceKey: St
|
|||||||
ComposePreferenceController(context, preferenceKey) {
|
ComposePreferenceController(context, preferenceKey) {
|
||||||
|
|
||||||
private lateinit var wifiEntry: WifiEntry
|
private lateinit var wifiEntry: WifiEntry
|
||||||
lateinit var certificateAliases: String
|
|
||||||
lateinit var certX509: X509Certificate
|
|
||||||
|
|
||||||
fun setWifiEntry(entry: WifiEntry) {
|
fun setWifiEntry(entry: WifiEntry) {
|
||||||
wifiEntry = entry
|
wifiEntry = entry
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getAvailabilityStatus(): Int {
|
override fun getAvailabilityStatus(): Int {
|
||||||
return if (Flags.androidVWifiApi() && getCertX509(wifiEntry)) AVAILABLE
|
return if (Flags.androidVWifiApi() && isCertificateDetailsAvailable(wifiEntry)) AVAILABLE
|
||||||
else CONDITIONALLY_UNAVAILABLE
|
else CONDITIONALLY_UNAVAILABLE
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,26 +65,52 @@ class CertificateDetailsPreferenceController(context: Context, preferenceKey: St
|
|||||||
@Composable
|
@Composable
|
||||||
fun CertificateDetails() {
|
fun CertificateDetails() {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
|
val validationMethod = wifiEntry.certificateInfo!!.validationMethod
|
||||||
|
val certificateDetailsSummary = when (validationMethod) {
|
||||||
|
CERTIFICATE_VALIDATION_METHOD_USING_SYSTEM_CERTIFICATE ->
|
||||||
|
stringResource(R.string.wifi_certificate_summary_system)
|
||||||
|
|
||||||
|
CERTIFICATE_VALIDATION_METHOD_USING_INSTALLED_ROOTCA -> {
|
||||||
|
val aliasesSize = wifiEntry.certificateInfo?.caCertificateAliases?.size
|
||||||
|
if (aliasesSize == 1) stringResource(R.string.one_cacrt)
|
||||||
|
else
|
||||||
|
String.format(
|
||||||
|
stringResource(R.string.wifi_certificate_summary_Certificates),
|
||||||
|
aliasesSize
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> stringResource(R.string.wifi_certificate_summary_pinning)
|
||||||
|
}
|
||||||
|
|
||||||
Preference(object : PreferenceModel {
|
Preference(object : PreferenceModel {
|
||||||
override val title = stringResource(com.android.internal.R.string.ssl_certificate)
|
override val title = stringResource(com.android.internal.R.string.ssl_certificate)
|
||||||
override val summary = { certificateAliases }
|
override val summary = { certificateDetailsSummary }
|
||||||
override val onClick: () -> Unit = { createCertificateDetailsDialog(context, certX509) }
|
override val onClick: () -> Unit = {
|
||||||
|
if (validationMethod == CERTIFICATE_VALIDATION_METHOD_USING_INSTALLED_ROOTCA)
|
||||||
|
getCertX509(wifiEntry)?.let {
|
||||||
|
createCertificateDetailsDialog(
|
||||||
|
context,
|
||||||
|
it
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getCertX509(wifiEntry: WifiEntry): Boolean {
|
private fun getCertX509(wifiEntry: WifiEntry): X509Certificate? {
|
||||||
certificateAliases =
|
val certificateAliases =
|
||||||
wifiEntry.wifiConfiguration?.enterpriseConfig?.caCertificateAliases?.get(0)
|
wifiEntry.certificateInfo?.caCertificateAliases?.get(0)
|
||||||
?: return false
|
?: return null
|
||||||
return try {
|
return try {
|
||||||
val keyStore = KeyStore.getInstance("AndroidKeyStore")
|
val keyStore = KeyStore.getInstance("AndroidKeyStore")
|
||||||
keyStore.load(AndroidKeyStoreLoadStoreParameter(KeyProperties.NAMESPACE_WIFI))
|
keyStore.load(AndroidKeyStoreLoadStoreParameter(KeyProperties.NAMESPACE_WIFI))
|
||||||
val cert = keyStore.getCertificate(certificateAliases)
|
val cert = keyStore.getCertificate(certificateAliases)
|
||||||
certX509 = KeyChain.toCertificate(cert.encoded)
|
KeyChain.toCertificate(cert.encoded)
|
||||||
true
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Failed to open Android Keystore.", e)
|
Log.e(TAG, "Failed to open Android Keystore.", e)
|
||||||
false
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,6 +151,15 @@ class CertificateDetailsPreferenceController(context: Context, preferenceKey: St
|
|||||||
dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setEnabled(false)
|
dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setEnabled(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun isCertificateDetailsAvailable(wifiEntry: WifiEntry): Boolean {
|
||||||
|
val validationMethod = wifiEntry.certificateInfo?.validationMethod
|
||||||
|
return validationMethod in listOf(
|
||||||
|
CERTIFICATE_VALIDATION_METHOD_USING_SYSTEM_CERTIFICATE,
|
||||||
|
CERTIFICATE_VALIDATION_METHOD_USING_INSTALLED_ROOTCA,
|
||||||
|
CERTIFICATE_VALIDATION_METHOD_USING_CERTIFICATE_PINNING
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "CertificateDetailsPreferenceController"
|
const val TAG = "CertificateDetailsPreferenceController"
|
||||||
}
|
}
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
package com.android.settings.wifi.details2
|
package com.android.settings.wifi.details2
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.platform.test.annotations.RequiresFlagsEnabled
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.test.assertIsDisplayed
|
import androidx.compose.ui.test.assertIsDisplayed
|
||||||
@@ -24,13 +25,15 @@ import androidx.compose.ui.test.junit4.createComposeRule
|
|||||||
import androidx.compose.ui.test.onNodeWithText
|
import androidx.compose.ui.test.onNodeWithText
|
||||||
import androidx.test.core.app.ApplicationProvider
|
import androidx.test.core.app.ApplicationProvider
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import java.security.cert.X509Certificate
|
import com.android.settings.R
|
||||||
|
import com.android.wifitrackerlib.WifiEntry
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.mockito.kotlin.any
|
import org.mockito.kotlin.any
|
||||||
import org.mockito.kotlin.doNothing
|
import org.mockito.kotlin.doNothing
|
||||||
|
import org.mockito.kotlin.doReturn
|
||||||
import org.mockito.kotlin.mock
|
import org.mockito.kotlin.mock
|
||||||
import org.mockito.kotlin.spy
|
import org.mockito.kotlin.spy
|
||||||
import org.mockito.kotlin.whenever
|
import org.mockito.kotlin.whenever
|
||||||
@@ -40,21 +43,26 @@ class CertificateDetailsPreferenceControllerTest {
|
|||||||
@get:Rule
|
@get:Rule
|
||||||
val composeTestRule = createComposeRule()
|
val composeTestRule = createComposeRule()
|
||||||
|
|
||||||
private val mockCertX509 = mock<X509Certificate> {}
|
|
||||||
|
|
||||||
private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
|
private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
|
||||||
doNothing().whenever(mock).startActivity(any())
|
doNothing().whenever(mock).startActivity(any())
|
||||||
}
|
}
|
||||||
|
|
||||||
private val controller = CertificateDetailsPreferenceController(context, TEST_KEY)
|
private val controller = CertificateDetailsPreferenceController(context, TEST_KEY)
|
||||||
|
|
||||||
|
private val mockCertificateInfo = mock<WifiEntry.CertificateInfo> {
|
||||||
|
it.validationMethod =
|
||||||
|
WifiEntry.CertificateInfo.CERTIFICATE_VALIDATION_METHOD_USING_INSTALLED_ROOTCA
|
||||||
|
it.caCertificateAliases = arrayOf(MOCK_CA)
|
||||||
|
}
|
||||||
|
private val mockWifiEntry =
|
||||||
|
mock<WifiEntry> { on { certificateInfo } doReturn mockCertificateInfo }
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
controller.certificateAliases = MOCK_CA
|
controller.setWifiEntry(mockWifiEntry)
|
||||||
controller.certX509 = mockCertX509
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@RequiresFlagsEnabled(com.android.wifi.flags.Flags.FLAG_ANDROID_V_WIFI_API)
|
||||||
fun title_isDisplayed() {
|
fun title_isDisplayed() {
|
||||||
composeTestRule.setContent {
|
composeTestRule.setContent {
|
||||||
CompositionLocalProvider(LocalContext provides context) {
|
CompositionLocalProvider(LocalContext provides context) {
|
||||||
@@ -62,8 +70,21 @@ class CertificateDetailsPreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
composeTestRule.onNodeWithText(context.getString(com.android.internal.R.string.ssl_certificate))
|
composeTestRule.onNodeWithText(
|
||||||
.assertIsDisplayed()
|
context.getString(com.android.internal.R.string.ssl_certificate)
|
||||||
|
).assertIsDisplayed()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@RequiresFlagsEnabled(com.android.wifi.flags.Flags.FLAG_ANDROID_V_WIFI_API)
|
||||||
|
fun one_caCertificate_summary() {
|
||||||
|
composeTestRule.setContent {
|
||||||
|
CompositionLocalProvider(LocalContext provides context) {
|
||||||
|
controller.Content()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
composeTestRule.onNodeWithText(context.getString(R.string.one_cacrt)).assertIsDisplayed()
|
||||||
}
|
}
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
|
Reference in New Issue
Block a user