[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.wifi.flags.Flags
|
||||
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.cert.X509Certificate
|
||||
|
||||
@@ -44,15 +47,13 @@ class CertificateDetailsPreferenceController(context: Context, preferenceKey: St
|
||||
ComposePreferenceController(context, preferenceKey) {
|
||||
|
||||
private lateinit var wifiEntry: WifiEntry
|
||||
lateinit var certificateAliases: String
|
||||
lateinit var certX509: X509Certificate
|
||||
|
||||
fun setWifiEntry(entry: WifiEntry) {
|
||||
wifiEntry = entry
|
||||
}
|
||||
|
||||
override fun getAvailabilityStatus(): Int {
|
||||
return if (Flags.androidVWifiApi() && getCertX509(wifiEntry)) AVAILABLE
|
||||
return if (Flags.androidVWifiApi() && isCertificateDetailsAvailable(wifiEntry)) AVAILABLE
|
||||
else CONDITIONALLY_UNAVAILABLE
|
||||
}
|
||||
|
||||
@@ -64,26 +65,52 @@ class CertificateDetailsPreferenceController(context: Context, preferenceKey: St
|
||||
@Composable
|
||||
fun CertificateDetails() {
|
||||
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 {
|
||||
override val title = stringResource(com.android.internal.R.string.ssl_certificate)
|
||||
override val summary = { certificateAliases }
|
||||
override val onClick: () -> Unit = { createCertificateDetailsDialog(context, certX509) }
|
||||
override val summary = { certificateDetailsSummary }
|
||||
override val onClick: () -> Unit = {
|
||||
if (validationMethod == CERTIFICATE_VALIDATION_METHOD_USING_INSTALLED_ROOTCA)
|
||||
getCertX509(wifiEntry)?.let {
|
||||
createCertificateDetailsDialog(
|
||||
context,
|
||||
it
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun getCertX509(wifiEntry: WifiEntry): Boolean {
|
||||
certificateAliases =
|
||||
wifiEntry.wifiConfiguration?.enterpriseConfig?.caCertificateAliases?.get(0)
|
||||
?: return false
|
||||
private fun getCertX509(wifiEntry: WifiEntry): X509Certificate? {
|
||||
val certificateAliases =
|
||||
wifiEntry.certificateInfo?.caCertificateAliases?.get(0)
|
||||
?: return null
|
||||
return try {
|
||||
val keyStore = KeyStore.getInstance("AndroidKeyStore")
|
||||
keyStore.load(AndroidKeyStoreLoadStoreParameter(KeyProperties.NAMESPACE_WIFI))
|
||||
val cert = keyStore.getCertificate(certificateAliases)
|
||||
certX509 = KeyChain.toCertificate(cert.encoded)
|
||||
true
|
||||
KeyChain.toCertificate(cert.encoded)
|
||||
} catch (e: Exception) {
|
||||
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)
|
||||
}
|
||||
|
||||
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 {
|
||||
const val TAG = "CertificateDetailsPreferenceController"
|
||||
}
|
||||
|
@@ -17,6 +17,7 @@
|
||||
package com.android.settings.wifi.details2
|
||||
|
||||
import android.content.Context
|
||||
import android.platform.test.annotations.RequiresFlagsEnabled
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
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.test.core.app.ApplicationProvider
|
||||
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.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.doNothing
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.spy
|
||||
import org.mockito.kotlin.whenever
|
||||
@@ -40,21 +43,26 @@ class CertificateDetailsPreferenceControllerTest {
|
||||
@get:Rule
|
||||
val composeTestRule = createComposeRule()
|
||||
|
||||
private val mockCertX509 = mock<X509Certificate> {}
|
||||
|
||||
private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
|
||||
doNothing().whenever(mock).startActivity(any())
|
||||
}
|
||||
|
||||
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
|
||||
fun setUp() {
|
||||
controller.certificateAliases = MOCK_CA
|
||||
controller.certX509 = mockCertX509
|
||||
controller.setWifiEntry(mockWifiEntry)
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsEnabled(com.android.wifi.flags.Flags.FLAG_ANDROID_V_WIFI_API)
|
||||
fun title_isDisplayed() {
|
||||
composeTestRule.setContent {
|
||||
CompositionLocalProvider(LocalContext provides context) {
|
||||
@@ -62,8 +70,21 @@ class CertificateDetailsPreferenceControllerTest {
|
||||
}
|
||||
}
|
||||
|
||||
composeTestRule.onNodeWithText(context.getString(com.android.internal.R.string.ssl_certificate))
|
||||
.assertIsDisplayed()
|
||||
composeTestRule.onNodeWithText(
|
||||
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 {
|
||||
|
Reference in New Issue
Block a user