diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index d1cd1dbe18bcf..1d71d8764bf7a 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -980,6 +980,10 @@ class ActivityStarter { if (mSupervisor.mRecentTasks.isCallerRecents(callingUid)) { return false; } + // don't abort if the callingPackage is a device owner + if (mService.getDevicePolicyManager().isDeviceOwnerApp(callingPackage)) { + return false; + } // anything that has fallen through would currently be aborted Slog.w(TAG, "Background activity start [callingPackage: " + callingPackage + "; callingUid: " + callingUid diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 09ef4b95e66b2..14c481455752b 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -151,6 +151,7 @@ import android.app.RemoteAction; import android.app.WaitResult; import android.app.WindowConfiguration; import android.app.admin.DevicePolicyCache; +import android.app.admin.DevicePolicyManager; import android.app.assist.AssistContent; import android.app.assist.AssistStructure; import android.app.usage.UsageStatsManagerInternal; @@ -362,6 +363,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { WindowManagerService mWindowManager; private UserManagerService mUserManager; private AppOpsService mAppOpsService; + private DevicePolicyManager mDpm; /** All active uids in the system. */ private final SparseArray mActiveUids = new SparseArray<>(); private final SparseArray mPendingTempWhitelist = new SparseArray<>(); @@ -836,6 +838,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return mAppOpsService; } + DevicePolicyManager getDevicePolicyManager() { + if (mDpm == null) { + mDpm = mContext.getSystemService(DevicePolicyManager.class); + } + return mDpm; + } + boolean hasUserRestriction(String restriction, int userId) { return getUserManager().hasUserRestriction(restriction, userId); } diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java index e86d7df285739..60f1ae26f5dd3 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java @@ -61,6 +61,7 @@ import static org.mockito.ArgumentMatchers.eq; import android.app.ActivityOptions; import android.app.IApplicationThread; +import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Intent; import android.content.pm.ActivityInfo; @@ -561,7 +562,7 @@ public class ActivityStarterTests extends ActivityTestsBase { runAndVerifyBackgroundActivityStartsSubtest("allowed_noStartsAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, - false, false, false, false); + false, false, false, false, false); } /** @@ -576,7 +577,7 @@ public class ActivityStarterTests extends ActivityTestsBase { "disallowed_unsupportedUsecase_aborted", true, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, - false, false, false, false); + false, false, false, false, false); } /** @@ -591,56 +592,61 @@ public class ActivityStarterTests extends ActivityTestsBase { runAndVerifyBackgroundActivityStartsSubtest("disallowed_rootUid_notAborted", false, Process.ROOT_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, - false, false, false, false); + false, false, false, false, false); runAndVerifyBackgroundActivityStartsSubtest("disallowed_systemUid_notAborted", false, Process.SYSTEM_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, - false, false, false, false); + false, false, false, false, false); runAndVerifyBackgroundActivityStartsSubtest("disallowed_nfcUid_notAborted", false, Process.NFC_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, - false, false, false, false); + false, false, false, false, false); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_callingUidHasVisibleWindow_notAborted", false, UNIMPORTANT_UID, true, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, - false, false, false, false); + false, false, false, false, false); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_callingUidProcessStateTop_notAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, - false, false, false, false); + false, false, false, false, false); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_realCallingUidHasVisibleWindow_notAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, true, PROCESS_STATE_TOP + 1, - false, false, false, false); + false, false, false, false, false); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_realCallingUidProcessStateTop_notAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP, - false, false, false, false); + false, false, false, false, false); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_hasForegroundActivities_notAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, - true, false, false, false); + true, false, false, false, false); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_callerIsRecents_notAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, - false, true, false, false); + false, true, false, false, false); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_callerIsWhitelisted_notAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, - false, false, true, false); + false, false, true, false, false); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_callerIsInstrumentingWithBackgroundActivityStartPrivileges_notAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, - false, false, false, true); + false, false, false, true, false); + runAndVerifyBackgroundActivityStartsSubtest( + "disallowed_callingPackageIsDeviceOwner_notAborted", false, + UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, + UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, + false, false, false, false, true); } private void runAndVerifyBackgroundActivityStartsSubtest(String name, boolean shouldHaveAborted, @@ -648,7 +654,8 @@ public class ActivityStarterTests extends ActivityTestsBase { int realCallingUid, boolean realCallingUidHasVisibleWindow, int realCallingUidProcState, boolean hasForegroundActivities, boolean callerIsRecents, boolean callerIsTempWhitelisted, - boolean callerIsInstrumentingWithBackgroundActivityStartPrivileges) { + boolean callerIsInstrumentingWithBackgroundActivityStartPrivileges, + boolean isCallingPackageDeviceOwner) { // window visibility doReturn(callingUidHasVisibleWindow).when(mService.mWindowManager.mRoot) .isAnyNonToastWindowVisibleForUid(callingUid); @@ -674,6 +681,9 @@ public class ActivityStarterTests extends ActivityTestsBase { // caller is instrumenting with background activity starts privileges callerApp.setInstrumenting(callerIsInstrumentingWithBackgroundActivityStartPrivileges, callerIsInstrumentingWithBackgroundActivityStartPrivileges); + // caller is device owner + DevicePolicyManager dpmMock = mService.getDevicePolicyManager(); + doReturn(isCallingPackageDeviceOwner).when(dpmMock).isDeviceOwnerApp(any()); final ActivityOptions options = spy(ActivityOptions.makeBasic()); ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK) diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java index 3b399ffc708c0..e27dd94b1a2c8 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java @@ -42,6 +42,7 @@ import static com.android.server.wm.ActivityStackSupervisor.ON_TOP; import android.app.ActivityManagerInternal; import android.app.ActivityOptions; import android.app.IApplicationThread; +import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -424,6 +425,7 @@ class ActivityTestsBase { spyOn(getLifecycleManager()); spyOn(getLockTaskController()); doReturn(mock(IPackageManager.class)).when(this).getPackageManager(); + doReturn(mock(DevicePolicyManager.class)).when(this).getDevicePolicyManager(); // allow background activity starts by default doReturn(true).when(this).isBackgroundActivityStartsEnabled(); doNothing().when(this).updateCpuStats();