Turn off profile by stopping the user.

Bug: 22541941
Change-Id: I713ab9b87f3dd1b7bd6206af137562d20a44d76d
diff --git a/api/current.txt b/api/current.txt
index 4d4be4b..927b5429 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -8366,7 +8366,6 @@
     field public static final java.lang.String ACTION_APP_ERROR = "android.intent.action.APP_ERROR";
     field public static final java.lang.String ACTION_ASSIST = "android.intent.action.ASSIST";
     field public static final java.lang.String ACTION_ATTACH_DATA = "android.intent.action.ATTACH_DATA";
-    field public static final java.lang.String ACTION_AVAILABILITY_CHANGED = "android.intent.action.AVAILABILITY_CHANGED";
     field public static final java.lang.String ACTION_BATTERY_CHANGED = "android.intent.action.BATTERY_CHANGED";
     field public static final java.lang.String ACTION_BATTERY_LOW = "android.intent.action.BATTERY_LOW";
     field public static final java.lang.String ACTION_BATTERY_OKAY = "android.intent.action.BATTERY_OKAY";
diff --git a/api/system-current.txt b/api/system-current.txt
index bba7075..7e8baac 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -8663,7 +8663,6 @@
     field public static final java.lang.String ACTION_APP_ERROR = "android.intent.action.APP_ERROR";
     field public static final java.lang.String ACTION_ASSIST = "android.intent.action.ASSIST";
     field public static final java.lang.String ACTION_ATTACH_DATA = "android.intent.action.ATTACH_DATA";
-    field public static final java.lang.String ACTION_AVAILABILITY_CHANGED = "android.intent.action.AVAILABILITY_CHANGED";
     field public static final java.lang.String ACTION_BATTERY_CHANGED = "android.intent.action.BATTERY_CHANGED";
     field public static final java.lang.String ACTION_BATTERY_LOW = "android.intent.action.BATTERY_LOW";
     field public static final java.lang.String ACTION_BATTERY_OKAY = "android.intent.action.BATTERY_OKAY";
diff --git a/api/test-current.txt b/api/test-current.txt
index 5db61f6..8370083 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -8371,7 +8371,6 @@
     field public static final java.lang.String ACTION_APP_ERROR = "android.intent.action.APP_ERROR";
     field public static final java.lang.String ACTION_ASSIST = "android.intent.action.ASSIST";
     field public static final java.lang.String ACTION_ATTACH_DATA = "android.intent.action.ATTACH_DATA";
-    field public static final java.lang.String ACTION_AVAILABILITY_CHANGED = "android.intent.action.AVAILABILITY_CHANGED";
     field public static final java.lang.String ACTION_BATTERY_CHANGED = "android.intent.action.BATTERY_CHANGED";
     field public static final java.lang.String ACTION_BATTERY_LOW = "android.intent.action.BATTERY_LOW";
     field public static final java.lang.String ACTION_BATTERY_OKAY = "android.intent.action.BATTERY_OKAY";
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 1e7512d..4bde378 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3028,27 +3028,15 @@
 
     /**
      * Broadcast sent to the primary user when an associated managed profile's availability has
-     * changed. This includes when the user toggles the profile's quiet mode, or when the profile
-     * owner suspends the profile. Carries an extra {@link #EXTRA_USER} that specifies the
-     * UserHandle of the profile. When quiet mode is changed, this broadcast will carry a boolean
-     * extra {@link #EXTRA_QUIET_MODE} indicating the new state of quiet mode. This is only sent to
-     * registered receivers, not manifest receivers.
+     * changed. This includes when the user toggles the profile's quiet mode. Carries an extra
+     * {@link #EXTRA_USER} that specifies the UserHandle of the profile. When quiet mode is changed,
+     * this broadcast will carry a boolean extra {@link #EXTRA_QUIET_MODE} indicating the new state
+     * of quiet mode. This is only sent to registered receivers, not manifest receivers.
      */
     public static final String ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED =
             "android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED";
 
     /**
-     * Broadcast sent to the managed profile when its availability has changed. This includes when
-     * the user toggles the profile's quiet mode, or when the profile owner suspends the profile.
-     * When quiet mode is changed, this broadcast will carry a boolean extra
-     * {@link #EXTRA_QUIET_MODE} indicating the new state of quiet mode. This is only sent to
-     * registered receivers, not manifest receivers. See also
-     * {@link #ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED}
-     */
-    public static final String ACTION_AVAILABILITY_CHANGED =
-            "android.intent.action.AVAILABILITY_CHANGED";
-
-    /**
      * Sent when the user taps on the clock widget in the system's "quick settings" area.
      */
     public static final String ACTION_QUICK_CLOCK =
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index a82bfbe..c728195 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -339,7 +339,6 @@
     <protected-broadcast android:name="android.app.action.DEVICE_OWNER_CHANGED" />
 
     <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED" />
