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