diff options
| -rw-r--r-- | core/api/system-current.txt | 2 | ||||
| -rw-r--r-- | core/api/test-current.txt | 6 | ||||
| -rw-r--r-- | core/java/android/app/ActivityManager.java | 38 | ||||
| -rw-r--r-- | core/java/android/app/IActivityManager.aidl | 3 | ||||
| -rw-r--r-- | core/java/android/content/Intent.java | 2 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/ActivityManagerService.java | 21 | 
6 files changed, 64 insertions, 8 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 761230f8188a..25cef758af47 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -407,7 +407,7 @@ package android.app {      method @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS) public static void setPersistentVrThread(int);      method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) public boolean startProfile(@NonNull android.os.UserHandle);      method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) public boolean stopProfile(@NonNull android.os.UserHandle); -    method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean switchUser(@NonNull android.os.UserHandle); +    method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public boolean switchUser(@NonNull android.os.UserHandle);    }    public static interface ActivityManager.OnUidImportanceListener { diff --git a/core/api/test-current.txt b/core/api/test-current.txt index e486fa2c2e29..2f859d73fde4 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -104,7 +104,9 @@ package android.app {      method @RequiresPermission(android.Manifest.permission.RESET_APP_ERRORS) public void resetAppErrors();      method public static void resumeAppSwitches() throws android.os.RemoteException;      method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public void scheduleApplicationInfoChanged(java.util.List<java.lang.String>, int); +    method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public boolean stopUser(int, boolean);      method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public boolean updateMccMncConfiguration(@NonNull String, @NonNull String); +    method @RequiresPermission(android.Manifest.permission.DUMP) public void waitForBroadcastIdle();      field public static final long DROP_CLOSE_SYSTEM_DIALOGS = 174664120L; // 0xa6929b8L      field public static final long LOCK_DOWN_CLOSE_SYSTEM_DIALOGS = 174664365L; // 0xa692aadL      field public static final int PROCESS_CAPABILITY_ALL = 15; // 0xf @@ -709,6 +711,10 @@ package android.content {      method public int getDisplayId();    } +  public class Intent implements java.lang.Cloneable android.os.Parcelable { +    field public static final String ACTION_USER_STOPPED = "android.intent.action.USER_STOPPED"; +  } +    public class SyncAdapterType implements android.os.Parcelable {      method @Nullable public String getPackageName();    } diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index f905ec86aab7..3fedda36de2d 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -31,6 +31,7 @@ import android.annotation.RequiresPermission;  import android.annotation.SystemApi;  import android.annotation.SystemService;  import android.annotation.TestApi; +import android.annotation.UserIdInt;  import android.compat.annotation.ChangeId;  import android.compat.annotation.EnabledSince;  import android.compat.annotation.UnsupportedAppUsage; @@ -4048,7 +4049,8 @@ public class ActivityManager {       * @hide       */      @SystemApi -    @RequiresPermission(android.Manifest.permission.MANAGE_USERS) +    @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS, +            android.Manifest.permission.CREATE_USERS})      public boolean switchUser(@NonNull UserHandle user) {          if (user == null) {              throw new IllegalArgumentException("UserHandle cannot be null."); @@ -4144,6 +4146,25 @@ public class ActivityManager {          }      } +    /** +     * Stops the given {@code userId}. +     * +     * @hide +     */ +    @TestApi +    @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) +    public boolean stopUser(@UserIdInt int userId, boolean force) { +        if (userId == UserHandle.USER_SYSTEM) { +            return false; +        } +        try { +            return USER_OP_SUCCESS == getService().stopUser( +                    userId, force, /* callback= */ null); +        } catch (RemoteException e) { +            throw e.rethrowFromSystemServer(); +        } +    } +      /** {@hide} */      public static final int FLAG_OR_STOPPED = 1 << 0;      /** {@hide} */ @@ -4811,6 +4832,21 @@ public class ActivityManager {      }      /** +     * Blocks until all broadcast queues become idle. +     * +     * @hide +     */ +    @TestApi +    @RequiresPermission(android.Manifest.permission.DUMP) +    public void waitForBroadcastIdle() { +        try { +            getService().waitForBroadcastIdle(); +        } catch (RemoteException e) { +            e.rethrowFromSystemServer(); +        } +    } + +    /**       * A subset of immutable pending intent information suitable for caching on the client side.       *       * @hide diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index ef0dcabbe111..4c2433c04771 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -709,4 +709,7 @@ interface IActivityManager {      ParceledListSlice queryIntentComponentsForIntentSender(in IIntentSender sender, int matchFlags);      int getUidProcessCapabilities(int uid, in String callingPackage); + +    /** Blocks until all broadcast queues become idle. */ +    void waitForBroadcastIdle();  } diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index adf9ff32c4ec..96b8fbe293f5 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -28,6 +28,7 @@ import android.annotation.SdkConstant;  import android.annotation.SdkConstant.SdkConstantType;  import android.annotation.SuppressLint;  import android.annotation.SystemApi; +import android.annotation.TestApi;  import android.app.AppGlobals;  import android.compat.annotation.UnsupportedAppUsage;  import android.content.pm.ActivityInfo; @@ -3771,6 +3772,7 @@ public class Intent implements Parcelable, Cloneable {       * has just been stopped (which is no longer running).       * @hide       */ +    @TestApi      public static final String ACTION_USER_STOPPED =              "android.intent.action.USER_STOPPED"; diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 83cbf66ecaea..0e8644a6569e 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -16147,7 +16147,12 @@ public class ActivityManagerService extends IActivityManager.Stub          }      } -    public void waitForBroadcastIdle(PrintWriter pw) { +    @Override +    public void waitForBroadcastIdle() { +        waitForBroadcastIdle(/* printWriter= */ null); +    } + +    public void waitForBroadcastIdle(@Nullable PrintWriter pw) {          enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");          while (true) {              boolean idle = true; @@ -16155,9 +16160,11 @@ public class ActivityManagerService extends IActivityManager.Stub                  for (BroadcastQueue queue : mBroadcastQueues) {                      if (!queue.isIdle()) {                          final String msg = "Waiting for queue " + queue + " to become idle..."; -                        pw.println(msg); -                        pw.println(queue.describeState()); -                        pw.flush(); +                        if (pw != null) { +                            pw.println(msg); +                            pw.println(queue.describeState()); +                            pw.flush(); +                        }                          Slog.v(TAG, msg);                          queue.cancelDeferrals();                          idle = false; @@ -16167,8 +16174,10 @@ public class ActivityManagerService extends IActivityManager.Stub              if (idle) {                  final String msg = "All broadcast queues are idle!"; -                pw.println(msg); -                pw.flush(); +                if (pw != null) { +                    pw.println(msg); +                    pw.flush(); +                }                  Slog.v(TAG, msg);                  return;              } else {  |