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 org.mockito.ArgumentMatchers.any; 20 import static org.mockito.Mockito.doReturn; 21 import static org.mockito.Mockito.spy; 22 import static org.mockito.Mockito.verify; 23 24 import android.accessibilityservice.AccessibilityServiceInfo; 25 import android.content.ComponentName; 26 import android.content.Context; 27 import android.content.Intent; 28 import android.content.pm.ApplicationInfo; 29 import android.content.pm.ResolveInfo; 30 import android.content.pm.ServiceInfo; 31 import android.os.Bundle; 32 import android.view.accessibility.AccessibilityManager; 33 34 import androidx.fragment.app.FragmentActivity; 35 import org.junit.Before; 36 import org.junit.Test; 37 import org.junit.runner.RunWith; 38 import org.mockito.Mock; 39 import org.mockito.MockitoAnnotations; 40 import org.robolectric.RobolectricTestRunner; 41 import org.robolectric.RuntimeEnvironment; 42 import org.robolectric.shadow.api.Shadow; 43 import org.robolectric.shadows.ShadowAccessibilityManager; 44 import org.xmlpull.v1.XmlPullParserException; 45 46 import java.io.IOException; 47 import java.util.ArrayList; 48 import java.util.List; 49 50 @RunWith(RobolectricTestRunner.class) 51 public class AccessibilityDetailsSettingsFragmentTest { 52 private final static String PACKAGE_NAME = "com.foo.bar"; 53 private final static String CLASS_NAME = PACKAGE_NAME + ".fake_a11y_service"; 54 private final static String COMPONENT_NAME = PACKAGE_NAME + "/" + CLASS_NAME; 55 56 private Context mContext; 57 private AccessibilityDetailsSettingsFragment mFragment; 58 private ShadowAccessibilityManager mShadowAccessibilityManager; 59 @Mock private FragmentActivity mActivity; 60 61 @Before setUp()62 public void setUp() { 63 MockitoAnnotations.initMocks(this); 64 mContext = spy(RuntimeEnvironment.application); 65 mFragment = spy(new AccessibilityDetailsSettingsFragment()); 66 mShadowAccessibilityManager = Shadow.extract(AccessibilityManager.getInstance(mContext)); 67 mShadowAccessibilityManager.setInstalledAccessibilityServiceList(getMockServiceList()); 68 69 doReturn(mActivity).when(mFragment).getActivity(); 70 doReturn(mContext).when(mFragment).getContext(); 71 } 72 73 @Test onCreate_hasValidExtraComponentName_shouldOpenAccessibilityDetailsSettings()74 public void onCreate_hasValidExtraComponentName_shouldOpenAccessibilityDetailsSettings() { 75 final Intent intent = new Intent(); 76 intent.putExtra(Intent.EXTRA_COMPONENT_NAME, COMPONENT_NAME); 77 doReturn(intent).when(mActivity).getIntent(); 78 79 mFragment.onCreate(Bundle.EMPTY); 80 81 verify(mFragment).openAccessibilityDetailsSettingsAndFinish(any()); 82 } 83 84 @Test onCreate_hasInvalidExtraComponentName_shouldOpenAccessibilityServicesList()85 public void onCreate_hasInvalidExtraComponentName_shouldOpenAccessibilityServicesList() { 86 final Intent intent = new Intent(); 87 intent.putExtra(Intent.EXTRA_COMPONENT_NAME, PACKAGE_NAME + "/.service"); 88 doReturn(intent).when(mActivity).getIntent(); 89 90 mFragment.onCreate(Bundle.EMPTY); 91 92 verify(mFragment).openAccessibilitySettingsAndFinish(); 93 } 94 95 @Test onCreate_hasNoExtraComponentName_shouldOpenAccessibilityServicesList()96 public void onCreate_hasNoExtraComponentName_shouldOpenAccessibilityServicesList() { 97 final Intent intent = new Intent(); 98 doReturn(intent).when(mActivity).getIntent(); 99 100 mFragment.onCreate(Bundle.EMPTY); 101 102 verify(mFragment).openAccessibilitySettingsAndFinish(); 103 } 104 105 @Test onCreate_extraComponentNameIsDisallowed_shouldOpenAccessibilityServicesList()106 public void onCreate_extraComponentNameIsDisallowed_shouldOpenAccessibilityServicesList() { 107 final Intent intent = new Intent(); 108 intent.putExtra(Intent.EXTRA_COMPONENT_NAME, COMPONENT_NAME); 109 doReturn(intent).when(mActivity).getIntent(); 110 doReturn(false).when(mFragment).isServiceAllowed(any()); 111 112 mFragment.onCreate(Bundle.EMPTY); 113 114 verify(mFragment).openAccessibilitySettingsAndFinish(); 115 } 116 getMockAccessibilityServiceInfo()117 private AccessibilityServiceInfo getMockAccessibilityServiceInfo() { 118 final ApplicationInfo applicationInfo = new ApplicationInfo(); 119 final ServiceInfo serviceInfo = new ServiceInfo(); 120 applicationInfo.packageName = PACKAGE_NAME; 121 serviceInfo.packageName = PACKAGE_NAME; 122 serviceInfo.name = CLASS_NAME; 123 serviceInfo.applicationInfo = applicationInfo; 124 125 final ResolveInfo resolveInfo = new ResolveInfo(); 126 resolveInfo.serviceInfo = serviceInfo; 127 128 try { 129 final AccessibilityServiceInfo info = new AccessibilityServiceInfo(resolveInfo, 130 mContext); 131 ComponentName componentName = ComponentName.unflattenFromString(COMPONENT_NAME); 132 info.setComponentName(componentName); 133 return info; 134 } catch (XmlPullParserException | IOException e) { 135 // Do nothing 136 } 137 138 return null; 139 } 140 getMockServiceList()141 private List<AccessibilityServiceInfo> getMockServiceList() { 142 final List<AccessibilityServiceInfo> infoList = new ArrayList<>(); 143 infoList.add(getMockAccessibilityServiceInfo()); 144 return infoList; 145 } 146 } 147