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.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.ArgumentMatchers.any; 22 import static org.mockito.Mockito.when; 23 24 import static java.util.Collections.singletonList; 25 26 import android.accessibilityservice.AccessibilityServiceInfo; 27 import android.accessibilityservice.AccessibilityShortcutInfo; 28 import android.content.ComponentName; 29 import android.content.Context; 30 import android.content.pm.ActivityInfo; 31 import android.content.pm.ApplicationInfo; 32 import android.content.pm.ResolveInfo; 33 import android.content.pm.ServiceInfo; 34 import android.platform.test.annotations.EnableFlags; 35 import android.platform.test.flag.junit.SetFlagsRule; 36 37 import androidx.test.core.app.ApplicationProvider; 38 39 import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal; 40 import com.android.settingslib.RestrictedPreference; 41 42 import org.junit.Rule; 43 import org.junit.Test; 44 import org.junit.runner.RunWith; 45 import org.mockito.Mock; 46 import org.mockito.Mockito; 47 import org.mockito.Spy; 48 import org.mockito.junit.MockitoJUnit; 49 import org.mockito.junit.MockitoRule; 50 import org.robolectric.RobolectricTestRunner; 51 import org.robolectric.annotation.Config; 52 import org.xmlpull.v1.XmlPullParserException; 53 54 import java.io.IOException; 55 import java.util.ArrayList; 56 import java.util.List; 57 58 /** Test for {@link RestrictedPreferenceHelper}. */ 59 @RunWith(RobolectricTestRunner.class) 60 @Config(shadows = { 61 ShadowRestrictedLockUtilsInternal.class 62 }) 63 public class RestrictedPreferenceHelperTest { 64 65 private static final String PACKAGE_NAME = "com.android.test"; 66 private static final String CLASS_NAME = PACKAGE_NAME + ".test_a11y_service"; 67 private static final ComponentName COMPONENT_NAME = new ComponentName(PACKAGE_NAME, CLASS_NAME); 68 private static final String DEFAULT_SUMMARY = "default summary"; 69 private static final String DEFAULT_DESCRIPTION = "default description"; 70 private static final String DEFAULT_LABEL = "default label"; 71 72 @Rule 73 public final MockitoRule mocks = MockitoJUnit.rule(); 74 private final Context mContext = ApplicationProvider.getApplicationContext(); 75 @Spy 76 private final AccessibilityServiceInfo mServiceInfo = getMockAccessibilityServiceInfo( 77 PACKAGE_NAME, CLASS_NAME); 78 @Mock 79 private AccessibilityShortcutInfo mShortcutInfo; 80 private final RestrictedPreferenceHelper mHelper = new RestrictedPreferenceHelper(mContext); 81 82 @Rule 83 public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); 84 85 @Test createAccessibilityServicePreferenceList_hasOneInfo_containsSameKey()86 public void createAccessibilityServicePreferenceList_hasOneInfo_containsSameKey() { 87 final String key = COMPONENT_NAME.flattenToString(); 88 final List<AccessibilityServiceInfo> infoList = new ArrayList<>( 89 singletonList(mServiceInfo)); 90 91 final List<RestrictedPreference> preferenceList = 92 mHelper.createAccessibilityServicePreferenceList(infoList); 93 final RestrictedPreference preference = preferenceList.get(0); 94 95 assertThat(preference.getKey()).isEqualTo(key); 96 } 97 98 @Test 99 @EnableFlags(value = {android.security.Flags.FLAG_EXTEND_ECM_TO_ALL_SETTINGS, 100 android.permission.flags.Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED}) createAccessibilityServicePreferenceList_ecmRestricted_prefIsEcmRestricted()101 public void createAccessibilityServicePreferenceList_ecmRestricted_prefIsEcmRestricted() { 102 ShadowRestrictedLockUtilsInternal.setEcmRestrictedPkgs( 103 mServiceInfo.getResolveInfo().serviceInfo.packageName); 104 final List<AccessibilityServiceInfo> infoList = new ArrayList<>( 105 singletonList(mServiceInfo)); 106 107 final List<RestrictedPreference> preferenceList = 108 mHelper.createAccessibilityServicePreferenceList(infoList); 109 final RestrictedPreference preference = preferenceList.get(0); 110 111 assertThat(preference.isDisabledByEcm()).isTrue(); 112 } 113 114 @Test 115 @EnableFlags(value = {android.security.Flags.FLAG_EXTEND_ECM_TO_ALL_SETTINGS, 116 android.permission.flags.Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED}) createAccessibilityServicePreferenceList_ecmNotRestricted_prefIsNotEcmRestricted()117 public void createAccessibilityServicePreferenceList_ecmNotRestricted_prefIsNotEcmRestricted() { 118 ShadowRestrictedLockUtilsInternal.setEcmRestrictedPkgs(); 119 final List<AccessibilityServiceInfo> infoList = new ArrayList<>( 120 singletonList(mServiceInfo)); 121 122 final List<RestrictedPreference> preferenceList = 123 mHelper.createAccessibilityServicePreferenceList(infoList); 124 final RestrictedPreference preference = preferenceList.get(0); 125 126 assertThat(preference.isDisabledByEcm()).isFalse(); 127 } 128 129 @Test createAccessibilityActivityPreferenceList_hasOneInfo_containsSameKey()130 public void createAccessibilityActivityPreferenceList_hasOneInfo_containsSameKey() { 131 final String key = COMPONENT_NAME.flattenToString(); 132 setMockAccessibilityShortcutInfo(mShortcutInfo); 133 final List<AccessibilityShortcutInfo> infoList = new ArrayList<>( 134 singletonList(mShortcutInfo)); 135 136 final List<AccessibilityActivityPreference> preferenceList = 137 mHelper.createAccessibilityActivityPreferenceList(infoList); 138 final RestrictedPreference preference = preferenceList.get(0); 139 140 assertThat(preference.getKey()).isEqualTo(key); 141 } 142 143 @Test 144 @EnableFlags(value = { 145 android.security.Flags.FLAG_EXTEND_ECM_TO_ALL_SETTINGS, 146 android.permission.flags.Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED, 147 }) createAccessibilityActivityPreference_ecmRestricted_prefIsNotEcmRestricted()148 public void createAccessibilityActivityPreference_ecmRestricted_prefIsNotEcmRestricted() { 149 setMockAccessibilityShortcutInfo(mShortcutInfo); 150 ShadowRestrictedLockUtilsInternal.setEcmRestrictedPkgs(PACKAGE_NAME); 151 152 final List<AccessibilityActivityPreference> preferenceList = 153 mHelper.createAccessibilityActivityPreferenceList(List.of(mShortcutInfo)); 154 assertThat(preferenceList).hasSize(1); 155 final RestrictedPreference preference = preferenceList.get(0); 156 157 assertThat(preference.isDisabledByEcm()).isFalse(); 158 } 159 getMockAccessibilityServiceInfo(String packageName, String className)160 private AccessibilityServiceInfo getMockAccessibilityServiceInfo(String packageName, 161 String className) { 162 final ApplicationInfo applicationInfo = new ApplicationInfo(); 163 final ServiceInfo serviceInfo = new ServiceInfo(); 164 applicationInfo.packageName = packageName; 165 serviceInfo.packageName = packageName; 166 serviceInfo.name = className; 167 serviceInfo.applicationInfo = applicationInfo; 168 169 final ResolveInfo resolveInfo = new ResolveInfo(); 170 resolveInfo.serviceInfo = serviceInfo; 171 try { 172 final AccessibilityServiceInfo info = new AccessibilityServiceInfo(resolveInfo, 173 mContext); 174 info.setComponentName(new ComponentName(packageName, className)); 175 return info; 176 } catch (XmlPullParserException | IOException e) { 177 // Do nothing 178 } 179 return null; 180 } 181 setMockAccessibilityShortcutInfo(AccessibilityShortcutInfo mockInfo)182 private void setMockAccessibilityShortcutInfo(AccessibilityShortcutInfo mockInfo) { 183 final ActivityInfo activityInfo = Mockito.mock(ActivityInfo.class); 184 activityInfo.applicationInfo = new ApplicationInfo(); 185 when(mockInfo.getActivityInfo()).thenReturn(activityInfo); 186 when(activityInfo.loadLabel(any())).thenReturn(DEFAULT_LABEL); 187 when(mockInfo.loadSummary(any())).thenReturn(DEFAULT_SUMMARY); 188 when(mockInfo.loadDescription(any())).thenReturn(DEFAULT_DESCRIPTION); 189 when(mockInfo.getComponentName()).thenReturn(COMPONENT_NAME); 190 } 191 } 192