Merge "Trapping backspace at EditText level to prevent popping Docs." 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/android/view/View.java b/core/java/android/view/View.java
index d4ac300..a64827a 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -3744,7 +3744,8 @@
/**
* Flag indicating that a drag can cross window boundaries. When
* {@link #startDragAndDrop(ClipData, DragShadowBuilder, Object, int)} is called
- * with this flag set, all visible applications will be able to participate
+ * with this flag set, all visible applications with targetSdkVersion >=
+ * {@link android.os.Build.VERSION_CODES#N API 24} will be able to participate
* in the drag operation and receive the dragged content.
*
* If this is the only flag set, then the drag recipient will only have access to text data
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/services/core/java/com/android/server/AnyMotionDetector.java b/services/core/java/com/android/server/AnyMotionDetector.java
index a8ae914d..f93c716 100644
--- a/services/core/java/com/android/server/AnyMotionDetector.java
+++ b/services/core/java/com/android/server/AnyMotionDetector.java
@@ -70,6 +70,9 @@
/** The interval between accelerometer orientation measurements. */
private static final long ORIENTATION_MEASUREMENT_INTERVAL_MILLIS = 5000;
+ /** The maximum duration we will hold a wakelock to determine stationary status. */
+ private static final long WAKELOCK_TIMEOUT_MILLIS = 30000;
+
/**
* The duration in milliseconds after which an orientation measurement is considered
* too stale to be used.
@@ -141,25 +144,30 @@
mCurrentGravityVector = null;
mPreviousGravityVector = null;
mWakeLock.acquire();
+ Message wakelockTimeoutMsg = Message.obtain(mHandler, mWakelockTimeout);
+ mHandler.sendMessageDelayed(wakelockTimeoutMsg, WAKELOCK_TIMEOUT_MILLIS);
startOrientationMeasurementLocked();
}
}
}
public void stop() {
- if (mState == STATE_ACTIVE) {
- synchronized (mLock) {
+ synchronized (mLock) {
+ if (mState == STATE_ACTIVE) {
mState = STATE_INACTIVE;
if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE.");
- if (mMeasurementInProgress) {
- mMeasurementInProgress = false;
- mSensorManager.unregisterListener(mListener);
- }
- mHandler.removeCallbacks(mMeasurementTimeout);
- mHandler.removeCallbacks(mSensorRestart);
- mCurrentGravityVector = null;
- mPreviousGravityVector = null;
+ }
+ if (mMeasurementInProgress) {
+ mMeasurementInProgress = false;
+ mSensorManager.unregisterListener(mListener);
+ }
+ mHandler.removeCallbacks(mMeasurementTimeout);
+ mHandler.removeCallbacks(mSensorRestart);
+ mCurrentGravityVector = null;
+ mPreviousGravityVector = null;
+ if (mWakeLock.isHeld()) {
mWakeLock.release();
+ mHandler.removeCallbacks(mWakelockTimeout);
}
}
}
@@ -173,9 +181,8 @@
mMeasurementInProgress = true;
mRunningStats.reset();
}
- Message msg = Message.obtain(mHandler, mMeasurementTimeout);
- msg.setAsynchronous(true);
- mHandler.sendMessageDelayed(msg, ACCELEROMETER_DATA_TIMEOUT_MILLIS);
+ Message measurementTimeoutMsg = Message.obtain(mHandler, mMeasurementTimeout);
+ mHandler.sendMessageDelayed(measurementTimeoutMsg, ACCELEROMETER_DATA_TIMEOUT_MILLIS);
}
}
@@ -186,10 +193,12 @@
if (mMeasurementInProgress) {
mSensorManager.unregisterListener(mListener);
mHandler.removeCallbacks(mMeasurementTimeout);
- long detectionEndTime = SystemClock.elapsedRealtime();
mMeasurementInProgress = false;
mPreviousGravityVector = mCurrentGravityVector;
mCurrentGravityVector = mRunningStats.getRunningAverage();
+ if (mRunningStats.getSampleCount() == 0) {
+ Slog.w(TAG, "No accelerometer data acquired for orientation measurement.");
+ }
if (DEBUG) {
Slog.d(TAG, "mRunningStats = " + mRunningStats.toString());
String currentGravityVectorString = (mCurrentGravityVector == null) ?
@@ -203,7 +212,10 @@
status = getStationaryStatus();
if (DEBUG) Slog.d(TAG, "getStationaryStatus() returned " + status);
if (status != RESULT_UNKNOWN) {
- mWakeLock.release();
+ if (mWakeLock.isHeld()) {
+ mWakeLock.release();
+ mHandler.removeCallbacks(mWakelockTimeout);
+ }
if (DEBUG) {
Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE. status = " + status);
}
@@ -217,7 +229,6 @@
" scheduled in " + ORIENTATION_MEASUREMENT_INTERVAL_MILLIS +
" milliseconds.");
Message msg = Message.obtain(mHandler, mSensorRestart);
- msg.setAsynchronous(true);
mHandler.sendMessageDelayed(msg, ORIENTATION_MEASUREMENT_INTERVAL_MILLIS);
}
}
@@ -271,6 +282,7 @@
}
}
if (status != RESULT_UNKNOWN) {
+ mHandler.removeCallbacks(mWakelockTimeout);
mCallback.onAnyMotionResult(status);
}
}
@@ -290,20 +302,30 @@
};
private final Runnable mMeasurementTimeout = new Runnable() {
- @Override
- public void run() {
- int status = RESULT_UNKNOWN;
- synchronized (mLock) {
- if (DEBUG) Slog.i(TAG, "mMeasurementTimeout. Failed to collect sufficient accel " +
+ @Override
+ public void run() {
+ int status = RESULT_UNKNOWN;
+ synchronized (mLock) {
+ if (DEBUG) Slog.i(TAG, "mMeasurementTimeout. Failed to collect sufficient accel " +
"data within " + ACCELEROMETER_DATA_TIMEOUT_MILLIS + " ms. Stopping " +
"orientation measurement.");
- status = stopOrientationMeasurementLocked();
- }
- if (status != RESULT_UNKNOWN) {
- mCallback.onAnyMotionResult(status);
- }
- }
- };
+ status = stopOrientationMeasurementLocked();
+ }
+ if (status != RESULT_UNKNOWN) {
+ mHandler.removeCallbacks(mWakelockTimeout);
+ mCallback.onAnyMotionResult(status);
+ }
+ }
+ };
+
+ private final Runnable mWakelockTimeout = new Runnable() {
+ @Override
+ public void run() {
+ synchronized (mLock) {
+ stop();
+ }
+ }
+ };
/**
* A timestamped three dimensional vector and some vector operations.
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index afed5ef..488f0e7 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -973,13 +973,12 @@
cancelSensingTimeoutAlarmLocked();
}
}
- if (result == AnyMotionDetector.RESULT_MOVED) {
- if (DEBUG) Slog.d(TAG, "RESULT_MOVED received.");
+ if ((result == AnyMotionDetector.RESULT_MOVED) ||
+ (result == AnyMotionDetector.RESULT_UNKNOWN)) {
synchronized (this) {
- handleMotionDetectedLocked(mConstants.INACTIVE_TIMEOUT, "sense_motion");
+ handleMotionDetectedLocked(mConstants.INACTIVE_TIMEOUT, "non_stationary");
}
} else if (result == AnyMotionDetector.RESULT_STATIONARY) {
- if (DEBUG) Slog.d(TAG, "RESULT_STATIONARY received.");
if (mState == STATE_SENSING) {
// If we are currently sensing, it is time to move to locating.
synchronized (this) {
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;
}