Document when ControllerInfo's package name and UID may not be precise
Bug: 153723529
Test: Manual check after './gradlew disttipOfTreeDocs'
Change-Id: I6b2a9c02be68abdee532c615d282cdcdc91ac43a
diff --git a/media2/session/src/main/java/androidx/media2/session/MediaLibraryService.java b/media2/session/src/main/java/androidx/media2/session/MediaLibraryService.java
index 688aaaa..ae15547 100644
--- a/media2/session/src/main/java/androidx/media2/session/MediaLibraryService.java
+++ b/media2/session/src/main/java/androidx/media2/session/MediaLibraryService.java
@@ -30,6 +30,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
+import androidx.media.MediaSessionManager.RemoteUserInfo;
import androidx.media2.common.MediaMetadata;
import androidx.media2.common.SessionPlayer;
import androidx.media2.session.LibraryResult.ResultCode;
@@ -70,7 +71,32 @@
/**
* Session for the {@link MediaLibraryService}. Build this object with
* {@link Builder} and return in {@link MediaSessionService#onGetSession(ControllerInfo)}.
- */
+ *
+ * <h3 id="BackwardCompatibility">Backward compatibility with legacy media browser APIs</h3>
+ * Media library session supports connection from both {@link MediaBrowser} and
+ * {@link android.support.v4.media.MediaBrowserCompat}, but {@link ControllerInfo} may not be
+ * precise. Here are current limitations with details.
+ *
+ * <table>
+ * <tr><th>SDK version</th>
+ * <th>{@link ControllerInfo#getPackageName()}<br>for legacy browser</th>
+ * <th>{@link ControllerInfo#getUid()}<br>for legacy browser</th></tr>
+ * <tr><td>{@code SDK_VERSION} < 21</td>
+ * <td>Actual package name via {@link Context#getPackageName()}</td>
+ * <td>Actual UID</td></tr>
+ * <tr><td>21 ≥ {@code SDK_VERSION} < 28,<br>
+ * {@code MediaLibrarySessionCallback#onConnect} and<br>
+ * {@code MediaLibrarySessionCallback#onGetLibraryRoot}</td>
+ * <td>Actual package name via {@link Context#getPackageName()}</td>
+ * <td>Actual UID</td></tr>
+ * <tr><td>21 ≥ {@code SDK_VERSION} < 28, for other callbacks</td>
+ * <td>{@link RemoteUserInfo#LEGACY_CONTROLLER}</td>
+ * <td>Negative value</td></tr>
+ * <tr><td>28 ≥ {@code SDK_VERSION}</td>
+ * <td>Actual package name via {@link Context#getPackageName()}</td>
+ * <td>Actual UID</td></tr>
+ * </table>
+ **/
public static final class MediaLibrarySession extends MediaSession {
/**
* Callback for the {@link MediaLibrarySession}.
diff --git a/media2/session/src/main/java/androidx/media2/session/MediaSession.java b/media2/session/src/main/java/androidx/media2/session/MediaSession.java
index 277ee9c..e631099 100644
--- a/media2/session/src/main/java/androidx/media2/session/MediaSession.java
+++ b/media2/session/src/main/java/androidx/media2/session/MediaSession.java
@@ -23,6 +23,7 @@
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
@@ -87,7 +88,9 @@
* <li><a href="#Thread">Thread</a>
* <li><a href="#KeyEvents">Media key events mapping</a>
* <li><a href="#MultipleSessions">Supporting Multiple Sessions</a>
- * <li><a href="#BackwardCompatibility">Backward compatibility with legacy media session APIs</a>
+ * <li><a href="#CompatibilitySession">Backward compatibility with legacy session APIs</a>
+ * <li><a href="#CompatibilityController">Backward compatibility with legacy controller APIs</a>
+ *
* </ol>
* <h3 id="SessionLifecycle">Session Lifecycle</h3>
* <p>
@@ -142,12 +145,23 @@
* not playing multiple audio content at the same time. Also keep in mind that multiple media
* sessions would make Android Auto and Bluetooth device with display to show your apps multiple
* times, because they list up media sessions, not media apps.
- * <h3 id="BackwardCompatibility">Backward compatibility with legacy media session APIs</h3>
+ * <h3 id="CompatibilitySession">Backward compatibility with legacy session APIs</h3>
* An active {@link MediaSessionCompat} is internally created with the MediaSession for the backward
* compatibility. It's used to handle incoming connection and command from
* {@link android.support.v4.media.session.MediaControllerCompat}. And helps to utilize existing
* APIs that are built with legacy media session APIs. Use {@link #getSessionCompatToken} for
* getting the token for the underlying MediaSessionCompat.
+ * <h3 id="CompatibilityController">Backward compatibility with legacy controller APIs</h3>
+ * In addition to the {@link MediaController media2 controller} API, session also supports
+ * connection from the legacy controller API -
+ * {@link android.media.session.MediaController framework controller} and
+ * {@link android.support.v4.media.session.MediaControllerCompat AndroidX controller compat}.
+ * However, {@link ControllerInfo} may not be precise for legacy controller.
+ * See {@link ControllerInfo} for the details.
+ * <p>
+ * Unknown package name nor UID doesn't mean that you should disallow connection nor commands. For
+ * SDK levels where such issue happen, session tokens could only be obtained by trusted apps (e.g.
+ * Bluetooth, Auto, ...), so it may be better for you to allow them as you did with legacy session.
*
* @see MediaSessionService
*/
@@ -835,8 +849,26 @@
}
/**
- * Gets the package name of the controller. Can be {@link RemoteUserInfo#LEGACY_CONTROLLER}
- * if the package name cannot be obtained.
+ * Gets the package name. Can be
+ * {@link androidx.media.MediaSessionManager.RemoteUserInfo#LEGACY_CONTROLLER} for
+ * interoperability.
+ * <p>
+ * Interoperability: Package name may not be precisely obtained for legacy controller API on
+ * older device. Here are details.
+ * <table>
+ * <tr><th>SDK version when package name isn't precise</th>
+ * <th>{@code ControllerInfo#getPackageName()} for legacy controller</th>
+ * <tr><td>{@code SDK_VERSION} < {@code 21}</td>
+ * <td>Actual package name via {@link PackageManager#getNameForUid} with UID.<br>
+ * It's sufficient for most cases, but doesn't precisely distinguish caller if it
+ * uses shared user ID.</td>
+ * <tr><td>{@code 21} ≤ {@code SDK_VERSION} < {@code 24}</td>
+ * <td>{@link RemoteUserInfo#LEGACY_CONTROLLER LEGACY_CONTROLLER}</td>
+ * </table>
+ *
+ * @return package name of the controller. Can be
+ * {@link RemoteUserInfo#LEGACY_CONTROLLER LEGACY_CONTROLLER} if the package name
+ * cannot be obtained.
*/
@NonNull
public String getPackageName() {
@@ -844,7 +876,12 @@
}
/**
- * Gets the uid of the controller. Can be a negative value if the uid cannot be obtained.
+ * Gets the UID of the controller. Can be a negative value for interoperability.
+ * <p>
+ * Interoperability: If {@code 21} ≤ {@code SDK_VERSION} < {@code 28}, then UID would
+ * be a negative value because it cannot be obtained.
+ *
+ * @return uid of the controller. Can be a negative value if the uid cannot be obtained.
*/
public int getUid() {
return mRemoteUserInfo.getUid();