blob: e9349bd136ceb999680d7817c7bcbeb1486da5ac [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.media;
import android.annotation.TargetApi;
import android.os.Build;
import org.chromium.base.Callback;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.MainDex;
import org.chromium.base.annotations.NativeMethods;
/**
* Origin isolated media drm scope id storage. Isolated origin is guranteed by native
* implementation. Thus no origin information is stored here.
*/
@JNINamespace("media")
@MainDex
@TargetApi(Build.VERSION_CODES.M)
class MediaDrmStorageBridge {
private static final long INVALID_NATIVE_MEDIA_DRM_STORAGE_BRIDGE = -1;
private long mNativeMediaDrmStorageBridge;
/**
* Information that need to be persistent on the device. Exposed to JNI.
*/
static class PersistentInfo {
// EME session ID, which is generated randomly.
private final byte[] mEmeId;
// Key set ID used to identify persistent license in MediaDrm.
private final byte[] mKeySetId;
// Mime type for the license.
private final String mMimeType;
// Key type of session. It can be any value. Caller should check it before actual using it.
private final int mKeyType;
@CalledByNative("PersistentInfo")
private static PersistentInfo create(
byte[] emeId, byte[] keySetId, String mime, int keyType) {
return new PersistentInfo(emeId, keySetId, mime, keyType);
}
PersistentInfo(byte[] emeId, byte[] keySetId, String mime, int keyType) {
mEmeId = emeId;
mKeySetId = keySetId;
mMimeType = mime;
mKeyType = keyType;
}
@CalledByNative("PersistentInfo")
byte[] emeId() {
return mEmeId;
}
@CalledByNative("PersistentInfo")
byte[] keySetId() {
return mKeySetId;
}
@CalledByNative("PersistentInfo")
String mimeType() {
return mMimeType;
}
@CalledByNative("PersistentInfo")
int keyType() {
return mKeyType;
}
}
MediaDrmStorageBridge(long nativeMediaDrmStorageBridge) {
mNativeMediaDrmStorageBridge = nativeMediaDrmStorageBridge;
assert isNativeMediaDrmStorageValid();
}
/**
* Called when device provisioning is finished.
*/
void onProvisioned(Callback<Boolean> cb) {
if (isNativeMediaDrmStorageValid()) {
MediaDrmStorageBridgeJni.get().onProvisioned(
mNativeMediaDrmStorageBridge, MediaDrmStorageBridge.this, cb);
} else {
cb.onResult(true);
}
}
/**
* Load |emeId|'s storage into memory.
*/
void loadInfo(byte[] emeId, Callback<PersistentInfo> cb) {
if (isNativeMediaDrmStorageValid()) {
MediaDrmStorageBridgeJni.get().onLoadInfo(
mNativeMediaDrmStorageBridge, MediaDrmStorageBridge.this, emeId, cb);
} else {
cb.onResult(null);
}
}
/**
* Save persistent information. Override the existing value.
*/
void saveInfo(PersistentInfo info, Callback<Boolean> cb) {
if (isNativeMediaDrmStorageValid()) {
MediaDrmStorageBridgeJni.get().onSaveInfo(
mNativeMediaDrmStorageBridge, MediaDrmStorageBridge.this, info, cb);
} else {
cb.onResult(false);
}
}
/**
* Remove persistent information related |emeId|.
*/
void clearInfo(byte[] emeId, Callback<Boolean> cb) {
if (isNativeMediaDrmStorageValid()) {
MediaDrmStorageBridgeJni.get().onClearInfo(
mNativeMediaDrmStorageBridge, MediaDrmStorageBridge.this, emeId, cb);
} else {
cb.onResult(true);
}
}
private boolean isNativeMediaDrmStorageValid() {
return mNativeMediaDrmStorageBridge != INVALID_NATIVE_MEDIA_DRM_STORAGE_BRIDGE;
}
@NativeMethods
interface Natives {
void onProvisioned(long nativeMediaDrmStorageBridge, MediaDrmStorageBridge caller,
Callback<Boolean> cb);
void onLoadInfo(long nativeMediaDrmStorageBridge, MediaDrmStorageBridge caller,
byte[] sessionId, Callback<PersistentInfo> cb);
void onSaveInfo(long nativeMediaDrmStorageBridge, MediaDrmStorageBridge caller,
PersistentInfo info, Callback<Boolean> cb);
void onClearInfo(long nativeMediaDrmStorageBridge, MediaDrmStorageBridge caller,
byte[] sessionId, Callback<Boolean> cb);
}
}