Skip to content

Commit

Permalink
Do not require package visibility when connecting to a Media3 session
Browse files Browse the repository at this point in the history
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
  • Loading branch information
tonihei authored and microkatz committed Nov 22, 2022
1 parent dba9d81 commit 2fd4aac
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ public SessionToken(Context context, ComponentName serviceComponent) {
}
}

/** Creates a session token connected to a Media3 session. */
/* package */ SessionToken(
int uid,
int type,
Expand All @@ -143,21 +144,9 @@ public SessionToken(Context context, ComponentName serviceComponent) {
uid, type, libraryVersion, interfaceVersion, packageName, iSession, tokenExtras);
}

/* package */ SessionToken(Context context, MediaSessionCompat.Token compatToken) {
checkNotNull(context, "context must not be null");
checkNotNull(compatToken, "compatToken must not be null");

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;
/** Creates a session token connected to a legacy media session. */
private SessionToken(MediaSessionCompat.Token token, String packageName, int uid, Bundle extras) {
this.impl = new SessionTokenImplLegacy(token, packageName, uid, extras);
}

private SessionToken(Bundle bundle) {
Expand Down Expand Up @@ -283,32 +272,37 @@ public static ListenableFuture<SessionToken> createSessionToken(
MediaControllerCompat controller =
createMediaControllerCompat(context, (MediaSessionCompat.Token) compatToken);
String packageName = controller.getPackageName();
int uid = getUid(context.getPackageManager(), packageName);
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(
MediaConstants.SESSION_COMMAND_REQUEST_SESSION3_TOKEN,
/* params= */ null,
new ResultReceiver(handler) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
// Remove timeout callback.
handler.removeCallbacksAndMessages(null);
future.set(SessionToken.CREATOR.fromBundle(resultData));
try {
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();
}
}
});

handler.postDelayed(
() -> {
// 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);
// Post creating a fallback token if the command receives no result after a timeout.
handler.postDelayed(createFallbackLegacyToken, WAIT_TIME_MS_FOR_SESSION3_TOKEN);
future.addListener(() -> thread.quit(), MoreExecutors.directExecutor());
return future;
}
Expand Down Expand Up @@ -399,7 +393,8 @@ private static int getUid(PackageManager manager, String packageName) {
try {
return manager.getApplicationInfo(packageName, 0).uid;
} 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);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ public void cleanUp() {
}

private RemoteMediaController createControllerAndWaitConnection() throws Exception {
SessionToken sessionToken = new SessionToken(context, session.getSessionToken());
SessionToken sessionToken =
SessionToken.createSessionToken(context, session.getSessionToken()).get();
return controllerTestRule.createRemoteController(sessionToken);
}

Expand Down

0 comments on commit 2fd4aac

Please sign in to comment.