Loading res/xml/accessibility_service_detail_screen.xml 0 → 100644 +78 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?><!-- ~ Copyright (C) 2025 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. --> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"> <com.android.settingslib.widget.TopIntroPreference android:key="top_intro" app:controller="com.android.settings.accessibility.detail.a11yservice.TopIntroPreferenceController" app:searchable="false" tools:title="Top intro title" /> <com.android.settingslib.widget.IllustrationPreference android:key="animated_image" app:controller="com.android.settings.accessibility.detail.a11yservice.AccessibilityServiceIllustrationPreferenceController" app:searchable="false" /> <com.android.settingslib.widget.MainSwitchPreference android:key="use_service" app:controller="com.android.settings.accessibility.detail.a11yservice.UseServiceTogglePreferenceController" tools:title="Use TalkBack" /> <PreferenceCategory android:key="general_categories" android:title="@string/accessibility_screen_option" app:searchable="false"> <com.android.settings.accessibility.ShortcutPreference android:key="service_shortcut" android:persistent="false" app:controller="com.android.settings.accessibility.detail.a11yservice.ShortcutPreferenceController" tools:title="TalkBack shortcut" /> <Preference android:iconSpaceReserved="false" android:key="accessibility_service_settings" android:persistent="false" android:title="@string/accessibility_menu_item_settings" app:controller="com.android.settings.accessibility.detail.a11yservice.SettingsPreferenceController" app:searchable="false" /> <Preference android:iconSpaceReserved="false" android:key="accessibility_service_app_info" android:persistent="false" android:title="@string/application_info_label" app:controller="com.android.settings.accessibility.shared.LaunchAppInfoPreferenceController" app:searchable="false" /> </PreferenceCategory> <com.android.settings.accessibility.AccessibilityFooterPreference android:key="html_footer_info" tools:title="html footer" app:controller="com.android.settings.accessibility.detail.a11yservice.AccessibilityServiceHtmlFooterPreferenceController" app:searchable="false" /> <com.android.settings.accessibility.AccessibilityFooterPreference android:key="footer_info" tools:title="footer" app:controller="com.android.settings.accessibility.detail.a11yservice.AccessibilityServiceFooterPreferenceController" app:searchable="false" /> </PreferenceScreen> No newline at end of file src/com/android/settings/accessibility/AccessibilitySettings.java +1 −1 Original line number Diff line number Diff line Loading @@ -85,7 +85,7 @@ public class AccessibilitySettings extends BaseSupportFragment implements static final String EXTRA_SUMMARY = "summary"; static final String EXTRA_INTRO = "intro"; static final String EXTRA_SETTINGS_TITLE = "settings_title"; static final String EXTRA_COMPONENT_NAME = "component_name"; public static final String EXTRA_COMPONENT_NAME = "component_name"; static final String EXTRA_SETTINGS_COMPONENT_NAME = "settings_component_name"; static final String EXTRA_TILE_SERVICE_COMPONENT_NAME = "tile_service_component_name"; static final String EXTRA_LAUNCHED_FROM_SUW = "from_suw"; Loading src/com/android/settings/accessibility/IllustrationPreferenceController.kt +16 −0 Original line number Diff line number Diff line Loading @@ -19,12 +19,15 @@ package com.android.settings.accessibility import android.content.ContentResolver import android.content.Context import android.net.Uri import android.view.ViewGroup import androidx.preference.PreferenceScreen import com.airbnb.lottie.LottieAnimationView import com.android.settings.R import com.android.settings.accessibility.extensions.isInSetupWizard import com.android.settings.core.BasePreferenceController import com.android.settingslib.utils.ThreadUtils import com.android.settingslib.widget.IllustrationPreference import com.android.settingslib.widget.SettingsThemeHelper /** BasePreferenceController for [IllustrationPreference] */ open class IllustrationPreferenceController(context: Context, prefKey: String) : Loading Loading @@ -54,6 +57,19 @@ open class IllustrationPreferenceController(context: Context, prefKey: String) : isSelectable = false setMaxHeight(displayHalfHeight) setOnBindListener { view: LottieAnimationView? -> // IllustrationPreference changes the illustrationFrame's width to the shortest // device side. // This potentially breaks the image when shown in SetupWizard. Sets the width to // MATCH_PARENT solves the image cutoff issue on SUW if (SettingsThemeHelper.isExpressiveTheme(mContext) && mContext.isInSetupWizard()) { if (view?.parent is ViewGroup) { val illustrationFrame = view.parent as ViewGroup val lp: ViewGroup.LayoutParams = illustrationFrame.layoutParams lp.width = ViewGroup.LayoutParams.MATCH_PARENT illustrationFrame.layoutParams = lp } } // isAnimatable is decided in // [IllustrationPreference#onBindViewHolder(PreferenceViewHolder)]. Therefore, we // wait until the view is bond to set the content description for it. Loading src/com/android/settings/accessibility/ShortcutFragment.kt +34 −16 Original line number Diff line number Diff line Loading @@ -27,17 +27,21 @@ import com.android.settings.accessibility.shortcuts.EditShortcutsPreferenceFragm import com.google.android.setupcompat.util.WizardManagerHelper /** * Base class for Fragment that holds a [ShortcutPreference]. By default, the fragment * is not restricted. If the fragment should be restricted, pass the restriction key when calling * super's constructor. See [com.android.settings.dashboard.RestrictedDashboardFragment] * Base class for Fragment that holds a [ShortcutPreference]. By default, the fragment is not * restricted. If the fragment should be restricted, pass the restriction key when calling super's * constructor. See [com.android.settings.dashboard.RestrictedDashboardFragment] */ abstract class ShortcutFragment(restrictionKey: String? = null) : BaseRestrictedSupportFragment(restrictionKey) { abstract fun getFeatureName(): CharSequence abstract fun getFeatureComponentName(): ComponentName open fun getShortcutPreferenceController(): ToggleShortcutPreferenceController { return use<ToggleShortcutPreferenceController>(ToggleShortcutPreferenceController::class.java) return use<ToggleShortcutPreferenceController>( ToggleShortcutPreferenceController::class.java ) } override fun onDisplayPreferenceDialog(preference: Preference) { Loading @@ -45,11 +49,8 @@ abstract class ShortcutFragment(restrictionKey: String? = null) : val isChecked = preference.isChecked val prefController = getShortcutPreferenceController() if (isChecked) { AccessibilityShortcutsTutorial.DialogFragment.showDialog( getChildFragmentManager(), prefController.getUserPreferredShortcutTypes(getFeatureComponentName()), getFeatureName(), WizardManagerHelper.isAnySetupWizard(getIntent()) showShortcutsTutorial( prefController.getUserPreferredShortcutTypes(getFeatureComponentName()) ) } return Loading @@ -60,10 +61,9 @@ abstract class ShortcutFragment(restrictionKey: String? = null) : override fun onPreferenceTreeClick(preference: Preference): Boolean { if (preference is ShortcutPreference) { EditShortcutsPreferenceFragment.showEditShortcutScreen( requireContext(), getMetricsCategory(), preference.title, getFeatureComponentName(), getIntent() ) showEditShortcutsScreen(preference.title ?: "") // log here since calling super.onPreferenceTreeClick will be skipped writePreferenceClickMetric(preference) return true } return super.onPreferenceTreeClick(preference) Loading @@ -77,10 +77,28 @@ abstract class ShortcutFragment(restrictionKey: String? = null) : override fun onCreateRecyclerView( inflater: LayoutInflater, parent: ViewGroup, savedInstanceState: Bundle? savedInstanceState: Bundle?, ): RecyclerView { val recyclerView = super.onCreateRecyclerView(inflater, parent, savedInstanceState) val recyclerView = super.onCreateRecyclerView(inflater, parent, savedInstanceState) return AccessibilityFragmentUtils.addCollectionInfoToAccessibilityDelegate(recyclerView) } protected fun showShortcutsTutorial(shortcutTypes: Int) { AccessibilityShortcutsTutorial.DialogFragment.showDialog( getChildFragmentManager(), shortcutTypes, getFeatureName(), WizardManagerHelper.isAnySetupWizard(getIntent()), ) } protected fun showEditShortcutsScreen(screenTitle: CharSequence) { EditShortcutsPreferenceFragment.showEditShortcutScreen( requireContext(), getMetricsCategory(), screenTitle, getFeatureComponentName(), getIntent(), ) } } src/com/android/settings/accessibility/ShortcutPreference.java +3 −1 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.widget.LinearLayout; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.preference.PreferenceViewHolder; import com.android.settings.R; Loading Loading @@ -80,7 +81,8 @@ public class ShortcutPreference extends TwoTargetPreference { : androidx.preference.R.layout.preference_widget_switch_compat; } int getSwitchResId() { @VisibleForTesting public int getSwitchResId() { return SettingsThemeHelper.isExpressiveTheme(getContext()) ? com.android.settingslib.widget.theme.R.id.switchWidget : androidx.preference.R.id.switchWidget; Loading Loading
res/xml/accessibility_service_detail_screen.xml 0 → 100644 +78 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?><!-- ~ Copyright (C) 2025 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. --> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"> <com.android.settingslib.widget.TopIntroPreference android:key="top_intro" app:controller="com.android.settings.accessibility.detail.a11yservice.TopIntroPreferenceController" app:searchable="false" tools:title="Top intro title" /> <com.android.settingslib.widget.IllustrationPreference android:key="animated_image" app:controller="com.android.settings.accessibility.detail.a11yservice.AccessibilityServiceIllustrationPreferenceController" app:searchable="false" /> <com.android.settingslib.widget.MainSwitchPreference android:key="use_service" app:controller="com.android.settings.accessibility.detail.a11yservice.UseServiceTogglePreferenceController" tools:title="Use TalkBack" /> <PreferenceCategory android:key="general_categories" android:title="@string/accessibility_screen_option" app:searchable="false"> <com.android.settings.accessibility.ShortcutPreference android:key="service_shortcut" android:persistent="false" app:controller="com.android.settings.accessibility.detail.a11yservice.ShortcutPreferenceController" tools:title="TalkBack shortcut" /> <Preference android:iconSpaceReserved="false" android:key="accessibility_service_settings" android:persistent="false" android:title="@string/accessibility_menu_item_settings" app:controller="com.android.settings.accessibility.detail.a11yservice.SettingsPreferenceController" app:searchable="false" /> <Preference android:iconSpaceReserved="false" android:key="accessibility_service_app_info" android:persistent="false" android:title="@string/application_info_label" app:controller="com.android.settings.accessibility.shared.LaunchAppInfoPreferenceController" app:searchable="false" /> </PreferenceCategory> <com.android.settings.accessibility.AccessibilityFooterPreference android:key="html_footer_info" tools:title="html footer" app:controller="com.android.settings.accessibility.detail.a11yservice.AccessibilityServiceHtmlFooterPreferenceController" app:searchable="false" /> <com.android.settings.accessibility.AccessibilityFooterPreference android:key="footer_info" tools:title="footer" app:controller="com.android.settings.accessibility.detail.a11yservice.AccessibilityServiceFooterPreferenceController" app:searchable="false" /> </PreferenceScreen> No newline at end of file
src/com/android/settings/accessibility/AccessibilitySettings.java +1 −1 Original line number Diff line number Diff line Loading @@ -85,7 +85,7 @@ public class AccessibilitySettings extends BaseSupportFragment implements static final String EXTRA_SUMMARY = "summary"; static final String EXTRA_INTRO = "intro"; static final String EXTRA_SETTINGS_TITLE = "settings_title"; static final String EXTRA_COMPONENT_NAME = "component_name"; public static final String EXTRA_COMPONENT_NAME = "component_name"; static final String EXTRA_SETTINGS_COMPONENT_NAME = "settings_component_name"; static final String EXTRA_TILE_SERVICE_COMPONENT_NAME = "tile_service_component_name"; static final String EXTRA_LAUNCHED_FROM_SUW = "from_suw"; Loading
src/com/android/settings/accessibility/IllustrationPreferenceController.kt +16 −0 Original line number Diff line number Diff line Loading @@ -19,12 +19,15 @@ package com.android.settings.accessibility import android.content.ContentResolver import android.content.Context import android.net.Uri import android.view.ViewGroup import androidx.preference.PreferenceScreen import com.airbnb.lottie.LottieAnimationView import com.android.settings.R import com.android.settings.accessibility.extensions.isInSetupWizard import com.android.settings.core.BasePreferenceController import com.android.settingslib.utils.ThreadUtils import com.android.settingslib.widget.IllustrationPreference import com.android.settingslib.widget.SettingsThemeHelper /** BasePreferenceController for [IllustrationPreference] */ open class IllustrationPreferenceController(context: Context, prefKey: String) : Loading Loading @@ -54,6 +57,19 @@ open class IllustrationPreferenceController(context: Context, prefKey: String) : isSelectable = false setMaxHeight(displayHalfHeight) setOnBindListener { view: LottieAnimationView? -> // IllustrationPreference changes the illustrationFrame's width to the shortest // device side. // This potentially breaks the image when shown in SetupWizard. Sets the width to // MATCH_PARENT solves the image cutoff issue on SUW if (SettingsThemeHelper.isExpressiveTheme(mContext) && mContext.isInSetupWizard()) { if (view?.parent is ViewGroup) { val illustrationFrame = view.parent as ViewGroup val lp: ViewGroup.LayoutParams = illustrationFrame.layoutParams lp.width = ViewGroup.LayoutParams.MATCH_PARENT illustrationFrame.layoutParams = lp } } // isAnimatable is decided in // [IllustrationPreference#onBindViewHolder(PreferenceViewHolder)]. Therefore, we // wait until the view is bond to set the content description for it. Loading
src/com/android/settings/accessibility/ShortcutFragment.kt +34 −16 Original line number Diff line number Diff line Loading @@ -27,17 +27,21 @@ import com.android.settings.accessibility.shortcuts.EditShortcutsPreferenceFragm import com.google.android.setupcompat.util.WizardManagerHelper /** * Base class for Fragment that holds a [ShortcutPreference]. By default, the fragment * is not restricted. If the fragment should be restricted, pass the restriction key when calling * super's constructor. See [com.android.settings.dashboard.RestrictedDashboardFragment] * Base class for Fragment that holds a [ShortcutPreference]. By default, the fragment is not * restricted. If the fragment should be restricted, pass the restriction key when calling super's * constructor. See [com.android.settings.dashboard.RestrictedDashboardFragment] */ abstract class ShortcutFragment(restrictionKey: String? = null) : BaseRestrictedSupportFragment(restrictionKey) { abstract fun getFeatureName(): CharSequence abstract fun getFeatureComponentName(): ComponentName open fun getShortcutPreferenceController(): ToggleShortcutPreferenceController { return use<ToggleShortcutPreferenceController>(ToggleShortcutPreferenceController::class.java) return use<ToggleShortcutPreferenceController>( ToggleShortcutPreferenceController::class.java ) } override fun onDisplayPreferenceDialog(preference: Preference) { Loading @@ -45,11 +49,8 @@ abstract class ShortcutFragment(restrictionKey: String? = null) : val isChecked = preference.isChecked val prefController = getShortcutPreferenceController() if (isChecked) { AccessibilityShortcutsTutorial.DialogFragment.showDialog( getChildFragmentManager(), prefController.getUserPreferredShortcutTypes(getFeatureComponentName()), getFeatureName(), WizardManagerHelper.isAnySetupWizard(getIntent()) showShortcutsTutorial( prefController.getUserPreferredShortcutTypes(getFeatureComponentName()) ) } return Loading @@ -60,10 +61,9 @@ abstract class ShortcutFragment(restrictionKey: String? = null) : override fun onPreferenceTreeClick(preference: Preference): Boolean { if (preference is ShortcutPreference) { EditShortcutsPreferenceFragment.showEditShortcutScreen( requireContext(), getMetricsCategory(), preference.title, getFeatureComponentName(), getIntent() ) showEditShortcutsScreen(preference.title ?: "") // log here since calling super.onPreferenceTreeClick will be skipped writePreferenceClickMetric(preference) return true } return super.onPreferenceTreeClick(preference) Loading @@ -77,10 +77,28 @@ abstract class ShortcutFragment(restrictionKey: String? = null) : override fun onCreateRecyclerView( inflater: LayoutInflater, parent: ViewGroup, savedInstanceState: Bundle? savedInstanceState: Bundle?, ): RecyclerView { val recyclerView = super.onCreateRecyclerView(inflater, parent, savedInstanceState) val recyclerView = super.onCreateRecyclerView(inflater, parent, savedInstanceState) return AccessibilityFragmentUtils.addCollectionInfoToAccessibilityDelegate(recyclerView) } protected fun showShortcutsTutorial(shortcutTypes: Int) { AccessibilityShortcutsTutorial.DialogFragment.showDialog( getChildFragmentManager(), shortcutTypes, getFeatureName(), WizardManagerHelper.isAnySetupWizard(getIntent()), ) } protected fun showEditShortcutsScreen(screenTitle: CharSequence) { EditShortcutsPreferenceFragment.showEditShortcutScreen( requireContext(), getMetricsCategory(), screenTitle, getFeatureComponentName(), getIntent(), ) } }
src/com/android/settings/accessibility/ShortcutPreference.java +3 −1 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.widget.LinearLayout; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.preference.PreferenceViewHolder; import com.android.settings.R; Loading Loading @@ -80,7 +81,8 @@ public class ShortcutPreference extends TwoTargetPreference { : androidx.preference.R.layout.preference_widget_switch_compat; } int getSwitchResId() { @VisibleForTesting public int getSwitchResId() { return SettingsThemeHelper.isExpressiveTheme(getContext()) ? com.android.settingslib.widget.theme.R.id.switchWidget : androidx.preference.R.id.switchWidget; Loading