Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 55eb3067 authored by Ryan Lin's avatar Ryan Lin Committed by Android (Google) Code Review
Browse files

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

parents f10600c7 d323c922
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -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" />
+1 −71
Original line number Diff line number Diff line
@@ -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;
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -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(
+6 −109
Original line number Diff line number Diff line
@@ -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,40 +612,11 @@ public class AccessibilitySecurityPolicyTest {
    }

    @Test
    public void onBoundServicesChanged_sysA11yTool_noAction()
            throws PackageManager.NameNotFoundException {
        final ArrayList<AccessibilityServiceConnection> boundServices = new ArrayList<>();
        initServiceInfoAndConnection(TEST_COMPONENT_NAME,
                mMockA11yServiceConnection,
                /* isAccessibilityTool= */ true,
                /* isSystemApp= */true,
                /* installSourceInfo= */ null);
        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_nonSysA11yToolFromAllowedInstallerInAllowedList_noAction()
            throws PackageManager.NameNotFoundException {
    public void onBoundServicesChanged_isA11yTool_noAction() {
        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);
                /* isAccessibilityTool= */ true);
        boundServices.add(mMockA11yServiceConnection);

        mA11ySecurityPolicy.onBoundServicesChangedLocked(TEST_USER_ID, boundServices);
@@ -675,37 +628,7 @@ public class AccessibilitySecurityPolicyTest {
    }

    @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;
    }
}
+1 −2
Original line number Diff line number Diff line
@@ -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,