-    <protected-broadcast android:name="android.intent.action.AVAILABILITY_CHANGED" />
 
     <!-- Added in N -->
     <protected-broadcast android:name="android.intent.action.ANR" />
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 8c16872..a21570ce 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -525,7 +525,7 @@
         List<UserInfo> profilesToStart = new ArrayList<>(profiles.size());
         for (UserInfo user : profiles) {
             if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
-                    && user.id != mCurrentUserId) {
+                    && user.id != mCurrentUserId && !user.isQuietModeEnabled()) {
                 profilesToStart.add(user);
             }
         }
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 1e057aa..637feaa 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -552,22 +552,13 @@
     }
 
     private void broadcastProfileAvailabilityChanges(UserHandle profileHandle,
-            UserHandle parentHandle, Bundle extras) {
-        // Send intent to profile
-        Intent intent = new Intent(Intent.ACTION_AVAILABILITY_CHANGED);
+            UserHandle parentHandle, boolean inQuietMode) {
+        Intent intent = new Intent(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED);
+        intent.putExtra(Intent.EXTRA_QUIET_MODE, inQuietMode);
+        intent.putExtra(Intent.EXTRA_USER, profileHandle);
+        intent.putExtra(Intent.EXTRA_USER_HANDLE, profileHandle.getIdentifier());
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-        intent.putExtras(extras);
-        mContext.sendBroadcastAsUser(intent, profileHandle);
-
-        // Send intent to parent
-        if (parentHandle != null) {
-            intent = new Intent(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED);
-            intent.putExtra(Intent.EXTRA_USER, profileHandle);
-            intent.putExtra(Intent.EXTRA_USER_HANDLE, profileHandle.getIdentifier());
-            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-            intent.putExtras(extras);
-            mContext.sendBroadcastAsUser(intent, parentHandle);
-        }
+        mContext.sendBroadcastAsUser(intent, parentHandle);
     }
 
     @Override
@@ -591,10 +582,21 @@
             }
         }
         if (changed) {
-            Bundle extras = new Bundle();
-            extras.putBoolean(Intent.EXTRA_QUIET_MODE, enableQuietMode);
-            broadcastProfileAvailabilityChanges(profile.getUserHandle(),
-                    parent != null ? parent.getUserHandle() : null, extras);
+            long identity = Binder.clearCallingIdentity();
+            try {
+                if (enableQuietMode) {
+                    ActivityManagerNative.getDefault().stopUser(userHandle, /* force */true, null);
+                } else {
+                    ActivityManagerNative.getDefault().startUserInBackground(userHandle);
+                }
+            } catch (RemoteException e) {
+                Slog.e(LOG_TAG, "fail to start/stop user for quiet mode", e);
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+
+            broadcastProfileAvailabilityChanges(profile.getUserHandle(), parent.getUserHandle(),
+                    enableQuietMode);
         }
     }
 
@@ -606,7 +608,7 @@
                 info = getUserInfoLU(userHandle);
             }
             if (info == null || !info.isManagedProfile()) {
-                throw new IllegalArgumentException("User " + userHandle + " is not a profile");
+                return false;
             }
             return info.isQuietModeEnabled();
         }