1 /* 2 * Copyright (C) 2021 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 android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON; 20 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL; 21 22 import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE; 23 24 import static com.google.common.truth.Truth.assertThat; 25 26 import static org.mockito.Mockito.spy; 27 import static org.mockito.Mockito.when; 28 29 import android.app.settings.SettingsEnums; 30 import android.content.Context; 31 import android.content.res.Resources; 32 import android.os.Bundle; 33 import android.platform.test.annotations.DisableFlags; 34 import android.platform.test.annotations.EnableFlags; 35 import android.platform.test.flag.junit.SetFlagsRule; 36 import android.provider.Flags; 37 import android.provider.Settings; 38 39 import androidx.fragment.app.FragmentActivity; 40 import androidx.preference.PreferenceManager; 41 import androidx.preference.PreferenceScreen; 42 import androidx.test.core.app.ApplicationProvider; 43 44 import com.android.internal.accessibility.util.ShortcutUtils; 45 import com.android.settings.R; 46 import com.android.settings.testutils.XmlTestUtils; 47 import com.android.settings.testutils.shadow.ShadowFragment; 48 49 import org.junit.Before; 50 import org.junit.Rule; 51 import org.junit.Test; 52 import org.junit.runner.RunWith; 53 import org.mockito.Spy; 54 import org.mockito.junit.MockitoJUnit; 55 import org.mockito.junit.MockitoRule; 56 import org.robolectric.Robolectric; 57 import org.robolectric.RobolectricTestRunner; 58 import org.robolectric.annotation.Config; 59 60 import java.util.List; 61 62 /** Tests for {@link AccessibilityButtonFragment}. */ 63 @Config(shadows = ShadowFragment.class) 64 @RunWith(RobolectricTestRunner.class) 65 public class AccessibilityButtonFragmentTest { 66 67 @Rule 68 public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); 69 @Rule 70 public MockitoRule mMockitoRule = MockitoJUnit.rule(); 71 @Spy 72 private final Context mContext = ApplicationProvider.getApplicationContext(); 73 @Spy 74 private Resources mResources = spy(mContext.getResources()); 75 private AccessibilityButtonFragment mFragment; 76 77 @Before setUp()78 public void setUp() { 79 mFragment = spy(new TestAccessibilityButtonFragment(mContext)); 80 when(mContext.getResources()).thenReturn(mResources); 81 when(mFragment.getResources()).thenReturn(mResources); 82 when(mFragment.getActivity()).thenReturn(Robolectric.setupActivity(FragmentActivity.class)); 83 } 84 85 @Test getMetricsCategory_returnsCorrectCategory()86 public void getMetricsCategory_returnsCorrectCategory() { 87 assertThat(mFragment.getMetricsCategory()).isEqualTo( 88 SettingsEnums.ACCESSIBILITY_BUTTON_SETTINGS); 89 } 90 91 @Test getLogTag_returnsCorrectTag()92 public void getLogTag_returnsCorrectTag() { 93 assertThat(mFragment.getLogTag()).isEqualTo("AccessibilityButtonFragment"); 94 } 95 96 @Test 97 @DisableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED) onCreate_navigationGestureEnabled_setCorrectTitle()98 public void onCreate_navigationGestureEnabled_setCorrectTitle() { 99 Settings.Secure.putIntForUser( 100 mContext.getContentResolver(), Settings.Secure.NAVIGATION_MODE, 101 NAV_BAR_MODE_GESTURAL, mContext.getUserId()); 102 103 mFragment.onAttach(mContext); 104 mFragment.onCreate(Bundle.EMPTY); 105 106 assertThat(mFragment.getActivity().getTitle().toString()).isEqualTo( 107 mContext.getString(R.string.accessibility_button_gesture_title)); 108 } 109 110 @Test 111 @EnableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED) onCreate_navigationGestureEnabled_flag_setCorrectTitle()112 public void onCreate_navigationGestureEnabled_flag_setCorrectTitle() { 113 Settings.Secure.putIntForUser( 114 mContext.getContentResolver(), Settings.Secure.NAVIGATION_MODE, 115 NAV_BAR_MODE_GESTURAL, mContext.getUserId()); 116 117 mFragment.onAttach(mContext); 118 mFragment.onCreate(Bundle.EMPTY); 119 120 assertThat(mFragment.getActivity().getTitle().toString()).isEqualTo( 121 mContext.getString(R.string.accessibility_button_title)); 122 } 123 124 @Test onCreate_navigationBarEnabled_setCorrectTitle()125 public void onCreate_navigationBarEnabled_setCorrectTitle() { 126 Settings.Secure.putIntForUser( 127 mContext.getContentResolver(), Settings.Secure.NAVIGATION_MODE, 128 NAV_BAR_MODE_2BUTTON, mContext.getUserId()); 129 130 mFragment.onAttach(mContext); 131 mFragment.onCreate(Bundle.EMPTY); 132 133 assertThat(mFragment.getActivity().getTitle().toString()).isEqualTo( 134 mContext.getString(R.string.accessibility_button_title)); 135 } 136 137 @Test 138 @DisableFlags(com.android.settings.accessibility.Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH) getNonIndexableKeys_existInXmlLayout()139 public void getNonIndexableKeys_existInXmlLayout() { 140 final List<String> niks = AccessibilityButtonFragment.SEARCH_INDEX_DATA_PROVIDER 141 .getNonIndexableKeys(mContext); 142 final List<String> keys = 143 XmlTestUtils.getKeysFromPreferenceXml(mContext, 144 R.xml.accessibility_button_settings); 145 146 assertThat(keys).isNotNull(); 147 assertThat(niks).containsAtLeastElementsIn(keys); 148 } 149 150 @Test 151 @EnableFlags(com.android.settings.accessibility.Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH) getNonIndexableKeys_noTargets_doesNotExistInXmlLayout()152 public void getNonIndexableKeys_noTargets_doesNotExistInXmlLayout() { 153 Settings.Secure.putStringForUser(mContext.getContentResolver(), 154 ShortcutUtils.convertToKey(SOFTWARE), "", mContext.getUserId()); 155 final List<String> niks = AccessibilityButtonFragment.SEARCH_INDEX_DATA_PROVIDER 156 .getNonIndexableKeys(mContext); 157 final List<String> keys = 158 XmlTestUtils.getKeysFromPreferenceXml(mContext, 159 R.xml.accessibility_button_settings); 160 161 assertThat(keys).isNotNull(); 162 assertThat(niks).containsAtLeastElementsIn(keys); 163 } 164 165 @Test 166 @EnableFlags(com.android.settings.accessibility.Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH) getNonIndexableKeys_hasTargets_expectedKeys()167 public void getNonIndexableKeys_hasTargets_expectedKeys() { 168 Settings.Secure.putStringForUser(mContext.getContentResolver(), 169 ShortcutUtils.convertToKey(SOFTWARE), "Foo", mContext.getUserId()); 170 final List<String> niks = AccessibilityButtonFragment.SEARCH_INDEX_DATA_PROVIDER 171 .getNonIndexableKeys(mContext); 172 173 // Some keys should show up anyway, as they're flagged as unsearchable in the xml. 174 assertThat(niks).containsAtLeast( 175 "accessibility_button_preview", 176 "accessibility_button_footer", 177 "accessibility_button_or_gesture"); 178 } 179 180 private static class TestAccessibilityButtonFragment extends AccessibilityButtonFragment { 181 182 private final Context mContext; 183 private final PreferenceManager mPreferenceManager; 184 TestAccessibilityButtonFragment(Context context)185 TestAccessibilityButtonFragment(Context context) { 186 super(); 187 mContext = context; 188 mPreferenceManager = new PreferenceManager(context); 189 mPreferenceManager.setPreferences(mPreferenceManager.createPreferenceScreen(context)); 190 } 191 192 @Override getPreferenceScreenResId()193 public int getPreferenceScreenResId() { 194 return R.xml.placeholder_prefs; 195 } 196 197 @Override getPreferenceScreen()198 public PreferenceScreen getPreferenceScreen() { 199 return mPreferenceManager.getPreferenceScreen(); 200 } 201 202 @Override getPreferenceManager()203 public PreferenceManager getPreferenceManager() { 204 return mPreferenceManager; 205 } 206 207 @Override getContext()208 public Context getContext() { 209 return mContext; 210 } 211 } 212 } 213