diff options
author | Pavel Grafov <pgrafov@google.com> | 2020-06-02 13:45:19 +0100 |
---|---|---|
committer | Pavel Grafov <pgrafov@google.com> | 2020-06-10 23:11:01 +0100 |
commit | 80b763830e277e9d4f44b82cbb793f06930dbcb2 (patch) | |
tree | 8d9de92842f66ae845ff9e699260bfaca0c24e18 /services/devicepolicy | |
parent | 2ad21ed9ddc6b9bcc4f8acfc4560195cf2c83e3d (diff) |
Convert personal app suspension on COMP->COPE migration
* if no apps are suspended by the DO prior to migration, nothing
changes
* if some apps were suspended by the DO and the DPC targets R+
via DPM.setPackagesSuspended(), this will result in personal
apps suspended explicitly by the PO DPC as if it called
DPM.setPersonalAppsSuspended(). The apps will stay suspended.
* if the DPC target SDK is below R, the apps will be unsuspended
because the DPC won't have a way to unsuspend them. And the
user will be stuck with suspended apps.
+ when unsuspending apps, don't collect the list of apps subject
to suspension, but rather unsuspend all that is suspended. It
is more robust, e.g. when some app stops meeting the
conditions, e.g. not SMS app anymore.
Bug: 157270093
Test: com.android.server.devicepolicy.DevicePolicyManagerServiceMigrationTest
Test: Manual, with TestDPC, also patching it to target R
Change-Id: I1eba7216dd557c94bef822b77d25b484dfcd6f63
Diffstat (limited to 'services/devicepolicy')
-rw-r--r-- | services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java | 55 |
1 files changed, 43 insertions, 12 deletions
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index f1064d153814..fde52092ce97 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -2742,7 +2742,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Slog.i(LOG_TAG, "Giving the PO additional power..."); markProfileOwnerOnOrganizationOwnedDeviceUncheckedLocked(poAdminComponent, poUserId); Slog.i(LOG_TAG, "Migrating DO policies to PO..."); - moveDoPoliciesToProfileParentAdmin(doAdmin, poAdmin.getParentActiveAdmin()); + moveDoPoliciesToProfileParentAdminLocked(doAdmin, poAdmin.getParentActiveAdmin()); + migratePersonalAppSuspensionLocked(doUserId, poUserId, poAdmin); saveSettingsLocked(poUserId); Slog.i(LOG_TAG, "Clearing the DO..."); final ComponentName doAdminReceiver = doAdmin.info.getComponent(); @@ -2762,6 +2763,25 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { .write(); } + @GuardedBy("getLockObject()") + private void migratePersonalAppSuspensionLocked( + int doUserId, int poUserId, ActiveAdmin poAdmin) { + final PackageManagerInternal pmi = mInjector.getPackageManagerInternal(); + if (!pmi.isSuspendingAnyPackages(PLATFORM_PACKAGE_NAME, doUserId)) { + Slog.i(LOG_TAG, "DO is not suspending any apps."); + return; + } + + if (getTargetSdk(poAdmin.info.getPackageName(), poUserId) >= Build.VERSION_CODES.R) { + Slog.i(LOG_TAG, "PO is targeting R+, keeping personal apps suspended."); + getUserData(doUserId).mAppsSuspended = true; + poAdmin.mSuspendPersonalApps = true; + } else { + Slog.i(LOG_TAG, "PO isn't targeting R+, unsuspending personal apps."); + pmi.unsuspendForSuspendingPackage(PLATFORM_PACKAGE_NAME, doUserId); + } + } + private void uninstallOrDisablePackage(String packageName, int userHandle) { final ApplicationInfo appInfo; try { @@ -2803,7 +2823,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { pi.uninstall(packageName, 0 /* flags */, new IntentSender((IIntentSender) mLocalSender)); } - private void moveDoPoliciesToProfileParentAdmin(ActiveAdmin doAdmin, ActiveAdmin parentAdmin) { + @GuardedBy("getLockObject()") + private void moveDoPoliciesToProfileParentAdminLocked( + ActiveAdmin doAdmin, ActiveAdmin parentAdmin) { // The following policies can be already controlled via parent instance, skip if so. if (parentAdmin.mPasswordPolicy.quality == PASSWORD_QUALITY_UNSPECIFIED) { parentAdmin.mPasswordPolicy = doAdmin.mPasswordPolicy; @@ -16132,25 +16154,34 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } Slog.i(LOG_TAG, String.format("%s personal apps for user %d", suspended ? "Suspending" : "Unsuspending", userId)); + + if (suspended) { + suspendPersonalAppsInPackageManager(userId); + } else { + mInjector.getPackageManagerInternal().unsuspendForSuspendingPackage( + PLATFORM_PACKAGE_NAME, userId); + } + + synchronized (getLockObject()) { + getUserData(userId).mAppsSuspended = suspended; + saveSettingsLocked(userId); + } + } + + private void suspendPersonalAppsInPackageManager(int userId) { mInjector.binderWithCleanCallingIdentity(() -> { try { final String[] appsToSuspend = mInjector.getPersonalAppsForSuspension(userId); - final String[] failedPackages = mIPackageManager.setPackagesSuspendedAsUser( - appsToSuspend, suspended, null, null, null, PLATFORM_PACKAGE_NAME, userId); - if (!ArrayUtils.isEmpty(failedPackages)) { - Slog.wtf(LOG_TAG, String.format("Failed to %s packages: %s", - suspended ? "suspend" : "unsuspend", String.join(",", failedPackages))); + final String[] failedApps = mIPackageManager.setPackagesSuspendedAsUser( + appsToSuspend, true, null, null, null, PLATFORM_PACKAGE_NAME, userId); + if (!ArrayUtils.isEmpty(failedApps)) { + Slog.wtf(LOG_TAG, "Failed to suspend apps: " + String.join(",", failedApps)); } } catch (RemoteException re) { // Shouldn't happen. Slog.e(LOG_TAG, "Failed talking to the package manager", re); } }); - - synchronized (getLockObject()) { - getUserData(userId).mAppsSuspended = suspended; - saveSettingsLocked(userId); - } } @GuardedBy("getLockObject()") |