diff --git a/res/layout/accessibility_shortcut_secondary_action.xml b/res/layout/accessibility_shortcut_secondary_action.xml index 9d59b2e97a3..b46c3030c42 100644 --- a/res/layout/accessibility_shortcut_secondary_action.xml +++ b/res/layout/accessibility_shortcut_secondary_action.xml @@ -24,12 +24,14 @@ android:clipToPadding="false"> @@ -39,23 +41,26 @@ android:gravity="start|center_vertical" android:minWidth="56dp" android:orientation="horizontal" - android:clipToPadding="false" android:paddingRight="16dp" android:paddingTop="4dp" - android:paddingBottom="4dp"> + android:paddingBottom="4dp" + android:focusable="false" + android:clickable="false"> + android:layout_gravity="center" + android:focusable="false" + android:clickable="false" + android:background="@null"/> @@ -71,8 +76,8 @@ android:id="@android:id/summary" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_below="@+android:id/title" - android:layout_alignStart="@+android:id/title" + android:layout_below="@android:id/title" + android:layout_alignStart="@android:id/title" android:textAppearance="?android:attr/textAppearanceListItemSecondary" android:textColor="?android:attr/textColorSecondary" android:maxLines="10" /> @@ -81,41 +86,20 @@ - - - - - + android:layout_marginTop="16dp" + android:layout_marginBottom="16dp" + android:background="?android:attr/listDivider" /> - - - - - + android:minWidth="58dp" + android:gravity="end|center_vertical" + android:orientation="vertical" /> \ No newline at end of file diff --git a/res/layout/preference_widget_settings.xml b/res/layout/preference_widget_settings.xml new file mode 100644 index 00000000000..73c6875893f --- /dev/null +++ b/res/layout/preference_widget_settings.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/src/com/android/settings/accessibility/ShortcutPreference.java b/src/com/android/settings/accessibility/ShortcutPreference.java index cc91b84fa1a..f76bb01e745 100644 --- a/src/com/android/settings/accessibility/ShortcutPreference.java +++ b/src/com/android/settings/accessibility/ShortcutPreference.java @@ -20,8 +20,8 @@ import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.widget.CheckBox; +import android.widget.LinearLayout; -import androidx.annotation.Nullable; import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; @@ -33,76 +33,112 @@ import com.android.settings.R; */ public class ShortcutPreference extends Preference { - private View.OnClickListener mCheckBoxListener; - private View.OnClickListener mSettingButtonListener; + /** + * Interface definition for a callback to be invoked when the checkbox or settings has been + * clicked. + */ + public interface OnClickListener { + /** + * Called when the checkbox in ShortcutPreference has been clicked. + * + * @param preference The clicked preference + */ + void onCheckboxClicked(ShortcutPreference preference); + /** + * Called when the settings view has been clicked. + * + * @param preference The clicked preference + */ + void onSettingsClicked(ShortcutPreference preference); + } + private OnClickListener mListener = null; + private int mSettingsVisibility = View.VISIBLE; private boolean mChecked = false; ShortcutPreference(Context context, AttributeSet attrs) { super(context, attrs); - - setLayoutResource(R.layout.accessibility_shortcut_secondary_action); + init(); } @Override public void onBindViewHolder(PreferenceViewHolder holder) { super.onBindViewHolder(holder); - holder.itemView.setClickable(false); final CheckBox checkBox = holder.itemView.findViewById(R.id.checkbox); - checkBox.setOnClickListener(mCheckBoxListener); - checkBox.setChecked(mChecked); - final View settingButton = holder.itemView.findViewById(R.id.settings_button); - settingButton.setOnClickListener(mSettingButtonListener); + final LinearLayout mainFrame = holder.itemView.findViewById(R.id.main_frame); + if (mainFrame != null && checkBox != null) { + mainFrame.setOnClickListener(view -> callOnCheckboxClicked()); + checkBox.setChecked(mChecked); + } + + final View settings = holder.itemView.findViewById(android.R.id.widget_frame); + if (settings != null) { + settings.setOnClickListener(view -> callOnSettingsClicked()); + settings.setVisibility(mSettingsVisibility); + } } /** * Set the shortcut checkbox according to checked value. * - * @param checked the state value of shortcut checkbox. + * @param checked the state value of shortcut checkbox */ public void setChecked(boolean checked) { - if (checked != mChecked) { + if (mChecked != checked) { mChecked = checked; notifyChanged(); } } /** - * Set the given onClickListener to the SettingButtonListener. + * Get the checked value of shortcut checkbox. * - * @param listener the given onClickListener. + * @return the checked value of shortcut checkbox */ - public void setSettingButtonListener(@Nullable View.OnClickListener listener) { - mSettingButtonListener = listener; - notifyChanged(); + public boolean getChecked() { + return mChecked; + } + + + + /** + * Sets the visibility state of Settings view. + * + * @param visibility one of {@link View#VISIBLE}, {@link View#INVISIBLE}, or {@link View#GONE}. + */ + public void setSettingsVisibility(@View.Visibility int visibility) { + if (mSettingsVisibility != visibility) { + mSettingsVisibility = visibility; + notifyChanged(); + } } /** - * Returns the callback to be invoked when the setting button is clicked. + * Sets the callback to be invoked when this preference is clicked by the user. * - * @return The callback to be invoked + * @param listener the callback to be invoked */ - public View.OnClickListener getSettingButtonListener() { - return mSettingButtonListener; + public void setOnClickListener(OnClickListener listener) { + mListener = listener; } - /** - * Set the given onClickListener to the CheckBoxListener. - * - * @param listener the given onClickListener. - */ - public void setCheckBoxListener(@Nullable View.OnClickListener listener) { - mCheckBoxListener = listener; - notifyChanged(); + private void init() { + setLayoutResource(R.layout.accessibility_shortcut_secondary_action); + setWidgetLayoutResource(R.layout.preference_widget_settings); + setIconSpaceReserved(false); } - /** - * Returns the callback to be invoked when the checkbox is clicked. - * - * @return The callback to be invoked - */ - public View.OnClickListener getCheckBoxListener() { - return mCheckBoxListener; + private void callOnSettingsClicked() { + if (mListener != null) { + mListener.onSettingsClicked(this); + } + } + + private void callOnCheckboxClicked() { + setChecked(!mChecked); + if (mListener != null) { + mListener.onCheckboxClicked(this); + } } } diff --git a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java index e54446f0b69..76ec0421db3 100644 --- a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java @@ -43,7 +43,6 @@ import android.view.MenuInflater; import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityManager; -import android.widget.CheckBox; import androidx.preference.PreferenceScreen; @@ -57,8 +56,11 @@ import com.android.settingslib.accessibility.AccessibilityUtils; import java.util.List; -public class ToggleAccessibilityServicePreferenceFragment extends ToggleFeaturePreferenceFragment { +/** Fragment for providing toggle bar and basic accessibility service setup. */ +public class ToggleAccessibilityServicePreferenceFragment extends + ToggleFeaturePreferenceFragment implements ShortcutPreference.OnClickListener { + private static final String KEY_SHORTCUT_PREFERENCE = "shortcut_preference"; private static final int DIALOG_ID_ENABLE_WARNING = 1; private static final int DIALOG_ID_DISABLE_WARNING = 2; private static final int DIALOG_ID_LAUNCH_ACCESSIBILITY_TUTORIAL = 3; @@ -77,18 +79,6 @@ public class ToggleAccessibilityServicePreferenceFragment extends ToggleFeatureP } }; - private final View.OnClickListener mSettingButtonListener = (View view) -> showDialog( - DIALOG_ID_EDIT_SHORTCUT); - - private final View.OnClickListener mCheckBoxListener = (View view) -> { - CheckBox checkBox = (CheckBox) view; - if (checkBox.isChecked()) { - // TODO(b/142530063): Enable shortcut when checkbox is checked. - } else { - // TODO(b/142530063): Disable shortcut when checkbox is unchecked. - } - }; - private final SettingsContentObserver mSettingsContentObserver = new SettingsContentObserver(new Handler()) { @Override @@ -275,16 +265,22 @@ public class ToggleAccessibilityServicePreferenceFragment extends ToggleFeatureP final ShortcutPreference shortcutPreference = new ShortcutPreference( preferenceScreen.getContext(), null); // Put the shortcutPreference before settingsPreference. + shortcutPreference.setPersistent(false); + shortcutPreference.setKey(getShortcutPreferenceKey()); shortcutPreference.setOrder(-1); shortcutPreference.setTitle(R.string.accessibility_shortcut_title); + shortcutPreference.setOnClickListener(this); + // TODO(b/142530063): Check the new setting key to decide which summary should be shown. // TODO(b/142530063): Check if gesture mode is on to decide which summary should be shown. // TODO(b/142530063): Check the new key to decide whether checkbox should be checked. - shortcutPreference.setSettingButtonListener(mSettingButtonListener); - shortcutPreference.setCheckBoxListener(mCheckBoxListener); preferenceScreen.addPreference(shortcutPreference); } + public String getShortcutPreferenceKey() { + return KEY_SHORTCUT_PREFERENCE; + } + private void updateSwitchBarToggleSwitch() { final boolean checked = AccessibilityUtils.getEnabledServicesFromSettings(getActivity()) .contains(mComponentName); @@ -387,6 +383,20 @@ public class ToggleAccessibilityServicePreferenceFragment extends ToggleFeatureP }); } + @Override + public void onCheckboxClicked(ShortcutPreference preference) { + if (preference.getChecked()) { + // TODO(b/142530063): Enable shortcut when checkbox is checked. + } else { + // TODO(b/142530063): Disable shortcut when checkbox is unchecked. + } + } + + @Override + public void onSettingsClicked(ShortcutPreference preference) { + showDialog(DIALOG_ID_EDIT_SHORTCUT); + } + @Override protected void onProcessArguments(Bundle arguments) { super.onProcessArguments(arguments); diff --git a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java index f093dc7f329..9fb93efd9cd 100644 --- a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java @@ -26,7 +26,6 @@ import android.provider.Settings; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.CheckBox; import android.widget.Switch; import androidx.preference.Preference; @@ -46,7 +45,7 @@ import java.util.List; @SearchIndexable public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePreferenceFragment implements DaltonizerRadioButtonPreferenceController.OnChangeListener, - SwitchBar.OnSwitchChangeListener { + SwitchBar.OnSwitchChangeListener, ShortcutPreference.OnClickListener { public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = new BaseSearchIndexProvider(R.xml.accessibility_daltonizer_settings); @@ -77,18 +76,6 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe } }; - private final View.OnClickListener mSettingButtonListener = - (View view) -> showDialog(DIALOG_ID_EDIT_SHORTCUT); - - private final View.OnClickListener mCheckBoxListener = (View view) -> { - CheckBox checkBox = (CheckBox) view; - if (checkBox.isChecked()) { - // TODO(b/142530063): Enable shortcut when checkbox is checked. - } else { - // TODO(b/142530063): Disable shortcut when checkbox is unchecked. - } - }; - private Dialog mDialog; @Override @@ -191,6 +178,20 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe mSwitchBar.addOnSwitchChangeListener(this); } + @Override + public void onCheckboxClicked(ShortcutPreference preference) { + if (preference.getChecked()) { + // TODO(b/142530063): Enable shortcut when checkbox is checked. + } else { + // TODO(b/142530063): Disable shortcut when checkbox is unchecked. + } + } + + @Override + public void onSettingsClicked(ShortcutPreference preference) { + showDialog(DIALOG_ID_EDIT_SHORTCUT); + } + private void initShortcutPreference() { final PreferenceScreen preferenceScreen = getPreferenceScreen(); final ShortcutPreference shortcutPreference = new ShortcutPreference( @@ -202,8 +203,7 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe // TODO(b/142530063): Check the new setting key to decide which summary should be shown. // TODO(b/142530063): Check if gesture mode is on to decide which summary should be shown. // TODO(b/142530063): Check the new key to decide whether checkbox should be checked. - shortcutPreference.setSettingButtonListener(mSettingButtonListener); - shortcutPreference.setCheckBoxListener(mCheckBoxListener); + shortcutPreference.setOnClickListener(this); preferenceScreen.addPreference(shortcutPreference); } } diff --git a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java index f9016e8002d..2111f9ed589 100644 --- a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java @@ -38,7 +38,6 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.WindowManager; -import android.widget.CheckBox; import android.widget.ImageView; import android.widget.RelativeLayout.LayoutParams; import android.widget.Switch; @@ -52,7 +51,8 @@ import com.android.settings.R; import com.android.settings.widget.SwitchBar; public class ToggleScreenMagnificationPreferenceFragment extends - ToggleFeaturePreferenceFragment implements SwitchBar.OnSwitchChangeListener { + ToggleFeaturePreferenceFragment implements SwitchBar.OnSwitchChangeListener, + ShortcutPreference.OnClickListener { private static final String SETTINGS_KEY = "screen_magnification_settings"; private static final int DIALOG_ID_GESTURE_NAVIGATION_TUTORIAL = 1; @@ -66,18 +66,6 @@ public class ToggleScreenMagnificationPreferenceFragment extends } }; - private final View.OnClickListener mSettingButtonListener = - (View view) -> showDialog(DIALOG_ID_EDIT_SHORTCUT); - - private final View.OnClickListener mCheckBoxListener = (View view) -> { - CheckBox checkBox = (CheckBox) view; - if (checkBox.isChecked()) { - // TODO(b/142530063): Enable shortcut when checkbox is checked. - } else { - // TODO(b/142530063): Disable shortcut when checkbox is unchecked. - } - }; - private Dialog mDialog; protected class VideoPreference extends Preference { @@ -327,6 +315,20 @@ public class ToggleScreenMagnificationPreferenceFragment extends } } + @Override + public void onCheckboxClicked(ShortcutPreference preference) { + if (preference.getChecked()) { + // TODO(b/142530063): Enable shortcut when checkbox is checked. + } else { + // TODO(b/142530063): Disable shortcut when checkbox is unchecked. + } + } + + @Override + public void onSettingsClicked(ShortcutPreference preference) { + showDialog(DIALOG_ID_EDIT_SHORTCUT); + } + private void initShortcutPreference() { final PreferenceScreen preferenceScreen = getPreferenceScreen(); final ShortcutPreference shortcutPreference = new ShortcutPreference( @@ -334,11 +336,10 @@ public class ToggleScreenMagnificationPreferenceFragment extends // Put the shortcutPreference before videoPreference. shortcutPreference.setOrder(mVideoPreference.getOrder() - 1); shortcutPreference.setTitle(R.string.accessibility_magnification_shortcut_title); + shortcutPreference.setOnClickListener(this); // TODO(b/142530063): Check the new setting key to decide which summary should be shown. // TODO(b/142530063): Check if gesture mode is on to decide which summary should be shown. // TODO(b/142530063): Check the new key to decide whether checkbox should be checked. - shortcutPreference.setSettingButtonListener(mSettingButtonListener); - shortcutPreference.setCheckBoxListener(mCheckBoxListener); preferenceScreen.addPreference(shortcutPreference); } diff --git a/tests/robotests/src/com/android/settings/accessibility/ShortcutPreferenceTest.java b/tests/robotests/src/com/android/settings/accessibility/ShortcutPreferenceTest.java index 3c86f4c12b9..989bb5c6bf0 100644 --- a/tests/robotests/src/com/android/settings/accessibility/ShortcutPreferenceTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/ShortcutPreferenceTest.java @@ -19,7 +19,13 @@ package com.android.settings.accessibility; import static com.google.common.truth.Truth.assertThat; import android.content.Context; +import android.view.LayoutInflater; import android.view.View; +import android.widget.LinearLayout; + +import androidx.preference.PreferenceViewHolder; + +import com.android.settings.R; import org.junit.Before; import org.junit.Test; @@ -31,23 +37,64 @@ import org.robolectric.RuntimeEnvironment; @RunWith(RobolectricTestRunner.class) public class ShortcutPreferenceTest { + private static final String CHECKBOX_CLICKED = "checkbox_clicked"; + private static final String SETTINGS_CLICKED = "settings_clicked"; + private ShortcutPreference mShortcutPreference; - private View.OnClickListener mSettingButtonListener; - private View.OnClickListener mCheckBoxListener; + private PreferenceViewHolder mPreferenceViewHolder; + private String mResult; + + private ShortcutPreference.OnClickListener mListener = + new ShortcutPreference.OnClickListener() { + @Override + public void onCheckboxClicked(ShortcutPreference preference) { + mResult = CHECKBOX_CLICKED; + } + + @Override + public void onSettingsClicked(ShortcutPreference preference) { + mResult = SETTINGS_CLICKED; + } + }; @Before public void setUp() { - final Context mContext = RuntimeEnvironment.application; - mShortcutPreference = new ShortcutPreference(mContext, null); + final Context context = RuntimeEnvironment.application; + mShortcutPreference = new ShortcutPreference(context, null); + + final LayoutInflater inflater = LayoutInflater.from(context); + final View view = + inflater.inflate(R.layout.accessibility_shortcut_secondary_action, null); + mPreferenceViewHolder = PreferenceViewHolder.createInstanceForTests(view); + } + + @Test + public void testClickLinearLayout_checkboxClicked() { + mShortcutPreference.onBindViewHolder(mPreferenceViewHolder); + mShortcutPreference.setOnClickListener(mListener); + + LinearLayout mainFrame = mPreferenceViewHolder.itemView.findViewById(R.id.main_frame); + mainFrame.performClick(); + + assertThat(mResult).isEqualTo(CHECKBOX_CLICKED); + assertThat(mShortcutPreference.getChecked()).isTrue(); } @Test - public void setOnClickListeners_shouldSetListeners() { - mShortcutPreference.setSettingButtonListener(mSettingButtonListener); - mShortcutPreference.setCheckBoxListener(mCheckBoxListener); + public void testClickSettings_settingsClicked() { + mShortcutPreference.onBindViewHolder(mPreferenceViewHolder); + mShortcutPreference.setOnClickListener(mListener); - assertThat(mShortcutPreference.getCheckBoxListener()).isEqualTo(mCheckBoxListener); - assertThat(mShortcutPreference.getSettingButtonListener()).isEqualTo( - mSettingButtonListener); + View settings = mPreferenceViewHolder.itemView.findViewById(android.R.id.widget_frame); + settings.performClick(); + + assertThat(mResult).isEqualTo(SETTINGS_CLICKED); + } + + @Test + public void testSetCheckedTrue_getCheckedIsTrue() { + mShortcutPreference.setChecked(true); + + assertThat(mShortcutPreference.getChecked()).isEqualTo(true); } }