diff --git a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreference.kt b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreference.kt new file mode 100644 index 00000000000..a039a3a4e82 --- /dev/null +++ b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreference.kt @@ -0,0 +1,104 @@ +/* + * 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.os.Build +import android.os.SystemClock +import android.os.UserHandle +import android.os.UserManager +import androidx.preference.Preference +import com.android.internal.app.PlatLogoActivity +import com.android.settings.R +import com.android.settings.Utils +import com.android.settingslib.RestrictedLockUtils +import com.android.settingslib.RestrictedLockUtilsInternal +import com.android.settingslib.metadata.PreferenceMetadata +import com.android.settingslib.metadata.PreferenceSummaryProvider +import com.android.settingslib.preference.PreferenceBinding + +// LINT.IfChange +class FirmwareVersionDetailPreference : + PreferenceMetadata, + PreferenceSummaryProvider, + PreferenceBinding, + Preference.OnPreferenceClickListener { + + private val hits = LongArray(ACTIVITY_TRIGGER_COUNT) + + override val key: String + get() = "os_firmware_version" + + override val title: Int + get() = R.string.firmware_version + + override fun isIndexable(context: Context) = false + + override fun intent(context: Context): Intent? = + Intent(Intent.ACTION_MAIN) + .setClassName("android", PlatLogoActivity::class.java.name) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + + override fun getSummary(context: Context): CharSequence? = + Build.VERSION.RELEASE_OR_PREVIEW_DISPLAY + + override fun bind(preference: Preference, metadata: PreferenceMetadata) { + super.bind(preference, metadata) + preference.isCopyingEnabled = true + preference.onPreferenceClickListener = this + } + + // return true swallows the click event, while return false will start the intent + override fun onPreferenceClick(preference: Preference): Boolean { + if (Utils.isMonkeyRunning()) return true + + // remove oldest hit and check whether there are 3 clicks within 500ms + for (index in 1.. DELAY_TIMER_MILLIS) return true + + val context = preference.context + val userManager = context.getSystemService(Context.USER_SERVICE) as? UserManager + if (userManager?.hasUserRestriction(UserManager.DISALLOW_FUN) != true) return false + + // Sorry, no fun for you! + val myUserId = UserHandle.myUserId() + val enforcedAdmin = + RestrictedLockUtilsInternal.checkIfRestrictionEnforced( + context, + UserManager.DISALLOW_FUN, + myUserId, + ) ?: return true + val disallowedBySystem = + RestrictedLockUtilsInternal.hasBaseUserRestriction( + context, + UserManager.DISALLOW_FUN, + myUserId, + ) + if (!disallowedBySystem) { + RestrictedLockUtils.sendShowAdminSupportDetailsIntent(context, enforcedAdmin) + } + return true + } + + companion object { + const val DELAY_TIMER_MILLIS = 500L + const val ACTIVITY_TRIGGER_COUNT = 3 + } +} +// LINT.ThenChange(FirmwareVersionDetailPreferenceController.java) diff --git a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceController.java b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceController.java index e6ac6069d9a..7b0b2a67c63 100644 --- a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceController.java +++ b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceController.java @@ -33,6 +33,7 @@ import com.android.settings.core.BasePreferenceController; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtilsInternal; +// LINT.IfChange public class FirmwareVersionDetailPreferenceController extends BasePreferenceController { private static final String TAG = "firmwareDialogCtrl"; @@ -125,3 +126,4 @@ public class FirmwareVersionDetailPreferenceController extends BasePreferenceCon mContext, UserManager.DISALLOW_FUN, UserHandle.myUserId()); } } +// LINT.ThenChange(FirmwareVersionDetailPreference.kt) diff --git a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionScreen.kt b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionScreen.kt index 0075068f4dc..fbc749bb1ec 100644 --- a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionScreen.kt +++ b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionScreen.kt @@ -20,7 +20,6 @@ import android.content.Context import android.os.Build import com.android.settings.R import com.android.settings.flags.Flags -import com.android.settingslib.metadata.PreferenceMetadata import com.android.settingslib.metadata.PreferenceSummaryProvider import com.android.settingslib.metadata.ProvidePreferenceScreen import com.android.settingslib.metadata.preferenceHierarchy @@ -47,7 +46,7 @@ class FirmwareVersionScreen : PreferenceScreenCreator, PreferenceSummaryProvider override fun getPreferenceHierarchy(context: Context) = preferenceHierarchy(this) { - +PreferenceWidget("os_firmware_version", R.string.firmware_version) + +FirmwareVersionDetailPreference() +SecurityPatchLevelPreference() +MainlineModuleVersionPreference() +BasebandVersionPreference() @@ -55,9 +54,6 @@ class FirmwareVersionScreen : PreferenceScreenCreator, PreferenceSummaryProvider +SimpleBuildNumberPreference() } - private class PreferenceWidget(override val key: String, override val title: Int) : - PreferenceMetadata - companion object { const val KEY = "firmware_version" } diff --git a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceControllerTest.java index 420b9a337b4..51763bc2a71 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceControllerTest.java @@ -41,6 +41,7 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.util.ReflectionHelpers; +// LINT.IfChange @RunWith(RobolectricTestRunner.class) public class FirmwareVersionDetailPreferenceControllerTest { @@ -112,3 +113,4 @@ public class FirmwareVersionDetailPreferenceControllerTest { } } } +// LINT.ThenChange(FirmwareVersionDetailPreferenceTest.kt) diff --git a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceTest.kt b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceTest.kt new file mode 100644 index 00000000000..69ea549bc43 --- /dev/null +++ b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceTest.kt @@ -0,0 +1,76 @@ +/* + * 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.ContextWrapper +import android.os.Build +import android.os.SystemClock +import android.os.UserManager +import androidx.preference.Preference +import androidx.test.core.app.ApplicationProvider +import com.android.settings.deviceinfo.firmwareversion.FirmwareVersionDetailPreference.Companion.DELAY_TIMER_MILLIS +import com.google.common.truth.Truth.assertThat +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.kotlin.doReturn +import org.mockito.kotlin.mock +import org.robolectric.RobolectricTestRunner + +// LINT.IfChange +@RunWith(RobolectricTestRunner::class) +class FirmwareVersionDetailPreferenceTest { + private var userManager: UserManager? = null + + private val context: Context = + object : ContextWrapper(ApplicationProvider.getApplicationContext()) { + override fun getSystemService(name: String): Any? = + if (name == Context.USER_SERVICE) userManager else super.getSystemService(name) + } + + private val preference = Preference(context) + + private val firmwareVersionDetailPreference = FirmwareVersionDetailPreference() + + @Test + fun getSummary() { + assertThat(firmwareVersionDetailPreference.getSummary(context)) + .isEqualTo(Build.VERSION.RELEASE_OR_PREVIEW_DISPLAY) + } + + @Test + fun onPreferenceClick_hits() { + prepareClick() + assertThat(firmwareVersionDetailPreference.onPreferenceClick(preference)).isFalse() + } + + @Test + fun onPreferenceClick_restricted() { + prepareClick() + userManager = mock { on { hasUserRestriction(UserManager.DISALLOW_FUN) } doReturn true } + assertThat(firmwareVersionDetailPreference.onPreferenceClick(preference)).isTrue() + } + + private fun prepareClick() { + SystemClock.sleep(DELAY_TIMER_MILLIS + 1) + assertThat(SystemClock.uptimeMillis()).isGreaterThan(DELAY_TIMER_MILLIS) + for (i in 1..