diff options
3 files changed, 141 insertions, 2 deletions
diff --git a/packages/SettingsLib/Preference/Android.bp b/packages/SettingsLib/Preference/Android.bp index 17852e8e7ece..e83e17cc8375 100644 --- a/packages/SettingsLib/Preference/Android.bp +++ b/packages/SettingsLib/Preference/Android.bp @@ -22,3 +22,16 @@ android_library { ], kotlincflags: ["-Xjvm-default=all"], } + +android_library { + name: "SettingsLibPreference-testutils", + srcs: ["testutils/**/*.kt"], + static_libs: [ + "SettingsLibPreference", + "androidx.fragment_fragment-testing", + "androidx.test.core", + "androidx.test.ext.junit", + "flag-junit", + "truth", + ], +} diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceBinding.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceBinding.kt index 5fcf4784f43b..5e6989546cb9 100644 --- a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceBinding.kt +++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceBinding.kt @@ -68,10 +68,13 @@ interface PreferenceBinding { preference.icon = null } val context = preference.context + val isPreferenceScreen = preference is PreferenceScreen preference.peekExtras()?.clear() extras(context)?.let { preference.extras.putAll(it) } preference.title = getPreferenceTitle(context) - preference.summary = getPreferenceSummary(context) + if (!isPreferenceScreen) { + preference.summary = getPreferenceSummary(context) + } preference.isEnabled = isEnabled(context) preference.isVisible = (this as? PreferenceAvailabilityProvider)?.isAvailable(context) != false @@ -81,7 +84,7 @@ interface PreferenceBinding { // dependency here. This simplifies dependency management and avoid the // IllegalStateException when call Preference.setDependency preference.dependency = null - if (preference !is PreferenceScreen) { // avoid recursive loop when build graph + if (!isPreferenceScreen) { // avoid recursive loop when build graph preference.fragment = (this as? PreferenceScreenCreator)?.fragmentClass()?.name preference.intent = intent(context) } diff --git a/packages/SettingsLib/Preference/testutils/com/android/settingslib/preference/CatalystScreenTestCase.kt b/packages/SettingsLib/Preference/testutils/com/android/settingslib/preference/CatalystScreenTestCase.kt new file mode 100644 index 000000000000..4d5f85fa9020 --- /dev/null +++ b/packages/SettingsLib/Preference/testutils/com/android/settingslib/preference/CatalystScreenTestCase.kt @@ -0,0 +1,123 @@ +/* + * 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.settingslib.preference + +import android.content.Context +import android.platform.test.flag.junit.SetFlagsRule +import android.util.Log +import androidx.fragment.app.testing.FragmentScenario +import androidx.preference.Preference +import androidx.preference.PreferenceFragmentCompat +import androidx.preference.PreferenceGroup +import androidx.preference.PreferenceScreen +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.google.common.truth.Truth.assertThat +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +/** Test case for catalyst screen. */ +@RunWith(AndroidJUnit4::class) +abstract class CatalystScreenTestCase { + @get:Rule val setFlagsRule = SetFlagsRule() + + protected val context: Context = ApplicationProvider.getApplicationContext() + + /** Catalyst screen. */ + protected abstract val preferenceScreenCreator: PreferenceScreenCreator + + /** Flag to control catalyst screen. */ + protected abstract val flagName: String + + /** + * Test to compare the preference screen hierarchy between legacy screen (flag is disabled) and + * catalyst screen (flag is enabled). + */ + @Test + fun migration() { + enableCatalystScreen() + assertThat(preferenceScreenCreator.isFlagEnabled(context)).isTrue() + val catalystScreen = stringifyPreferenceScreen() + Log.i("Catalyst", catalystScreen) + + disableCatalystScreen() + assertThat(preferenceScreenCreator.isFlagEnabled(context)).isFalse() + val legacyScreen = stringifyPreferenceScreen() + + assertThat(catalystScreen).isEqualTo(legacyScreen) + } + + /** + * Enables the catalyst screen. + * + * By default, enable the [flagName]. Override for more complex situation. + */ + @Suppress("DEPRECATION") + protected open fun enableCatalystScreen() { + setFlagsRule.enableFlags(flagName) + } + + /** + * Disables the catalyst screen (legacy screen is shown). + * + * By default, disable the [flagName]. Override for more complex situation. + */ + @Suppress("DEPRECATION") + protected open fun disableCatalystScreen() { + setFlagsRule.disableFlags(flagName) + } + + private fun stringifyPreferenceScreen(): String { + @Suppress("UNCHECKED_CAST") + val clazz = preferenceScreenCreator.fragmentClass() as Class<PreferenceFragmentCompat> + val builder = StringBuilder() + FragmentScenario.launch(clazz).use { + it.onFragment { fragment -> fragment.preferenceScreen.toString(builder) } + } + return builder.toString() + } + + private fun Preference.toString(builder: StringBuilder, indent: String = "") { + val clazz = javaClass + builder.append(indent).append(clazz).append(" {\n") + val indent2 = "$indent " + if (clazz != PreferenceScreen::class.java) { + key?.let { builder.append(indent2).append("key: \"$it\"\n") } + } + title?.let { builder.append(indent2).append("title: \"$it\"\n") } + summary?.let { builder.append(indent2).append("summary: \"$it\"\n") } + fragment?.let { builder.append(indent2).append("fragment: \"$it\"\n") } + builder.append(indent2).append("order: $order\n") + builder.append(indent2).append("isCopyingEnabled: $isCopyingEnabled\n") + builder.append(indent2).append("isEnabled: $isEnabled\n") + builder.append(indent2).append("isIconSpaceReserved: $isIconSpaceReserved\n") + if (clazz != Preference::class.java && clazz != PreferenceScreen::class.java) { + builder.append(indent2).append("isPersistent: $isPersistent\n") + } + builder.append(indent2).append("isSelectable: $isSelectable\n") + if (this is PreferenceGroup) { + val count = preferenceCount + builder.append(indent2).append("preferenceCount: $count\n") + val indent4 = "$indent2 " + for (index in 0..<count) { + getPreference(index).toString(builder, indent4) + } + } + builder.append(indent).append("}\n") + } +} |