SessionToken2ImplBase.java
/*
* Copyright 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.media2;
import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
import static androidx.media2.SessionToken2.KEY_PACKAGE_NAME;
import static androidx.media2.SessionToken2.KEY_SERVICE_NAME;
import static androidx.media2.SessionToken2.KEY_SESSION_BINDER;
import static androidx.media2.SessionToken2.KEY_SESSION_ID;
import static androidx.media2.SessionToken2.KEY_TYPE;
import static androidx.media2.SessionToken2.KEY_UID;
import static androidx.media2.SessionToken2.TYPE_BROWSER_SERVICE_LEGACY;
import static androidx.media2.SessionToken2.TYPE_LIBRARY_SERVICE;
import static androidx.media2.SessionToken2.TYPE_SESSION;
import static androidx.media2.SessionToken2.TYPE_SESSION_SERVICE;
import android.content.ComponentName;
import android.os.Bundle;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.core.app.BundleCompat;
import androidx.media2.SessionToken2.SessionToken2Impl;
import androidx.media2.SessionToken2.TokenType;
final class SessionToken2ImplBase implements SessionToken2Impl {
private final int mUid;
private final @TokenType int mType;
private final String mPackageName;
private final String mServiceName;
private final String mSessionId;
private final IMediaSession2 mISession2;
private final ComponentName mComponentName;
/**
* Constructor for the token. You can only create token for session service or library service
* to use by {@link MediaController2} or {@link MediaBrowser2}.
* @hide
*/
@RestrictTo(LIBRARY_GROUP)
SessionToken2ImplBase(@NonNull ComponentName serviceComponent, int uid, String id, int type) {
if (serviceComponent == null) {
throw new IllegalArgumentException("serviceComponent shouldn't be null");
}
mComponentName = serviceComponent;
mPackageName = serviceComponent.getPackageName();
mServiceName = serviceComponent.getClassName();
mUid = uid;
mSessionId = id;
mType = type;
mISession2 = null;
}
/**
* @hide
*/
@RestrictTo(LIBRARY_GROUP)
SessionToken2ImplBase(int uid, int type, String packageName, String serviceName,
String sessionId, IMediaSession2 iSession2) {
mUid = uid;
mType = type;
mPackageName = packageName;
mServiceName = serviceName;
mComponentName = (mType == TYPE_SESSION) ? null
: new ComponentName(packageName, serviceName);
mSessionId = sessionId;
mISession2 = iSession2;
}
@Override
public int hashCode() {
final int prime = 31;
return mType
+ prime * (mUid
+ prime * (mPackageName.hashCode()
+ prime * (mSessionId.hashCode()
+ prime * (mServiceName != null ? mServiceName.hashCode() : 0))));
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof SessionToken2ImplBase)) {
return false;
}
SessionToken2ImplBase other = (SessionToken2ImplBase) obj;
return mUid == other.mUid
&& TextUtils.equals(mPackageName, other.mPackageName)
&& TextUtils.equals(mServiceName, other.mServiceName)
&& TextUtils.equals(mSessionId, other.mSessionId)
&& mType == other.mType
&& sessionBinderEquals(mISession2, other.mISession2);
}
private boolean sessionBinderEquals(IMediaSession2 a, IMediaSession2 b) {
if (a == null || b == null) {
return a == b;
}
return a.asBinder().equals(b.asBinder());
}
@Override
public String toString() {
return "SessionToken {pkg=" + mPackageName + " id=" + mSessionId + " type=" + mType
+ " service=" + mServiceName + " IMediaSession2=" + mISession2 + "}";
}
@Override
public boolean isLegacySession() {
return false;
}
@Override
public int getUid() {
return mUid;
}
@Override
public @NonNull String getPackageName() {
return mPackageName;
}
@Override
public @Nullable String getServiceName() {
return mServiceName;
}
/**
* @hide
* @return component name of this session token. Can be null for TYPE_SESSION.
*/
@RestrictTo(LIBRARY_GROUP)
@Override
public ComponentName getComponentName() {
return mComponentName;
}
@Override
public String getSessionId() {
return mSessionId;
}
@Override
public @TokenType int getType() {
return mType;
}
@Override
public Bundle toBundle() {
Bundle bundle = new Bundle();
bundle.putInt(KEY_UID, mUid);
bundle.putString(KEY_PACKAGE_NAME, mPackageName);
bundle.putString(KEY_SERVICE_NAME, mServiceName);
bundle.putString(KEY_SESSION_ID, mSessionId);
bundle.putInt(KEY_TYPE, mType);
if (mISession2 != null) {
BundleCompat.putBinder(bundle, KEY_SESSION_BINDER, mISession2.asBinder());
}
return bundle;
}
@Override
public Object getBinder() {
return mISession2 == null ? null : mISession2.asBinder();
}
/**
* Create a token from the bundle, exported by {@link #toBundle()}.
*
* @param bundle
* @return SessionToken2 object
*/
public static SessionToken2ImplBase fromBundle(@NonNull Bundle bundle) {
if (bundle == null) {
return null;
}
final int uid = bundle.getInt(KEY_UID);
final @TokenType int type = bundle.getInt(KEY_TYPE, -1);
final String packageName = bundle.getString(KEY_PACKAGE_NAME);
final String serviceName = bundle.getString(KEY_SERVICE_NAME);
final String sessionId = bundle.getString(KEY_SESSION_ID);
final IMediaSession2 iSession2 = IMediaSession2.Stub.asInterface(BundleCompat.getBinder(
bundle, KEY_SESSION_BINDER));
// Sanity check.
switch (type) {
case TYPE_SESSION:
if (iSession2 == null) {
throw new IllegalArgumentException("Unexpected token for session,"
+ " binder=" + iSession2);
}
break;
case TYPE_SESSION_SERVICE:
case TYPE_LIBRARY_SERVICE:
case TYPE_BROWSER_SERVICE_LEGACY:
if (TextUtils.isEmpty(serviceName)) {
throw new IllegalArgumentException("Session service needs service name");
}
break;
default:
throw new IllegalArgumentException("Invalid type");
}
if (TextUtils.isEmpty(packageName) || sessionId == null) {
throw new IllegalArgumentException("Package name nor ID cannot be null.");
}
return new SessionToken2ImplBase(uid, type, packageName, serviceName, sessionId, iSession2);
}
}