On uninstall cred mng app

Changes
* when ACTION_PACKAGE_REMOVE is received
  in the DPMS broadcast receiver, remove
  the cred mng app if the removed package
  is the cred mng app.

Manual testing steps:
* Request to manage credentials in TestDPC
* Check Settings > encryption & credentials
  and verify the cred mng app is set successfully
* Uninstall TestDPC
* Check Settings to and verify there is no
  cred mng app.

Bug: 165641221
Test: Manual testing
      atest com.android.server.devicepolicy.DevicePolicyManagerTest
Change-Id: I6e8004da40c35c0dfe25540bf143f255d9f839d7
This commit is contained in:
Alex Johnston
2021-01-05 13:10:11 +00:00
parent 8bf124b0d1
commit 141652b464
3 changed files with 51 additions and 0 deletions

View File

@@ -819,6 +819,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
} else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)
&& !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
handlePackagesChanged(intent.getData().getSchemeSpecificPart(), userHandle);
removeCredentialManagementApp(intent.getData().getSchemeSpecificPart());
} else if (Intent.ACTION_MANAGED_PROFILE_ADDED.equals(action)) {
clearWipeProfileNotification();
} else if (Intent.ACTION_DATE_CHANGED.equals(action)
@@ -949,6 +950,20 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
}
private void removeCredentialManagementApp(String packageName) {
mBackgroundHandler.post(() -> {
try (KeyChainConnection connection = mInjector.keyChainBind()) {
IKeyChainService service = connection.getService();
if (service.hasCredentialManagementApp()
&& packageName.equals(service.getCredentialManagementAppPackageName())) {
service.removeCredentialManagementApp();
}
} catch (RemoteException | InterruptedException | IllegalStateException e) {
Log.e(LOG_TAG, "Unable to remove the credential management app");
}
});
}
private boolean isRemovedPackage(String changedPackage, String targetPackage, int userHandle) {
try {
return targetPackage != null
@@ -1419,6 +1434,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
return SecurityLog.isLoggingEnabled();
}
KeyChainConnection keyChainBind() throws InterruptedException {
return KeyChain.bind(mContext);
}
KeyChainConnection keyChainBindAsUser(UserHandle user) throws InterruptedException {
return KeyChain.bindAsUser(mContext, user);
}

View File

@@ -459,6 +459,11 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi
return services.buildMock.isDebuggable;
}
@Override
KeyChain.KeyChainConnection keyChainBind() {
return services.keyChainConnection;
}
@Override
KeyChain.KeyChainConnection keyChainBindAsUser(UserHandle user) {
return services.keyChainConnection;

View File

@@ -1616,6 +1616,33 @@ public class DevicePolicyManagerTest extends DpmTestBase {
)), eq(user));
}
@Test
public void testRemoveCredentialManagementApp() throws Exception {
final String packageName = "com.test.cred.mng";
Intent intent = new Intent(Intent.ACTION_PACKAGE_REMOVED);
intent.setData(Uri.parse("package:" + packageName));
dpms.mReceiver.setPendingResult(
new BroadcastReceiver.PendingResult(Activity.RESULT_OK,
"resultData",
/* resultExtras= */ null,
BroadcastReceiver.PendingResult.TYPE_UNREGISTERED,
/* ordered= */ true,
/* sticky= */ false,
/* token= */ null,
CALLER_USER_HANDLE,
/* flags= */ 0));
when(getServices().keyChainConnection.getService().hasCredentialManagementApp())
.thenReturn(true);
when(getServices().keyChainConnection.getService().getCredentialManagementAppPackageName())
.thenReturn(packageName);
dpms.mReceiver.onReceive(mContext, intent);
flushTasks(dpms);
verify(getServices().keyChainConnection.getService()).hasCredentialManagementApp();
verify(getServices().keyChainConnection.getService()).removeCredentialManagementApp();
}
/**
* Simple test for delegate set/get and general delegation. Tests verifying that delegated
* privileges can acually be exercised by a delegate are not covered here.