Merge "Add atom and puller for AppOps with FeatureIds" into rvc-dev
diff --git a/api/current.txt b/api/current.txt
index c8a7956..1227006 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5943,7 +5943,7 @@
     method public boolean isImportantConversation();
     method public void setAllowBubbles(boolean);
     method public void setBypassDnd(boolean);
-    method public void setConversationId(@Nullable String, @Nullable String);
+    method public void setConversationId(@NonNull String, @NonNull String);
     method public void setDescription(String);
     method public void setGroup(String);
     method public void setImportance(int);
@@ -5956,7 +5956,6 @@
     method public boolean shouldShowLights();
     method public boolean shouldVibrate();
     method public void writeToParcel(android.os.Parcel, int);
-    field public static final String CONVERSATION_CHANNEL_ID_FORMAT = "%1$s : %2$s";
     field @NonNull public static final android.os.Parcelable.Creator<android.app.NotificationChannel> CREATOR;
     field public static final String DEFAULT_CHANNEL_ID = "miscellaneous";
   }
diff --git a/api/system-current.txt b/api/system-current.txt
index 85ad66f..f84b415 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -7199,9 +7199,9 @@
   }
 
   public final class SoftApCapability implements android.os.Parcelable {
+    method public boolean areFeaturesSupported(long);
     method public int describeContents();
     method public int getMaxSupportedClients();
-    method public boolean isFeatureSupported(long);
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApCapability> CREATOR;
     field public static final long SOFTAP_FEATURE_ACS_OFFLOAD = 1L; // 0x1L
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index 7212be8..3f2ec44 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -15,6 +15,7 @@
  */
 package android.app;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
@@ -63,6 +64,7 @@
      * string takes two arguments, in this order: the
      * {@link #getId()} of the original notification channel, and the
      * {@link ShortcutInfo#getId() id} of the conversation.
+     * @hide
      */
     public static final String CONVERSATION_CHANNEL_ID_FORMAT = "%1$s : %2$s";
 
@@ -554,8 +556,8 @@
     }
 
     /**
-     * Sets this channel as being person-centric. Different settings and functionality may be
-     * exposed for people-centric channels.
+     * Sets this channel as being converastion-centric. Different settings and functionality may be
+     * exposed for conversation-centric channels.
      *
      * @param parentChannelId The {@link #getId()} id} of the generic channel that notifications of
      *                        this type would be posted to in absence of a specific conversation id.
@@ -564,8 +566,8 @@
      * @param conversationId The {@link ShortcutInfo#getId()} of the shortcut representing this
      *                       channel's conversation.
      */
-    public void setConversationId(@Nullable String parentChannelId,
-            @Nullable String conversationId) {
+    public void setConversationId(@NonNull String parentChannelId,
+            @NonNull String conversationId) {
         mParentId = parentChannelId;
         mConversationId = conversationId;
     }
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 88edb05..cbbdf63 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -1573,6 +1573,15 @@
                 PRIORITY_CATEGORY_CONVERSATIONS,
         };
 
+        /** @hide */
+        @IntDef(prefix = { "PRIORITY_SENDERS_" }, value = {
+                PRIORITY_SENDERS_ANY,
+                PRIORITY_SENDERS_CONTACTS,
+                PRIORITY_SENDERS_STARRED,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface PrioritySenders {}
+
         /** Any sender is prioritized. */
         public static final int PRIORITY_SENDERS_ANY = 0;
         /** Saved contacts are prioritized. */
@@ -1816,8 +1825,9 @@
          * @param suppressedVisualEffects which visual interruptions should be suppressed from
          *                                notifications that are filtered by DND.
          */
-        public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders,
-                int suppressedVisualEffects, int priorityConversationSenders) {
+        public Policy(int priorityCategories, @PrioritySenders int priorityCallSenders,
+                @PrioritySenders int priorityMessageSenders,
+                int suppressedVisualEffects, @ConversationSenders int priorityConversationSenders) {
             this(priorityCategories, priorityCallSenders, priorityMessageSenders,
                     suppressedVisualEffects, STATE_UNSET, priorityConversationSenders);
         }
diff --git a/services/api/current.txt b/services/api/current.txt
index 4a0a0d8..8c90165 100644
--- a/services/api/current.txt
+++ b/services/api/current.txt
@@ -49,14 +49,15 @@
   public abstract class SystemService {
     ctor public SystemService(@NonNull android.content.Context);
     method @NonNull public final android.content.Context getContext();
-    method public boolean isSupportedUser(@NonNull com.android.server.SystemService.TargetUser);
+    method public boolean isUserSupported(@NonNull com.android.server.SystemService.TargetUser);
     method public void onBootPhase(int);
-    method public void onCleanupUser(@NonNull com.android.server.SystemService.TargetUser);
     method public abstract void onStart();
-    method public void onStartUser(@NonNull com.android.server.SystemService.TargetUser);
-    method public void onStopUser(@NonNull com.android.server.SystemService.TargetUser);
-    method public void onSwitchUser(@Nullable com.android.server.SystemService.TargetUser, @NonNull com.android.server.SystemService.TargetUser);
-    method public void onUnlockUser(@NonNull com.android.server.SystemService.TargetUser);
+    method public void onUserStarting(@NonNull com.android.server.SystemService.TargetUser);
+    method public void onUserStopped(@NonNull com.android.server.SystemService.TargetUser);
+    method public void onUserStopping(@NonNull com.android.server.SystemService.TargetUser);
+    method public void onUserSwitching(@Nullable com.android.server.SystemService.TargetUser, @NonNull com.android.server.SystemService.TargetUser);
+    method public void onUserUnlocked(@NonNull com.android.server.SystemService.TargetUser);
+    method public void onUserUnlocking(@NonNull com.android.server.SystemService.TargetUser);
     method protected final void publishBinderService(@NonNull String, @NonNull android.os.IBinder);
     method protected final void publishBinderService(@NonNull String, @NonNull android.os.IBinder, boolean);
     field public static final int PHASE_ACTIVITY_MANAGER_READY = 550; // 0x226
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 5405fc7..e49c1ed 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -331,7 +331,7 @@
     }
 
     @Override // from SystemService
-    public boolean isSupportedUser(TargetUser user) {
+    public boolean isUserSupported(TargetUser user) {
         return user.getUserInfo().isFull() || user.getUserInfo().isManagedProfile();
     }
 
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
index 9a33fc9..5d2b9f3 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
@@ -201,7 +201,7 @@
     }
 
     @Override // from SystemService
-    public boolean isSupportedUser(TargetUser user) {
+    public boolean isUserSupported(TargetUser user) {
         return user.getUserInfo().isFull() || user.getUserInfo().isManagedProfile();
     }
 
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index d86b223..b1cb138 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -279,7 +279,7 @@
         }
 
         @Override
-        public void onStartUser(TargetUser user) {
+        public void onUserStarting(TargetUser user) {
             mStorageManagerService.snapshotAndMonitorLegacyStorageAppOp(user.getUserHandle());
         }
     }
diff --git a/services/core/java/com/android/server/SystemService.java b/services/core/java/com/android/server/SystemService.java
index aabe98b..e5c0540 100644
--- a/services/core/java/com/android/server/SystemService.java
+++ b/services/core/java/com/android/server/SystemService.java
@@ -238,12 +238,12 @@
      * <p>By default returns {@code true}, but subclasses should extend for optimization, if they
      * don't support some types (like headless system user).
      */
-    public boolean isSupportedUser(@NonNull TargetUser user) {
+    public boolean isUserSupported(@NonNull TargetUser user) {
         return true;
     }
 
     /**
-     * Helper method used to dump which users are {@link #onStartUser(TargetUser) supported}.
+     * Helper method used to dump which users are {@link #onUserStarting(TargetUser) supported}.
      *
      * @hide
      */
@@ -264,7 +264,7 @@
     }
 
     /**
-     * @deprecated subclasses should extend {@link #onStartUser(TargetUser)} instead
+     * @deprecated subclasses should extend {@link #onUserStarting(TargetUser)} instead
      * (which by default calls this method).
      *
      * @hide
@@ -273,7 +273,7 @@
     public void onStartUser(@UserIdInt int userId) {}
 
     /**
-     * @deprecated subclasses should extend {@link #onStartUser(TargetUser)} instead
+     * @deprecated subclasses should extend {@link #onUserStarting(TargetUser)} instead
      * (which by default calls this method).
      *
      * @hide
@@ -287,17 +287,17 @@
      * Called when a new user is starting, for system services to initialize any per-user
      * state they maintain for running users.
      *
-     * <p>This method is only called when the service {@link #isSupportedUser(TargetUser) supports}
+     * <p>This method is only called when the service {@link #isUserSupported(TargetUser) supports}
      * this user.
      *
      * @param user target user
      */
-    public void onStartUser(@NonNull TargetUser user) {
+    public void onUserStarting(@NonNull TargetUser user) {
         onStartUser(user.getUserInfo());
     }
 
     /**
-     * @deprecated subclasses should extend {@link #onUnlockUser(TargetUser)} instead (which by
+     * @deprecated subclasses should extend {@link #onUserUnlocking(TargetUser)} instead (which by
      * default calls this method).
      *
      * @hide
@@ -306,7 +306,7 @@
     public void onUnlockUser(@UserIdInt int userId) {}
 
     /**
-     * @deprecated subclasses should extend {@link #onUnlockUser(TargetUser)} instead (which by
+     * @deprecated subclasses should extend {@link #onUserUnlocking(TargetUser)} instead (which by
      * default calls this method).
      *
      * @hide
@@ -326,19 +326,30 @@
      * the user will transition into the {@code STATE_RUNNING_UNLOCKED} state.
      * Code written inside system services should use
      * {@link UserManager#isUserUnlockingOrUnlocked(int)} to handle both of
-     * these states.
+     * these states, or use {@link #onUserUnlocked(TargetUser)} instead.
      * <p>
-     * This method is only called when the service {@link #isSupportedUser(TargetUser) supports}
+     * This method is only called when the service {@link #isUserSupported(TargetUser) supports}
      * this user.
      *
      * @param user target user
      */
-    public void onUnlockUser(@NonNull TargetUser user) {
+    public void onUserUnlocking(@NonNull TargetUser user) {
         onUnlockUser(user.getUserInfo());
     }
 
     /**
-     * @deprecated subclasses should extend {@link #onSwitchUser(TargetUser, TargetUser)} instead
+     * Called after an existing user is unlocked.
+     *
+     * <p>This method is only called when the service {@link #isUserSupported(TargetUser) supports}
+     * this user.
+     *
+     * @param user target user
+     */
+    public void onUserUnlocked(@NonNull TargetUser user) {
+    }
+
+    /**
+     * @deprecated subclasses should extend {@link #onUserSwitching(TargetUser, TargetUser)} instead
      * (which by default calls this method).
      *
      * @hide
@@ -347,7 +358,7 @@
     public void onSwitchUser(@UserIdInt int toUserId) {}
 
     /**
-     * @deprecated subclasses should extend {@link #onSwitchUser(TargetUser, TargetUser)} instead
+     * @deprecated subclasses should extend {@link #onUserSwitching(TargetUser, TargetUser)} instead
      * (which by default calls this method).
      *
      * @hide
@@ -362,7 +373,7 @@
      * special behavior for whichever user is currently in the foreground.  This is called
      * before any application processes are aware of the new user.
      *
-     * <p>This method is only called when the service {@link #isSupportedUser(TargetUser) supports}
+     * <p>This method is only called when the service {@link #isUserSupported(TargetUser) supports}
      * either of the users ({@code from} or {@code to}).
      *
      * <b>NOTE: </b> both {@code from} and {@code to} are "live" objects
@@ -371,12 +382,12 @@
      * @param from the user switching from
      * @param to the user switching to
      */
-    public void onSwitchUser(@Nullable TargetUser from, @NonNull TargetUser to) {
+    public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
         onSwitchUser((from == null ? null : from.getUserInfo()), to.getUserInfo());
     }
 
     /**
-     * @deprecated subclasses should extend {@link #onStopUser(TargetUser)} instead
+     * @deprecated subclasses should extend {@link #onUserStopping(TargetUser)} instead
      * (which by default calls this method).
      *
      * @hide
@@ -385,7 +396,7 @@
     public void onStopUser(@UserIdInt int userId) {}
 
     /**
-     * @deprecated subclasses should extend {@link #onStopUser(TargetUser)} instead
+     * @deprecated subclasses should extend {@link #onUserStopping(TargetUser)} instead
      * (which by default calls this method).
      *
      * @hide
@@ -402,19 +413,19 @@
      * broadcast to the user; it is a good place to stop making use of any resources of that
      * user (such as binding to a service running in the user).
      *
-     * <p>This method is only called when the service {@link #isSupportedUser(TargetUser) supports}
+     * <p>This method is only called when the service {@link #isUserSupported(TargetUser) supports}
      * this user.
      *
      * <p>NOTE: This is the last callback where the callee may access the target user's CE storage.
      *
      * @param user target user
      */
-    public void onStopUser(@NonNull TargetUser user) {
+    public void onUserStopping(@NonNull TargetUser user) {
         onStopUser(user.getUserInfo());
     }
 
     /**
-     * @deprecated subclasses should extend {@link #onCleanupUser(TargetUser)} instead (which by
+     * @deprecated subclasses should extend {@link #onUserStopped(TargetUser)} instead (which by
      * default calls this method).
      *
      * @hide
@@ -423,7 +434,7 @@
     public void onCleanupUser(@UserIdInt int userId) {}
 
     /**
-     * @deprecated subclasses should extend {@link #onCleanupUser(TargetUser)} instead (which by
+     * @deprecated subclasses should extend {@link #onUserStopped(TargetUser)} instead (which by
      * default calls this method).
      *
      * @hide
@@ -434,20 +445,16 @@
     }
 
     /**
-     * Called when an existing user is stopping, for system services to finalize any per-user
-     * state they maintain for running users.  This is called after all application process
-     * teardown of the user is complete.
+     * Called after an existing user is stopped.
      *
-     * <p>This method is only called when the service {@link #isSupportedUser(TargetUser) supports}
+     * <p>This is called after all application process teardown of the user is complete.
+     *
+     * <p>This method is only called when the service {@link #isUserSupported(TargetUser) supports}
      * this user.
      *
-     * <p>NOTE: When this callback is called, the CE storage for the target user may not be
-     * accessible already.  Use {@link #onStopUser(TargetUser)} instead if you need to access the CE
-     * storage.
-     *
      * @param user target user
      */
-    public void onCleanupUser(@NonNull TargetUser user) {
+    public void onUserStopped(@NonNull TargetUser user) {
         onCleanupUser(user.getUserInfo());
     }
 
diff --git a/services/core/java/com/android/server/SystemServiceManager.java b/services/core/java/com/android/server/SystemServiceManager.java
index e7f7846..f16f6ef 100644
--- a/services/core/java/com/android/server/SystemServiceManager.java
+++ b/services/core/java/com/android/server/SystemServiceManager.java
@@ -51,7 +51,8 @@
 
     // Constants used on onUser(...)
     private static final String START = "Start";
-    private static final String UNLOCK = "Unlock";
+    private static final String UNLOCKING = "Unlocking";
+    private static final String UNLOCKED = "Unlocked";
     private static final String SWITCH = "Switch";
     private static final String STOP = "Stop";
     private static final String CLEANUP = "Cleanup";
@@ -260,7 +261,14 @@
      * Unlocks the given user.
      */
     public void unlockUser(final @UserIdInt int userHandle) {
-        onUser(UNLOCK, userHandle);
+        onUser(UNLOCKING, userHandle);
+    }
+
+    /**
+     * Called after the user was unlocked.
+     */
+    public void onUserUnlocked(final @UserIdInt int userHandle) {
+        onUser(UNLOCKED, userHandle);
     }
 
     /**
@@ -304,12 +312,12 @@
         for (int i = 0; i < serviceLen; i++) {
             final SystemService service = mServices.get(i);
             final String serviceName = service.getClass().getName();
-            boolean supported = service.isSupportedUser(curUser);
+            boolean supported = service.isUserSupported(curUser);
 
             // Must check if either curUser or prevUser is supported (for example, if switching from
             // unsupported to supported, we still need to notify the services)
             if (!supported && prevUser != null) {
-                supported = service.isSupportedUser(prevUser);
+                supported = service.isUserSupported(prevUser);
             }
 
             if (!supported) {
@@ -328,19 +336,22 @@
             try {
                 switch (onWhat) {
                     case SWITCH:
-                        service.onSwitchUser(prevUser, curUser);
+                        service.onUserSwitching(prevUser, curUser);
                         break;
                     case START:
-                        service.onStartUser(curUser);
+                        service.onUserStarting(curUser);
                         break;
-                    case UNLOCK:
-                        service.onUnlockUser(curUser);
+                    case UNLOCKING:
+                        service.onUserUnlocking(curUser);
+                        break;
+                    case UNLOCKED:
+                        service.onUserUnlocked(curUser);
                         break;
                     case STOP:
-                        service.onStopUser(curUser);
+                        service.onUserStopping(curUser);
                         break;
                     case CLEANUP:
-                        service.onCleanupUser(curUser);
+                        service.onUserStopped(curUser);
                         break;
                     default:
                         throw new IllegalArgumentException(onWhat + " what?");
diff --git a/services/core/java/com/android/server/UserspaceRebootLogger.java b/services/core/java/com/android/server/UserspaceRebootLogger.java
index 74f113f..9a9374c 100644
--- a/services/core/java/com/android/server/UserspaceRebootLogger.java
+++ b/services/core/java/com/android/server/UserspaceRebootLogger.java
@@ -26,6 +26,7 @@
 
 import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.text.TextUtils;
 import android.util.Slog;
 
 import com.android.internal.util.FrameworkStatsLog;
@@ -45,7 +46,7 @@
             "sys.userspace_reboot.log.last_started";
     private static final String USERSPACE_REBOOT_LAST_FINISHED_PROPERTY =
             "sys.userspace_reboot.log.last_finished";
-    private static final String BOOT_REASON_PROPERTY = "sys.boot.reason";
+    private static final String LAST_BOOT_REASON_PROPERTY = "sys.boot.reason.last";
 
     private UserspaceRebootLogger() {}
 
@@ -111,26 +112,28 @@
         if (SystemProperties.getLong(USERSPACE_REBOOT_LAST_STARTED_PROPERTY, -1) != -1) {
             return USERSPACE_REBOOT_REPORTED__OUTCOME__SUCCESS;
         }
-        String reason = SystemProperties.get(BOOT_REASON_PROPERTY, "");
+        String reason = TextUtils.emptyIfNull(SystemProperties.get(LAST_BOOT_REASON_PROPERTY, ""));
         if (reason.startsWith("reboot,")) {
             reason = reason.substring("reboot".length());
         }
-        switch (reason) {
-            case "userspace_failed,watchdog_fork":
-                // Since fork happens before shutdown sequence, attribute it to
-                // USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_SHUTDOWN_SEQUENCE_ABORTED.
-            case "userspace_failed,shutdown_aborted":
-                return USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_SHUTDOWN_SEQUENCE_ABORTED;
-            case "userspace_failed,init_user0_failed":
-                // init_user0 will fail if userdata wasn't remounted correctly, attribute to
-                // USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_USERDATA_REMOUNT.
-            case "mount_userdata_failed":
-                return USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_USERDATA_REMOUNT;
-            case "userspace_failed,watchdog_triggered":
-                return
-                    USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_USERSPACE_REBOOT_WATCHDOG_TRIGGERED;
-            default:
-                return USERSPACE_REBOOT_REPORTED__OUTCOME__OUTCOME_UNKNOWN;
+        if (reason.startsWith("userspace_failed,watchdog_fork")) {
+            return USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_SHUTDOWN_SEQUENCE_ABORTED;
         }
+        if (reason.startsWith("userspace_failed,shutdown_aborted")) {
+            return USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_SHUTDOWN_SEQUENCE_ABORTED;
+        }
+        if (reason.startsWith("mount_userdata_failed")) {
+            return USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_USERDATA_REMOUNT;
+        }
+        if (reason.startsWith("userspace_failed,init_user0")) {
+            return USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_USERDATA_REMOUNT;
+        }
+        if (reason.startsWith("userspace_failed,enablefilecrypto")) {
+            return USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_USERDATA_REMOUNT;
+        }
+        if (reason.startsWith("userspace_failed,watchdog_triggered")) {
+            return USERSPACE_REBOOT_REPORTED__OUTCOME__FAILED_USERSPACE_REBOOT_WATCHDOG_TRIGGERED;
+        }
+        return USERSPACE_REBOOT_REPORTED__OUTCOME__OUTCOME_UNKNOWN;
     }
 }
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index fb48db4..a7125b4 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -146,6 +146,7 @@
     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 80;
     static final int USER_SWITCH_CALLBACKS_TIMEOUT_MSG = 90;
     static final int USER_UNLOCK_MSG = 100;
+    static final int USER_UNLOCKED_MSG = 105;
     static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 110;
     static final int START_USER_SWITCH_FG_MSG = 120;
 
@@ -625,6 +626,9 @@
                     FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__FRAMEWORK_BOOT_COMPLETED,
                     elapsedTimeMs);
         }
+
+        mHandler.obtainMessage(USER_UNLOCKED_MSG, userId, 0).sendToTarget();
+
         final Intent bootIntent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
         bootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
         bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
@@ -2366,6 +2370,9 @@
                 });
                 finishUserUnlocked((UserState) msg.obj);
                 break;
+            case USER_UNLOCKED_MSG:
+                mInjector.getSystemServiceManager().onUserUnlocked(msg.arg1);
+                break;
             case USER_CURRENT_MSG:
                 mInjector.batteryStatsServiceNoteEvent(
                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
index 8206fef..2672f84 100644
--- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
@@ -713,7 +713,7 @@
 
     /**
      * Gets a list of all supported users (i.e., those that pass the
-     * {@link #isSupportedUser(TargetUser)}check).
+     * {@link #isUserSupported(TargetUser)}check).
      */
     @NonNull
     protected List<UserInfo> getSupportedUsers() {
@@ -722,7 +722,7 @@
         final List<UserInfo> supportedUsers = new ArrayList<>(size);
         for (int i = 0; i < size; i++) {
             final UserInfo userInfo = allUsers[i];
-            if (isSupportedUser(new TargetUser(userInfo))) {
+            if (isUserSupported(new TargetUser(userInfo))) {
                 supportedUsers.add(userInfo);
             }
         }
diff --git a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
index 8d090f1..801d75b 100644
--- a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
+++ b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
@@ -218,11 +218,7 @@
                         packageInstaller.getSessionInfo(sessionId);
                 if (sessionInfo.isStagedSessionReady() && markStagedSessionHandled(rollbackId)) {
                     mContext.unregisterReceiver(listener);
-                    if (logPackage != null) {
-                        // We save the rollback id so that after reboot, we can log if rollback was
-                        // successful or not. If logPackage is null, then there is nothing to log.
-                        saveStagedRollbackId(rollbackId);
-                    }
+                    saveStagedRollbackId(rollbackId);
                     WatchdogRollbackLogger.logEvent(logPackage,
                             FrameworkStatsLog
                             .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_BOOT_TRIGGERED,
diff --git a/services/core/java/com/android/server/rollback/WatchdogRollbackLogger.java b/services/core/java/com/android/server/rollback/WatchdogRollbackLogger.java
index 1be6f22..659de00 100644
--- a/services/core/java/com/android/server/rollback/WatchdogRollbackLogger.java
+++ b/services/core/java/com/android/server/rollback/WatchdogRollbackLogger.java
@@ -159,6 +159,12 @@
             return;
         }
 
+        // If no logging packages are found, use a null package to ensure the rollback status
+        // is still logged.
+        if (oldLoggingPackages.isEmpty()) {
+            oldLoggingPackages.add(null);
+        }
+
         for (VersionedPackage oldLoggingPackage : oldLoggingPackages) {
             if (sessionInfo.isStagedSessionApplied()) {
                 logEvent(oldLoggingPackage,
diff --git a/services/people/java/com/android/server/people/PeopleService.java b/services/people/java/com/android/server/people/PeopleService.java
index 2499614..5d7f4e9 100644
--- a/services/people/java/com/android/server/people/PeopleService.java
+++ b/services/people/java/com/android/server/people/PeopleService.java
@@ -71,12 +71,12 @@
     }
 
     @Override
-    public void onUnlockUser(@NonNull TargetUser targetUser) {
+    public void onUserUnlocking(@NonNull TargetUser targetUser) {
         mDataManager.onUserUnlocked(targetUser.getUserIdentifier());
     }
 
     @Override
-    public void onStopUser(@NonNull TargetUser targetUser) {
+    public void onUserStopping(@NonNull TargetUser targetUser) {
         mDataManager.onUserStopped(targetUser.getUserIdentifier());
     }
 
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index 61f2c50..14c7f04 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -110,18 +110,18 @@
         }
 
         @Override
-        public void onSwitchUser(TargetUser from, TargetUser to) {
+        public void onUserSwitching(TargetUser from, TargetUser to) {
             FgThread.getHandler()
                     .postAtFrontOfQueue(() -> mUsbService.onSwitchUser(to.getUserIdentifier()));
         }
 
         @Override
-        public void onStopUser(TargetUser userInfo) {
+        public void onUserStopping(TargetUser userInfo) {
             mUsbService.onStopUser(userInfo.getUserHandle());
         }
 
         @Override
-        public void onUnlockUser(TargetUser userInfo) {
+        public void onUserUnlocking(TargetUser userInfo) {
             mUsbService.onUnlockUser(userInfo.getUserIdentifier());
         }
     }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 8378d8e..3c0e0af 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -167,7 +167,7 @@
     }
 
     @Override
-    public boolean isSupportedUser(TargetUser user) {
+    public boolean isUserSupported(TargetUser user) {
         return isSupported(user.getUserInfo());
     }
 
diff --git a/tests/RollbackTest/NetworkStagedRollbackTest/src/com/android/tests/rollback/host/NetworkStagedRollbackTest.java b/tests/RollbackTest/NetworkStagedRollbackTest/src/com/android/tests/rollback/host/NetworkStagedRollbackTest.java
index d4e34f9..f6dcff4 100644
--- a/tests/RollbackTest/NetworkStagedRollbackTest/src/com/android/tests/rollback/host/NetworkStagedRollbackTest.java
+++ b/tests/RollbackTest/NetworkStagedRollbackTest/src/com/android/tests/rollback/host/NetworkStagedRollbackTest.java
@@ -53,6 +53,7 @@
 
     private static final String ROLLBACK_INITIATE = "ROLLBACK_INITIATE";
     private static final String ROLLBACK_BOOT_TRIGGERED = "ROLLBACK_BOOT_TRIGGERED";
+    private static final String ROLLBACK_SUCCESS = "ROLLBACK_SUCCESS";
 
     private WatchdogEventLogger mLogger = new WatchdogEventLogger();
 
@@ -93,6 +94,7 @@
                     REASON_EXPLICIT_HEALTH_CHECK, null));
             assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_BOOT_TRIGGERED, null,
                     null, null));
+            assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_SUCCESS, null, null, null));
         } finally {
             // Reconnect internet again so we won't break tests which assume internet available
             getDevice().executeShellCommand("svc wifi enable");
diff --git a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
index 43759cf..4afebb5 100644
--- a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
+++ b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
@@ -76,10 +76,10 @@
 
     private static final String REASON_APP_CRASH = "REASON_APP_CRASH";
     private static final String REASON_NATIVE_CRASH = "REASON_NATIVE_CRASH";
-    private static final String REASON_EXPLICIT_HEALTH_CHECK = "REASON_EXPLICIT_HEALTH_CHECK";
 
     private static final String ROLLBACK_INITIATE = "ROLLBACK_INITIATE";
     private static final String ROLLBACK_BOOT_TRIGGERED = "ROLLBACK_BOOT_TRIGGERED";
+    private static final String ROLLBACK_SUCCESS = "ROLLBACK_SUCCESS";
 
     private WatchdogEventLogger mLogger = new WatchdogEventLogger();
 
@@ -146,6 +146,7 @@
                 REASON_APP_CRASH, TESTAPP_A));
         assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_BOOT_TRIGGERED, null,
                 null, null));
+        assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_SUCCESS, null, null, null));
     }
 
     @Test
@@ -179,6 +180,7 @@
                         REASON_NATIVE_CRASH, null));
         assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_BOOT_TRIGGERED, null,
                 null, null));
+        assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_SUCCESS, null, null, null));
     }
 
     @Test
@@ -219,6 +221,7 @@
                         REASON_NATIVE_CRASH, null));
         assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_BOOT_TRIGGERED, null,
                 null, null));
+        assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_SUCCESS, null, null, null));
     }
 
     /**
@@ -290,6 +293,7 @@
                 REASON_APP_CRASH, TESTAPP_A));
         assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_BOOT_TRIGGERED, null,
                 null, null));
+        assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_SUCCESS, null, null, null));
     }
 
     /**
diff --git a/wifi/java/android/net/wifi/SoftApCapability.java b/wifi/java/android/net/wifi/SoftApCapability.java
index a831984..18b26db 100644
--- a/wifi/java/android/net/wifi/SoftApCapability.java
+++ b/wifi/java/android/net/wifi/SoftApCapability.java
@@ -100,12 +100,12 @@
     }
 
     /**
-     * Returns true when feature supported, otherwise false.
+     * Returns true when all of the queried features are supported, otherwise false.
      *
-     * @param feature one of feature from {@link HotspotFeatures}
+     * @param features One or combination of the features from {@link @HotspotFeatures}
      */
-    public boolean isFeatureSupported(@HotspotFeatures long feature) {
-        return (mSupportedFeatures & feature) == feature;
+    public boolean areFeaturesSupported(@HotspotFeatures long features) {
+        return (mSupportedFeatures & features) == features;
     }
 
     /**
@@ -122,7 +122,7 @@
      * Constructor with combination of the feature.
      * Zero to no supported feature.
      *
-     * @param features One or combination of the feature from {@link @HotspotFeatures}.
+     * @param features One or combination of the features from {@link @HotspotFeatures}.
      * @hide
      */
     public SoftApCapability(@HotspotFeatures long features) {
diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java
index ae5bf7d..2b47623 100644
--- a/wifi/java/android/net/wifi/SoftApConfiguration.java
+++ b/wifi/java/android/net/wifi/SoftApConfiguration.java
@@ -762,7 +762,8 @@
          * {@link #setBand(@BandType int)}.
          *
          * The channel auto selection will offload to driver when
-         * {@link SoftApCapability#isFeatureSupported(SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD)}
+         * {@link SoftApCapability#areFeaturesSupported(
+         * SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD)}
          * return true. Driver will auto select best channel which based on environment
          * interference to get best performance. Check {@link SoftApCapability} to get more detail.
          *
@@ -807,7 +808,7 @@
          *
          * <p>
          * Use {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)} and
-         * {@link SoftApCapability#isFeatureSupported(int)}
+         * {@link SoftApCapability#areFeaturesSupported(int)}
          * with {@link SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT} to determine whether
          * or not this feature is supported.
          *
@@ -882,7 +883,7 @@
          * <p>
          * This method requires hardware support. Hardware support can be determined using
          * {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)} and
-         * {@link SoftApCapability#isFeatureSupported(int)}
+         * {@link SoftApCapability#areFeaturesSupported(int)}
          * with {@link SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT}
          *
          * <p>