diff --git a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionScreen.kt b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionScreen.kt index 6ca2776e06d..0075068f4dc 100644 --- a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionScreen.kt +++ b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionScreen.kt @@ -48,7 +48,7 @@ class FirmwareVersionScreen : PreferenceScreenCreator, PreferenceSummaryProvider override fun getPreferenceHierarchy(context: Context) = preferenceHierarchy(this) { +PreferenceWidget("os_firmware_version", R.string.firmware_version) - +PreferenceWidget("security_key", R.string.security_patch) + +SecurityPatchLevelPreference() +MainlineModuleVersionPreference() +BasebandVersionPreference() +KernelVersionPreference() diff --git a/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreference.kt b/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreference.kt new file mode 100644 index 00000000000..7af389ec6ac --- /dev/null +++ b/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreference.kt @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.deviceinfo.firmwareversion + +import android.content.Context +import android.content.Intent +import android.net.Uri +import androidx.preference.Preference +import com.android.settings.R +import com.android.settings.utils.getLocale +import com.android.settingslib.DeviceInfoUtils +import com.android.settingslib.metadata.PreferenceAvailabilityProvider +import com.android.settingslib.metadata.PreferenceMetadata +import com.android.settingslib.metadata.PreferenceSummaryProvider +import com.android.settingslib.preference.PreferenceBinding + +// LINT.IfChange +class SecurityPatchLevelPreference : + PreferenceMetadata, + PreferenceAvailabilityProvider, + PreferenceSummaryProvider, + PreferenceBinding { + + private var currentPatch: String? = null + + override val key: String + get() = "security_key" + + override val title: Int + get() = R.string.security_patch + + override fun intent(context: Context): Intent? = + Intent(Intent.ACTION_VIEW) + .setData(Uri.parse("https://source.android.com/docs/security/bulletin/")) + + override fun isAvailable(context: Context) = context.getPatch().isNotEmpty() + + override fun getSummary(context: Context) = context.getPatch() + + private fun Context.getPatch(): String = + currentPatch + ?: (DeviceInfoUtils.getSecurityPatch(getLocale()) ?: "").also { currentPatch = it } + + override fun bind(preference: Preference, metadata: PreferenceMetadata) { + super.bind(preference, metadata) + preference.isCopyingEnabled = true + } +} +// LINT.ThenChange(SecurityPatchLevelPreferenceController.java) diff --git a/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreferenceController.java b/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreferenceController.java index dcb5a37ffa0..b4648ee19f8 100644 --- a/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreferenceController.java +++ b/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreferenceController.java @@ -16,6 +16,7 @@ package com.android.settings.deviceinfo.firmwareversion; +// LINT.IfChange import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; @@ -73,3 +74,4 @@ public class SecurityPatchLevelPreferenceController extends BasePreferenceContro return true; } } +// LINT.ThenChange(SecurityPatchLevelPreference.kt) diff --git a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreferenceControllerTest.java index ccc91e60c8a..8bafc237c58 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreferenceControllerTest.java @@ -46,6 +46,7 @@ import org.robolectric.util.ReflectionHelpers; import java.util.Collections; +// LINT.IfChange @RunWith(RobolectricTestRunner.class) public class SecurityPatchLevelPreferenceControllerTest { @@ -108,3 +109,4 @@ public class SecurityPatchLevelPreferenceControllerTest { verify(mContext).startActivity(any()); } } +// LINT.ThenChange(SecurityPatchLevelPreferenceTest.kt) diff --git a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreferenceTest.kt b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreferenceTest.kt new file mode 100644 index 00000000000..695c0b6f490 --- /dev/null +++ b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/SecurityPatchLevelPreferenceTest.kt @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.deviceinfo.firmwareversion + +import android.content.Context +import android.os.Build +import androidx.test.core.app.ApplicationProvider +import com.google.common.truth.Truth.assertThat +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.util.ReflectionHelpers + +// LINT.IfChange +@RunWith(RobolectricTestRunner::class) +class SecurityPatchLevelPreferenceTest { + private val context: Context = ApplicationProvider.getApplicationContext() + + private val securityPatchLevelPreference = SecurityPatchLevelPreference() + + @Test + fun isAvailable_noPatch_unavailable() { + setSecurityPatch("") + assertThat(securityPatchLevelPreference.isAvailable(context)).isFalse() + } + + @Test + fun isAvailable_hasPatch_available() { + setSecurityPatch("foobar") + assertThat(securityPatchLevelPreference.isAvailable(context)).isTrue() + } + + @Test + fun getSummary_patchIsDate() { + setSecurityPatch("2024-09-24") + assertThat(securityPatchLevelPreference.getSummary(context)).isEqualTo("September 24, 2024") + } + + @Test + fun getSummary_patchIsNotDate() { + setSecurityPatch("foobar") + assertThat(securityPatchLevelPreference.getSummary(context)).isEqualTo("foobar") + } + + private fun setSecurityPatch(patch: String) { + ReflectionHelpers.setStaticField(Build.VERSION::class.java, "SECURITY_PATCH", patch) + } +} +// LINT.ThenChange(SecurityPatchLevelPreferenceControllerTest.java)