From bf12565276484a9ba003f760e8a61bbecc6815f7 Mon Sep 17 00:00:00 2001 From: Amith Yamasani Date: Fri, 13 May 2016 11:13:16 -0700 Subject: [PATCH] Allow Shell to change component enabled state But make sure that we don't allow Shell or other apps to disable an active profile or device owner. Also limit exactly what states Shell can switch apps between, similar to Settings UI. This is required for some CTS tests Bug: 27924655 Change-Id: I958f0d1de7f0bc1f5a0cbf853d57dfdeb2f9ad59 --- packages/Shell/AndroidManifest.xml | 1 + .../server/pm/PackageManagerService.java | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 4e9b59fe6b181..9c0aa35da9a43 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -111,6 +111,7 @@ + diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index b6c269ecf627f..c061720292f52 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -17484,6 +17484,14 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); throw new IllegalArgumentException( "Unknown component: " + packageName + "/" + className); } + // Don't allow other apps to disable an active profile owner + if (!UserHandle.isSameApp(uid, pkgSetting.appId)) { + final DevicePolicyManagerInternal dpmi = LocalServices + .getService(DevicePolicyManagerInternal.class); + if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) { + throw new SecurityException("Cannot disable a device owner or a profile owner"); + } + } // Allow root and verify that userId is not being specified by a different user if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) { throw new SecurityException( @@ -17491,6 +17499,25 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); + Binder.getCallingPid() + ", uid=" + uid + ", package uid=" + pkgSetting.appId); } + if (uid == Process.SHELL_UID) { + // Shell can only change whole packages between ENABLED and DISABLED_USER states + int oldState = pkgSetting.getEnabled(userId); + if (className == null + && + (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER + || oldState == COMPONENT_ENABLED_STATE_DEFAULT + || oldState == COMPONENT_ENABLED_STATE_ENABLED) + && + (newState == COMPONENT_ENABLED_STATE_DISABLED_USER + || newState == COMPONENT_ENABLED_STATE_DEFAULT + || newState == COMPONENT_ENABLED_STATE_ENABLED)) { + // ok + } else { + throw new SecurityException( + "Shell cannot change component state for " + packageName + "/" + + className + " to " + newState); + } + } if (className == null) { // We're dealing with an application/package level state change if (pkgSetting.getEnabled(userId) == newState) {