1 /* 2 * Copyright (C) 2019 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.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_BUTTON_COMPONENT_NAME; 20 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME; 21 22 import static com.google.common.truth.Truth.assertThat; 23 24 import static org.mockito.ArgumentMatchers.any; 25 import static org.mockito.Mockito.doReturn; 26 import static org.mockito.Mockito.spy; 27 import static org.mockito.Mockito.verify; 28 29 import android.accessibilityservice.AccessibilityServiceInfo; 30 import android.content.ComponentName; 31 import android.content.Context; 32 import android.content.Intent; 33 import android.content.pm.ApplicationInfo; 34 import android.content.pm.ResolveInfo; 35 import android.content.pm.ServiceInfo; 36 import android.os.Bundle; 37 import android.view.accessibility.AccessibilityManager; 38 39 import androidx.fragment.app.FragmentActivity; 40 41 import com.android.settings.SettingsActivity; 42 import com.android.settings.testutils.shadow.ShadowFragment; 43 44 import org.junit.Before; 45 import org.junit.Test; 46 import org.junit.runner.RunWith; 47 import org.mockito.ArgumentCaptor; 48 import org.mockito.Captor; 49 import org.mockito.Mock; 50 import org.mockito.MockitoAnnotations; 51 import org.robolectric.RobolectricTestRunner; 52 import org.robolectric.RuntimeEnvironment; 53 import org.robolectric.annotation.Config; 54 import org.robolectric.shadow.api.Shadow; 55 import org.robolectric.shadows.ShadowAccessibilityManager; 56 import org.xmlpull.v1.XmlPullParserException; 57 58 import java.io.IOException; 59 import java.util.ArrayList; 60 import java.util.List; 61 62 @Config(shadows = ShadowFragment.class) 63 @RunWith(RobolectricTestRunner.class) 64 public class AccessibilityDetailsSettingsFragmentTest { 65 private final static String PACKAGE_NAME = "com.foo.bar"; 66 private final static String CLASS_NAME = PACKAGE_NAME + ".fake_a11y_service"; 67 private final static String COMPONENT_NAME = PACKAGE_NAME + "/" + CLASS_NAME; 68 69 private Context mContext; 70 private AccessibilityDetailsSettingsFragment mFragment; 71 private ShadowAccessibilityManager mShadowAccessibilityManager; 72 @Captor 73 private ArgumentCaptor<Intent> mIntentArgumentCaptor; 74 @Mock private FragmentActivity mActivity; 75 76 @Before setUp()77 public void setUp() { 78 MockitoAnnotations.initMocks(this); 79 mContext = spy(RuntimeEnvironment.application); 80 mFragment = spy(new AccessibilityDetailsSettingsFragment()); 81 mShadowAccessibilityManager = Shadow.extract(AccessibilityManager.getInstance(mContext)); 82 mShadowAccessibilityManager.setInstalledAccessibilityServiceList(getMockServiceList()); 83 84 doReturn(mActivity).when(mFragment).getActivity(); 85 doReturn(mContext).when(mFragment).getContext(); 86 } 87 88 @Test onCreate_afterSuccessfullyLaunch_shouldBeFinished()89 public void onCreate_afterSuccessfullyLaunch_shouldBeFinished() { 90 final Intent intent = new Intent(); 91 intent.putExtra(Intent.EXTRA_COMPONENT_NAME, COMPONENT_NAME); 92 doReturn(intent).when(mActivity).getIntent(); 93 94 mFragment.onCreate(Bundle.EMPTY); 95 96 verify(mActivity).finish(); 97 } 98 99 @Test onCreate_hasValidExtraComponentName_launchExpectedFragment()100 public void onCreate_hasValidExtraComponentName_launchExpectedFragment() { 101 final Intent intent = new Intent(); 102 intent.putExtra(Intent.EXTRA_COMPONENT_NAME, COMPONENT_NAME); 103 doReturn(intent).when(mActivity).getIntent(); 104 105 mFragment.onCreate(Bundle.EMPTY); 106 107 assertStartActivityWithExpectedFragment(mActivity, 108 ToggleAccessibilityServicePreferenceFragment.class.getName()); 109 } 110 111 @Test onCreate_hasInvalidExtraComponentName_launchAccessibilitySettings()112 public void onCreate_hasInvalidExtraComponentName_launchAccessibilitySettings() { 113 final Intent intent = new Intent(); 114 intent.putExtra(Intent.EXTRA_COMPONENT_NAME, PACKAGE_NAME + "/.service"); 115 doReturn(intent).when(mActivity).getIntent(); 116 117 mFragment.onCreate(Bundle.EMPTY); 118 119 assertStartActivityWithExpectedFragment(mActivity, AccessibilitySettings.class.getName()); 120 } 121 122 @Test onCreate_hasNoExtraComponentName_launchAccessibilitySettings()123 public void onCreate_hasNoExtraComponentName_launchAccessibilitySettings() { 124 final Intent intent = new Intent(); 125 doReturn(intent).when(mActivity).getIntent(); 126 127 mFragment.onCreate(Bundle.EMPTY); 128 129 assertStartActivityWithExpectedFragment(mActivity, AccessibilitySettings.class.getName()); 130 } 131 132 @Test onCreate_extraComponentNameIsDisallowed_launchAccessibilitySettings()133 public void onCreate_extraComponentNameIsDisallowed_launchAccessibilitySettings() { 134 final Intent intent = new Intent(); 135 intent.putExtra(Intent.EXTRA_COMPONENT_NAME, COMPONENT_NAME); 136 doReturn(intent).when(mActivity).getIntent(); 137 doReturn(false).when(mFragment).isServiceAllowed(any()); 138 139 mFragment.onCreate(Bundle.EMPTY); 140 141 assertStartActivityWithExpectedFragment(mActivity, AccessibilitySettings.class.getName()); 142 } 143 144 @Test onCreate_magnificationComponentName_launchMagnificationFragment()145 public void onCreate_magnificationComponentName_launchMagnificationFragment() { 146 final Intent intent = new Intent(); 147 intent.putExtra(Intent.EXTRA_COMPONENT_NAME, 148 MAGNIFICATION_COMPONENT_NAME.flattenToString()); 149 doReturn(intent).when(mActivity).getIntent(); 150 151 mFragment.onCreate(Bundle.EMPTY); 152 153 154 assertStartActivityWithExpectedFragment(mActivity, 155 ToggleScreenMagnificationPreferenceFragment.class.getName()); 156 } 157 158 @Test onCreate_accessibilityButton_launchAccessibilityButtonFragment()159 public void onCreate_accessibilityButton_launchAccessibilityButtonFragment() { 160 final Intent intent = new Intent(); 161 intent.putExtra(Intent.EXTRA_COMPONENT_NAME, 162 ACCESSIBILITY_BUTTON_COMPONENT_NAME.flattenToString()); 163 doReturn(intent).when(mActivity).getIntent(); 164 165 mFragment.onCreate(Bundle.EMPTY); 166 167 assertStartActivityWithExpectedFragment(mActivity, 168 AccessibilityButtonFragment.class.getName()); 169 } 170 getMockAccessibilityServiceInfo()171 private AccessibilityServiceInfo getMockAccessibilityServiceInfo() { 172 final ApplicationInfo applicationInfo = new ApplicationInfo(); 173 final ServiceInfo serviceInfo = new ServiceInfo(); 174 applicationInfo.packageName = PACKAGE_NAME; 175 serviceInfo.packageName = PACKAGE_NAME; 176 serviceInfo.name = CLASS_NAME; 177 serviceInfo.applicationInfo = applicationInfo; 178 179 final ResolveInfo resolveInfo = new ResolveInfo(); 180 resolveInfo.serviceInfo = serviceInfo; 181 182 try { 183 final AccessibilityServiceInfo info = new AccessibilityServiceInfo(resolveInfo, 184 mContext); 185 ComponentName componentName = ComponentName.unflattenFromString(COMPONENT_NAME); 186 info.setComponentName(componentName); 187 return info; 188 } catch (XmlPullParserException | IOException e) { 189 // Do nothing 190 } 191 192 return null; 193 } 194 getMockServiceList()195 private List<AccessibilityServiceInfo> getMockServiceList() { 196 final List<AccessibilityServiceInfo> infoList = new ArrayList<>(); 197 infoList.add(getMockAccessibilityServiceInfo()); 198 return infoList; 199 } 200 assertStartActivityWithExpectedFragment(Context mockContext, String fragmentName)201 private void assertStartActivityWithExpectedFragment(Context mockContext, String fragmentName) { 202 verify(mockContext).startActivity(mIntentArgumentCaptor.capture()); 203 assertThat(mIntentArgumentCaptor.getValue() 204 .getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT)) 205 .isEqualTo(fragmentName); 206 } 207 } 208