MediaDrm.java revision 8a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906
18a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker/* 28a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Copyright (C) 2013 The Android Open Source Project 38a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * 48a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Licensed under the Apache License, Version 2.0 (the "License"); 58a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * you may not use this file except in compliance with the License. 68a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * You may obtain a copy of the License at 78a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * 88a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * http://www.apache.org/licenses/LICENSE-2.0 98a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * 108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Unless required by applicable law or agreed to in writing, software 118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * distributed under the License is distributed on an "AS IS" BASIS, 128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * See the License for the specific language governing permissions and 148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * limitations under the License. 158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker */ 168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerpackage android.media; 188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerimport android.media.MediaDrmException; 208a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerimport java.lang.ref.WeakReference; 218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerimport java.util.UUID; 228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerimport java.util.HashMap; 238a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerimport java.util.List; 248a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerimport android.os.Handler; 258a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerimport android.os.Looper; 268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerimport android.os.Message; 278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerimport android.os.Bundle; 288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerimport android.util.Log; 298a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 308a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker/** 318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * MediaDrm class can be used in conjunction with {@link android.media.MediaCrypto} 328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * to obtain licenses for decoding encrypted media data. 338a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * 348a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Crypto schemes are assigned 16 byte UUIDs, 358a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * the method {@link #isCryptoSchemeSupported} can be used to query if a given 368a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * scheme is supported on the device. 378a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * 388a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * <a name="Callbacks"></a> 398a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * <h3>Callbacks</h3> 408a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * <p>Applications may want to register for informational events in order 418a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * to be informed of some internal state update during playback or streaming. 428a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Registration for these events is done via a call to 438a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * {@link #setOnEventListener(OnInfoListener)}setOnInfoListener, 448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * In order to receive the respective callback 458a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * associated with this listener, applications are required to create 468a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * MediaDrm objects on a thread with its own Looper running (main UI 478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * thread by default has a Looper running). 488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * 498a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * @hide -- don't expose yet 508a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker */ 518a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerpublic final class MediaDrm { 528a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 538a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker private final static String TAG = "MediaDrm"; 548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker private EventHandler mEventHandler; 568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker private OnEventListener mOnEventListener; 578a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 588a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker private int mNativeContext; 598a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker /** 618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Query if the given scheme identified by its UUID is supported on 628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * this device. 638a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * @param uuid The UUID of the crypto scheme. 648a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker */ 658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public static final boolean isCryptoSchemeSupported(UUID uuid) { 668a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker return isCryptoSchemeSupportedNative(getByteArrayFromUUID(uuid)); 678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker } 688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker private static final byte[] getByteArrayFromUUID(UUID uuid) { 708a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker long msb = uuid.getMostSignificantBits(); 718a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker long lsb = uuid.getLeastSignificantBits(); 728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker byte[] uuidBytes = new byte[16]; 748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker for (int i = 0; i < 8; ++i) { 758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker uuidBytes[i] = (byte)(msb >>> (8 * (7 - i))); 768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker uuidBytes[8 + i] = (byte)(lsb >>> (8 * (7 - i))); 778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker } 788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker return uuidBytes; 808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker } 818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker private static final native boolean isCryptoSchemeSupportedNative(byte[] uuid); 838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker /** 858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Instantiate a MediaDrm object using opaque, crypto scheme specific 868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * data. 878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * @param uuid The UUID of the crypto scheme. 888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker */ 898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public MediaDrm(UUID uuid) throws MediaDrmException { 908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker Looper looper; 918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker if ((looper = Looper.myLooper()) != null) { 928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker mEventHandler = new EventHandler(this, looper); 938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker } else if ((looper = Looper.getMainLooper()) != null) { 948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker mEventHandler = new EventHandler(this, looper); 958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker } else { 968a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker mEventHandler = null; 978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker } 988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker /* Native setup requires a weak reference to our object. 1008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * It's easier to create it here than in C++. 1018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker */ 1028a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker native_setup(new WeakReference<MediaDrm>(this), 1038a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker getByteArrayFromUUID(uuid)); 1048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker } 1058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 1068a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker /** 1078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Register a callback to be invoked when an event occurs 1088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * 1098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * @param listener the callback that will be run 1108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker */ 1118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public void setOnEventListener(OnEventListener listener) 1128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker { 1138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker mOnEventListener = listener; 1148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker } 1158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 1168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker /** 1178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Interface definition for a callback to be invoked when a drm event 1188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * occurs. 1198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker */ 1208a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public interface OnEventListener 1218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker { 1228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker /** 1238a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Called when an event occurs that requires the app to be notified 1248a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * 1258a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * @param md the MediaDrm object on which the event occurred 1268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * @param sessionId the DRM session ID on which the event occurred 1278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * @param event indicates the event type 1288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * @param extra an secondary error code 1298a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * @param data optional byte array of data that may be associated with the event 1308a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker */ 1318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker void onEvent(MediaDrm md, byte[] sessionId, int event, int extra, byte[] data); 1328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker } 1338a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 1348a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker /* Do not change these values without updating their counterparts 1358a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * in include/media/mediadrm.h! 1368a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker */ 1378a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker private static final int DRM_EVENT = 200; 1388a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 1398a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker private class EventHandler extends Handler 1408a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker { 1418a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker private MediaDrm mMediaDrm; 1428a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 1438a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public EventHandler(MediaDrm md, Looper looper) { 1448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker super(looper); 1458a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker mMediaDrm = md; 1468a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker } 1478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 1488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker @Override 1498a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public void handleMessage(Message msg) { 1508a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker if (mMediaDrm.mNativeContext == 0) { 1518a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker Log.w(TAG, "MediaDrm went away with unhandled events"); 1528a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker return; 1538a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker } 1548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker switch(msg.what) { 1558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 1568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker case DRM_EVENT: 1578a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker Log.i(TAG, "Drm event (" + msg.arg1 + "," + msg.arg2 + ")"); 1588a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 1598a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker if (mOnEventListener != null) { 1608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker Bundle bundle = msg.getData(); 1618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker byte[] sessionId = bundle.getByteArray("sessionId"); 1628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker byte[] data = bundle.getByteArray("data"); 1638a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker mOnEventListener.onEvent(mMediaDrm, sessionId, msg.arg1, msg.arg2, data); 1648a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker } 1658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker return; 1668a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 1678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker default: 1688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker Log.e(TAG, "Unknown message type " + msg.what); 1698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker return; 1708a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker } 1718a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker } 1728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker } 1738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 1748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker /* 1758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Called from native code when an interesting event happens. This method 1768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * just uses the EventHandler system to post the event back to the main app thread. 1778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * We use a weak reference to the original MediaPlayer object so that the native 1788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * code is safe from the object disappearing from underneath it. (This is 1798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * the cookie passed to native_setup().) 1808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker */ 1818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker private static void postEventFromNative(Object mediadrm_ref, 1828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker int what, int arg1, int arg2, Object obj) 1838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker { 1848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker MediaDrm md = (MediaDrm)((WeakReference)mediadrm_ref).get(); 1858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker if (md == null) { 1868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker return; 1878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker } 1888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker if (md.mEventHandler != null) { 1898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker Message m = md.mEventHandler.obtainMessage(what, arg1, arg2, obj); 1908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker md.mEventHandler.sendMessage(m); 1918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker } 1928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker } 1938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 1948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker /** 1958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Open a new session with the MediaDrm object. A session ID is returned. 1968a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker */ 1978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public native byte[] openSession() throws MediaDrmException; 1988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 1998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker /** 2008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Close a session on the MediaDrm object. 2018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker */ 2028a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public native void closeSession(byte[] sessionId) throws MediaDrmException; 2038a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 2048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public static final int MEDIA_DRM_LICENSE_TYPE_STREAMING = 1; 2058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public static final int MEDIA_DRM_LICENSE_TYPE_OFFLINE = 2; 2068a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 2078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public final class LicenseRequest { 2088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public LicenseRequest() {} 2098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public byte[] data; 2108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public String defaultUrl; 2118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker }; 2128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 2138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker /** 2148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * A license request/response exchange occurs between the app and a License 2158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Server to obtain the keys required to decrypt the content. getLicenseRequest() 2168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * is used to obtain an opaque license request byte array that is delivered to the 2178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * license server. The opaque license request byte array is returned in 2188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * LicenseReqeust.data. The recommended URL to deliver the license request to is 2198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * returned in LicenseRequest.defaultUrl 2208a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * 2218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * @param sessonId the session ID for the drm session 2228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * @param init container-specific data, its meaning is interpreted based on the 2238a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * mime type provided in the mimeType parameter. It could contain, for example, 2248a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * the content ID, key ID or other data obtained from the content metadata that is 2258a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * required in generating the license request. 2268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * @param mimeType identifies the mime type of the content 2278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * @param licenseType specifes if the license is for streaming or offline content 2288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * @param optionalParameters are included in the license server request message to 2298a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * allow a client application to provide additional message parameters to the server. 2308a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker */ 2318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public native LicenseRequest getLicenseRequest( byte[] sessionId, byte[] init, 2328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker String mimeType, int licenseType, 2338a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker HashMap<String, String> optionalParameters ) 2348a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker throws MediaDrmException; 2358a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 2368a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker /** 2378a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * After a license response is received by the app, it is provided to the DRM plugin 2388a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * using provideLicenseResponse. 2398a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * 2408a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * @param sessionId the session ID for the DRM session 2418a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * @param response the byte array response from the server 2428a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker */ 2438a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public native void provideLicenseResponse( byte[] sessionId, byte[] response ) 2448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker throws MediaDrmException; 2458a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 2468a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker /** 2478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Remove the keys associated with a license for a session 2488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * @param sessionId the session ID for the DRM session 2498a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker */ 2508a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public native void removeLicense( byte[] sessionId ) throws MediaDrmException; 2518a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 2528a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker /** 2538a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Request an informative description of the license for the session. The status is 2548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * in the form of {name, value} pairs. Since DRM license policies vary by vendor, 2558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * the specific status field names are determined by each DRM vendor. Refer to your 2568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * DRM provider documentation for definitions of the field names for a particular 2578a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * DrmEngine. 2588a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * 2598a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * @param sessionId the session ID for the DRM session 2608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker */ 2618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public native HashMap<String, String> queryLicenseStatus( byte[] sessionId ) 2628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker throws MediaDrmException; 2638a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 2648a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public final class ProvisionRequest { 2658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public ProvisionRequest() {} 2668a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public byte[] data; 2678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public String defaultUrl; 2688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker } 2698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 2708a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker /** 2718a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * A provision request/response exchange occurs between the app and a provisioning 2728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * server to retrieve a device certificate. getProvisionRequest is used to obtain 2738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * an opaque license request byte array that is delivered to the provisioning server. 2748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * The opaque provision request byte array is returned in ProvisionRequest.data 2758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * The recommended URL to deliver the license request to is returned in 2768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * ProvisionRequest.defaultUrl. 2778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker */ 2788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public native ProvisionRequest getProvisionRequest() throws MediaDrmException; 2798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 2808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker /** 2818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * After a provision response is received by the app, it is provided to the DRM 2828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * plugin using this method. 2838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * 2848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * @param response the opaque provisioning response byte array to provide to the 2858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * DrmEngine. 2868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker */ 2878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public native void provideProvisionResponse( byte[] response ) 2888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker throws MediaDrmException; 2898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 2908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker /** 2918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * A means of enforcing the contractual requirement for a concurrent stream limit 2928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * per subscriber across devices is provided via SecureStop. SecureStop is a means 2938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * of securely monitoring the lifetime of sessions. Since playback on a device can 2948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * be interrupted due to reboot, power failure, etc. a means of persisting the 2958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * lifetime information on the device is needed. 2968a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * 2978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * A signed version of the sessionID is written to persistent storage on the device 2988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * when each MediaCrypto object is created. The sessionID is signed by the device 2998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * private key to prevent tampering. 3008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * 3018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * In the normal case, playback will be completed, the session destroyed and the 3028a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Secure Stops will be queried. The App queries secure stops and forwards the 3038a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * secure stop message to the server which verifies the signature and notifies the 3048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * server side database that the session destruction has been confirmed. The persisted 3058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * record on the client is only removed after positive confirmation that the server 3068a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * received the message using releaseSecureStops(). 3078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker */ 3088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public native List<byte[]> getSecureStops() throws MediaDrmException; 3098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 3108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 3118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker /** 3128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Process the SecureStop server response message ssRelease. After authenticating 3138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * the message, remove the SecureStops identiied in the response. 3148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * 3158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * @param ssRelease the server response indicating which secure stops to release 3168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker */ 3178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public native void releaseSecureStops( byte[] ssRelease ) 3188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker throws MediaDrmException; 3198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 3208a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 3218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker /** 3228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Read a Drm plugin property value, given the property name string. There are several 3238a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * forms of property access functions, depending on the data type returned. 3248a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * 3258a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Standard fields names are: 3268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * vendor String - identifies the maker of the plugin 3278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * version String - identifies the version of the plugin 3288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * description String - describes the plugin 3298a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * deviceUniqueId byte[] - The device unique identifier is established during device 3308a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * provisioning and provides a means of uniquely identifying 3318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * each device 3328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker */ 3338a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public native String getPropertyString( String propertyName ) 3348a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker throws MediaDrmException; 3358a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 3368a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public native byte[] getPropertyByteArray( String propertyName ) 3378a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker throws MediaDrmException; 3388a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 3398a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker /** 3408a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Write a Drm plugin property value. There are several forms of property setting 3418a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * functions, depending on the data type being set. 3428a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker */ 3438a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public native void setPropertyString( String propertyName, String value ) 3448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker throws MediaDrmException; 3458a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 3468a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public native void setPropertyByteArray( String propertyName, byte[] value ) 3478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker throws MediaDrmException; 3488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 3498a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker @Override 3508a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker protected void finalize() { 3518a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker native_finalize(); 3528a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker } 3538a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 3548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker public native final void release(); 3558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker private static native final void native_init(); 3568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 3578a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker private native final void native_setup(Object mediadrm_this, byte[] uuid) 3588a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker throws MediaDrmException; 3598a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 3608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker private native final void native_finalize(); 3618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker 3628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker static { 3638a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker System.loadLibrary("media_jni"); 3648a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker native_init(); 3658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker } 3668a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker} 367