Do not require package visibility when connecting to a Media3 session
When we currently call SessionToken.createSessionToken with a legacy token, we call the package manager to get the process UID. This requires visiblity to the target package, which may not be available unless the target runs a service known to the controller app. However, when connecting to a Media3, this UID doesn't have to be known, so we can move the call closer to where it's needed to avoid the unncessary visibility check. In addition, a legacy session may reply with unknown result code to the session token request, which we should handle as well. One of the constructor can be removed since it was only used from a test. PiperOrigin-RevId: 489917706
This commit is contained in:
parent
dba9d81640
commit
2fd4aac310
@ -130,6 +130,7 @@ public final class SessionToken implements Bundleable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Creates a session token connected to a Media3 session. */
|
||||||
/* package */ SessionToken(
|
/* package */ SessionToken(
|
||||||
int uid,
|
int uid,
|
||||||
int type,
|
int type,
|
||||||
@ -143,21 +144,9 @@ public final class SessionToken implements Bundleable {
|
|||||||
uid, type, libraryVersion, interfaceVersion, packageName, iSession, tokenExtras);
|
uid, type, libraryVersion, interfaceVersion, packageName, iSession, tokenExtras);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ SessionToken(Context context, MediaSessionCompat.Token compatToken) {
|
/** Creates a session token connected to a legacy media session. */
|
||||||
checkNotNull(context, "context must not be null");
|
private SessionToken(MediaSessionCompat.Token token, String packageName, int uid, Bundle extras) {
|
||||||
checkNotNull(compatToken, "compatToken must not be null");
|
this.impl = new SessionTokenImplLegacy(token, packageName, uid, extras);
|
||||||
|
|
||||||
MediaControllerCompat controller = createMediaControllerCompat(context, compatToken);
|
|
||||||
|
|
||||||
String packageName = controller.getPackageName();
|
|
||||||
int uid = getUid(context.getPackageManager(), packageName);
|
|
||||||
Bundle extras = controller.getSessionInfo();
|
|
||||||
|
|
||||||
impl = new SessionTokenImplLegacy(compatToken, packageName, uid, extras);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* package */ SessionToken(SessionTokenImpl impl) {
|
|
||||||
this.impl = impl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private SessionToken(Bundle bundle) {
|
private SessionToken(Bundle bundle) {
|
||||||
@ -283,32 +272,37 @@ public final class SessionToken implements Bundleable {
|
|||||||
MediaControllerCompat controller =
|
MediaControllerCompat controller =
|
||||||
createMediaControllerCompat(context, (MediaSessionCompat.Token) compatToken);
|
createMediaControllerCompat(context, (MediaSessionCompat.Token) compatToken);
|
||||||
String packageName = controller.getPackageName();
|
String packageName = controller.getPackageName();
|
||||||
int uid = getUid(context.getPackageManager(), packageName);
|
|
||||||
Handler handler = new Handler(thread.getLooper());
|
Handler handler = new Handler(thread.getLooper());
|
||||||
|
Runnable createFallbackLegacyToken =
|
||||||
|
() -> {
|
||||||
|
int uid = getUid(context.getPackageManager(), packageName);
|
||||||
|
SessionToken resultToken =
|
||||||
|
new SessionToken(
|
||||||
|
(MediaSessionCompat.Token) compatToken,
|
||||||
|
packageName,
|
||||||
|
uid,
|
||||||
|
controller.getSessionInfo());
|
||||||
|
future.set(resultToken);
|
||||||
|
};
|
||||||
controller.sendCommand(
|
controller.sendCommand(
|
||||||
MediaConstants.SESSION_COMMAND_REQUEST_SESSION3_TOKEN,
|
MediaConstants.SESSION_COMMAND_REQUEST_SESSION3_TOKEN,
|
||||||
/* params= */ null,
|
/* params= */ null,
|
||||||
new ResultReceiver(handler) {
|
new ResultReceiver(handler) {
|
||||||
@Override
|
@Override
|
||||||
protected void onReceiveResult(int resultCode, Bundle resultData) {
|
protected void onReceiveResult(int resultCode, Bundle resultData) {
|
||||||
|
// Remove timeout callback.
|
||||||
handler.removeCallbacksAndMessages(null);
|
handler.removeCallbacksAndMessages(null);
|
||||||
|
try {
|
||||||
future.set(SessionToken.CREATOR.fromBundle(resultData));
|
future.set(SessionToken.CREATOR.fromBundle(resultData));
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
// Fallback to a legacy token if we receive an unexpected result, e.g. a legacy
|
||||||
|
// session acknowledging commands by a success callback.
|
||||||
|
createFallbackLegacyToken.run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// Post creating a fallback token if the command receives no result after a timeout.
|
||||||
handler.postDelayed(
|
handler.postDelayed(createFallbackLegacyToken, WAIT_TIME_MS_FOR_SESSION3_TOKEN);
|
||||||
() -> {
|
|
||||||
// Timed out getting session3 token. Handle this as a legacy token.
|
|
||||||
SessionToken resultToken =
|
|
||||||
new SessionToken(
|
|
||||||
new SessionTokenImplLegacy(
|
|
||||||
(MediaSessionCompat.Token) compatToken,
|
|
||||||
packageName,
|
|
||||||
uid,
|
|
||||||
controller.getSessionInfo()));
|
|
||||||
future.set(resultToken);
|
|
||||||
},
|
|
||||||
WAIT_TIME_MS_FOR_SESSION3_TOKEN);
|
|
||||||
future.addListener(() -> thread.quit(), MoreExecutors.directExecutor());
|
future.addListener(() -> thread.quit(), MoreExecutors.directExecutor());
|
||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
@ -399,7 +393,8 @@ public final class SessionToken implements Bundleable {
|
|||||||
try {
|
try {
|
||||||
return manager.getApplicationInfo(packageName, 0).uid;
|
return manager.getApplicationInfo(packageName, 0).uid;
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
throw new IllegalArgumentException("Cannot find package " + packageName, e);
|
throw new IllegalArgumentException(
|
||||||
|
"Cannot find package " + packageName + " or package is not visible", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,8 @@ public class MediaSessionCompatCallbackWithMediaControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private RemoteMediaController createControllerAndWaitConnection() throws Exception {
|
private RemoteMediaController createControllerAndWaitConnection() throws Exception {
|
||||||
SessionToken sessionToken = new SessionToken(context, session.getSessionToken());
|
SessionToken sessionToken =
|
||||||
|
SessionToken.createSessionToken(context, session.getSessionToken()).get();
|
||||||
return controllerTestRule.createRemoteController(sessionToken);
|
return controllerTestRule.createRemoteController(sessionToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user