• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.accessibility;
18 
19 import static com.android.settings.accessibility.ToggleFeaturePreferenceFragment.KEY_SAVED_USER_SHORTCUT_TYPE;
20 
21 import static com.google.common.truth.Truth.assertThat;
22 
23 import static org.mockito.ArgumentMatchers.any;
24 import static org.mockito.ArgumentMatchers.eq;
25 import static org.mockito.Mockito.doReturn;
26 import static org.mockito.Mockito.mock;
27 import static org.mockito.Mockito.never;
28 import static org.mockito.Mockito.spy;
29 import static org.mockito.Mockito.verify;
30 import static org.mockito.Mockito.when;
31 
32 import android.content.ComponentName;
33 import android.content.ContentResolver;
34 import android.content.Context;
35 import android.content.DialogInterface;
36 import android.content.Intent;
37 import android.content.pm.PackageManager;
38 import android.icu.text.CaseMap;
39 import android.os.Bundle;
40 import android.platform.test.annotations.DisableFlags;
41 import android.platform.test.annotations.EnableFlags;
42 import android.platform.test.flag.junit.SetFlagsRule;
43 import android.provider.Settings;
44 import android.view.LayoutInflater;
45 import android.view.View;
46 import android.view.ViewGroup;
47 import android.widget.CheckBox;
48 import android.widget.PopupWindow;
49 
50 import androidx.appcompat.app.AlertDialog;
51 import androidx.fragment.app.FragmentActivity;
52 import androidx.preference.Preference;
53 import androidx.preference.PreferenceManager;
54 import androidx.preference.PreferenceScreen;
55 import androidx.test.core.app.ApplicationProvider;
56 
57 import com.android.settings.R;
58 import com.android.settings.accessibility.AccessibilityDialogUtils.DialogType;
59 import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
60 import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
61 import com.android.settings.flags.Flags;
62 import com.android.settings.testutils.shadow.ShadowFragment;
63 import com.android.settingslib.widget.TopIntroPreference;
64 
65 import com.google.android.setupcompat.util.WizardManagerHelper;
66 
67 import org.junit.Before;
68 import org.junit.Rule;
69 import org.junit.Test;
70 import org.junit.runner.RunWith;
71 import org.mockito.Answers;
72 import org.mockito.Mock;
73 import org.mockito.MockitoAnnotations;
74 import org.mockito.Spy;
75 import org.robolectric.RobolectricTestRunner;
76 import org.robolectric.annotation.Config;
77 import org.robolectric.shadow.api.Shadow;
78 import org.robolectric.shadows.ShadowApplication;
79 import org.robolectric.shadows.ShadowLooper;
80 
81 import java.util.Locale;
82 
83 /** Tests for {@link ToggleFeaturePreferenceFragment} */
84 @RunWith(RobolectricTestRunner.class)
85 @Config(shadows = {
86         ShadowFragment.class,
87 })
88 public class ToggleFeaturePreferenceFragmentTest {
89     @Rule
90     public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
91 
92     private static final String PLACEHOLDER_PACKAGE_NAME = "com.placeholder.example";
93     private static final String PLACEHOLDER_CLASS_NAME = PLACEHOLDER_PACKAGE_NAME + ".placeholder";
94     private static final ComponentName PLACEHOLDER_COMPONENT_NAME = new ComponentName(
95             PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_CLASS_NAME);
96     private static final String PLACEHOLDER_TILE_CLASS_NAME =
97             PLACEHOLDER_PACKAGE_NAME + "tile.placeholder";
98     private static final ComponentName PLACEHOLDER_TILE_COMPONENT_NAME = new ComponentName(
99             PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_TILE_CLASS_NAME);
100     private static final String PLACEHOLDER_TILE_TOOLTIP_CONTENT =
101             PLACEHOLDER_PACKAGE_NAME + "tooltip_content";
102     private static final String PLACEHOLDER_DIALOG_TITLE = "title";
103     private static final String DEFAULT_SUMMARY = "default summary";
104     private static final String DEFAULT_DESCRIPTION = "default description";
105     private static final String DEFAULT_TOP_INTRO = "default top intro";
106 
107     private static final String SOFTWARE_SHORTCUT_KEY =
108             Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
109     private static final String HARDWARE_SHORTCUT_KEY =
110             Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
111 
112     private TestToggleFeaturePreferenceFragment mFragment;
113     @Spy
114     private final Context mContext = ApplicationProvider.getApplicationContext();
115 
116     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
117     private PreferenceManager mPreferenceManager;
118 
119     @Mock
120     private FragmentActivity mActivity;
121     @Mock
122     private ContentResolver mContentResolver;
123     @Mock
124     private PackageManager mPackageManager;
125 
126     @Before
setUpTestFragment()127     public void setUpTestFragment() {
128         MockitoAnnotations.initMocks(this);
129 
130         mFragment = spy(new TestToggleFeaturePreferenceFragment());
131         when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
132         when(mFragment.getPreferenceManager().getContext()).thenReturn(mContext);
133         when(mFragment.getContext()).thenReturn(mContext);
134         when(mFragment.getActivity()).thenReturn(mActivity);
135         when(mActivity.getContentResolver()).thenReturn(mContentResolver);
136         when(mContext.getPackageManager()).thenReturn(mPackageManager);
137         final PreferenceScreen screen = spy(new PreferenceScreen(mContext, null));
138         when(screen.getPreferenceManager()).thenReturn(mPreferenceManager);
139         doReturn(screen).when(mFragment).getPreferenceScreen();
140         mContext.setTheme(androidx.appcompat.R.style.Theme_AppCompat);
141     }
142 
143     @Test
getPreferenceScreenResId_returnsExpectedPreferenceScreenResId()144     public void getPreferenceScreenResId_returnsExpectedPreferenceScreenResId() {
145         assertThat(mFragment.getPreferenceScreenResId()).isEqualTo(R.xml.placeholder_prefs);
146     }
147 
148     @Test
149     @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
150     @Config(shadows = {ShadowFragment.class})
onResume_flagEnabled_haveRegisterToSpecificUris()151     public void onResume_flagEnabled_haveRegisterToSpecificUris() {
152         mFragment.onAttach(mContext);
153         mFragment.onCreate(Bundle.EMPTY);
154 
155         mFragment.onResume();
156 
157         verify(mContentResolver).registerContentObserver(
158                 eq(Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS)),
159                 eq(false),
160                 any(AccessibilitySettingsContentObserver.class));
161         verify(mContentResolver).registerContentObserver(
162                 eq(Settings.Secure.getUriFor(
163                         Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)),
164                 eq(false),
165                 any(AccessibilitySettingsContentObserver.class));
166         verify(mContentResolver).registerContentObserver(
167                 eq(Settings.Secure.getUriFor(
168                         Settings.Secure.ACCESSIBILITY_QS_TARGETS)),
169                 eq(false),
170                 any(AccessibilitySettingsContentObserver.class));
171     }
172 
173     @Test
174     @DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
175     @Config(shadows = {ShadowFragment.class})
onResume_flagDisabled_haveRegisterToSpecificUris()176     public void onResume_flagDisabled_haveRegisterToSpecificUris() {
177         mFragment.onAttach(mContext);
178         mFragment.onCreate(Bundle.EMPTY);
179 
180         mFragment.onResume();
181 
182         verify(mContentResolver).registerContentObserver(
183                 eq(Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS)),
184                 eq(false),
185                 any(AccessibilitySettingsContentObserver.class));
186         verify(mContentResolver).registerContentObserver(
187                 eq(Settings.Secure.getUriFor(
188                         Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)),
189                 eq(false),
190                 any(AccessibilitySettingsContentObserver.class));
191         verify(mContentResolver, never()).registerContentObserver(
192                 eq(Settings.Secure.getUriFor(
193                         Settings.Secure.ACCESSIBILITY_QS_TARGETS)),
194                 eq(false),
195                 any(AccessibilitySettingsContentObserver.class));
196     }
197 
198     @Test
updateShortcutPreferenceData_assignDefaultValueToVariable()199     public void updateShortcutPreferenceData_assignDefaultValueToVariable() {
200         mFragment.mComponentName = PLACEHOLDER_COMPONENT_NAME;
201 
202         mFragment.updateShortcutPreferenceData();
203 
204         final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
205                 mFragment.mComponentName.flattenToString());
206         // Compare to default UserShortcutType
207         assertThat(expectedType).isEqualTo(UserShortcutType.SOFTWARE);
208     }
209 
210     @Test
updateShortcutPreferenceData_hasValueInSettings_assignToVariable()211     public void updateShortcutPreferenceData_hasValueInSettings_assignToVariable() {
212         mFragment.mComponentName = PLACEHOLDER_COMPONENT_NAME;
213         putSecureStringIntoSettings(SOFTWARE_SHORTCUT_KEY,
214                 PLACEHOLDER_COMPONENT_NAME.flattenToString());
215         putSecureStringIntoSettings(HARDWARE_SHORTCUT_KEY,
216                 PLACEHOLDER_COMPONENT_NAME.flattenToString());
217 
218         mFragment.updateShortcutPreferenceData();
219 
220         final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
221                 mFragment.mComponentName.flattenToString());
222         assertThat(expectedType).isEqualTo(UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE);
223     }
224 
225     @Test
updateShortcutPreferenceData_hasValueInSharedPreference_assignToVariable()226     public void updateShortcutPreferenceData_hasValueInSharedPreference_assignToVariable() {
227         mFragment.mComponentName = PLACEHOLDER_COMPONENT_NAME;
228         final PreferredShortcut hardwareShortcut = new PreferredShortcut(
229                 PLACEHOLDER_COMPONENT_NAME.flattenToString(), UserShortcutType.HARDWARE);
230 
231         putUserShortcutTypeIntoSharedPreference(mContext, hardwareShortcut);
232         mFragment.updateShortcutPreferenceData();
233 
234         final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
235                 mFragment.mComponentName.flattenToString());
236         assertThat(expectedType).isEqualTo(UserShortcutType.HARDWARE);
237     }
238 
239     @Test
dialogCheckboxClicked_hardwareType_skipTimeoutRestriction()240     public void dialogCheckboxClicked_hardwareType_skipTimeoutRestriction() {
241         final ShortcutPreference shortcutPreference = new ShortcutPreference(mContext, /* attrs= */
242                 null);
243         mFragment.mComponentName = PLACEHOLDER_COMPONENT_NAME;
244         mFragment.mShortcutPreference = shortcutPreference;
245         final AlertDialog dialog = AccessibilityDialogUtils.showEditShortcutDialog(
246                 mContext, DialogType.EDIT_SHORTCUT_GENERIC, PLACEHOLDER_DIALOG_TITLE,
247                 mFragment::callOnAlertDialogCheckboxClicked);
248         mFragment.setupEditShortcutDialog(dialog);
249 
250         final View dialogHardwareView = dialog.findViewById(R.id.hardware_shortcut);
251         final CheckBox hardwareTypeCheckBox = dialogHardwareView.findViewById(R.id.checkbox);
252         hardwareTypeCheckBox.setChecked(true);
253         dialog.getButton(DialogInterface.BUTTON_POSITIVE).callOnClick();
254         ShadowLooper.idleMainLooper();
255         final boolean skipTimeoutRestriction = Settings.Secure.getInt(mContext.getContentResolver(),
256                 Settings.Secure.SKIP_ACCESSIBILITY_SHORTCUT_DIALOG_TIMEOUT_RESTRICTION, 0) != 0;
257 
258         assertThat(skipTimeoutRestriction).isTrue();
259     }
260 
261     @Test
setupEditShortcutDialog_shortcutPreferenceOff_checkboxIsEmptyValue()262     public void setupEditShortcutDialog_shortcutPreferenceOff_checkboxIsEmptyValue() {
263         final AlertDialog dialog = AccessibilityDialogUtils.showEditShortcutDialog(
264                 mContext, DialogType.EDIT_SHORTCUT_GENERIC, PLACEHOLDER_DIALOG_TITLE,
265                 this::callEmptyOnClicked);
266         final ShortcutPreference shortcutPreference = new ShortcutPreference(mContext, /* attrs= */
267                 null);
268         mFragment.mComponentName = PLACEHOLDER_COMPONENT_NAME;
269         mFragment.mShortcutPreference = shortcutPreference;
270 
271         mFragment.mShortcutPreference.setChecked(false);
272         mFragment.setupEditShortcutDialog(dialog);
273 
274         final int checkboxValue = mFragment.getShortcutTypeCheckBoxValue();
275         assertThat(checkboxValue).isEqualTo(UserShortcutType.EMPTY);
276     }
277 
278     @Test
setupEditShortcutDialog_shortcutPreferenceOn_checkboxIsSavedValue()279     public void setupEditShortcutDialog_shortcutPreferenceOn_checkboxIsSavedValue() {
280         final AlertDialog dialog = AccessibilityDialogUtils.showEditShortcutDialog(
281                 mContext, DialogType.EDIT_SHORTCUT_GENERIC, PLACEHOLDER_DIALOG_TITLE,
282                 this::callEmptyOnClicked);
283         final ShortcutPreference shortcutPreference = new ShortcutPreference(mContext, /* attrs= */
284                 null);
285         final PreferredShortcut hardwareShortcut = new PreferredShortcut(
286                 PLACEHOLDER_COMPONENT_NAME.flattenToString(), UserShortcutType.HARDWARE);
287         mFragment.mComponentName = PLACEHOLDER_COMPONENT_NAME;
288         mFragment.mShortcutPreference = shortcutPreference;
289 
290         PreferredShortcuts.saveUserShortcutType(mContext, hardwareShortcut);
291         mFragment.mShortcutPreference.setChecked(true);
292         mFragment.setupEditShortcutDialog(dialog);
293 
294         final int checkboxValue = mFragment.getShortcutTypeCheckBoxValue();
295         assertThat(checkboxValue).isEqualTo(UserShortcutType.HARDWARE);
296     }
297 
298     @Test
299     @Config(shadows = ShadowFragment.class)
restoreValueFromSavedInstanceState_assignShortcutTypeToVariable()300     public void restoreValueFromSavedInstanceState_assignShortcutTypeToVariable() {
301         final AlertDialog dialog = AccessibilityDialogUtils.showEditShortcutDialog(
302                 mContext, DialogType.EDIT_SHORTCUT_GENERIC, PLACEHOLDER_DIALOG_TITLE,
303                 this::callEmptyOnClicked);
304         final Bundle savedInstanceState = new Bundle();
305         final ShortcutPreference shortcutPreference = new ShortcutPreference(mContext, /* attrs= */
306                 null);
307         mFragment.mComponentName = PLACEHOLDER_COMPONENT_NAME;
308         mFragment.mShortcutPreference = shortcutPreference;
309 
310         savedInstanceState.putInt(KEY_SAVED_USER_SHORTCUT_TYPE,
311                 UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE);
312         mFragment.onCreate(savedInstanceState);
313         mFragment.setupEditShortcutDialog(dialog);
314         final int value = mFragment.getShortcutTypeCheckBoxValue();
315         mFragment.saveNonEmptyUserShortcutType(value);
316 
317         final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
318                 mFragment.mComponentName.flattenToString());
319         assertThat(expectedType).isEqualTo(UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE);
320     }
321 
322     @Test
323     @Config(shadows = ShadowFragment.class)
onPreferenceToggledOnDisabledService_notShowTooltipView()324     public void onPreferenceToggledOnDisabledService_notShowTooltipView() {
325         mFragment.onPreferenceToggled(
326                 ToggleFeaturePreferenceFragment.KEY_USE_SERVICE_PREFERENCE, /* enabled= */ false);
327 
328         assertThat(getLatestPopupWindow()).isNull();
329     }
330 
331     @Test
332     @DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
333     @Config(shadows = ShadowFragment.class)
onPreferenceToggledOnEnabledService_showTooltipView()334     public void onPreferenceToggledOnEnabledService_showTooltipView() {
335         mFragment.onPreferenceToggled(
336                 ToggleFeaturePreferenceFragment.KEY_USE_SERVICE_PREFERENCE, /* enabled= */ true);
337 
338         assertThat(getLatestPopupWindow().isShowing()).isTrue();
339     }
340 
341     @Test
342     @Config(shadows = ShadowFragment.class)
onPreferenceToggledOnEnabledService_inSuw_toolTipViewShouldNotShow()343     public void onPreferenceToggledOnEnabledService_inSuw_toolTipViewShouldNotShow() {
344         Intent suwIntent = new Intent();
345         suwIntent.putExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, true);
346         when(mActivity.getIntent()).thenReturn(suwIntent);
347 
348         mFragment.onPreferenceToggled(
349                 ToggleFeaturePreferenceFragment.KEY_USE_SERVICE_PREFERENCE, /* enabled= */ true);
350 
351         assertThat(getLatestPopupWindow()).isNull();
352     }
353 
354     @Test
355     @DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
356     @Config(shadows = ShadowFragment.class)
onPreferenceToggledOnEnabledService_tooltipViewShown_notShowTooltipView()357     public void onPreferenceToggledOnEnabledService_tooltipViewShown_notShowTooltipView() {
358         mFragment.onPreferenceToggled(
359                 ToggleFeaturePreferenceFragment.KEY_USE_SERVICE_PREFERENCE, /* enabled= */ true);
360         getLatestPopupWindow().dismiss();
361 
362         mFragment.onPreferenceToggled(
363                 ToggleFeaturePreferenceFragment.KEY_USE_SERVICE_PREFERENCE, /* enabled= */ true);
364 
365         assertThat(getLatestPopupWindow().isShowing()).isFalse();
366     }
367 
368     @Test
initTopIntroPreference_hasTopIntroTitle_shouldSetAsExpectedValue()369     public void initTopIntroPreference_hasTopIntroTitle_shouldSetAsExpectedValue() {
370         mFragment.mTopIntroTitle = DEFAULT_TOP_INTRO;
371         mFragment.initTopIntroPreference();
372 
373         TopIntroPreference topIntroPreference =
374                 (TopIntroPreference) mFragment.getPreferenceScreen().getPreference(/* index= */ 0);
375         assertThat(topIntroPreference.getTitle().toString()).isEqualTo(DEFAULT_TOP_INTRO);
376     }
377 
378     @Test
initTopIntroPreference_topIntroTitleIsNull_shouldNotAdded()379     public void initTopIntroPreference_topIntroTitleIsNull_shouldNotAdded() {
380         mFragment.initTopIntroPreference();
381 
382         assertThat(mFragment.getPreferenceScreen().getPreferenceCount()).isEqualTo(0);
383     }
384 
385     @Test
386     @EnableFlags(Flags.FLAG_ACCESSIBILITY_SHOW_APP_INFO_BUTTON)
createAppInfoPreference_withValidComponentName()387     public void createAppInfoPreference_withValidComponentName() {
388         when(mPackageManager.isPackageAvailable(PLACEHOLDER_PACKAGE_NAME)).thenReturn(true);
389         mFragment.mComponentName = PLACEHOLDER_COMPONENT_NAME;
390 
391         final Preference preference = mFragment.createAppInfoPreference();
392 
393         assertThat(preference).isNotNull();
394         final Intent appInfoIntent = preference.getIntent();
395         assertThat(appInfoIntent.getAction())
396                 .isEqualTo(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
397         assertThat(appInfoIntent.getDataString()).isEqualTo("package:" + PLACEHOLDER_PACKAGE_NAME);
398     }
399 
400     @Test
401     @EnableFlags(Flags.FLAG_ACCESSIBILITY_SHOW_APP_INFO_BUTTON)
createAppInfoPreference_noComponentName_shouldBeNull()402     public void createAppInfoPreference_noComponentName_shouldBeNull() {
403         mFragment.mComponentName = null;
404 
405         final Preference preference = mFragment.createAppInfoPreference();
406 
407         assertThat(preference).isNull();
408     }
409 
410     @Test
411     @EnableFlags(Flags.FLAG_ACCESSIBILITY_SHOW_APP_INFO_BUTTON)
createAppInfoPreference_withUnavailablePackage_shouldBeNull()412     public void createAppInfoPreference_withUnavailablePackage_shouldBeNull() {
413         when(mPackageManager.isPackageAvailable(PLACEHOLDER_PACKAGE_NAME)).thenReturn(false);
414         mFragment.mComponentName = PLACEHOLDER_COMPONENT_NAME;
415 
416         final Preference preference = mFragment.createAppInfoPreference();
417 
418         assertThat(preference).isNull();
419     }
420 
421     @Test
422     @EnableFlags(Flags.FLAG_ACCESSIBILITY_SHOW_APP_INFO_BUTTON)
createAppInfoPreference_inSetupWizard_shouldBeNull()423     public void createAppInfoPreference_inSetupWizard_shouldBeNull() {
424         when(mFragment.isAnySetupWizard()).thenReturn(true);
425         mFragment.mComponentName = PLACEHOLDER_COMPONENT_NAME;
426 
427         final Preference preference = mFragment.createAppInfoPreference();
428 
429         assertThat(preference).isNull();
430     }
431 
432     @Test
createFooterPreference_shouldSetAsExpectedValue()433     public void createFooterPreference_shouldSetAsExpectedValue() {
434         mFragment.createFooterPreference(mFragment.getPreferenceScreen(),
435                 DEFAULT_SUMMARY, DEFAULT_DESCRIPTION);
436 
437         AccessibilityFooterPreference accessibilityFooterPreference =
438                 (AccessibilityFooterPreference) mFragment.getPreferenceScreen().getPreference(
439                         mFragment.getPreferenceScreen().getPreferenceCount() - 1);
440         assertThat(accessibilityFooterPreference.getSummary()).isEqualTo(DEFAULT_SUMMARY);
441         assertThat(accessibilityFooterPreference.isSelectable()).isEqualTo(false);
442         assertThat(accessibilityFooterPreference.getOrder()).isEqualTo(Integer.MAX_VALUE - 1);
443     }
444 
445     @Test
446     @Config(shadows = ShadowFragment.class)
writeConfigDefaultIfNeeded_sameCNWithFragAndConfig_SameValueInVolumeSettingsKey()447     public void writeConfigDefaultIfNeeded_sameCNWithFragAndConfig_SameValueInVolumeSettingsKey() {
448         mFragment.mComponentName = PLACEHOLDER_COMPONENT_NAME;
449         doReturn(PLACEHOLDER_COMPONENT_NAME.flattenToString()).when(mFragment).getString(
450                 com.android.internal.R.string.config_defaultAccessibilityService);
451 
452         mFragment.writeConfigDefaultAccessibilityServiceIntoShortcutTargetServiceIfNeeded(mContext);
453 
454         assertThat(
455                 getSecureStringFromSettings(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE))
456                 .isEqualTo(PLACEHOLDER_COMPONENT_NAME.flattenToString());
457     }
458 
459     @Test
460     @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
461     @Config(shadows = ShadowFragment.class)
showQuickSettingsTooltipIfNeeded_qsFlagOn_dontShowTooltipView()462     public void showQuickSettingsTooltipIfNeeded_qsFlagOn_dontShowTooltipView() {
463         mFragment.showQuickSettingsTooltipIfNeeded(QuickSettingsTooltipType.GUIDE_TO_EDIT);
464 
465         assertThat(getLatestPopupWindow()).isNull();
466     }
467 
468     @Test
469     @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
getShortcutTypeSummary_shortcutSummaryIsCorrectlySet()470     public void getShortcutTypeSummary_shortcutSummaryIsCorrectlySet() {
471         final PreferredShortcut userPreferredShortcut = new PreferredShortcut(
472                 PLACEHOLDER_COMPONENT_NAME.flattenToString(),
473                 UserShortcutType.HARDWARE | UserShortcutType.QUICK_SETTINGS);
474         putUserShortcutTypeIntoSharedPreference(mContext, userPreferredShortcut);
475         final ShortcutPreference shortcutPreference =
476                 new ShortcutPreference(mContext, /* attrs= */ null);
477         shortcutPreference.setChecked(true);
478         shortcutPreference.setSettingsEditable(true);
479         mFragment.mComponentName = PLACEHOLDER_COMPONENT_NAME;
480         mFragment.mShortcutPreference = shortcutPreference;
481         String expected = CaseMap.toTitle().wholeString().noLowercase().apply(Locale.getDefault(),
482                 /* iter= */ null,
483                 mContext.getString(
484                         R.string.accessibility_feature_shortcut_setting_summary_quick_settings)
485                         + ", "
486                         + mContext.getString(R.string.accessibility_shortcut_hardware_keyword));
487 
488         String summary = mFragment.getShortcutTypeSummary(mContext).toString();
489 
490         assertThat(summary).isEqualTo(expected);
491     }
492 
putSecureStringIntoSettings(String key, String componentName)493     private void putSecureStringIntoSettings(String key, String componentName) {
494         Settings.Secure.putString(mContext.getContentResolver(), key, componentName);
495     }
496 
getSecureStringFromSettings(String key)497     private String getSecureStringFromSettings(String key) {
498         return Settings.Secure.getString(mContext.getContentResolver(), key);
499     }
500 
putUserShortcutTypeIntoSharedPreference(Context context, PreferredShortcut shortcut)501     private void putUserShortcutTypeIntoSharedPreference(Context context,
502             PreferredShortcut shortcut) {
503         PreferredShortcuts.saveUserShortcutType(context, shortcut);
504     }
505 
callEmptyOnClicked(DialogInterface dialog, int which)506     private void callEmptyOnClicked(DialogInterface dialog, int which) {}
507 
getLatestPopupWindow()508     private static PopupWindow getLatestPopupWindow() {
509         final ShadowApplication shadowApplication =
510                 Shadow.extract(ApplicationProvider.getApplicationContext());
511         return shadowApplication.getLatestPopupWindow();
512     }
513 
514     public static class TestToggleFeaturePreferenceFragment
515             extends ToggleFeaturePreferenceFragment {
516 
517         @Override
getMetricsCategory()518         public int getMetricsCategory() {
519             return 0;
520         }
521 
522         @Override
getUserShortcutTypes()523         int getUserShortcutTypes() {
524             return 0;
525         }
526 
527         @Override
getTileComponentName()528         ComponentName getTileComponentName() {
529             return PLACEHOLDER_TILE_COMPONENT_NAME;
530         }
531 
532         @Override
getTileTooltipContent(@uickSettingsTooltipType int type)533         protected CharSequence getTileTooltipContent(@QuickSettingsTooltipType int type) {
534             return PLACEHOLDER_TILE_TOOLTIP_CONTENT;
535         }
536 
537         @Override
getPreferenceScreenResId()538         public int getPreferenceScreenResId() {
539             return R.xml.placeholder_prefs;
540         }
541 
542         @Override
getLogTag()543         protected String getLogTag() {
544             return null;
545         }
546 
547         @Override
onProcessArguments(Bundle arguments)548         protected void onProcessArguments(Bundle arguments) {
549             // do nothing
550         }
551 
552         @Override
onCreatePreferences(Bundle savedInstanceState, String rootKey)553         public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
554             // do nothing
555         }
556 
557         @Override
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)558         public View onCreateView(LayoutInflater inflater, ViewGroup container,
559                 Bundle savedInstanceState) {
560             return mock(View.class);
561         }
562 
563         @Override
onViewCreated(View view, Bundle savedInstanceState)564         public void onViewCreated(View view, Bundle savedInstanceState) {
565             // do nothing
566         }
567 
568         @SuppressWarnings("MissingSuperCall")
569         @Override
onDestroyView()570         public void onDestroyView() {
571             // do nothing
572         }
573 
574         @Override
updateShortcutPreference()575         protected void updateShortcutPreference() {
576             // UI related function, do nothing in tests
577         }
578 
579         @Override
getView()580         public View getView() {
581             return mock(View.class);
582         }
583     }
584 }
585