Merge "Revert "Adds install source checks for accessibility service"" into tm-dev
This commit is contained in:
@@ -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" />
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user