Merge "MediaSession2: Ensure NonNull/Nullable for parameters of public methods" into pi-dev
diff --git a/packages/MediaComponents/src/com/android/media/IMediaSession2.aidl b/packages/MediaComponents/src/com/android/media/IMediaSession2.aidl
index 34251fb..ef7120d 100644
--- a/packages/MediaComponents/src/com/android/media/IMediaSession2.aidl
+++ b/packages/MediaComponents/src/com/android/media/IMediaSession2.aidl
@@ -62,7 +62,7 @@
//////////////////////////////////////////////////////////////////////////////////////////////
// library service specific
//////////////////////////////////////////////////////////////////////////////////////////////
- void getBrowserRoot(IMediaSession2Callback caller, in Bundle rootHints);
+ void getLibraryRoot(IMediaSession2Callback caller, in Bundle rootHints);
void getItem(IMediaSession2Callback caller, String mediaId);
void getChildren(IMediaSession2Callback caller, String parentId, int page, int pageSize,
in Bundle extras);
diff --git a/packages/MediaComponents/src/com/android/media/MediaBrowser2Impl.java b/packages/MediaComponents/src/com/android/media/MediaBrowser2Impl.java
index 122ebe7..c909099 100644
--- a/packages/MediaComponents/src/com/android/media/MediaBrowser2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaBrowser2Impl.java
@@ -54,7 +54,7 @@
final IMediaSession2 binder = getSessionBinder();
if (binder != null) {
try {
- binder.getBrowserRoot(getControllerStub(), rootHints);
+ binder.getLibraryRoot(getControllerStub(), rootHints);
} catch (RemoteException e) {
// TODO(jaewan): Handle disconnect.
if (DEBUG) {
diff --git a/packages/MediaComponents/src/com/android/media/MediaLibraryService2Impl.java b/packages/MediaComponents/src/com/android/media/MediaLibraryService2Impl.java
index 5351394..b3512cc 100644
--- a/packages/MediaComponents/src/com/android/media/MediaLibraryService2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaLibraryService2Impl.java
@@ -72,8 +72,8 @@
VolumeProvider2 volumeProvider,
PendingIntent sessionActivity, Executor callbackExecutor,
MediaLibrarySessionCallback callback) {
- super(context, player, id, playlistAgent, volumeProvider, sessionActivity, callbackExecutor,
- callback);
+ super(context, player, id, playlistAgent, volumeProvider, sessionActivity,
+ callbackExecutor, callback);
// Don't put any extra initialization here. Here's the reason.
// System service will recognize this session inside of the super constructor and would
// connect to this session assuming that initialization is finished. However, if any
@@ -154,8 +154,7 @@
public LibraryRootImpl(Context context, LibraryRoot instance, String rootId,
Bundle extras) {
if (rootId == null) {
- throw new IllegalArgumentException("The root id in BrowserRoot cannot be null. " +
- "Use null for BrowserRoot instead.");
+ throw new IllegalArgumentException("rootId shouldn't be null.");
}
mInstance = instance;
mRootId = rootId;
diff --git a/packages/MediaComponents/src/com/android/media/MediaMetadata2Impl.java b/packages/MediaComponents/src/com/android/media/MediaMetadata2Impl.java
index 7b2ee32..333455d 100644
--- a/packages/MediaComponents/src/com/android/media/MediaMetadata2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaMetadata2Impl.java
@@ -123,11 +123,17 @@
@Override
public boolean containsKey_impl(String key) {
+ if (key == null) {
+ throw new IllegalArgumentException("key shouldn't be null");
+ }
return mBundle.containsKey(key);
}
@Override
public CharSequence getText_impl(@TextKey String key) {
+ if (key == null) {
+ throw new IllegalArgumentException("key shouldn't be null");
+ }
return mBundle.getCharSequence(key);
}
@@ -138,6 +144,9 @@
@Override
public String getString_impl(@TextKey String key) {
+ if (key == null) {
+ throw new IllegalArgumentException("key shouldn't be null");
+ }
CharSequence text = mBundle.getCharSequence(key);
if (text != null) {
return text.toString();
@@ -147,11 +156,17 @@
@Override
public long getLong_impl(@LongKey String key) {
+ if (key == null) {
+ throw new IllegalArgumentException("key shouldn't be null");
+ }
return mBundle.getLong(key, 0);
}
@Override
public Rating2 getRating_impl(@RatingKey String key) {
+ if (key == null) {
+ throw new IllegalArgumentException("key shouldn't be null");
+ }
// TODO(jaewan): Add backward compatibility
Rating2 rating = null;
try {
@@ -165,11 +180,17 @@
@Override
public float getFloat_impl(@FloatKey String key) {
+ if (key == null) {
+ throw new IllegalArgumentException("key shouldn't be null");
+ }
return mBundle.getFloat(key);
}
@Override
public Bitmap getBitmap_impl(@BitmapKey String key) {
+ if (key == null) {
+ throw new IllegalArgumentException("key shouldn't be null");
+ }
Bitmap bmp = null;
try {
bmp = mBundle.getParcelable(key);
@@ -221,7 +242,8 @@
mBundle = new Bundle();
}
- public BuilderImpl(Context context, MediaMetadata2.Builder instance, MediaMetadata2 source) {
+ public BuilderImpl(Context context, MediaMetadata2.Builder instance,
+ MediaMetadata2 source) {
if (source == null) {
throw new IllegalArgumentException("source shouldn't be null");
}
@@ -248,6 +270,9 @@
@Override
public Builder putText_impl(@TextKey String key, CharSequence value) {
+ if (key == null) {
+ throw new IllegalArgumentException("key shouldn't be null");
+ }
if (METADATA_KEYS_TYPE.containsKey(key)) {
if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_TEXT) {
throw new IllegalArgumentException("The " + key
@@ -260,6 +285,9 @@
@Override
public Builder putString_impl(@TextKey String key, String value) {
+ if (key == null) {
+ throw new IllegalArgumentException("key shouldn't be null");
+ }
if (METADATA_KEYS_TYPE.containsKey(key)) {
if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_TEXT) {
throw new IllegalArgumentException("The " + key
@@ -272,6 +300,9 @@
@Override
public Builder putLong_impl(@LongKey String key, long value) {
+ if (key == null) {
+ throw new IllegalArgumentException("key shouldn't be null");
+ }
if (METADATA_KEYS_TYPE.containsKey(key)) {
if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_LONG) {
throw new IllegalArgumentException("The " + key
@@ -284,6 +315,9 @@
@Override
public Builder putRating_impl(@RatingKey String key, Rating2 value) {
+ if (key == null) {
+ throw new IllegalArgumentException("key shouldn't be null");
+ }
if (METADATA_KEYS_TYPE.containsKey(key)) {
if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_RATING) {
throw new IllegalArgumentException("The " + key
@@ -296,6 +330,9 @@
@Override
public Builder putBitmap_impl(@BitmapKey String key, Bitmap value) {
+ if (key == null) {
+ throw new IllegalArgumentException("key shouldn't be null");
+ }
if (METADATA_KEYS_TYPE.containsKey(key)) {
if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_BITMAP) {
throw new IllegalArgumentException("The " + key
@@ -308,6 +345,9 @@
@Override
public Builder putFloat_impl(@FloatKey String key, float value) {
+ if (key == null) {
+ throw new IllegalArgumentException("key shouldn't be null");
+ }
if (METADATA_KEYS_TYPE.containsKey(key)) {
if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_FLOAT) {
throw new IllegalArgumentException("The " + key
@@ -329,7 +369,8 @@
return new MediaMetadata2Impl(mContext, mBundle).getInstance();
}
- private Bitmap scaleBitmap(Bitmap bmp, int maxSize) { float maxSizeF = maxSize;
+ private Bitmap scaleBitmap(Bitmap bmp, int maxSize) {
+ float maxSizeF = maxSize;
float widthScale = maxSizeF / bmp.getWidth();
float heightScale = maxSizeF / bmp.getHeight();
float scale = Math.min(widthScale, heightScale);
diff --git a/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java b/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
index 7e24bb0..5c18515 100644
--- a/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
@@ -29,6 +29,7 @@
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.media.AudioAttributes;
+import android.media.AudioFocusRequest;
import android.media.AudioManager;
import android.media.DataSourceDesc;
import android.media.MediaController2;
@@ -346,7 +347,7 @@
}
@Override
- public void setAudioFocusRequest_impl(int focusGain) {
+ public void setAudioFocusRequest_impl(AudioFocusRequest afr) {
// implement
}
@@ -477,11 +478,20 @@
@Override
public void sendCustomCommand_impl(ControllerInfo controller, Command command, Bundle args,
ResultReceiver receiver) {
+ if (controller == null) {
+ throw new IllegalArgumentException("controller shouldn't be null");
+ }
+ if (command == null) {
+ throw new IllegalArgumentException("command shouldn't be null");
+ }
mSessionStub.sendCustomCommand(controller, command, args, receiver);
}
@Override
public void sendCustomCommand_impl(Command command, Bundle args) {
+ if (command == null) {
+ throw new IllegalArgumentException("command shouldn't be null");
+ }
mSessionStub.sendCustomCommand(command, args);
}
@@ -506,21 +516,39 @@
@Override
public void addPlaylistItem_impl(int index, MediaItem2 item) {
+ if (index < 0) {
+ throw new IllegalArgumentException("index shouldn't be negative");
+ }
+ if (item == null) {
+ throw new IllegalArgumentException("item shouldn't be null");
+ }
// TODO(jaewan): Implement
}
@Override
public void removePlaylistItem_impl(MediaItem2 item) {
+ if (item == null) {
+ throw new IllegalArgumentException("item shouldn't be null");
+ }
// TODO(jaewan): Implement
}
@Override
public void editPlaylistItem_impl(MediaItem2 item) {
+ if (item == null) {
+ throw new IllegalArgumentException("item shouldn't be null");
+ }
// TODO(jaewan): Implement
}
@Override
public void replacePlaylistItem_impl(int index, MediaItem2 item) {
+ if (index < 0) {
+ throw new IllegalArgumentException("index shouldn't be negative");
+ }
+ if (item == null) {
+ throw new IllegalArgumentException("item shouldn't be null");
+ }
// TODO(jaewan): Implement
}
@@ -603,6 +631,9 @@
@Override
public void skipToPlaylistItem_impl(MediaItem2 item) {
ensureCallingThread();
+ if (item == null) {
+ throw new IllegalArgumentException("item shouldn't be null");
+ }
// TODO: Uncomment or remove
/*
final MediaPlayerBase player = mPlayer;
@@ -887,6 +918,9 @@
* @return a new Command instance from the Bundle
*/
public static Command fromBundle_impl(Context context, Bundle command) {
+ if (command == null) {
+ throw new IllegalArgumentException("command shouldn't be null");
+ }
int code = command.getInt(KEY_COMMAND_CODE);
if (code != COMMAND_CODE_CUSTOM) {
return new Command(context, code);
@@ -939,6 +973,9 @@
@Override
public void addCommand_impl(Command command) {
+ if (command == null) {
+ throw new IllegalArgumentException("command shouldn't be null");
+ }
mCommands.add(command);
}
@@ -951,11 +988,17 @@
@Override
public void removeCommand_impl(Command command) {
+ if (command == null) {
+ throw new IllegalArgumentException("command shouldn't be null");
+ }
mCommands.remove(command);
}
@Override
public boolean hasCommand_impl(Command command) {
+ if (command == null) {
+ throw new IllegalArgumentException("command shouldn't be null");
+ }
return mCommands.contains(command);
}
@@ -1029,6 +1072,13 @@
public ControllerInfoImpl(Context context, ControllerInfo instance, int uid,
int pid, String packageName, IMediaSession2Callback callback) {
+ if (TextUtils.isEmpty(packageName)) {
+ throw new IllegalArgumentException("packageName shouldn't be empty");
+ }
+ if (callback == null) {
+ throw new IllegalArgumentException("callback shouldn't be null");
+ }
+
mInstance = instance;
mUid = uid;
mPackageName = packageName;
@@ -1351,6 +1401,7 @@
mId = "";
}
+ @Override
public void setPlayer_impl(MediaPlayerBase player) {
if (player == null) {
throw new IllegalArgumentException("player shouldn't be null");
@@ -1366,17 +1417,17 @@
mPlaylistAgent = playlistAgent;
}
+ @Override
public void setVolumeProvider_impl(VolumeProvider2 volumeProvider) {
- if (volumeProvider == null) {
- throw new IllegalArgumentException("volumeProvider shouldn't be null");
- }
mVolumeProvider = volumeProvider;
}
+ @Override
public void setSessionActivity_impl(PendingIntent pi) {
mSessionActivity = pi;
}
+ @Override
public void setId_impl(String id) {
if (id == null) {
throw new IllegalArgumentException("id shouldn't be null");
@@ -1384,6 +1435,7 @@
mId = id;
}
+ @Override
public void setSessionCallback_impl(Executor executor, C callback) {
if (executor == null) {
throw new IllegalArgumentException("executor shouldn't be null");
@@ -1395,6 +1447,7 @@
mCallback = callback;
}
+ @Override
public abstract T build_impl();
}
@@ -1411,7 +1464,6 @@
if (mCallback == null) {
mCallback = new SessionCallback(mContext) {};
}
-
return new MediaSession2Impl(mContext, mPlayer, mId, mPlaylistAgent,
mVolumeProvider, mSessionActivity, mCallbackExecutor, mCallback).getInstance();
}
diff --git a/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java b/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java
index d4164f6..a9c5224 100644
--- a/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java
+++ b/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java
@@ -481,6 +481,11 @@
return;
}
final Command command = Command.fromBundle(session.getContext(), commandBundle);
+ if (command == null) {
+ Log.w(TAG, "sendCustomCommand(): Ignoring null command from "
+ + getControllerIfAble(caller));
+ return;
+ }
final ControllerInfo controller = getControllerIfAble(caller, command);
if (controller == null) {
return;
@@ -503,6 +508,10 @@
if (session == null || controller == null) {
return;
}
+ if (uri == null) {
+ Log.w(TAG, "prepareFromUri(): Ignoring null uri from " + controller);
+ return;
+ }
session.getCallbackExecutor().execute(() -> {
if (getControllerIfAble(
caller, MediaSession2.COMMAND_CODE_PREPARE_FROM_URI) == null) {
@@ -522,6 +531,10 @@
if (session == null || controller == null) {
return;
}
+ if (TextUtils.isEmpty(query)) {
+ Log.w(TAG, "prepareFromSearch(): Ignoring empty query from " + controller);
+ return;
+ }
session.getCallbackExecutor().execute(() -> {
if (getControllerIfAble(
caller, MediaSession2.COMMAND_CODE_PREPARE_FROM_SEARCH) == null) {
@@ -541,6 +554,10 @@
if (session == null || controller == null) {
return;
}
+ if (mediaId == null) {
+ Log.w(TAG, "prepareFromMediaId(): Ignoring null mediaId from " + controller);
+ return;
+ }
session.getCallbackExecutor().execute(() -> {
if (getControllerIfAble(
caller, MediaSession2.COMMAND_CODE_PREPARE_FROM_MEDIA_ID) == null) {
@@ -560,6 +577,10 @@
if (session == null || controller == null) {
return;
}
+ if (uri == null) {
+ Log.w(TAG, "playFromUri(): Ignoring null uri from " + controller);
+ return;
+ }
session.getCallbackExecutor().execute(() -> {
if (getControllerIfAble(
caller, MediaSession2.COMMAND_CODE_PLAY_FROM_URI) == null) {
@@ -578,6 +599,10 @@
if (session == null || controller == null) {
return;
}
+ if (TextUtils.isEmpty(query)) {
+ Log.w(TAG, "playFromSearch(): Ignoring empty query from " + controller);
+ return;
+ }
session.getCallbackExecutor().execute(() -> {
if (getControllerIfAble(
caller, MediaSession2.COMMAND_CODE_PLAY_FROM_SEARCH) == null) {
@@ -597,6 +622,10 @@
if (session == null || controller == null) {
return;
}
+ if (mediaId == null) {
+ Log.w(TAG, "playFromMediaId(): Ignoring null mediaId from " + controller);
+ return;
+ }
session.getCallbackExecutor().execute(() -> {
if (session == null) {
return;
@@ -617,14 +646,17 @@
}
return;
}
+ Rating2 rating = Rating2Impl.fromBundle(sessionImpl.getContext(), ratingBundle);
+ if (rating == null) {
+ Log.w(TAG, "setRating(): Ignore null rating");
+ return;
+ }
sessionImpl.getCallbackExecutor().execute(() -> {
final MediaSession2Impl session = mSession.get();
if (session == null) {
return;
}
- Rating2 rating = Rating2Impl.fromBundle(session.getContext(), ratingBundle);
- session.getCallback().onSetRating(session.getInstance(),
- controller, mediaId, rating);
+ session.getCallback().onSetRating(session.getInstance(), controller, mediaId, rating);
});
}
@@ -633,7 +665,7 @@
//////////////////////////////////////////////////////////////////////////////////////////////
@Override
- public void getBrowserRoot(final IMediaSession2Callback caller, final Bundle rootHints)
+ public void getLibraryRoot(final IMediaSession2Callback caller, final Bundle rootHints)
throws RuntimeException {
final MediaLibrarySessionImpl session = getLibrarySession();
final ControllerInfo controller = getControllerIfAble(
@@ -744,36 +776,36 @@
if (session == null || controller == null) {
return;
}
+ if (TextUtils.isEmpty(query)) {
+ Log.w(TAG, "search(): Ignoring empty query from " + controller);
+ return;
+ }
session.getCallbackExecutor().execute(() -> {
if (getControllerIfAble(caller, MediaSession2.COMMAND_CODE_BROWSER) == null) {
return;
}
- session.getCallback().onSearch(session.getInstance(),
- controller, query, extras);
+ session.getCallback().onSearch(session.getInstance(), controller, query, extras);
});
}
@Override
public void getSearchResult(final IMediaSession2Callback caller, final String query,
final int page, final int pageSize, final Bundle extras) {
- if (TextUtils.isEmpty(query)) {
- if (DEBUG) {
- Log.d(TAG, "query shouldn't be empty");
- }
- return;
- }
- if (page < 1 || pageSize < 1) {
- if (DEBUG) {
- Log.d(TAG, "Neither page nor pageSize should be less than 1");
- }
- return;
- }
final MediaLibrarySessionImpl session = getLibrarySession();
final ControllerInfo controller = getControllerIfAble(
caller, MediaSession2.COMMAND_CODE_BROWSER);
if (session == null || controller == null) {
return;
}
+ if (TextUtils.isEmpty(query)) {
+ Log.w(TAG, "getSearchResult(): Ignoring empty query from " + controller);
+ return;
+ }
+ if (page < 1 || pageSize < 1) {
+ Log.w(TAG, "getSearchResult(): Ignoring negative page / pageSize."
+ + " page=" + page + " pageSize=" + pageSize + " from " + controller);
+ return;
+ }
session.getCallbackExecutor().execute(() -> {
if (getControllerIfAble(caller, MediaSession2.COMMAND_CODE_BROWSER) == null) {
return;
@@ -811,6 +843,10 @@
if (session == null || controller == null) {
return;
}
+ if (parentId == null) {
+ Log.w(TAG, "subscribe(): Ignoring null parentId from " + controller);
+ return;
+ }
session.getCallbackExecutor().execute(() -> {
if (getControllerIfAble(caller, MediaSession2.COMMAND_CODE_BROWSER) == null) {
return;
@@ -836,6 +872,10 @@
if (session == null || controller == null) {
return;
}
+ if (parentId == null) {
+ Log.w(TAG, "unsubscribe(): Ignoring null parentId from " + controller);
+ return;
+ }
session.getCallbackExecutor().execute(() -> {
if (getControllerIfAble(caller, MediaSession2.COMMAND_CODE_BROWSER) == null) {
return;
diff --git a/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java b/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java
index 3965ccb..723622e 100644
--- a/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java
@@ -59,10 +59,10 @@
public SessionToken2Impl(Context context, SessionToken2 instance,
String packageName, String serviceName, int uid) {
if (TextUtils.isEmpty(packageName)) {
- throw new IllegalArgumentException("package name shouldn't be null");
+ throw new IllegalArgumentException("packageName shouldn't be empty");
}
if (TextUtils.isEmpty(serviceName)) {
- throw new IllegalArgumentException("service name shouldn't be null");
+ throw new IllegalArgumentException("serviceName shouldn't be empty");
}
mInstance = instance;
// Calculate uid if it's not specified.
diff --git a/packages/MediaComponents/src/com/android/media/VolumeProvider2Impl.java b/packages/MediaComponents/src/com/android/media/VolumeProvider2Impl.java
index 5af3ddf..156bcae 100644
--- a/packages/MediaComponents/src/com/android/media/VolumeProvider2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/VolumeProvider2Impl.java
@@ -15,6 +15,10 @@
*/
package com.android.media;
+import static android.media.VolumeProvider2.VOLUME_CONTROL_ABSOLUTE;
+import static android.media.VolumeProvider2.VOLUME_CONTROL_FIXED;
+import static android.media.VolumeProvider2.VOLUME_CONTROL_RELATIVE;
+
import android.content.Context;
import android.media.VolumeProvider2;
import android.media.update.VolumeProvider2Provider;
@@ -31,6 +35,18 @@
public VolumeProvider2Impl(Context context, VolumeProvider2 instance,
@VolumeProvider2.ControlType int controlType, int maxVolume, int currentVolume) {
+ if (controlType != VOLUME_CONTROL_FIXED && controlType != VOLUME_CONTROL_RELATIVE
+ && controlType != VOLUME_CONTROL_ABSOLUTE) {
+ throw new IllegalArgumentException("wrong controlType " + controlType);
+ }
+ if (maxVolume < 0 || currentVolume < 0) {
+ throw new IllegalArgumentException("volume shouldn't be negative"
+ + ", maxVolume=" + maxVolume + ", currentVolume=" + currentVolume);
+ }
+ if (currentVolume > maxVolume) {
+ throw new IllegalArgumentException("currentVolume shouldn't be greater than maxVolume"
+ + ", maxVolume=" + maxVolume + ", currentVolume=" + currentVolume);
+ }
mContext = context;
mInstance = instance;
mControlType = controlType;
@@ -55,6 +71,10 @@
@Override
public void setCurrentVolume_impl(int currentVolume) {
+ if (currentVolume < 0) {
+ throw new IllegalArgumentException("currentVolume shouldn't be negative"
+ + ", currentVolume=" + currentVolume);
+ }
mCurrentVolume = currentVolume;
if (mCallback != null) {
mCallback.onVolumeChanged(mInstance);