Merge "Revert "Adds install source checks for accessibility service"" into tm-dev

This commit is contained in:
Ryan Lin
2022-03-22 01:30:39 +00:00
committed by Android (Google) Code Review
5 changed files with 9 additions and 185 deletions

View File

@@ -4650,8 +4650,6 @@
<java-symbol type="drawable" name="ic_accessibility_24dp" />
<java-symbol type="string" name="view_and_control_notification_title" />
<java-symbol type="string" name="view_and_control_notification_content" />
<java-symbol type="array" name="config_accessibility_allowed_install_source" />
<!-- Translation -->
<java-symbol type="string" name="ui_translation_accessibility_translated_text" />
<java-symbol type="string" name="ui_translation_accessibility_translation_finished" />

View File

@@ -18,7 +18,6 @@ package com.android.server.accessibility;
import static android.accessibilityservice.AccessibilityService.SoftKeyboardController.ENABLE_IME_FAIL_BY_ADMIN;
import static android.accessibilityservice.AccessibilityService.SoftKeyboardController.ENABLE_IME_SUCCESS;
import static android.content.pm.PackageManagerInternal.PACKAGE_INSTALLER;
import android.Manifest;
import android.accessibilityservice.AccessibilityService;
@@ -31,9 +30,7 @@ import android.app.admin.DevicePolicyManager;
import android.appwidget.AppWidgetManagerInternal;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.InstallSourceInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
@@ -42,14 +39,12 @@ import android.os.IBinder;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Slog;
import android.view.accessibility.AccessibilityEvent;
import android.view.inputmethod.InputMethodInfo;
import com.android.internal.util.ArrayUtils;
import com.android.server.LocalServices;
import com.android.server.inputmethod.InputMethodManagerInternal;
import com.android.settingslib.RestrictedLockUtils;
@@ -734,7 +729,7 @@ public class AccessibilitySecurityPolicy {
final AccessibilityServiceInfo a11yServiceInfo = boundServices.get(
i).getServiceInfo();
final ComponentName service = a11yServiceInfo.getComponentName().clone();
if (!isA11yCategoryService(a11yServiceInfo)) {
if (!a11yServiceInfo.isAccessibilityTool()) {
tempNonA11yCategoryServices.add(service);
if (mNonA11yCategoryServices.contains(service)) {
mNonA11yCategoryServices.remove(service);
@@ -794,69 +789,4 @@ public class AccessibilitySecurityPolicy {
mPolicyWarningUIController.onEnabledServicesChangedLocked(userId, enabledServices);
}
/**
* Identifies whether the accessibility service is true and designed for accessibility. An
* accessibility service is considered as accessibility category if meets all conditions below:
* <ul>
* <li> {@link AccessibilityServiceInfo#isAccessibilityTool} is true</li>
* <li> is installed from the trusted install source</li>
* </ul>
*
* @param serviceInfo The accessibility service's serviceInfo.
* @return Returns true if it is a true accessibility service.
*/
public boolean isA11yCategoryService(AccessibilityServiceInfo serviceInfo) {
if (!serviceInfo.isAccessibilityTool()) {
return false;
}
if (!serviceInfo.getResolveInfo().serviceInfo.applicationInfo.isSystemApp()) {
return hasTrustedSystemInstallSource(
serviceInfo.getResolveInfo().serviceInfo.packageName);
}
return true;
}
/** Returns true if the {@code installedPackage} is installed from the trusted install source.
*/
private boolean hasTrustedSystemInstallSource(String installedPackage) {
try {
InstallSourceInfo installSourceInfo = mPackageManager.getInstallSourceInfo(
installedPackage);
if (installSourceInfo == null) {
return false;
}
final String installSourcePackageName = installSourceInfo.getInitiatingPackageName();
if (installSourcePackageName == null || !mPackageManager.getPackageInfo(
installSourcePackageName,
0).applicationInfo.isSystemApp()) {
return false;
}
return isTrustedInstallSource(installSourcePackageName);
} catch (PackageManager.NameNotFoundException e) {
Slog.w(LOG_TAG, "can't find the package's install source:" + installedPackage);
}
return false;
}
/** Returns true if the {@code installerPackage} is a trusted install source. */
private boolean isTrustedInstallSource(String installerPackage) {
final String[] allowedInstallingSources = mContext.getResources().getStringArray(
com.android.internal.R.array
.config_accessibility_allowed_install_source);
if (allowedInstallingSources.length == 0) {
//Filters unwanted default installers if no allowed install sources.
String defaultInstaller = ArrayUtils.firstOrNull(LocalServices.getService(
PackageManagerInternal.class).getKnownPackageNames(PACKAGE_INSTALLER,
mCurrentUserId));
return !TextUtils.equals(defaultInstaller, installerPackage);
}
for (int i = 0; i < allowedInstallingSources.length; i++) {
if (TextUtils.equals(allowedInstallingSources[i], installerPackage)) {
return true;
}
}
return false;
}
}

View File

@@ -270,7 +270,7 @@ public class PolicyWarningUIController {
final AccessibilityServiceInfo a11yServiceInfo = enabledServiceInfos.get(i);
if (componentName.flattenToShortString().equals(
a11yServiceInfo.getComponentName().flattenToShortString())) {
if (!mAccessibilitySecurityPolicy.isA11yCategoryService(a11yServiceInfo)
if (!a11yServiceInfo.isAccessibilityTool()
&& !mNotifiedA11yServices.contains(componentName)) {
final CharSequence displayName =
a11yServiceInfo.getResolveInfo().serviceInfo.loadLabel(

View File

@@ -16,8 +16,6 @@
package com.android.server.accessibility;
import static android.content.pm.PackageManagerInternal.PACKAGE_INSTALLER;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static junit.framework.Assert.assertFalse;
@@ -45,14 +43,10 @@ import android.appwidget.AppWidgetManagerInternal;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.InstallSourceInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.SigningInfo;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
@@ -63,7 +57,6 @@ import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityWindowInfo;
import com.android.internal.R;
import com.android.server.LocalServices;
import org.junit.Before;
import org.junit.Rule;
@@ -150,22 +143,12 @@ public class AccessibilitySecurityPolicyTest {
@Mock
private AccessibilityServiceInfo mMockA11yServiceInfo;
@Mock
private ResolveInfo mMockResolveInfo;
@Mock
private ServiceInfo mMockServiceInfo;
@Mock
private ApplicationInfo mMockApplicationInfo;
@Mock
private ApplicationInfo mMockSourceApplicationInfo;
@Mock
private PackageInfo mMockSourcePackageInfo;
@Mock
private PolicyWarningUIController mPolicyWarningUIController;
@Mock
private PackageManagerInternal mPackageManagerInternal;
@Before
public void setUp() throws PackageManager.NameNotFoundException {
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext.setMockPackageManager(mMockPackageManager);
mContext.addMockSystemService(Context.USER_SERVICE, mMockUserManager);
@@ -612,8 +595,7 @@ public class AccessibilitySecurityPolicyTest {
}
@Test
public void onBoundServicesChanged_nonA11yTool_invokeAction()
throws PackageManager.NameNotFoundException {
public void onBoundServicesChanged_nonA11yTool_invokeAction() {
final ArrayList<AccessibilityServiceConnection> boundServices = new ArrayList<>();
boundServices.add(mMockA11yServiceConnection);
initServiceInfoAndConnection(TEST_COMPONENT_NAME,
@@ -630,14 +612,11 @@ public class AccessibilitySecurityPolicyTest {
}
@Test
public void onBoundServicesChanged_sysA11yTool_noAction()
throws PackageManager.NameNotFoundException {
public void onBoundServicesChanged_isA11yTool_noAction() {
final ArrayList<AccessibilityServiceConnection> boundServices = new ArrayList<>();
initServiceInfoAndConnection(TEST_COMPONENT_NAME,
mMockA11yServiceConnection,
/* isAccessibilityTool= */ true,
/* isSystemApp= */true,
/* installSourceInfo= */ null);
/* isAccessibilityTool= */ true);
boundServices.add(mMockA11yServiceConnection);
mA11ySecurityPolicy.onBoundServicesChangedLocked(TEST_USER_ID, boundServices);
@@ -649,63 +628,7 @@ public class AccessibilitySecurityPolicyTest {
}
@Test
public void onBoundServicesChanged_nonSysA11yToolFromAllowedInstallerInAllowedList_noAction()
throws PackageManager.NameNotFoundException {
final ArrayList<AccessibilityServiceConnection> boundServices = new ArrayList<>();
final String allowedSourcePackageName = "com.allowed.install.package";
mContext.getOrCreateTestableResources().addOverride(R.array
.config_accessibility_allowed_install_source,
new String[]{allowedSourcePackageName});
// The allowed Installer should be system app in the allowed list.
InstallSourceInfo allowedSource = initInstallSourceInfo(
allowedSourcePackageName, /* isSystemApp= */ true);
initServiceInfoAndConnection(TEST_COMPONENT_NAME,
mMockA11yServiceConnection,
/* isAccessibilityTool= */ true,
/* isSystemApp= */ false,
allowedSource);
boundServices.add(mMockA11yServiceConnection);
mA11ySecurityPolicy.onBoundServicesChangedLocked(TEST_USER_ID, boundServices);
verify(mPolicyWarningUIController, never()).onNonA11yCategoryServiceBound(anyInt(), any());
mA11ySecurityPolicy.onBoundServicesChangedLocked(TEST_USER_ID, new ArrayList<>());
verify(mPolicyWarningUIController, never()).onNonA11yCategoryServiceUnbound(anyInt(),
any());
}
@Test
public void onBoundServicesChanged_nonSysA11yToolFromValidInstallerWithoutAllowedList_noAction()
throws PackageManager.NameNotFoundException {
final ArrayList<AccessibilityServiceConnection> boundServices = new ArrayList<>();
final String validInstallerPackageName = "com.valid.install.package";
final String defaultInstallerPackageName = "com.default.install.package";
LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternal);
when(mPackageManagerInternal.getKnownPackageNames(PACKAGE_INSTALLER,
TEST_USER_ID)).thenReturn(new String[]{defaultInstallerPackageName});
mContext.getOrCreateTestableResources().addOverride(R.array
.config_accessibility_allowed_install_source,
new String[]{});
// The valid Installer should be system app and not the default installer.
InstallSourceInfo validSource = initInstallSourceInfo(
validInstallerPackageName, /* isSystemApp= */ true);
initServiceInfoAndConnection(TEST_COMPONENT_NAME,
mMockA11yServiceConnection, /* isAccessibilityTool= */ true,
/* isSystemApp= */ false,
validSource);
boundServices.add(mMockA11yServiceConnection);
mA11ySecurityPolicy.onBoundServicesChangedLocked(TEST_USER_ID, boundServices);
verify(mPolicyWarningUIController, never()).onNonA11yCategoryServiceBound(anyInt(), any());
mA11ySecurityPolicy.onBoundServicesChangedLocked(TEST_USER_ID, new ArrayList<>());
verify(mPolicyWarningUIController, never()).onNonA11yCategoryServiceUnbound(anyInt(),
any());
}
@Test
public void onSwitchUser_oldUserHadAction_invokeActionForOldUser()
throws PackageManager.NameNotFoundException {
public void onSwitchUser_oldUserHadAction_invokeActionForOldUser() {
final int newUserId = 2;
final ArrayList<AccessibilityServiceConnection> boundServices = new ArrayList<>();
initServiceInfoAndConnection(TEST_COMPONENT_NAME,
@@ -725,35 +648,9 @@ public class AccessibilitySecurityPolicyTest {
private void initServiceInfoAndConnection(ComponentName componentName,
AccessibilityServiceConnection connection,
boolean isAccessibilityTool) throws PackageManager.NameNotFoundException {
initServiceInfoAndConnection(componentName, connection, isAccessibilityTool, false, null);
}
private void initServiceInfoAndConnection(ComponentName componentName,
AccessibilityServiceConnection connection,
boolean isAccessibilityTool, boolean isSystemApp, InstallSourceInfo installSourceInfo)
throws PackageManager.NameNotFoundException {
boolean isAccessibilityTool) {
when(connection.getServiceInfo()).thenReturn(mMockA11yServiceInfo);
when(mMockA11yServiceInfo.getComponentName()).thenReturn(componentName);
when(mMockA11yServiceInfo.isAccessibilityTool()).thenReturn(isAccessibilityTool);
when(mMockA11yServiceInfo.getResolveInfo()).thenReturn(mMockResolveInfo);
mMockResolveInfo.serviceInfo = mMockServiceInfo;
mMockServiceInfo.applicationInfo = mMockApplicationInfo;
mMockServiceInfo.packageName = componentName.getPackageName();
when(mMockApplicationInfo.isSystemApp()).thenReturn(isSystemApp);
when(mMockPackageManager.getInstallSourceInfo(componentName.getPackageName())).thenReturn(
installSourceInfo);
}
private InstallSourceInfo initInstallSourceInfo(String packageName, boolean isSystemApp)
throws PackageManager.NameNotFoundException {
final InstallSourceInfo installSourceInfo = new InstallSourceInfo(
packageName, new SigningInfo(), null,
packageName, PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED);
when(mMockPackageManager.getPackageInfo(packageName, 0)).thenReturn(
mMockSourcePackageInfo);
mMockSourcePackageInfo.applicationInfo = mMockSourceApplicationInfo;
when(mMockSourceApplicationInfo.isSystemApp()).thenReturn(isSystemApp);
return installSourceInfo;
}
}

View File

@@ -116,8 +116,7 @@ public class PolicyWarningUIControllerTest {
mMockResolveInfo.serviceInfo = mMockServiceInfo;
when(mMockA11yServiceInfo.getResolveInfo()).thenReturn(mMockResolveInfo);
when(mMockA11yServiceInfo.getComponentName()).thenReturn(TEST_COMPONENT_NAME);
when(mAccessibilitySecurityPolicy.isA11yCategoryService(
mMockA11yServiceInfo)).thenReturn(false);
when(mMockA11yServiceInfo.isAccessibilityTool()).thenReturn(false);
mFakeNotificationController.onReceive(mContext,
PolicyWarningUIController.createIntent(mContext, TEST_USER_ID,