Merge "a11y: Clean up magnification mode controller and fix lint errors" into main

This commit is contained in:
Yongshun Liu
2025-02-18 17:28:49 -08:00
committed by Android (Google) Code Review
6 changed files with 204 additions and 146 deletions

View File

@@ -24,6 +24,7 @@ import android.content.DialogInterface;
import android.view.View; import android.view.View;
import android.widget.AbsListView; import android.widget.AbsListView;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView; import android.widget.ListView;
import android.widget.ScrollView; import android.widget.ScrollView;
@@ -34,14 +35,15 @@ import androidx.appcompat.app.AlertDialog;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.List; import java.util.List;
import java.util.Optional;
/** /**
* Utility class for creating the edit dialog. * Utility class for creating the edit dialog.
*/ */
public class AccessibilityDialogUtils { public class AccessibilityDialogUtils {
private static final String TAG = "AccessibilityDialogUtils"; private static final String TAG = AccessibilityDialogUtils.class.getSimpleName();
/** Denotes the dialog emuns for show dialog. */ /** Denotes the dialog enums for show dialog. */
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
public @interface DialogEnums { public @interface DialogEnums {
/** /**
@@ -89,6 +91,19 @@ public class AccessibilityDialogUtils {
* OPEN: Settings > Accessibility > Display size and text > Click 'Reset settings' button. * OPEN: Settings > Accessibility > Display size and text > Click 'Reset settings' button.
*/ */
int DIALOG_RESET_SETTINGS = 1009; int DIALOG_RESET_SETTINGS = 1009;
/**
* OPEN: Settings > Accessibility > Magnification > Magnification type.
*/
int DIALOG_MAGNIFICATION_MODE = 1010;
/**
* Enable: Settings > Accessibility > Magnification > Magnification shortcut > Advanced >
* Triple tap.
* OPEN: Settings > Accessibility > Magnification > Magnification type > Magnify part of
* screen / Switch between full and partial screen > Save.
*/
int DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING = 1011;
} }
/** /**
@@ -118,17 +133,26 @@ public class AccessibilityDialogUtils {
* is clicked * is clicked
* @return the {@link Dialog} with the given view * @return the {@link Dialog} with the given view
*/ */
public static Dialog createCustomDialog(Context context, CharSequence dialogTitle, @NonNull
View customView, CharSequence positiveButtonText, public static Dialog createCustomDialog(@NonNull Context context,
DialogInterface.OnClickListener positiveListener, CharSequence negativeButtonText, @NonNull CharSequence dialogTitle, @Nullable View customView,
DialogInterface.OnClickListener negativeListener) { @NonNull CharSequence positiveButtonText,
final AlertDialog alertDialog = new AlertDialog.Builder(context) @Nullable DialogInterface.OnClickListener positiveListener,
.setView(customView) @NonNull CharSequence negativeButtonText,
@Nullable DialogInterface.OnClickListener negativeListener) {
DialogInterface.OnClickListener doNothingListener =
(DialogInterface dialogInterface, int which) -> {};
final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context)
.setTitle(dialogTitle) .setTitle(dialogTitle)
.setCancelable(true) .setCancelable(true)
.setPositiveButton(positiveButtonText, positiveListener) .setPositiveButton(positiveButtonText,
.setNegativeButton(negativeButtonText, negativeListener) Optional.ofNullable(positiveListener).orElse(doNothingListener))
.create(); .setNegativeButton(negativeButtonText,
Optional.ofNullable(negativeListener).orElse(doNothingListener));
if (customView != null) {
dialogBuilder.setView(customView);
}
final AlertDialog alertDialog = dialogBuilder.create();
if (customView instanceof ScrollView || customView instanceof AbsListView) { if (customView instanceof ScrollView || customView instanceof AbsListView) {
setScrollIndicators(customView); setScrollIndicators(customView);
} }
@@ -151,8 +175,7 @@ public class AccessibilityDialogUtils {
list.setId(android.R.id.list); list.setId(android.R.id.list);
list.setDivider(/* divider= */ null); list.setDivider(/* divider= */ null);
list.setChoiceMode(ListView.CHOICE_MODE_SINGLE); list.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
final ItemInfoArrayAdapter final ListAdapter adapter = new ItemInfoArrayAdapter<>(context, itemInfoList);
adapter = new ItemInfoArrayAdapter(context, itemInfoList);
list.setAdapter(adapter); list.setAdapter(adapter);
list.setOnItemClickListener(itemListener); list.setOnItemClickListener(itemListener);
return list; return list;

View File

@@ -0,0 +1,30 @@
/*
* 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.
*/
package com.android.settings.accessibility;
/**
* The {@code DialogHelper} interface provides methods for displaying dialogs.
* It helps the dialog delegate to show the dialog, and will be injected to the dialog delegate.
*/
public interface DialogHelper {
/**
* Shows a dialog with the specified dialog ID.
*
* @param dialogId The ID of the dialog to display.
*/
void showDialog(int dialogId);
}

View File

@@ -37,11 +37,13 @@ import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import androidx.core.util.Preconditions;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import com.android.settings.DialogCreatable; import com.android.settings.DialogCreatable;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.accessibility.AccessibilityDialogUtils.DialogEnums;
import com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode; import com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode;
import com.android.settings.core.BasePreferenceController; import com.android.settings.core.BasePreferenceController;
import com.android.settings.utils.AnnotationSpan; import com.android.settings.utils.AnnotationSpan;
@@ -57,33 +59,37 @@ public class MagnificationModePreferenceController extends BasePreferenceControl
DialogCreatable, LifecycleObserver, OnCreate, OnSaveInstanceState { DialogCreatable, LifecycleObserver, OnCreate, OnSaveInstanceState {
static final String PREF_KEY = "screen_magnification_mode"; static final String PREF_KEY = "screen_magnification_mode";
private static final int DIALOG_ID_BASE = 10;
@VisibleForTesting
static final int DIALOG_MAGNIFICATION_MODE = DIALOG_ID_BASE + 1;
@VisibleForTesting
static final int DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING = DIALOG_ID_BASE + 2;
@VisibleForTesting
static final String EXTRA_MODE = "mode"; static final String EXTRA_MODE = "mode";
private static final String TAG = "MagnificationModePreferenceController"; private static final String TAG = MagnificationModePreferenceController.class.getSimpleName();
@Nullable
private DialogHelper mDialogHelper; private DialogHelper mDialogHelper;
// The magnification mode in the dialog. // The magnification mode in the dialog.
@MagnificationMode @MagnificationMode
private int mModeCache = MagnificationMode.NONE; private int mModeCache = MagnificationMode.NONE;
@Nullable
private Preference mModePreference; private Preference mModePreference;
@Nullable
private ShortcutPreference mLinkPreference; private ShortcutPreference mLinkPreference;
@VisibleForTesting @VisibleForTesting
@Nullable
ListView mMagnificationModesListView; ListView mMagnificationModesListView;
private final List<MagnificationModeInfo> mModeInfos = new ArrayList<>(); private final List<MagnificationModeInfo> mModeInfos = new ArrayList<>();
public MagnificationModePreferenceController(Context context, String preferenceKey) { public MagnificationModePreferenceController(@NonNull Context context,
@NonNull String preferenceKey) {
super(context, preferenceKey); super(context, preferenceKey);
initModeInfos(); initModeInfos();
} }
public void setDialogHelper(@NonNull DialogHelper dialogHelper) {
mDialogHelper = dialogHelper;
}
private void initModeInfos() { private void initModeInfos() {
mModeInfos.add(new MagnificationModeInfo(mContext.getText( mModeInfos.add(new MagnificationModeInfo(mContext.getText(
R.string.accessibility_magnification_mode_dialog_option_full_screen), null, R.string.accessibility_magnification_mode_dialog_option_full_screen), null,
@@ -103,6 +109,7 @@ public class MagnificationModePreferenceController extends BasePreferenceControl
return AVAILABLE; return AVAILABLE;
} }
@NonNull
@Override @Override
public CharSequence getSummary() { public CharSequence getSummary() {
final int capabilities = MagnificationCapabilities.getCapabilities(mContext); final int capabilities = MagnificationCapabilities.getCapabilities(mContext);
@@ -110,99 +117,98 @@ public class MagnificationModePreferenceController extends BasePreferenceControl
} }
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(@Nullable Bundle savedInstanceState) {
if (savedInstanceState != null) { if (savedInstanceState != null) {
mModeCache = savedInstanceState.getInt(EXTRA_MODE, MagnificationMode.NONE); mModeCache = savedInstanceState.getInt(EXTRA_MODE, MagnificationMode.NONE);
} }
} }
@Override @Override
public void displayPreference(PreferenceScreen screen) { public void displayPreference(@NonNull PreferenceScreen screen) {
super.displayPreference(screen); super.displayPreference(screen);
mModePreference = screen.findPreference(getPreferenceKey()); mModePreference = screen.findPreference(getPreferenceKey());
mLinkPreference = screen.findPreference( mLinkPreference = screen.findPreference(
ToggleFeaturePreferenceFragment.KEY_SHORTCUT_PREFERENCE); ToggleFeaturePreferenceFragment.KEY_SHORTCUT_PREFERENCE);
mModePreference.setOnPreferenceClickListener(preference -> { Preconditions.checkNotNull(mModePreference).setOnPreferenceClickListener(preference -> {
mModeCache = MagnificationCapabilities.getCapabilities(mContext); mModeCache = MagnificationCapabilities.getCapabilities(mContext);
mDialogHelper.showDialog(DIALOG_MAGNIFICATION_MODE); Preconditions.checkNotNull(mDialogHelper).showDialog(
DialogEnums.DIALOG_MAGNIFICATION_MODE);
return true; return true;
}); });
} }
@Override @Override
public void onSaveInstanceState(Bundle outState) { public void onSaveInstanceState(@NonNull Bundle outState) {
outState.putInt(EXTRA_MODE, mModeCache); outState.putInt(EXTRA_MODE, mModeCache);
} }
/** @NonNull
* Sets {@link DialogHelper} used to show the dialog.
*/
public void setDialogHelper(DialogHelper dialogHelper) {
mDialogHelper = dialogHelper;
mDialogHelper.setDialogDelegate(this);
}
@Override @Override
public Dialog onCreateDialog(int dialogId) { public Dialog onCreateDialog(int dialogId) {
switch (dialogId) { return switch (dialogId) {
case DIALOG_MAGNIFICATION_MODE: case DialogEnums.DIALOG_MAGNIFICATION_MODE -> createMagnificationModeDialog();
return createMagnificationModeDialog(); case DialogEnums.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING ->
createMagnificationTripleTapWarningDialog();
case DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING: default -> throw new IllegalArgumentException(
return createMagnificationTripleTapWarningDialog(); "This only handles magnification mode and triple tap warning dialog");
} };
return null;
} }
@Override @Override
public int getDialogMetricsCategory(int dialogId) { public int getDialogMetricsCategory(int dialogId) {
switch (dialogId) { return switch (dialogId) {
case DIALOG_MAGNIFICATION_MODE: case DialogEnums.DIALOG_MAGNIFICATION_MODE ->
return SettingsEnums.DIALOG_MAGNIFICATION_CAPABILITY; SettingsEnums.DIALOG_MAGNIFICATION_CAPABILITY;
case DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING: case DialogEnums.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING ->
return SettingsEnums.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING; SettingsEnums.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING;
default: default -> 0;
return 0; };
}
} }
@NonNull
private ListView getMagnificationModesListView() {
return Preconditions.checkNotNull(mMagnificationModesListView);
}
@NonNull
private Dialog createMagnificationModeDialog() { private Dialog createMagnificationModeDialog() {
mMagnificationModesListView = AccessibilityDialogUtils.createSingleChoiceListView( mMagnificationModesListView = AccessibilityDialogUtils.createSingleChoiceListView(
mContext, mModeInfos, this::onMagnificationModeSelected); mContext, mModeInfos, this::onMagnificationModeSelected);
final View headerView = LayoutInflater.from(mContext).inflate( final View headerView = LayoutInflater.from(mContext).inflate(
R.layout.accessibility_magnification_mode_header, mMagnificationModesListView, R.layout.accessibility_magnification_mode_header,
false); getMagnificationModesListView(), /* attachToRoot= */false);
mMagnificationModesListView.addHeaderView(headerView, /* data= */ null, /* isSelectable= */ getMagnificationModesListView().addHeaderView(headerView, /* data= */null,
false); /* isSelectable= */false);
mMagnificationModesListView.setItemChecked(computeSelectionIndex(), true); getMagnificationModesListView().setItemChecked(computeSelectionIndex(), /* value= */true);
final CharSequence title = mContext.getString( final CharSequence title = mContext.getString(
R.string.accessibility_magnification_mode_dialog_title); R.string.accessibility_magnification_mode_dialog_title);
final CharSequence positiveBtnText = mContext.getString(R.string.save); final CharSequence positiveBtnText = mContext.getString(R.string.save);
final CharSequence negativeBtnText = mContext.getString(R.string.cancel); final CharSequence negativeBtnText = mContext.getString(R.string.cancel);
return AccessibilityDialogUtils.createCustomDialog(mContext, title, return AccessibilityDialogUtils.createCustomDialog(mContext, title,
mMagnificationModesListView, getMagnificationModesListView(), positiveBtnText,
positiveBtnText, this::onMagnificationModeDialogPositiveButtonClicked, this::onMagnificationModeDialogPositiveButtonClicked,
negativeBtnText, /* negativeListener= */ null); negativeBtnText, /* negativeListener= */null);
} }
@VisibleForTesting @VisibleForTesting
void onMagnificationModeDialogPositiveButtonClicked(DialogInterface dialogInterface, void onMagnificationModeDialogPositiveButtonClicked(@NonNull DialogInterface dialogInterface,
int which) { int which) {
final int selectedIndex = mMagnificationModesListView.getCheckedItemPosition(); final int selectedIndex = getMagnificationModesListView().getCheckedItemPosition();
if (selectedIndex == AdapterView.INVALID_POSITION) { if (selectedIndex == AdapterView.INVALID_POSITION) {
Log.w(TAG, "invalid index"); Log.w(TAG, "Selected positive button with INVALID_POSITION index");
return; return;
} }
mModeCache = ((MagnificationModeInfo) mMagnificationModesListView.getItemAtPosition( mModeCache = ((MagnificationModeInfo) getMagnificationModesListView().getItemAtPosition(
selectedIndex)).mMagnificationMode; selectedIndex)).mMagnificationMode;
// Do not save mode until user clicks positive button in triple tap warning dialog. // Do not save mode until user clicks positive button in triple tap warning dialog.
if (isTripleTapEnabled(mContext) && mModeCache != MagnificationMode.FULLSCREEN) { if (isTripleTapEnabled(mContext) && mModeCache != MagnificationMode.FULLSCREEN) {
mDialogHelper.showDialog(DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING); Preconditions.checkNotNull(mDialogHelper).showDialog(
DialogEnums.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING);
} else { // Save mode (capabilities) value, don't need to show dialog to confirm. } else { // Save mode (capabilities) value, don't need to show dialog to confirm.
updateCapabilitiesAndSummary(mModeCache); updateCapabilitiesAndSummary(mModeCache);
} }
@@ -211,15 +217,14 @@ public class MagnificationModePreferenceController extends BasePreferenceControl
private void updateCapabilitiesAndSummary(@MagnificationMode int mode) { private void updateCapabilitiesAndSummary(@MagnificationMode int mode) {
mModeCache = mode; mModeCache = mode;
MagnificationCapabilities.setCapabilities(mContext, mModeCache); MagnificationCapabilities.setCapabilities(mContext, mModeCache);
mModePreference.setSummary( Preconditions.checkNotNull(mModePreference).setSummary(
MagnificationCapabilities.getSummary(mContext, mModeCache)); MagnificationCapabilities.getSummary(mContext, mModeCache));
} }
private void onMagnificationModeSelected(AdapterView<?> parent, View view, int position, private void onMagnificationModeSelected(@NonNull AdapterView<?> parent, @NonNull View view,
long id) { int position, long id) {
final MagnificationModeInfo modeInfo = final MagnificationModeInfo modeInfo =
(MagnificationModeInfo) mMagnificationModesListView.getItemAtPosition( (MagnificationModeInfo) getMagnificationModesListView().getItemAtPosition(position);
position);
if (modeInfo.mMagnificationMode == mModeCache) { if (modeInfo.mMagnificationMode == mModeCache) {
return; return;
} }
@@ -230,20 +235,22 @@ public class MagnificationModePreferenceController extends BasePreferenceControl
final int modesSize = mModeInfos.size(); final int modesSize = mModeInfos.size();
for (int i = 0; i < modesSize; i++) { for (int i = 0; i < modesSize; i++) {
if (mModeInfos.get(i).mMagnificationMode == mModeCache) { if (mModeInfos.get(i).mMagnificationMode == mModeCache) {
return i + mMagnificationModesListView.getHeaderViewsCount(); return i + getMagnificationModesListView().getHeaderViewsCount();
} }
} }
Log.w(TAG, "computeSelectionIndex failed"); Log.w(TAG, "Can not find matching mode in mModeInfos");
return 0; return 0;
} }
@VisibleForTesting @VisibleForTesting
static boolean isTripleTapEnabled(Context context) { static boolean isTripleTapEnabled(@NonNull Context context) {
return Settings.Secure.getInt(context.getContentResolver(), return Settings.Secure.getInt(context.getContentResolver(),
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, OFF) == ON; Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, OFF) == ON;
} }
@NonNull
private Dialog createMagnificationTripleTapWarningDialog() { private Dialog createMagnificationTripleTapWarningDialog() {
@SuppressWarnings({"InflateParams"})
final View contentView = LayoutInflater.from(mContext).inflate( final View contentView = LayoutInflater.from(mContext).inflate(
R.layout.magnification_triple_tap_warning_dialog, /* root= */ null); R.layout.magnification_triple_tap_warning_dialog, /* root= */ null);
final CharSequence title = mContext.getString( final CharSequence title = mContext.getString(
@@ -263,12 +270,13 @@ public class MagnificationModePreferenceController extends BasePreferenceControl
return dialog; return dialog;
} }
private void updateLinkInTripleTapWarningDialog(Dialog dialog, View contentView) { private void updateLinkInTripleTapWarningDialog(@NonNull Dialog dialog,
@NonNull View contentView) {
final TextView messageView = contentView.findViewById(R.id.message); final TextView messageView = contentView.findViewById(R.id.message);
// TODO(b/225682559): Need to remove performClick() after refactoring accessibility dialog. // TODO(b/225682559): Need to remove performClick() after refactoring accessibility dialog.
final View.OnClickListener linkListener = view -> { final View.OnClickListener linkListener = view -> {
updateCapabilitiesAndSummary(mModeCache); updateCapabilitiesAndSummary(mModeCache);
mLinkPreference.performClick(); Preconditions.checkNotNull(mLinkPreference).performClick();
dialog.dismiss(); dialog.dismiss();
}; };
final AnnotationSpan.LinkInfo linkInfo = new AnnotationSpan.LinkInfo( final AnnotationSpan.LinkInfo linkInfo = new AnnotationSpan.LinkInfo(
@@ -285,25 +293,18 @@ public class MagnificationModePreferenceController extends BasePreferenceControl
@VisibleForTesting @VisibleForTesting
void onMagnificationTripleTapWarningDialogNegativeButtonClicked( void onMagnificationTripleTapWarningDialogNegativeButtonClicked(
DialogInterface dialogInterface, int which) { @NonNull DialogInterface dialogInterface, int which) {
mModeCache = MagnificationCapabilities.getCapabilities(mContext); mModeCache = MagnificationCapabilities.getCapabilities(mContext);
mDialogHelper.showDialog(DIALOG_MAGNIFICATION_MODE); Preconditions.checkNotNull(mDialogHelper).showDialog(
DialogEnums.DIALOG_MAGNIFICATION_MODE);
} }
@VisibleForTesting @VisibleForTesting
void onMagnificationTripleTapWarningDialogPositiveButtonClicked( void onMagnificationTripleTapWarningDialogPositiveButtonClicked(
DialogInterface dialogInterface, int which) { @NonNull DialogInterface dialogInterface, int which) {
updateCapabilitiesAndSummary(mModeCache); updateCapabilitiesAndSummary(mModeCache);
} }
/**
* An interface to help the delegate to show the dialog. It will be injected to the delegate.
*/
interface DialogHelper extends DialogCreatable {
void showDialog(int dialogId);
void setDialogDelegate(DialogCreatable delegate);
}
@VisibleForTesting @VisibleForTesting
static class MagnificationModeInfo extends ItemInfoArrayAdapter.ItemInfo { static class MagnificationModeInfo extends ItemInfoArrayAdapter.ItemInfo {
@MagnificationMode @MagnificationMode

View File

@@ -19,7 +19,6 @@ package com.android.settings.accessibility;
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME; import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME; import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.DEFAULT; import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.DEFAULT;
import static com.android.settings.accessibility.AccessibilityDialogUtils.DialogEnums;
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF; import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
import static com.android.settings.accessibility.AccessibilityUtil.State.ON; import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
import static com.android.settings.accessibility.AccessibilityUtil.getShortcutSummaryList; import static com.android.settings.accessibility.AccessibilityUtil.getShortcutSummaryList;
@@ -42,8 +41,10 @@ import android.view.ViewGroup;
import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener; import android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.StringRes; import androidx.annotation.StringRes;
import androidx.core.util.Preconditions;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceCategory;
import androidx.preference.SwitchPreferenceCompat; import androidx.preference.SwitchPreferenceCompat;
@@ -53,6 +54,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.server.accessibility.Flags; import com.android.server.accessibility.Flags;
import com.android.settings.DialogCreatable; import com.android.settings.DialogCreatable;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.accessibility.AccessibilityDialogUtils.DialogEnums;
import com.android.settings.accessibility.shortcuts.EditShortcutsPreferenceFragment; import com.android.settings.accessibility.shortcuts.EditShortcutsPreferenceFragment;
import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.AbstractPreferenceController;
@@ -74,10 +76,10 @@ import java.util.stream.Stream;
*/ */
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC) @SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class ToggleScreenMagnificationPreferenceFragment extends public class ToggleScreenMagnificationPreferenceFragment extends
ToggleFeaturePreferenceFragment implements ToggleFeaturePreferenceFragment implements DialogHelper {
MagnificationModePreferenceController.DialogHelper {
private static final String TAG = "ToggleScreenMagnificationPreferenceFragment"; private static final String TAG =
ToggleScreenMagnificationPreferenceFragment.class.getSimpleName();
@VisibleForTesting @VisibleForTesting
static final String KEY_MAGNIFICATION_SHORTCUT_PREFERENCE = "magnification_shortcut_preference"; static final String KEY_MAGNIFICATION_SHORTCUT_PREFERENCE = "magnification_shortcut_preference";
private static final char COMPONENT_NAME_SEPARATOR = ':'; private static final char COMPONENT_NAME_SEPARATOR = ':';
@@ -86,23 +88,30 @@ public class ToggleScreenMagnificationPreferenceFragment extends
// TODO(b/147021230): Move duplicated functions with android/internal/accessibility into util. // TODO(b/147021230): Move duplicated functions with android/internal/accessibility into util.
private TouchExplorationStateChangeListener mTouchExplorationStateChangeListener; private TouchExplorationStateChangeListener mTouchExplorationStateChangeListener;
private DialogCreatable mDialogDelegate; @Nullable
private DialogCreatable mMagnificationModeDialogDelegate;
@Nullable @Nullable
MagnificationOneFingerPanningPreferenceController mOneFingerPanningPreferenceController; MagnificationOneFingerPanningPreferenceController mOneFingerPanningPreferenceController;
private boolean mInSetupWizard; private boolean mInSetupWizard;
@VisibleForTesting
public void setMagnificationModeDialogDelegate(@NonNull DialogCreatable delegate) {
mMagnificationModeDialogDelegate = delegate;
}
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
getActivity().setTitle(R.string.accessibility_screen_magnification_title); getActivity().setTitle(R.string.accessibility_screen_magnification_title);
mInSetupWizard = WizardManagerHelper.isAnySetupWizard(getIntent()); mInSetupWizard = WizardManagerHelper.isAnySetupWizard(getIntent());
} }
@NonNull
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
Bundle savedInstanceState) { @NonNull Bundle savedInstanceState) {
mFeatureName = getString(R.string.accessibility_screen_magnification_title); mFeatureName = getString(R.string.accessibility_screen_magnification_title);
mImageUri = new Uri.Builder().scheme(ContentResolver.SCHEME_ANDROID_RESOURCE) mImageUri = new Uri.Builder().scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
.authority(getPrefContext().getPackageName()) .authority(getPrefContext().getPackageName())
@@ -161,15 +170,14 @@ public class ToggleScreenMagnificationPreferenceFragment extends
super.onPause(); super.onPause();
} }
@NonNull
@Override @Override
public Dialog onCreateDialog(int dialogId) { public Dialog onCreateDialog(int dialogId) {
if (mDialogDelegate != null) {
mDialog = mDialogDelegate.onCreateDialog(dialogId);
if (mDialog != null) {
return mDialog;
}
}
switch (dialogId) { switch (dialogId) {
case DialogEnums.DIALOG_MAGNIFICATION_MODE:
case DialogEnums.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING:
return Preconditions.checkNotNull(mMagnificationModeDialogDelegate)
.onCreateDialog(dialogId);
case DialogEnums.GESTURE_NAVIGATION_TUTORIAL: case DialogEnums.GESTURE_NAVIGATION_TUTORIAL:
return AccessibilityShortcutsTutorial return AccessibilityShortcutsTutorial
.showAccessibilityGestureTutorialDialog(getPrefContext()); .showAccessibilityGestureTutorialDialog(getPrefContext());
@@ -238,9 +246,10 @@ public class ToggleScreenMagnificationPreferenceFragment extends
generalCategory.addPreference(mSettingsPreference); generalCategory.addPreference(mSettingsPreference);
final MagnificationModePreferenceController magnificationModePreferenceController = final MagnificationModePreferenceController magnificationModePreferenceController =
new MagnificationModePreferenceController(getContext(), new MagnificationModePreferenceController(Preconditions.checkNotNull(getContext()),
MagnificationModePreferenceController.PREF_KEY); MagnificationModePreferenceController.PREF_KEY);
magnificationModePreferenceController.setDialogHelper(this); magnificationModePreferenceController.setDialogHelper(/* dialogHelper= */this);
mMagnificationModeDialogDelegate = magnificationModePreferenceController;
getSettingsLifecycle().addObserver(magnificationModePreferenceController); getSettingsLifecycle().addObserver(magnificationModePreferenceController);
magnificationModePreferenceController.displayPreference(getPreferenceScreen()); magnificationModePreferenceController.displayPreference(getPreferenceScreen());
addPreferenceController(magnificationModePreferenceController); addPreferenceController(magnificationModePreferenceController);
@@ -388,11 +397,6 @@ public class ToggleScreenMagnificationPreferenceFragment extends
super.showDialog(dialogId); super.showDialog(dialogId);
} }
@Override
public void setDialogDelegate(DialogCreatable delegate) {
mDialogDelegate = delegate;
}
@Override @Override
protected void registerKeysToObserverCallback( protected void registerKeysToObserverCallback(
AccessibilitySettingsContentObserver contentObserver) { AccessibilitySettingsContentObserver contentObserver) {
@@ -470,14 +474,11 @@ public class ToggleScreenMagnificationPreferenceFragment extends
@Override @Override
public int getDialogMetricsCategory(int dialogId) { public int getDialogMetricsCategory(int dialogId) {
if (mDialogDelegate != null) {
final int category = mDialogDelegate.getDialogMetricsCategory(dialogId);
if (category != 0) {
return category;
}
}
switch (dialogId) { switch (dialogId) {
case DialogEnums.DIALOG_MAGNIFICATION_MODE:
case DialogEnums.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING:
return Preconditions.checkNotNull(mMagnificationModeDialogDelegate)
.getDialogMetricsCategory(dialogId);
case DialogEnums.GESTURE_NAVIGATION_TUTORIAL: case DialogEnums.GESTURE_NAVIGATION_TUTORIAL:
return SettingsEnums.DIALOG_TOGGLE_SCREEN_MAGNIFICATION_GESTURE_NAVIGATION; return SettingsEnums.DIALOG_TOGGLE_SCREEN_MAGNIFICATION_GESTURE_NAVIGATION;
case DialogEnums.ACCESSIBILITY_BUTTON_TUTORIAL: case DialogEnums.ACCESSIBILITY_BUTTON_TUTORIAL:
@@ -514,7 +515,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends
} }
@Override @Override
public void onToggleClicked(ShortcutPreference preference) { public void onToggleClicked(@NonNull ShortcutPreference preference) {
final int shortcutTypes = getUserPreferredShortcutTypes(); final int shortcutTypes = getUserPreferredShortcutTypes();
getPrefContext().getSystemService(AccessibilityManager.class).enableShortcutsForTargets( getPrefContext().getSystemService(AccessibilityManager.class).enableShortcutsForTargets(
preference.isChecked(), shortcutTypes, preference.isChecked(), shortcutTypes,
@@ -527,7 +528,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends
} }
@Override @Override
public void onSettingsClicked(ShortcutPreference preference) { public void onSettingsClicked(@NonNull ShortcutPreference preference) {
EditShortcutsPreferenceFragment.showEditShortcutScreen( EditShortcutsPreferenceFragment.showEditShortcutScreen(
requireContext(), requireContext(),
getMetricsCategory(), getMetricsCategory(),
@@ -581,7 +582,8 @@ public class ToggleScreenMagnificationPreferenceFragment extends
* *
* @param context The current context. * @param context The current context.
*/ */
public static CharSequence getServiceSummary(Context context) { @NonNull
public static CharSequence getServiceSummary(@NonNull Context context) {
// Get the user shortcut type from settings provider. // Get the user shortcut type from settings provider.
final int userShortcutType = ShortcutUtils.getEnabledShortcutTypes( final int userShortcutType = ShortcutUtils.getEnabledShortcutTypes(
context, MAGNIFICATION_CONTROLLER_NAME); context, MAGNIFICATION_CONTROLLER_NAME);
@@ -604,8 +606,9 @@ public class ToggleScreenMagnificationPreferenceFragment extends
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() { new BaseSearchIndexProvider() {
// LINT.IfChange(search_data) // LINT.IfChange(search_data)
@NonNull
@Override @Override
public List<SearchIndexableRaw> getRawDataToIndex(Context context, public List<SearchIndexableRaw> getRawDataToIndex(@NonNull Context context,
boolean enabled) { boolean enabled) {
final List<SearchIndexableRaw> rawData = final List<SearchIndexableRaw> rawData =
super.getRawDataToIndex(context, enabled); super.getRawDataToIndex(context, enabled);
@@ -628,8 +631,9 @@ public class ToggleScreenMagnificationPreferenceFragment extends
return rawData; return rawData;
} }
@NonNull
@Override @Override
public List<String> getNonIndexableKeys(Context context) { public List<String> getNonIndexableKeys(@NonNull Context context) {
final List<String> niks = super.getNonIndexableKeys(context); final List<String> niks = super.getNonIndexableKeys(context);
if (!com.android.settings.accessibility.Flags.fixA11ySettingsSearch()) { if (!com.android.settings.accessibility.Flags.fixA11ySettingsSearch()) {

View File

@@ -17,8 +17,6 @@
package com.android.settings.accessibility; package com.android.settings.accessibility;
import static com.android.settings.accessibility.AccessibilityUtil.State.ON; import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
import static com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode;
import static com.android.settings.accessibility.MagnificationModePreferenceController.MagnificationModeInfo;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
@@ -37,6 +35,7 @@ import android.widget.AdapterView;
import android.widget.ListView; import android.widget.ListView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
@@ -44,6 +43,9 @@ import androidx.test.core.app.ApplicationProvider;
import com.android.settings.DialogCreatable; import com.android.settings.DialogCreatable;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.accessibility.AccessibilityDialogUtils.DialogEnums;
import com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode;
import com.android.settings.accessibility.MagnificationModePreferenceController.MagnificationModeInfo;
import com.android.settings.utils.AnnotationSpan; import com.android.settings.utils.AnnotationSpan;
import org.junit.Before; import org.junit.Before;
@@ -82,6 +84,8 @@ public class MagnificationModePreferenceControllerTest {
mScreen.addPreference(mModePreference); mScreen.addPreference(mModePreference);
MagnificationCapabilities.setCapabilities(mContext, MAGNIFICATION_MODE_DEFAULT); MagnificationCapabilities.setCapabilities(mContext, MAGNIFICATION_MODE_DEFAULT);
mController = new MagnificationModePreferenceController(mContext, PREF_KEY); mController = new MagnificationModePreferenceController(mContext, PREF_KEY);
mController.setDialogHelper(mDialogHelper);
mDialogHelper.setDialogDelegate(mController);
showPreferenceOnTheScreen(null); showPreferenceOnTheScreen(null);
} }
@@ -107,7 +111,7 @@ public class MagnificationModePreferenceControllerTest {
performItemClickWith(MagnificationMode.WINDOW); performItemClickWith(MagnificationMode.WINDOW);
reshowPreferenceOnTheScreen(); reshowPreferenceOnTheScreen();
mDialogHelper.showDialog(MagnificationModePreferenceController.DIALOG_MAGNIFICATION_MODE); mDialogHelper.showDialog(DialogEnums.DIALOG_MAGNIFICATION_MODE);
assertThat(getCheckedModeFromDialog()).isEqualTo( assertThat(getCheckedModeFromDialog()).isEqualTo(
MagnificationMode.WINDOW); MagnificationMode.WINDOW);
@@ -123,7 +127,7 @@ public class MagnificationModePreferenceControllerTest {
DialogInterface.BUTTON_POSITIVE); DialogInterface.BUTTON_POSITIVE);
verify(mDialogHelper, never()).showDialog( verify(mDialogHelper, never()).showDialog(
MagnificationModePreferenceController.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING); DialogEnums.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING);
} }
@Test @Test
@@ -135,8 +139,7 @@ public class MagnificationModePreferenceControllerTest {
mController.onMagnificationModeDialogPositiveButtonClicked(mDialogHelper.getDialog(), mController.onMagnificationModeDialogPositiveButtonClicked(mDialogHelper.getDialog(),
DialogInterface.BUTTON_POSITIVE); DialogInterface.BUTTON_POSITIVE);
verify(mDialogHelper).showDialog( verify(mDialogHelper).showDialog(DialogEnums.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING);
MagnificationModePreferenceController.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING);
} }
@Test @Test
@@ -148,20 +151,17 @@ public class MagnificationModePreferenceControllerTest {
mController.onMagnificationModeDialogPositiveButtonClicked(mDialogHelper.getDialog(), mController.onMagnificationModeDialogPositiveButtonClicked(mDialogHelper.getDialog(),
DialogInterface.BUTTON_POSITIVE); DialogInterface.BUTTON_POSITIVE);
verify(mDialogHelper).showDialog( verify(mDialogHelper).showDialog(DialogEnums.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING);
MagnificationModePreferenceController.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING);
} }
@Test @Test
public void onTripleTapWarningDialogNegativeButtonClicked_showModeDialog() { public void onTripleTapWarningDialogNegativeButtonClicked_showModeDialog() {
mDialogHelper.showDialog( mDialogHelper.showDialog(DialogEnums.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING);
MagnificationModePreferenceController.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING);
mController.onMagnificationTripleTapWarningDialogNegativeButtonClicked( mController.onMagnificationTripleTapWarningDialogNegativeButtonClicked(
mDialogHelper.getDialog(), DialogInterface.BUTTON_NEGATIVE); mDialogHelper.getDialog(), DialogInterface.BUTTON_NEGATIVE);
verify(mDialogHelper).showDialog( verify(mDialogHelper).showDialog(DialogEnums.DIALOG_MAGNIFICATION_MODE);
MagnificationModePreferenceController.DIALOG_MAGNIFICATION_MODE);
} }
@Test @Test
@@ -182,8 +182,7 @@ public class MagnificationModePreferenceControllerTest {
@Test @Test
public void checkSpansInTripleTapWarningDialog_existAnnotationSpan() { public void checkSpansInTripleTapWarningDialog_existAnnotationSpan() {
mDialogHelper.showDialog( mDialogHelper.showDialog(DialogEnums.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING);
MagnificationModePreferenceController.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING);
final View contentView = mDialogHelper.getDialog().findViewById(android.R.id.content); final View contentView = mDialogHelper.getDialog().findViewById(android.R.id.content);
final TextView messageView = contentView.findViewById(R.id.message); final TextView messageView = contentView.findViewById(R.id.message);
final CharSequence textInTripleTapWarningDialog = messageView.getText(); final CharSequence textInTripleTapWarningDialog = messageView.getText();
@@ -256,13 +255,11 @@ public class MagnificationModePreferenceControllerTest {
} }
private void showPreferenceOnTheScreen(Bundle savedInstanceState) { private void showPreferenceOnTheScreen(Bundle savedInstanceState) {
mController.setDialogHelper(mDialogHelper);
mController.onCreate(savedInstanceState); mController.onCreate(savedInstanceState);
mController.displayPreference(mScreen); mController.displayPreference(mScreen);
} }
private static class TestDialogHelper implements DialogCreatable, private static class TestDialogHelper implements DialogCreatable, DialogHelper {
MagnificationModePreferenceController.DialogHelper {
private DialogCreatable mDialogDelegate; private DialogCreatable mDialogDelegate;
private Dialog mDialog; private Dialog mDialog;
@@ -271,11 +268,11 @@ public class MagnificationModePreferenceControllerTest {
mDialog = onCreateDialog(dialogId); mDialog = onCreateDialog(dialogId);
} }
@Override public void setDialogDelegate(@NonNull DialogCreatable delegate) {
public void setDialogDelegate(DialogCreatable delegate) {
mDialogDelegate = delegate; mDialogDelegate = delegate;
} }
@NonNull
@Override @Override
public Dialog onCreateDialog(int dialogId) { public Dialog onCreateDialog(int dialogId) {
return mDialogDelegate.onCreateDialog(dialogId); return mDialogDelegate.onCreateDialog(dialogId);

View File

@@ -64,6 +64,8 @@ import com.android.server.accessibility.Flags;
import com.android.settings.DialogCreatable; import com.android.settings.DialogCreatable;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
import com.android.settings.accessibility.AccessibilityDialogUtils.DialogEnums;
import com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode;
import com.android.settings.testutils.shadow.ShadowAccessibilityManager; import com.android.settings.testutils.shadow.ShadowAccessibilityManager;
import com.android.settings.testutils.shadow.ShadowDeviceConfig; import com.android.settings.testutils.shadow.ShadowDeviceConfig;
import com.android.settings.testutils.shadow.ShadowStorageManager; import com.android.settings.testutils.shadow.ShadowStorageManager;
@@ -550,7 +552,8 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
ToggleScreenMagnificationPreferenceFragment fragment = mFragController.create( ToggleScreenMagnificationPreferenceFragment fragment = mFragController.create(
R.id.main_content, /* bundle= */ null).start().resume().get(); R.id.main_content, /* bundle= */ null).start().resume().get();
DialogCreatable dialogDelegate = ReflectionHelpers.getField(fragment, "mDialogDelegate"); DialogCreatable dialogDelegate = ReflectionHelpers.getField(fragment,
"mMagnificationModeDialogDelegate");
List<LifecycleObserver> lifecycleObservers = ReflectionHelpers.getField( List<LifecycleObserver> lifecycleObservers = ReflectionHelpers.getField(
fragment.getSettingsLifecycle(), "mObservers"); fragment.getSettingsLifecycle(), "mObservers");
assertThat(dialogDelegate).isInstanceOf(MagnificationModePreferenceController.class); assertThat(dialogDelegate).isInstanceOf(MagnificationModePreferenceController.class);
@@ -592,19 +595,19 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
} }
@Test @Test
public void onCreateDialog_setDialogDelegate_invokeDialogDelegate() { public void onCreateDialog_setMagnificationModeDialogDelegate_invokeDialogDelegate() {
ToggleScreenMagnificationPreferenceFragment fragment = ToggleScreenMagnificationPreferenceFragment fragment =
mFragController.create( mFragController.create(
R.id.main_content, /* bundle= */ null).start().resume().get(); R.id.main_content, /* bundle= */ null).start().resume().get();
final DialogCreatable dialogDelegate = mock(DialogCreatable.class, RETURNS_DEEP_STUBS); final DialogCreatable dialogDelegate = mock(DialogCreatable.class, RETURNS_DEEP_STUBS);
when(dialogDelegate.getDialogMetricsCategory(anyInt())).thenReturn(1); final int dialogId = DialogEnums.DIALOG_MAGNIFICATION_MODE;
fragment.setDialogDelegate(dialogDelegate); when(dialogDelegate.getDialogMetricsCategory(anyInt())).thenReturn(dialogId);
fragment.setMagnificationModeDialogDelegate(dialogDelegate);
fragment.onCreateDialog(1); fragment.onCreateDialog(dialogId);
fragment.getDialogMetricsCategory(1); fragment.getDialogMetricsCategory(dialogId);
verify(dialogDelegate).onCreateDialog(dialogId);
verify(dialogDelegate).onCreateDialog(1); verify(dialogDelegate).getDialogMetricsCategory(dialogId);
verify(dialogDelegate).getDialogMetricsCategory(1);
} }
@Test @Test