- 28,932 files - Full Java source code - Smali files - Resources Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
445 lines
16 KiB
Java
445 lines
16 KiB
Java
package com.mbridge.msdk.playercommon.exoplayer2.drm;
|
|
|
|
import android.annotation.SuppressLint;
|
|
import android.annotation.TargetApi;
|
|
import android.media.NotProvisionedException;
|
|
import android.os.Handler;
|
|
import android.os.HandlerThread;
|
|
import android.os.Looper;
|
|
import android.os.Message;
|
|
import android.util.Log;
|
|
import android.util.Pair;
|
|
import androidx.annotation.Nullable;
|
|
import com.mbridge.msdk.playercommon.exoplayer2.C;
|
|
import com.mbridge.msdk.playercommon.exoplayer2.drm.DefaultDrmSessionEventListener;
|
|
import com.mbridge.msdk.playercommon.exoplayer2.drm.DrmInitData;
|
|
import com.mbridge.msdk.playercommon.exoplayer2.drm.DrmSession;
|
|
import com.mbridge.msdk.playercommon.exoplayer2.drm.ExoMediaCrypto;
|
|
import com.mbridge.msdk.playercommon.exoplayer2.drm.ExoMediaDrm;
|
|
import java.util.Arrays;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
import java.util.UUID;
|
|
|
|
@TargetApi(18)
|
|
/* loaded from: classes4.dex */
|
|
class DefaultDrmSession<T extends ExoMediaCrypto> implements DrmSession<T> {
|
|
private static final int MAX_LICENSE_DURATION_TO_RENEW = 60;
|
|
private static final int MSG_KEYS = 1;
|
|
private static final int MSG_PROVISION = 0;
|
|
private static final String TAG = "DefaultDrmSession";
|
|
final MediaDrmCallback callback;
|
|
private Object currentKeyRequest;
|
|
private Object currentProvisionRequest;
|
|
private final DefaultDrmSessionEventListener.EventDispatcher eventDispatcher;
|
|
private final int initialDrmRequestRetryCount;
|
|
private DrmSession.DrmSessionException lastException;
|
|
private T mediaCrypto;
|
|
private final ExoMediaDrm<T> mediaDrm;
|
|
private final int mode;
|
|
private byte[] offlineLicenseKeySetId;
|
|
private int openCount;
|
|
private final HashMap<String, String> optionalKeyRequestParameters;
|
|
private DefaultDrmSession<T>.PostRequestHandler postRequestHandler;
|
|
final DefaultDrmSession<T>.PostResponseHandler postResponseHandler;
|
|
private final ProvisioningManager<T> provisioningManager;
|
|
private HandlerThread requestHandlerThread;
|
|
private final DrmInitData.SchemeData schemeData;
|
|
private byte[] sessionId;
|
|
private int state;
|
|
final UUID uuid;
|
|
|
|
public interface ProvisioningManager<T extends ExoMediaCrypto> {
|
|
void onProvisionCompleted();
|
|
|
|
void onProvisionError(Exception exc);
|
|
|
|
void provisionRequired(DefaultDrmSession<T> defaultDrmSession);
|
|
}
|
|
|
|
private boolean isOpen() {
|
|
int i = this.state;
|
|
return i == 3 || i == 4;
|
|
}
|
|
|
|
@Override // com.mbridge.msdk.playercommon.exoplayer2.drm.DrmSession
|
|
public final DrmSession.DrmSessionException getError() {
|
|
if (this.state == 1) {
|
|
return this.lastException;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override // com.mbridge.msdk.playercommon.exoplayer2.drm.DrmSession
|
|
public final T getMediaCrypto() {
|
|
return this.mediaCrypto;
|
|
}
|
|
|
|
@Override // com.mbridge.msdk.playercommon.exoplayer2.drm.DrmSession
|
|
public byte[] getOfflineLicenseKeySetId() {
|
|
return this.offlineLicenseKeySetId;
|
|
}
|
|
|
|
@Override // com.mbridge.msdk.playercommon.exoplayer2.drm.DrmSession
|
|
public final int getState() {
|
|
return this.state;
|
|
}
|
|
|
|
public DefaultDrmSession(UUID uuid, ExoMediaDrm<T> exoMediaDrm, ProvisioningManager<T> provisioningManager, @Nullable DrmInitData.SchemeData schemeData, int i, @Nullable byte[] bArr, HashMap<String, String> hashMap, MediaDrmCallback mediaDrmCallback, Looper looper, DefaultDrmSessionEventListener.EventDispatcher eventDispatcher, int i2) {
|
|
this.uuid = uuid;
|
|
this.provisioningManager = provisioningManager;
|
|
this.mediaDrm = exoMediaDrm;
|
|
this.mode = i;
|
|
this.offlineLicenseKeySetId = bArr;
|
|
this.schemeData = bArr != null ? null : schemeData;
|
|
this.optionalKeyRequestParameters = hashMap;
|
|
this.callback = mediaDrmCallback;
|
|
this.initialDrmRequestRetryCount = i2;
|
|
this.eventDispatcher = eventDispatcher;
|
|
this.state = 2;
|
|
this.postResponseHandler = new PostResponseHandler(looper);
|
|
HandlerThread handlerThread = new HandlerThread("DrmRequestHandler");
|
|
this.requestHandlerThread = handlerThread;
|
|
handlerThread.start();
|
|
this.postRequestHandler = new PostRequestHandler(this.requestHandlerThread.getLooper());
|
|
}
|
|
|
|
public void acquire() {
|
|
int i = this.openCount + 1;
|
|
this.openCount = i;
|
|
if (i == 1 && this.state != 1 && openInternal(true)) {
|
|
doLicense(true);
|
|
}
|
|
}
|
|
|
|
public boolean release() {
|
|
int i = this.openCount - 1;
|
|
this.openCount = i;
|
|
if (i != 0) {
|
|
return false;
|
|
}
|
|
this.state = 0;
|
|
this.postResponseHandler.removeCallbacksAndMessages(null);
|
|
this.postRequestHandler.removeCallbacksAndMessages(null);
|
|
this.postRequestHandler = null;
|
|
this.requestHandlerThread.quit();
|
|
this.requestHandlerThread = null;
|
|
this.mediaCrypto = null;
|
|
this.lastException = null;
|
|
this.currentKeyRequest = null;
|
|
this.currentProvisionRequest = null;
|
|
byte[] bArr = this.sessionId;
|
|
if (bArr != null) {
|
|
this.mediaDrm.closeSession(bArr);
|
|
this.sessionId = null;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public boolean hasInitData(byte[] bArr) {
|
|
DrmInitData.SchemeData schemeData = this.schemeData;
|
|
return Arrays.equals(schemeData != null ? schemeData.data : null, bArr);
|
|
}
|
|
|
|
public boolean hasSessionId(byte[] bArr) {
|
|
return Arrays.equals(this.sessionId, bArr);
|
|
}
|
|
|
|
public void onMediaDrmEvent(int i) {
|
|
if (isOpen()) {
|
|
if (i == 1) {
|
|
this.state = 3;
|
|
this.provisioningManager.provisionRequired(this);
|
|
} else if (i == 2) {
|
|
doLicense(false);
|
|
} else {
|
|
if (i != 3) {
|
|
return;
|
|
}
|
|
onKeysExpired();
|
|
}
|
|
}
|
|
}
|
|
|
|
public void provision() {
|
|
ExoMediaDrm.ProvisionRequest provisionRequest = this.mediaDrm.getProvisionRequest();
|
|
this.currentProvisionRequest = provisionRequest;
|
|
this.postRequestHandler.post(0, provisionRequest, true);
|
|
}
|
|
|
|
public void onProvisionCompleted() {
|
|
if (openInternal(false)) {
|
|
doLicense(true);
|
|
}
|
|
}
|
|
|
|
public void onProvisionError(Exception exc) {
|
|
onError(exc);
|
|
}
|
|
|
|
@Override // com.mbridge.msdk.playercommon.exoplayer2.drm.DrmSession
|
|
public Map<String, String> queryKeyStatus() {
|
|
byte[] bArr = this.sessionId;
|
|
if (bArr == null) {
|
|
return null;
|
|
}
|
|
return this.mediaDrm.queryKeyStatus(bArr);
|
|
}
|
|
|
|
private boolean openInternal(boolean z) {
|
|
if (isOpen()) {
|
|
return true;
|
|
}
|
|
try {
|
|
byte[] openSession = this.mediaDrm.openSession();
|
|
this.sessionId = openSession;
|
|
this.mediaCrypto = this.mediaDrm.createMediaCrypto(openSession);
|
|
this.state = 3;
|
|
return true;
|
|
} catch (NotProvisionedException e) {
|
|
if (z) {
|
|
this.provisioningManager.provisionRequired(this);
|
|
return false;
|
|
}
|
|
onError(e);
|
|
return false;
|
|
} catch (Exception e2) {
|
|
onError(e2);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public void onProvisionResponse(Object obj, Object obj2) {
|
|
if (obj == this.currentProvisionRequest) {
|
|
if (this.state == 2 || isOpen()) {
|
|
this.currentProvisionRequest = null;
|
|
if (obj2 instanceof Exception) {
|
|
this.provisioningManager.onProvisionError((Exception) obj2);
|
|
return;
|
|
}
|
|
try {
|
|
this.mediaDrm.provideProvisionResponse((byte[]) obj2);
|
|
this.provisioningManager.onProvisionCompleted();
|
|
} catch (Exception e) {
|
|
this.provisioningManager.onProvisionError(e);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void doLicense(boolean z) {
|
|
int i = this.mode;
|
|
if (i != 0 && i != 1) {
|
|
if (i != 2) {
|
|
if (i == 3 && restoreKeys()) {
|
|
postKeyRequest(3, z);
|
|
return;
|
|
}
|
|
return;
|
|
}
|
|
if (this.offlineLicenseKeySetId == null) {
|
|
postKeyRequest(2, z);
|
|
return;
|
|
} else {
|
|
if (restoreKeys()) {
|
|
postKeyRequest(2, z);
|
|
return;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
if (this.offlineLicenseKeySetId == null) {
|
|
postKeyRequest(1, z);
|
|
return;
|
|
}
|
|
if (this.state == 4 || restoreKeys()) {
|
|
long licenseDurationRemainingSec = getLicenseDurationRemainingSec();
|
|
if (this.mode == 0 && licenseDurationRemainingSec <= 60) {
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.append("Offline license has expired or will expire soon. Remaining seconds: ");
|
|
sb.append(licenseDurationRemainingSec);
|
|
postKeyRequest(2, z);
|
|
return;
|
|
}
|
|
if (licenseDurationRemainingSec <= 0) {
|
|
onError(new KeysExpiredException());
|
|
} else {
|
|
this.state = 4;
|
|
this.eventDispatcher.drmKeysRestored();
|
|
}
|
|
}
|
|
}
|
|
|
|
private boolean restoreKeys() {
|
|
try {
|
|
this.mediaDrm.restoreKeys(this.sessionId, this.offlineLicenseKeySetId);
|
|
return true;
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error trying to restore Widevine keys.", e);
|
|
onError(e);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private long getLicenseDurationRemainingSec() {
|
|
if (!C.WIDEVINE_UUID.equals(this.uuid)) {
|
|
return Long.MAX_VALUE;
|
|
}
|
|
Pair<Long, Long> licenseDurationRemainingSec = WidevineUtil.getLicenseDurationRemainingSec(this);
|
|
return Math.min(((Long) licenseDurationRemainingSec.first).longValue(), ((Long) licenseDurationRemainingSec.second).longValue());
|
|
}
|
|
|
|
private void postKeyRequest(int i, boolean z) {
|
|
String str;
|
|
byte[] bArr;
|
|
String str2;
|
|
byte[] bArr2 = i == 3 ? this.offlineLicenseKeySetId : this.sessionId;
|
|
DrmInitData.SchemeData schemeData = this.schemeData;
|
|
if (schemeData != null) {
|
|
byte[] bArr3 = schemeData.data;
|
|
String str3 = schemeData.mimeType;
|
|
str = schemeData.licenseServerUrl;
|
|
str2 = str3;
|
|
bArr = bArr3;
|
|
} else {
|
|
str = null;
|
|
bArr = null;
|
|
str2 = null;
|
|
}
|
|
try {
|
|
Pair create = Pair.create(this.mediaDrm.getKeyRequest(bArr2, bArr, str2, i, this.optionalKeyRequestParameters), str);
|
|
this.currentKeyRequest = create;
|
|
this.postRequestHandler.post(1, create, z);
|
|
} catch (Exception e) {
|
|
onKeysError(e);
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public void onKeyResponse(Object obj, Object obj2) {
|
|
if (obj == this.currentKeyRequest && isOpen()) {
|
|
this.currentKeyRequest = null;
|
|
if (obj2 instanceof Exception) {
|
|
onKeysError((Exception) obj2);
|
|
return;
|
|
}
|
|
try {
|
|
byte[] bArr = (byte[]) obj2;
|
|
if (this.mode == 3) {
|
|
this.mediaDrm.provideKeyResponse(this.offlineLicenseKeySetId, bArr);
|
|
this.eventDispatcher.drmKeysRemoved();
|
|
return;
|
|
}
|
|
byte[] provideKeyResponse = this.mediaDrm.provideKeyResponse(this.sessionId, bArr);
|
|
int i = this.mode;
|
|
if ((i == 2 || (i == 0 && this.offlineLicenseKeySetId != null)) && provideKeyResponse != null && provideKeyResponse.length != 0) {
|
|
this.offlineLicenseKeySetId = provideKeyResponse;
|
|
}
|
|
this.state = 4;
|
|
this.eventDispatcher.drmKeysLoaded();
|
|
} catch (Exception e) {
|
|
onKeysError(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void onKeysExpired() {
|
|
if (this.state == 4) {
|
|
this.state = 3;
|
|
onError(new KeysExpiredException());
|
|
}
|
|
}
|
|
|
|
private void onKeysError(Exception exc) {
|
|
if (exc instanceof NotProvisionedException) {
|
|
this.provisioningManager.provisionRequired(this);
|
|
} else {
|
|
onError(exc);
|
|
}
|
|
}
|
|
|
|
private void onError(Exception exc) {
|
|
this.lastException = new DrmSession.DrmSessionException(exc);
|
|
this.eventDispatcher.drmSessionManagerError(exc);
|
|
if (this.state != 4) {
|
|
this.state = 1;
|
|
}
|
|
}
|
|
|
|
@SuppressLint({"HandlerLeak"})
|
|
public class PostResponseHandler extends Handler {
|
|
public PostResponseHandler(Looper looper) {
|
|
super(looper);
|
|
}
|
|
|
|
@Override // android.os.Handler
|
|
public void handleMessage(Message message) {
|
|
Pair pair = (Pair) message.obj;
|
|
Object obj = pair.first;
|
|
Object obj2 = pair.second;
|
|
int i = message.what;
|
|
if (i == 0) {
|
|
DefaultDrmSession.this.onProvisionResponse(obj, obj2);
|
|
} else {
|
|
if (i != 1) {
|
|
return;
|
|
}
|
|
DefaultDrmSession.this.onKeyResponse(obj, obj2);
|
|
}
|
|
}
|
|
}
|
|
|
|
@SuppressLint({"HandlerLeak"})
|
|
public class PostRequestHandler extends Handler {
|
|
public PostRequestHandler(Looper looper) {
|
|
super(looper);
|
|
}
|
|
|
|
public void post(int i, Object obj, boolean z) {
|
|
obtainMessage(i, z ? 1 : 0, 0, obj).sendToTarget();
|
|
}
|
|
|
|
@Override // android.os.Handler
|
|
public void handleMessage(Message message) {
|
|
Object obj = message.obj;
|
|
try {
|
|
int i = message.what;
|
|
if (i == 0) {
|
|
DefaultDrmSession defaultDrmSession = DefaultDrmSession.this;
|
|
e = defaultDrmSession.callback.executeProvisionRequest(defaultDrmSession.uuid, (ExoMediaDrm.ProvisionRequest) obj);
|
|
} else if (i == 1) {
|
|
Pair pair = (Pair) obj;
|
|
ExoMediaDrm.KeyRequest keyRequest = (ExoMediaDrm.KeyRequest) pair.first;
|
|
String str = (String) pair.second;
|
|
DefaultDrmSession defaultDrmSession2 = DefaultDrmSession.this;
|
|
e = defaultDrmSession2.callback.executeKeyRequest(defaultDrmSession2.uuid, keyRequest, str);
|
|
} else {
|
|
throw new RuntimeException();
|
|
}
|
|
} catch (Exception e) {
|
|
e = e;
|
|
if (maybeRetryRequest(message)) {
|
|
return;
|
|
}
|
|
}
|
|
DefaultDrmSession.this.postResponseHandler.obtainMessage(message.what, Pair.create(obj, e)).sendToTarget();
|
|
}
|
|
|
|
private boolean maybeRetryRequest(Message message) {
|
|
int i;
|
|
if (message.arg1 != 1 || (i = message.arg2 + 1) > DefaultDrmSession.this.initialDrmRequestRetryCount) {
|
|
return false;
|
|
}
|
|
Message obtain = Message.obtain(message);
|
|
obtain.arg2 = i;
|
|
sendMessageDelayed(obtain, getRetryDelayMillis(i));
|
|
return true;
|
|
}
|
|
|
|
private long getRetryDelayMillis(int i) {
|
|
return Math.min((i - 1) * 1000, 5000);
|
|
}
|
|
}
|
|
}
|