1 /* 2 * Copyright (C) 2022 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.AccessibilitySettingsForSetupWizard.SCREEN_READER_PACKAGE_NAME; 20 import static com.android.settings.accessibility.AccessibilitySettingsForSetupWizard.SCREEN_READER_SERVICE_NAME; 21 import static com.android.settings.accessibility.AccessibilitySettingsForSetupWizard.SELECT_TO_SPEAK_PACKAGE_NAME; 22 import static com.android.settings.accessibility.AccessibilitySettingsForSetupWizard.SELECT_TO_SPEAK_SERVICE_NAME; 23 24 import static com.google.common.truth.Truth.assertThat; 25 26 import static org.mockito.ArgumentMatchers.any; 27 import static org.mockito.Mockito.doReturn; 28 import static org.mockito.Mockito.mock; 29 import static org.mockito.Mockito.spy; 30 import static org.mockito.Mockito.verify; 31 import static org.mockito.Mockito.when; 32 33 import android.accessibilityservice.AccessibilityServiceInfo; 34 import android.content.ComponentName; 35 import android.content.Context; 36 import android.content.pm.ResolveInfo; 37 import android.content.pm.ServiceInfo; 38 import android.view.accessibility.AccessibilityManager; 39 40 import androidx.fragment.app.FragmentActivity; 41 import androidx.lifecycle.LifecycleOwner; 42 import androidx.preference.Preference; 43 import androidx.preference.PreferenceManager; 44 import androidx.preference.PreferenceScreen; 45 import androidx.test.core.app.ApplicationProvider; 46 47 import com.android.settings.R; 48 import com.android.settingslib.RestrictedPreference; 49 50 import com.google.android.setupcompat.template.FooterBarMixin; 51 import com.google.android.setupdesign.GlifPreferenceLayout; 52 53 import org.junit.Before; 54 import org.junit.Rule; 55 import org.junit.Test; 56 import org.junit.runner.RunWith; 57 import org.mockito.Mock; 58 import org.mockito.junit.MockitoJUnit; 59 import org.mockito.junit.MockitoRule; 60 import org.robolectric.RobolectricTestRunner; 61 62 import java.util.ArrayList; 63 import java.util.List; 64 65 /** 66 * Tests for {@link AccessibilitySettingsForSetupWizard}. 67 */ 68 @RunWith(RobolectricTestRunner.class) 69 public class AccessibilitySettingsForSetupWizardTest { 70 71 private static final ComponentName TEST_SCREEN_READER_COMPONENT_NAME = new ComponentName( 72 SCREEN_READER_PACKAGE_NAME, SCREEN_READER_SERVICE_NAME); 73 private static final ComponentName TEST_SELECT_TO_SPEAK_COMPONENT_NAME = new ComponentName( 74 SELECT_TO_SPEAK_PACKAGE_NAME, SELECT_TO_SPEAK_SERVICE_NAME); 75 private final Context mContext = ApplicationProvider.getApplicationContext(); 76 private final List<AccessibilityServiceInfo> mAccessibilityServices = new ArrayList<>(); 77 @Rule 78 public MockitoRule mMockitoRule = MockitoJUnit.rule(); 79 @Mock 80 private AccessibilityManager mAccessibilityManager; 81 @Mock 82 private FragmentActivity mActivity; 83 @Mock 84 private GlifPreferenceLayout mGlifLayoutView; 85 @Mock 86 private FooterBarMixin mFooterBarMixin; 87 private AccessibilitySettingsForSetupWizard mFragment; 88 89 @Before setUp()90 public void setUp() { 91 mFragment = spy(new TestAccessibilitySettingsForSetupWizard(mContext)); 92 doReturn(mAccessibilityManager).when(mActivity).getSystemService( 93 AccessibilityManager.class); 94 when(mAccessibilityManager.getInstalledAccessibilityServiceList()).thenReturn( 95 mAccessibilityServices); 96 doReturn(mActivity).when(mFragment).getActivity(); 97 doReturn(mock(LifecycleOwner.class)).when(mFragment).getViewLifecycleOwner(); 98 doReturn(mFooterBarMixin).when(mGlifLayoutView).getMixin(FooterBarMixin.class); 99 } 100 101 @Test onViewCreated_verifyAction()102 public void onViewCreated_verifyAction() { 103 mFragment.onViewCreated(mGlifLayoutView, null); 104 105 verify(mGlifLayoutView).setHeaderText( 106 mContext.getString(R.string.vision_settings_title)); 107 verify(mGlifLayoutView).setDescriptionText( 108 mContext.getString(R.string.vision_settings_description)); 109 verify(mFooterBarMixin).setPrimaryButton(any()); 110 } 111 112 @Test onResume_accessibilityServiceListInstalled_returnExpectedValue()113 public void onResume_accessibilityServiceListInstalled_returnExpectedValue() { 114 addEnabledServiceInfo(TEST_SCREEN_READER_COMPONENT_NAME, true); 115 addEnabledServiceInfo(TEST_SELECT_TO_SPEAK_COMPONENT_NAME, true); 116 mFragment.onAttach(mContext); 117 mFragment.onViewCreated(mGlifLayoutView, null); 118 119 mFragment.onResume(); 120 121 assertRestrictedPreferenceMatch(mFragment.mScreenReaderPreference, 122 TEST_SCREEN_READER_COMPONENT_NAME.getPackageName(), 123 TEST_SCREEN_READER_COMPONENT_NAME.flattenToString()); 124 assertRestrictedPreferenceMatch(mFragment.mSelectToSpeakPreference, 125 TEST_SELECT_TO_SPEAK_COMPONENT_NAME.getPackageName(), 126 TEST_SELECT_TO_SPEAK_COMPONENT_NAME.flattenToString()); 127 } 128 129 @Test onResume_accessibilityServiceListNotInstalled_returnNull()130 public void onResume_accessibilityServiceListNotInstalled_returnNull() { 131 mFragment.onAttach(mContext); 132 mFragment.onViewCreated(mGlifLayoutView, null); 133 134 mFragment.onResume(); 135 136 assertThat(mFragment.mScreenReaderPreference.getKey()).isNull(); 137 assertThat(mFragment.mSelectToSpeakPreference.getKey()).isNull(); 138 } 139 addEnabledServiceInfo(ComponentName componentName, boolean isAccessibilityTool)140 private void addEnabledServiceInfo(ComponentName componentName, boolean isAccessibilityTool) { 141 final AccessibilityServiceInfo a11yServiceInfo = mock(AccessibilityServiceInfo.class); 142 when(a11yServiceInfo.getComponentName()).thenReturn(componentName); 143 when(a11yServiceInfo.isAccessibilityTool()).thenReturn(isAccessibilityTool); 144 final ResolveInfo resolveInfo = mock(ResolveInfo.class); 145 when(a11yServiceInfo.getResolveInfo()).thenReturn(resolveInfo); 146 resolveInfo.serviceInfo = mock(ServiceInfo.class); 147 resolveInfo.serviceInfo.packageName = componentName.getPackageName(); 148 resolveInfo.serviceInfo.name = componentName.getClassName(); 149 when(resolveInfo.loadLabel(mActivity.getPackageManager())).thenReturn( 150 componentName.getPackageName()); 151 mAccessibilityServices.add(a11yServiceInfo); 152 } 153 assertRestrictedPreferenceMatch(RestrictedPreference preference, String title, String key)154 private void assertRestrictedPreferenceMatch(RestrictedPreference preference, String title, 155 String key) { 156 assertThat(preference.getTitle().toString()).isEqualTo(title); 157 assertThat(preference.getKey()).isEqualTo(key); 158 assertThat(preference.getExtras().getString(AccessibilitySettings.EXTRA_TITLE)) 159 .isEqualTo(title); 160 assertThat(preference.getExtras().getString(AccessibilitySettings.EXTRA_PREFERENCE_KEY)) 161 .isEqualTo(key); 162 } 163 164 private static class TestAccessibilitySettingsForSetupWizard 165 extends AccessibilitySettingsForSetupWizard { 166 167 private final Context mContext; 168 private final PreferenceManager mPreferenceManager; 169 TestAccessibilitySettingsForSetupWizard(Context context)170 TestAccessibilitySettingsForSetupWizard(Context context) { 171 super(); 172 mContext = context; 173 mPreferenceManager = new PreferenceManager(context); 174 mPreferenceManager.setPreferences(mPreferenceManager.createPreferenceScreen(context)); 175 mDisplayMagnificationPreference = new Preference(context); 176 mScreenReaderPreference = new RestrictedPreference(context); 177 mSelectToSpeakPreference = new RestrictedPreference(context); 178 } 179 180 @Override getPreferenceScreenResId()181 public int getPreferenceScreenResId() { 182 return R.xml.placeholder_prefs; 183 } 184 185 @Override getPreferenceScreen()186 public PreferenceScreen getPreferenceScreen() { 187 return mPreferenceManager.getPreferenceScreen(); 188 } 189 190 @Override getPreferenceManager()191 public PreferenceManager getPreferenceManager() { 192 return mPreferenceManager; 193 } 194 195 @Override getContext()196 public Context getContext() { 197 return mContext; 198 } 199 } 200 } 201