MediaDescrambler.java revision d5927ae8833780395f8fc5070d0a0a4f8f668292
1d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang/* 2d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * Copyright (C) 2017 The Android Open Source Project 3d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * 4d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * Licensed under the Apache License, Version 2.0 (the "License"); 5d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * you may not use this file except in compliance with the License. 6d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * You may obtain a copy of the License at 7d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * 8d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * http://www.apache.org/licenses/LICENSE-2.0 9d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * 10d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * Unless required by applicable law or agreed to in writing, software 11d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * distributed under the License is distributed on an "AS IS" BASIS, 12d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * See the License for the specific language governing permissions and 14d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * limitations under the License. 15d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang */ 16d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 17d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhangpackage android.media; 18d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 19d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhangimport android.annotation.NonNull; 20d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhangimport android.os.IBinder; 21d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhangimport android.os.Parcel; 22d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhangimport android.os.Parcelable; 23d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhangimport android.os.RemoteException; 24d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhangimport android.util.Log; 25d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 26d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhangimport java.nio.ByteBuffer; 27d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 28d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang/** 29d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * MediaDescrambler class can be used in conjunction with {@link android.media.MediaCodec} 30d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * and {@link android.media.MediaExtractor} to decode media data scrambled by conditional 31d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * access (CA) systems such as those in the ISO/IEC13818-1. 32d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * 33d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * A MediaDescrambler object is initialized from a session opened by a MediaCas object, 34d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * and can be used to descramble media streams scrambled with that session's keys. 35d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * 36d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * Scrambling schemes are identified by 16-bit unsigned integer as in CA_system_id. 37d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * 38d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang */ 39d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhangpublic final class MediaDescrambler { 40d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang private static final String TAG = "MediaDescrambler"; 41d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang private IDescrambler mIDescrambler; 42d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 43d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang private final void validateInternalStates() { 44d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang if (mIDescrambler == null) { 45d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang throw new IllegalStateException(); 46d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 47d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 48d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 49d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang private final void cleanupAndRethrowIllegalState() { 50d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang mIDescrambler = null; 51d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang throw new IllegalStateException(); 52d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 53d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 54d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang /** 55d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * Class for parceling descrambling parameters over IDescrambler binder. 56d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang */ 57d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang static class DescrambleInfo implements Parcelable { 58d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang private DescrambleInfo() { 59d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang // TODO: implement 60d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 61d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 62d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang private DescrambleInfo(Parcel in) { 63d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang // TODO: disable 64d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 65d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 66d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang @Override 67d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang public int describeContents() { 68d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang return 0; 69d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 70d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 71d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang @Override 72d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang public void writeToParcel(Parcel dest, int flags) { 73d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang // TODO: implement 74d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 75d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 76d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang public static final Parcelable.Creator<DescrambleInfo> CREATOR 77d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang = new Parcelable.Creator<DescrambleInfo>() { 78d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang public DescrambleInfo createFromParcel(Parcel in) { 79d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang return new DescrambleInfo(in); 80d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 81d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 82d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang public DescrambleInfo[] newArray(int size) { 83d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang return new DescrambleInfo[size]; 84d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 85d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang }; 86d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 87d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 88d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang /** 89d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * Instantiate a MediaDescrambler. 90d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * 91d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * @param CA_system_id The system id of the scrambling scheme. 92d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * 93d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * @throws UnsupportedCasException if the scrambling scheme is not supported. 94d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang */ 95d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang public MediaDescrambler(int CA_system_id) throws UnsupportedCasException { 96d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang try { 97d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang mIDescrambler = MediaCas.getService().createDescrambler(CA_system_id); 98d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } catch(Exception e) { 99d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang Log.e(TAG, "Failed to create descrambler: " + e); 100d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang mIDescrambler = null; 101d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } finally { 102d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang if (mIDescrambler == null) { 103d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang throw new UnsupportedCasException("Unsupported CA_system_id " + CA_system_id); 104d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 105d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 106d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang native_setup(mIDescrambler.asBinder()); 107d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 108d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 109d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang IBinder getBinder() { 110d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang validateInternalStates(); 111d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 112d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang return mIDescrambler.asBinder(); 113d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 114d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 115d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang /* 116d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * TODO: handle ServiceSpecificException from the mIDescrambler 117d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * All Drm-specific failures will be thrown by mIDescrambler as 118d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * ServiceSpecificException exception with Drm error code. 119d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * These need to be re-thrown as crypto exceptions. 120d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang */ 121d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 122d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang /** 123d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * Query if the scrambling scheme requires the use of a secure decoder 124d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * to decode data of the given mime type. 125d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * 126d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * @param mime The mime type of the media data 127d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * 128d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * @throws IllegalStateException if the descrambler instance is not valid. 129d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang */ 130d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang public final boolean requiresSecureDecoderComponent(@NonNull String mime) { 131d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang validateInternalStates(); 132d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 133d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang try { 134d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang return mIDescrambler.requiresSecureDecoderComponent(mime); 135d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } catch (RemoteException e) { 136d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang cleanupAndRethrowIllegalState(); 137d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 138d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang return true; 139d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 140d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 141d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang /** 142d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * Associate a MediaCas session with this MediaDescrambler instance. 143d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * The MediaCas session is used to securely load decryption keys for 144d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * the descrambler. The crypto keys loaded through the MediaCas session 145d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * may be selected for use during the descrambling operation performed 146d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * by {@link android.media.MediaExtractor or @link 147d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * android.media.MediaCodec#queueSecureInputBuffer} by specifying even 148d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * or odd key in the {@link android.media.MediaCodec.CryptoInfo#key} field. 149d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * 150d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * @param sessionId the MediaCas sessionId to associate with this 151d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * MediaDescrambler instance. 152d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * 153d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * @throws IllegalStateException if the descrambler instance is not valid, 154d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * or IllegalArgumentException if the sessionId is not valid. 155d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang */ 156d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang public final void setMediaCasSession(@NonNull byte[] sessionId) { 157d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang validateInternalStates(); 158d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 159d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang try { 160d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang mIDescrambler.setMediaCasSession(sessionId); 161d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } catch (RemoteException e) { 162d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang cleanupAndRethrowIllegalState(); 163d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 164d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 165d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 166d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang /** 167d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * Descramble a ByteBuffer of data described by a 168d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * {@link android.media.MediaCodec.CryptoInfo} structure. 169d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * 170d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * @param srcBuf ByteBuffer containing the scrambled data. 171d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * @param srcPos position within src where the scrambled data starts. 172d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * @param dstBuf ByteBuffer to descramble into. If null, descrambling will happen 173d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * in-place and src will be used as dst. 174d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * @param dstPos position within dst to put the descrambled data. 175d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * @param cryptoInfo a {@link android.media.MediaCodec.CryptoInfo} structure 176d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * describing the subsamples contained in src. 177d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * 178d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * @return number of bytes that have been successfully descrambled, with negative 179d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * values indicating errors. 180d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * 181d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * @throws IllegalStateException if the descrambler instance is not valid. 182d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang */ 183d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang /* 184d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * TODO: throw DRM-specific exception if decrambling is failing. 185d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang */ 186d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang public final int descramble( 187d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang @NonNull ByteBuffer srcBuf, int srcPos, ByteBuffer dstBuf, int dstPos, 188d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang @NonNull MediaCodec.CryptoInfo cryptoInfo) { 189d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang validateInternalStates(); 190d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 191d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang if (cryptoInfo.numSubSamples <= 0) { 192d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang throw new IllegalArgumentException( 193d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang "Invalid CryptoInfo: invalid numSubSamples=" + cryptoInfo.numSubSamples); 194d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } else if (cryptoInfo.numBytesOfClearData == null 195d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang && cryptoInfo.numBytesOfEncryptedData == null) { 196d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang throw new IllegalArgumentException( 197d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang "Invalid CryptoInfo: clearData and encryptedData size arrays are both null!"); 198d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } else if (cryptoInfo.numBytesOfClearData != null 199d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang && cryptoInfo.numBytesOfClearData.length < cryptoInfo.numSubSamples) { 200d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang throw new IllegalArgumentException( 201d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang "Invalid CryptoInfo: numBytesOfClearData is too small!"); 202d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } else if (cryptoInfo.numBytesOfEncryptedData != null 203d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang && cryptoInfo.numBytesOfEncryptedData.length < cryptoInfo.numSubSamples) { 204d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang throw new IllegalArgumentException( 205d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang "Invalid CryptoInfo: numBytesOfEncryptedData is too small!"); 206d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } else if (cryptoInfo.key == null || cryptoInfo.key.length != 16) { 207d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang throw new IllegalArgumentException( 208d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang "Invalid CryptoInfo: key array is invalid!"); 209d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 210d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 211d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang return native_descramble( 212d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang cryptoInfo.key[0], 213d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang cryptoInfo.numSubSamples, 214d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang cryptoInfo.numBytesOfClearData, 215d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang cryptoInfo.numBytesOfEncryptedData, 216d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang srcBuf, srcPos, dstBuf, dstPos); 217d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 218d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 219d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang public final void release() { 220d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang if (mIDescrambler != null) { 221d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang try { 222d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang mIDescrambler.release(); 223d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } catch (RemoteException e) { 224d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } finally { 225d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang mIDescrambler = null; 226d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 227d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 228d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang native_release(); 229d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 230d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 231d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang @Override 232d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang protected void finalize() { 233d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang release(); 234d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 235d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 236d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang private static native final void native_init(); 237d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang private native final void native_setup(@NonNull IBinder decramblerBinder); 238d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang private native final void native_release(); 239d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang private native final int native_descramble( 240d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang byte key, int numSubSamples, int[] numBytesOfClearData, int[] numBytesOfEncryptedData, 241d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang @NonNull ByteBuffer srcBuf, int srcOffset, ByteBuffer dstBuf, int dstOffset); 242d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 243d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang static { 244d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang System.loadLibrary("media_jni"); 245d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang native_init(); 246d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 247d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 248d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang private long mNativeContext; 249d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang}