Merge "Fix a few log messages that didn't have a space in the SoundTriggerTestApp" into nyc-mr1-dev
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index d82629d..4098772 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -72,6 +72,8 @@
 static const char LAST_TIME_CHANGED_FILE_PATH[] = "/data/system/time/last_time_change";
 static const char ACCURATE_TIME_FLAG_FILE_NAME[] = "time_is_accurate";
 static const char ACCURATE_TIME_FLAG_FILE_PATH[] = "/data/system/time/time_is_accurate";
+// Java timestamp format. Don't show the clock if the date is before 2000-01-01 00:00:00.
+static const long long ACCURATE_TIME_EPOCH = 946684800000;
 static const char EXIT_PROP_NAME[] = "service.bootanim.exit";
 static const int ANIM_ENTRY_NAME_MAX = 256;
 
@@ -932,8 +934,9 @@
         clock_gettime(CLOCK_REALTIME, &now);
         // Match the Java timestamp format
         long long rtcNow = (now.tv_sec * 1000LL) + (now.tv_nsec / 1000000LL);
-        if (lastChangedTime > rtcNow - MAX_TIME_IN_PAST
-            && lastChangedTime < rtcNow + MAX_TIME_IN_FUTURE) {
+        if (ACCURATE_TIME_EPOCH < rtcNow
+            && lastChangedTime > (rtcNow - MAX_TIME_IN_PAST)
+            && lastChangedTime < (rtcNow + MAX_TIME_IN_FUTURE)) {
             mTimeIsAccurate = true;
         }
       }
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index eff116b..0059d4d 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -149,7 +149,7 @@
     private DevicePolicyManager mDevicePolicyManager;
     private ILockSettings mLockSettingsService;
     private UserManager mUserManager;
-    private final Handler mHandler = new Handler();
+    private final Handler mHandler;
 
     /**
      * Use {@link TrustManager#isTrustUsuallyManaged(int)}.
@@ -231,6 +231,9 @@
     public LockPatternUtils(Context context) {
         mContext = context;
         mContentResolver = context.getContentResolver();
+
+        Looper looper = Looper.myLooper();
+        mHandler = looper != null ? new Handler(looper) : null;
     }
 
     private ILockSettings getLockSettings() {
@@ -1506,6 +1509,10 @@
         if (callback == null) {
             return null;
         } else {
+            if (mHandler == null) {
+                throw new IllegalStateException("Must construct LockPatternUtils on a looper thread"
+                        + " to use progress callbacks.");
+            }
             return new ICheckCredentialProgressCallback.Stub() {
 
                 @Override
diff --git a/docs/html/_redirects.yaml b/docs/html/_redirects.yaml
index 11e06f1..d4732f8 100644
--- a/docs/html/_redirects.yaml
+++ b/docs/html/_redirects.yaml
@@ -801,8 +801,8 @@
   to: http://android-developers.blogspot.com/2016/03/first-preview-of-android-n-developer.html
 - from: /reference/org/apache/http/...
   to: /about/versions/marshmallow/android-6.0-changes.html#behavior-apache-http-client
-- from: /shareables/
-  to: https://commondatastorage.googleapis.com/androiddevelopers/shareables/
+- from: /shareables/...
+  to: https://commondatastorage.googleapis.com/androiddevelopers/shareables/...
 - from: /downloads/
   to: https://commondatastorage.googleapis.com/androiddevelopers/
 - from: /training/performance/battery/network/action-any-traffic.html
diff --git a/location/java/android/location/GnssMeasurementsEvent.java b/location/java/android/location/GnssMeasurementsEvent.java
index 3151694..7db0466 100644
--- a/location/java/android/location/GnssMeasurementsEvent.java
+++ b/location/java/android/location/GnssMeasurementsEvent.java
@@ -98,13 +98,13 @@
             throw new InvalidParameterException("Parameter 'clock' must not be null.");
         }
         if (measurements == null || measurements.length == 0) {
-            throw new InvalidParameterException(
-                    "Parameter 'measurements' must not be null or empty.");
+            mReadOnlyMeasurements = Collections.emptyList();
+        } else {
+            Collection<GnssMeasurement> measurementCollection = Arrays.asList(measurements);
+            mReadOnlyMeasurements = Collections.unmodifiableCollection(measurementCollection);
         }
 
         mClock = clock;
-        Collection<GnssMeasurement> measurementCollection = Arrays.asList(measurements);
-        mReadOnlyMeasurements = Collections.unmodifiableCollection(measurementCollection);
     }
 
     /**
diff --git a/media/jni/android_media_MediaDataSource.cpp b/media/jni/android_media_MediaDataSource.cpp
index d07942b..2ab7e39 100644
--- a/media/jni/android_media_MediaDataSource.cpp
+++ b/media/jni/android_media_MediaDataSource.cpp
@@ -26,6 +26,7 @@
 #include "JNIHelp.h"
 
 #include <binder/MemoryDealer.h>
+#include <drm/drm_framework_common.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <nativehelper/ScopedLocalRef.h>
 
@@ -159,4 +160,8 @@
     return String8::format("JMediaDataSource(pid %d, uid %d)", getpid(), getuid());
 }
 
+sp<DecryptHandle> JMediaDataSource::DrmInitialization(const char * /* mime */) {
+    return NULL;
+}
+
 }  // namespace android
diff --git a/media/jni/android_media_MediaDataSource.h b/media/jni/android_media_MediaDataSource.h
index 378baf4..39405d2 100644
--- a/media/jni/android_media_MediaDataSource.h
+++ b/media/jni/android_media_MediaDataSource.h
@@ -47,6 +47,7 @@
     virtual void close();
     virtual uint32_t getFlags();
     virtual String8 toString();
+    virtual sp<DecryptHandle> DrmInitialization(const char *mime);
 
 private:
     // Protect all member variables with mLock because this object will be
diff --git a/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java b/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java
index d830c61..a37590d 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java
@@ -22,6 +22,7 @@
 import android.content.Context;
 import android.os.Bundle;
 import android.text.Editable;
+import android.text.TextUtils;
 import android.text.TextWatcher;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -91,6 +92,14 @@
                             return false;
                         }
 
+                        // Returning false in this method will bubble the event up to
+                        // {@link BaseActivity#onKeyDown}. In order to prevent backspace popping
+                        // documents once the textView is empty, we are going to trap it here.
+                        if (keyCode == KeyEvent.KEYCODE_DEL
+                                && TextUtils.isEmpty(mDisplayName.getText())) {
+                            return true;
+                        }
+
                         if (keyCode == KeyEvent.KEYCODE_ENTER && mSave.isEnabled()) {
                             performSave();
                             return true;
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 29c54e9..88d6c14 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -454,7 +454,7 @@
 
     @Override
     public String toString() {
-        return mPackageName + "/" + mTag;
+        return mPackageName + "/" + mTag + " (uid=" + mUserId + ")";
     }
 
     private void postAdjustLocalVolume(final int stream, final int direction, final int flags,
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index a4d2cd2..a3f09c0 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -47,10 +47,12 @@
 import android.os.IBinder;
 import android.os.Message;
 import android.os.PowerManager;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.Settings;
 import android.speech.RecognizerIntent;
 import android.text.TextUtils;
@@ -67,6 +69,7 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -97,7 +100,9 @@
     private ContentResolver mContentResolver;
     private SettingsObserver mSettingsObserver;
 
-    private int mCurrentUserId = -1;
+    // List of user IDs running in the foreground.
+    // Multiple users can be in the foreground if the work profile is on.
+    private final List<Integer> mCurrentUserIdList = new ArrayList<>();
 
     // Used to notify system UI when remote volume was changed. TODO find a
     // better way to handle this.
@@ -181,22 +186,26 @@
     }
 
     @Override
-    public void onStartUser(int userHandle) {
+    public void onStartUser(int userId) {
+        if (DEBUG) Log.d(TAG, "onStartUser: " + userId);
         updateUser();
     }
 
     @Override
-    public void onSwitchUser(int userHandle) {
+    public void onSwitchUser(int userId) {
+        if (DEBUG) Log.d(TAG, "onSwitchUser: " + userId);
         updateUser();
     }
 
     @Override
-    public void onStopUser(int userHandle) {
+    public void onStopUser(int userId) {
+        if (DEBUG) Log.d(TAG, "onStopUser: " + userId);
         synchronized (mLock) {
-            UserRecord user = mUserRecords.get(userHandle);
+            UserRecord user = mUserRecords.get(userId);
             if (user != null) {
                 destroyUserLocked(user);
             }
+            updateUser();
         }
     }
 
@@ -228,18 +237,23 @@
 
     private void updateUser() {
         synchronized (mLock) {
-            int userId = ActivityManager.getCurrentUser();
-            if (mCurrentUserId != userId) {
-                final int oldUserId = mCurrentUserId;
-                mCurrentUserId = userId; // do this first
-
-                UserRecord oldUser = mUserRecords.get(oldUserId);
-                if (oldUser != null) {
-                    oldUser.stopLocked();
+            UserManager manager = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
+            int currentUser = ActivityManager.getCurrentUser();
+            int[] userIds = manager.getEnabledProfileIds(currentUser);
+            mCurrentUserIdList.clear();
+            if (userIds != null && userIds.length > 0) {
+                for (int userId : userIds) {
+                    mCurrentUserIdList.add(userId);
                 }
-
-                UserRecord newUser = getOrCreateUser(userId);
-                newUser.startLocked();
+            } else {
+                // This shouldn't happen.
+                Log.w(TAG, "Failed to get enabled profiles.");
+                mCurrentUserIdList.add(currentUser);
+            }
+            for (int userId : mCurrentUserIdList) {
+                if (mUserRecords.get(userId) == null) {
+                    mUserRecords.put(userId, new UserRecord(getContext(), userId));
+                }
             }
         }
     }
@@ -272,7 +286,6 @@
      * @param user The user to dispose of
      */
     private void destroyUserLocked(UserRecord user) {
-        user.stopLocked();
         user.destroyLocked();
         mUserRecords.remove(user.mUserId);
     }
@@ -436,9 +449,9 @@
         }
 
         mAllSessions.add(session);
-        mPriorityStack.addSession(session);
+        mPriorityStack.addSession(session, mCurrentUserIdList.contains(userId));
 
-        UserRecord user = getOrCreateUser(userId);
+        UserRecord user = mUserRecords.get(userId);
         user.addSessionLocked(session);
 
         mHandler.post(MessageHandler.MSG_SESSIONS_CHANGED, userId, 0);
@@ -449,15 +462,6 @@
         return session;
     }
 
-    private UserRecord getOrCreateUser(int userId) {
-        UserRecord user = mUserRecords.get(userId);
-        if (user == null) {
-            user = new UserRecord(getContext(), userId);
-            mUserRecords.put(userId, user);
-        }
-        return user;
-    }
-
     private int findIndexOfSessionsListenerLocked(IActiveSessionsListener listener) {
         for (int i = mSessionsListeners.size() - 1; i >= 0; i--) {
             if (mSessionsListeners.get(i).mListener.asBinder() == listener.asBinder()) {
@@ -536,13 +540,6 @@
             restoreMediaButtonReceiver();
         }
 
-        public void startLocked() {
-        }
-
-        public void stopLocked() {
-            // nothing for now
-        }
-
         public void destroyLocked() {
             for (int i = mSessions.size() - 1; i >= 0; i--) {
                 MediaSessionRecord session = mSessions.get(i);
@@ -578,7 +575,7 @@
 
         private void restoreMediaButtonReceiver() {
             String receiverName = Settings.Secure.getStringForUser(mContentResolver,
-                    Settings.System.MEDIA_BUTTON_RECEIVER, UserHandle.USER_CURRENT);
+                    Settings.System.MEDIA_BUTTON_RECEIVER, mUserId);
             if (!TextUtils.isEmpty(receiverName)) {
                 ComponentName eventReceiver = ComponentName.unflattenFromString(receiverName);
                 if (eventReceiver == null) {
@@ -767,12 +764,22 @@
                 synchronized (mLock) {
                     // If we don't have a media button receiver to fall back on
                     // include non-playing sessions for dispatching
-                    UserRecord ur = mUserRecords.get(mCurrentUserId);
-                    boolean useNotPlayingSessions = (ur == null) ||
-                            (ur.mLastMediaButtonReceiver == null
-                                && ur.mRestoredMediaButtonReceiver == null);
-                    MediaSessionRecord session = mPriorityStack
-                            .getDefaultMediaButtonSession(mCurrentUserId, useNotPlayingSessions);
+                    boolean useNotPlayingSessions = true;
+                    for (int userId : mCurrentUserIdList) {
+                        UserRecord ur = mUserRecords.get(userId);
+                        if (ur.mLastMediaButtonReceiver != null
+                                || ur.mRestoredMediaButtonReceiver != null) {
+                            useNotPlayingSessions = false;
+                            break;
+                        }
+                    }
+
+                    if (DEBUG) {
+                        Log.d(TAG, "dispatchMediaKeyEvent, useNotPlayingSessions="
+                                + useNotPlayingSessions);
+                    }
+                    MediaSessionRecord session = mPriorityStack.getDefaultMediaButtonSession(
+                            mCurrentUserIdList, useNotPlayingSessions);
                     if (isVoiceKey(keyEvent.getKeyCode())) {
                         handleVoiceKeyEventLocked(keyEvent, needWakeLock, session);
                     } else {
@@ -786,13 +793,11 @@
 
         @Override
         public void dispatchAdjustVolume(int suggestedStream, int delta, int flags) {
-            final int pid = Binder.getCallingPid();
-            final int uid = Binder.getCallingUid();
             final long token = Binder.clearCallingIdentity();
             try {
                 synchronized (mLock) {
                     MediaSessionRecord session = mPriorityStack
-                            .getDefaultVolumeSession(mCurrentUserId);
+                            .getDefaultVolumeSession(mCurrentUserIdList);
                     dispatchAdjustVolumeLocked(suggestedStream, delta, flags, session);
                 }
             } finally {
@@ -899,7 +904,7 @@
                 }
             } else {
                 session.adjustVolume(direction, flags, getContext().getPackageName(),
-                        UserHandle.myUserId(), true);
+                        Process.SYSTEM_UID, true);
             }
         }
 
@@ -946,13 +951,16 @@
                 // won't release it later
                 session.sendMediaButton(keyEvent,
                         needWakeLock ? mKeyEventReceiver.mLastTimeoutId : -1,
-                        mKeyEventReceiver, getContext().getApplicationInfo().uid,
+                        mKeyEventReceiver, Process.SYSTEM_UID,
                         getContext().getPackageName());
             } else {
                 // Launch the last PendingIntent we had with priority
-                UserRecord user = mUserRecords.get(mCurrentUserId);
-                if (user != null && (user.mLastMediaButtonReceiver != null
-                        || user.mRestoredMediaButtonReceiver != null)) {
+                for (int userId : mCurrentUserIdList) {
+                    UserRecord user = mUserRecords.get(userId);
+                    if (user.mLastMediaButtonReceiver == null
+                            && user.mRestoredMediaButtonReceiver == null) {
+                        continue;
+                    }
                     if (DEBUG) {
                         Log.d(TAG, "Sending media key to last known PendingIntent "
                                 + user.mLastMediaButtonReceiver + " or restored Intent "
@@ -972,30 +980,30 @@
                         } else {
                             mediaButtonIntent.setComponent(user.mRestoredMediaButtonReceiver);
                             getContext().sendBroadcastAsUser(mediaButtonIntent,
-                                    new UserHandle(mCurrentUserId));
+                                    UserHandle.of(userId));
                         }
                     } catch (CanceledException e) {
                         Log.i(TAG, "Error sending key event to media button receiver "
                                 + user.mLastMediaButtonReceiver, e);
                     }
-                } else {
-                    if (DEBUG) {
-                        Log.d(TAG, "Sending media key ordered broadcast");
-                    }
-                    if (needWakeLock) {
-                        mMediaEventWakeLock.acquire();
-                    }
-                    // Fallback to legacy behavior
-                    Intent keyIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
-                    keyIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
-                    keyIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
-                    if (needWakeLock) {
-                        keyIntent.putExtra(EXTRA_WAKELOCK_ACQUIRED,
-                                WAKELOCK_RELEASE_ON_FINISHED);
-                    }
-                    getContext().sendOrderedBroadcastAsUser(keyIntent, UserHandle.CURRENT,
-                            null, mKeyEventDone, mHandler, Activity.RESULT_OK, null, null);
+                    return;
                 }
+                if (DEBUG) {
+                    Log.d(TAG, "Sending media key ordered broadcast");
+                }
+                if (needWakeLock) {
+                    mMediaEventWakeLock.acquire();
+                }
+                // Fallback to legacy behavior
+                Intent keyIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
+                keyIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+                keyIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
+                if (needWakeLock) {
+                    keyIntent.putExtra(EXTRA_WAKELOCK_ACQUIRED, WAKELOCK_RELEASE_ON_FINISHED);
+                }
+                // Send broadcast only to the full user.
+                getContext().sendOrderedBroadcastAsUser(keyIntent, UserHandle.CURRENT,
+                        null, mKeyEventDone, mHandler, Activity.RESULT_OK, null, null);
             }
         }
 
@@ -1025,6 +1033,7 @@
                 if (voiceIntent != null) {
                     voiceIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                             | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+                    if (DEBUG) Log.d(TAG, "voiceIntent: " + voiceIntent);
                     getContext().startActivityAsUser(voiceIntent, UserHandle.CURRENT);
                 }
             } catch (ActivityNotFoundException e) {
diff --git a/services/core/java/com/android/server/media/MediaSessionStack.java b/services/core/java/com/android/server/media/MediaSessionStack.java
index cc007ef..3327b36 100644
--- a/services/core/java/com/android/server/media/MediaSessionStack.java
+++ b/services/core/java/com/android/server/media/MediaSessionStack.java
@@ -32,7 +32,7 @@
  * Keeps track of media sessions and their priority for notifications, media
  * button dispatch, etc.
  */
-public class MediaSessionStack {
+class MediaSessionStack {
     /**
      * These are states that usually indicate the user took an action and should
      * bump priority regardless of the old state.
@@ -68,13 +68,10 @@
      * Checks if a media session is created from the most recent app.
      *
      * @param record A media session record to be examined.
-     * @return true if the media session's package name equals to the most recent app, false
-     * otherwise.
+     * @return {@code true} if the media session's package name equals to the most recent app, false
+     *            otherwise.
      */
     private static boolean isFromMostRecentApp(MediaSessionRecord record) {
-        if (ActivityManager.getCurrentUser() != record.getUserId()) {
-            return false;
-        }
         try {
             List<ActivityManager.RecentTaskInfo> tasks =
                     ActivityManagerNative.getDefault().getRecentTasks(1,
@@ -84,9 +81,10 @@
                             ActivityManager.RECENT_WITH_EXCLUDED, record.getUserId()).getList();
             if (tasks != null && !tasks.isEmpty()) {
                 ActivityManager.RecentTaskInfo recentTask = tasks.get(0);
-                if (recentTask.baseIntent != null)
+                if (recentTask.userId == record.getUserId() && recentTask.baseIntent != null) {
                     return recentTask.baseIntent.getComponent().getPackageName()
                             .equals(record.getPackageName());
+                }
             }
         } catch (RemoteException e) {
             return false;
@@ -98,11 +96,12 @@
      * Add a record to the priority tracker.
      *
      * @param record The record to add.
+     * @param fromForegroundUser {@code true} if the session is created by the foreground user.
      */
-    public void addSession(MediaSessionRecord record) {
+    public void addSession(MediaSessionRecord record, boolean fromForegroundUser) {
         mSessions.add(record);
         clearCache();
-        if (isFromMostRecentApp(record)) {
+        if (fromForegroundUser && isFromMostRecentApp(record)) {
             mLastInterestingRecord = record;
         }
     }
@@ -210,12 +209,13 @@
     /**
      * Get the highest priority session that can handle media buttons.
      *
-     * @param userId The user to check.
+     * @param userIdList The user lists to check.
      * @param includeNotPlaying Return a non-playing session if nothing else is
      *            available
      * @return The default media button session or null.
      */
-    public MediaSessionRecord getDefaultMediaButtonSession(int userId, boolean includeNotPlaying) {
+    public MediaSessionRecord getDefaultMediaButtonSession(
+            List<Integer> userIdList, boolean includeNotPlaying) {
         if (mGlobalPrioritySession != null && mGlobalPrioritySession.isActive()) {
             return mGlobalPrioritySession;
         }
@@ -223,7 +223,7 @@
             return mCachedButtonReceiver;
         }
         ArrayList<MediaSessionRecord> records = getPriorityListLocked(true,
-                MediaSession.FLAG_HANDLES_MEDIA_BUTTONS, userId);
+                MediaSession.FLAG_HANDLES_MEDIA_BUTTONS, userIdList);
         if (records.size() > 0) {
             MediaSessionRecord record = records.get(0);
             if (record.isPlaybackActive(false)) {
@@ -248,14 +248,14 @@
         return mCachedButtonReceiver;
     }
 
-    public MediaSessionRecord getDefaultVolumeSession(int userId) {
+    public MediaSessionRecord getDefaultVolumeSession(List<Integer> userIdList) {
         if (mGlobalPrioritySession != null && mGlobalPrioritySession.isActive()) {
             return mGlobalPrioritySession;
         }
         if (mCachedVolumeDefault != null) {
             return mCachedVolumeDefault;
         }
-        ArrayList<MediaSessionRecord> records = getPriorityListLocked(true, 0, userId);
+        ArrayList<MediaSessionRecord> records = getPriorityListLocked(true, 0, userIdList);
         int size = records.size();
         for (int i = 0; i < size; i++) {
             MediaSessionRecord record = records.get(i);
@@ -298,6 +298,13 @@
         }
     }
 
+    private ArrayList<MediaSessionRecord> getPriorityListLocked(boolean activeOnly, int withFlags,
+            int userId) {
+        List<Integer> userIdList = new ArrayList<>();
+        userIdList.add(userId);
+        return getPriorityListLocked(activeOnly, withFlags, userIdList);
+    }
+
     /**
      * Get a priority sorted list of sessions. Can filter to only return active
      * sessions or sessions with specific flags.
@@ -306,22 +313,23 @@
      *            all sessions.
      * @param withFlags Only return sessions with all the specified flags set. 0
      *            returns all sessions.
-     * @param userId The user to get sessions for. {@link UserHandle#USER_ALL}
+     * @param userIdList The user to get sessions for. {@link UserHandle#USER_ALL}
      *            will return sessions for all users.
      * @return The priority sorted list of sessions.
      */
     private ArrayList<MediaSessionRecord> getPriorityListLocked(boolean activeOnly, int withFlags,
-            int userId) {
+            List<Integer> userIdList) {
         ArrayList<MediaSessionRecord> result = new ArrayList<MediaSessionRecord>();
         int lastLocalIndex = 0;
         int lastActiveIndex = 0;
         int lastPublishedIndex = 0;
 
+        boolean filterUser = !userIdList.contains(UserHandle.USER_ALL);
         int size = mSessions.size();
         for (int i = 0; i < size; i++) {
             final MediaSessionRecord session = mSessions.get(i);
 
-            if (userId != UserHandle.USER_ALL && userId != session.getUserId()) {
+            if (filterUser && !userIdList.contains(session.getUserId())) {
                 // Filter out sessions for the wrong user
                 continue;
             }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 4c79149..fd037b6 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -545,7 +545,7 @@
     SparseArray<DisplayContent> mDisplayContents = new SparseArray<>(2);
 
     int mRotation = 0;
-    int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+    int mLastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
     boolean mAltOrientation = false;
 
     private boolean mKeyguardWaitingForActivityDrawn;
@@ -3521,13 +3521,16 @@
                 // can re-appear and inflict its own orientation on us.  Keep the
                 // orientation stable until this all settles down.
                 return mLastWindowForcedOrientation;
-            } else if (mPolicy.isKeyguardLocked()
-                    && mLastKeyguardForcedOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
-                // Use the last orientation the keyguard forced while the display is frozen with the
-                // keyguard locked.
+            } else if (mPolicy.isKeyguardLocked()) {
+                // Use the last orientation the while the display is frozen with the
+                // keyguard locked. This could be the keyguard forced orientation or
+                // from a SHOW_WHEN_LOCKED window. We don't want to check the show when
+                // locked window directly though as things aren't stable while
+                // the display is frozen, for example the window could be momentarily unavailable
+                // due to activity relaunch.
                 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display is frozen while keyguard locked, "
-                        + "return " + mLastKeyguardForcedOrientation);
-                return mLastKeyguardForcedOrientation;
+                        + "return " + mLastOrientation);
+                return mLastOrientation;
             }
         } else {
             // TODO(multidisplay): Change to the correct display.
@@ -3657,12 +3660,12 @@
             }
         }
         if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
-                "No app is requesting an orientation, return " + mForcedAppOrientation);
+                "No app is requesting an orientation, return " + mLastOrientation);
         // The next app has not been requested to be visible, so we keep the current orientation
         // to prevent freezing/unfreezing the display too early unless we are in multi-window, in
         // which we don't let the app customize the orientation unless it was the home task that
         // is handled above.
-        return inMultiWindow ? SCREEN_ORIENTATION_UNSPECIFIED : mForcedAppOrientation;
+        return inMultiWindow ? SCREEN_ORIENTATION_UNSPECIFIED : mLastOrientation;
     }
 
     @Override
@@ -3745,8 +3748,8 @@
         long ident = Binder.clearCallingIdentity();
         try {
             int req = getOrientationLocked();
-            if (req != mForcedAppOrientation) {
-                mForcedAppOrientation = req;
+            if (req != mLastOrientation) {
+                mLastOrientation = req;
                 //send a message to Policy indicating orientation change to take
                 //action like disabling/enabling sensors etc.,
                 mPolicy.setCurrentOrientationLw(req);
@@ -6622,13 +6625,13 @@
         //       an orientation that has different metrics than it expected.
         //       eg. Portrait instead of Landscape.
 
-        int rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation, mRotation);
+        int rotation = mPolicy.rotationForOrientationLw(mLastOrientation, mRotation);
         boolean altOrientation = !mPolicy.rotationHasCompatibleMetricsLw(
-                mForcedAppOrientation, rotation);
+                mLastOrientation, rotation);
 
         if (DEBUG_ORIENTATION) {
-            Slog.v(TAG_WM, "Application requested orientation "
-                    + mForcedAppOrientation + ", got rotation " + rotation
+            Slog.v(TAG_WM, "Selected orientation "
+                    + mLastOrientation + ", got rotation " + rotation
                     + " which has " + (altOrientation ? "incompatible" : "compatible")
                     + " metrics");
         }
@@ -6642,7 +6645,7 @@
             Slog.v(TAG_WM,
                 "Rotation changed to " + rotation + (altOrientation ? " (alt)" : "")
                 + " from " + mRotation + (mAltOrientation ? " (alt)" : "")
-                + ", forceApp=" + mForcedAppOrientation);
+                + ", lastOrientation=" + mLastOrientation);
         }
 
         int oldRotation = mRotation;
@@ -10487,7 +10490,7 @@
             pw.print("  mRotation="); pw.print(mRotation);
                     pw.print(" mAltOrientation="); pw.println(mAltOrientation);
             pw.print("  mLastWindowForcedOrientation="); pw.print(mLastWindowForcedOrientation);
-                    pw.print(" mForcedAppOrientation="); pw.println(mForcedAppOrientation);
+                    pw.print(" mLastOrientation="); pw.println(mLastOrientation);
             pw.print("  mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount);
             pw.print("  Animation settings: disabled="); pw.print(mAnimationsDisabled);
                     pw.print(" window="); pw.print(mWindowAnimationScaleSetting);