1 /* 2 * Copyright 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.media.tv.tuner; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.SystemApi; 23 import android.media.tv.tuner.Tuner.Result; 24 import android.media.tv.tuner.filter.Filter; 25 26 import java.lang.annotation.Retention; 27 import java.lang.annotation.RetentionPolicy; 28 import java.util.Objects; 29 30 /** 31 * This class is used to interact with descramblers. 32 * 33 * <p> Descrambler is a hardware component used to descramble data. 34 * 35 * <p> This class controls the TIS interaction with Tuner HAL. 36 * 37 * @hide 38 */ 39 @SystemApi 40 public class Descrambler implements AutoCloseable { 41 /** @hide */ 42 @IntDef(prefix = "PID_TYPE_", value = {PID_TYPE_T, PID_TYPE_MMTP}) 43 @Retention(RetentionPolicy.SOURCE) 44 public @interface PidType {} 45 46 /** 47 * Packet ID is used to specify packets in transport stream. 48 */ 49 public static final int PID_TYPE_T = 1; 50 /** 51 * Packet ID is used to specify packets in MMTP. 52 */ 53 public static final int PID_TYPE_MMTP = 2; 54 55 private static final String TAG = "Descrambler"; 56 57 58 private long mNativeContext; 59 private boolean mIsClosed = false; 60 private final Object mLock = new Object(); 61 nativeAddPid(int pidType, int pid, Filter filter)62 private native int nativeAddPid(int pidType, int pid, Filter filter); nativeRemovePid(int pidType, int pid, Filter filter)63 private native int nativeRemovePid(int pidType, int pid, Filter filter); nativeSetKeyToken(byte[] keyToken)64 private native int nativeSetKeyToken(byte[] keyToken); nativeClose()65 private native int nativeClose(); 66 67 // Called by JNI code Descrambler()68 private Descrambler() {} 69 70 /** 71 * Add packets' PID to the descrambler for descrambling. 72 * 73 * The descrambler will start descrambling packets with this PID. Multiple PIDs can be added 74 * into one descrambler instance because descambling can happen simultaneously on packets 75 * from different PIDs. 76 * 77 * If the Descrambler previously contained a filter for the PID, the old filter is replaced 78 * by the specified filter. 79 * 80 * @param pidType the type of the PID. 81 * @param pid the PID of packets to start to be descrambled. 82 * @param filter an optional filter instance to identify upper stream. 83 * @return result status of the operation. 84 */ 85 @Result addPid(@idType int pidType, int pid, @Nullable Filter filter)86 public int addPid(@PidType int pidType, int pid, @Nullable Filter filter) { 87 synchronized (mLock) { 88 TunerUtils.checkResourceState(TAG, mIsClosed); 89 return nativeAddPid(pidType, pid, filter); 90 } 91 } 92 93 /** 94 * Remove packets' PID from the descrambler 95 * 96 * The descrambler will stop descrambling packets with this PID. 97 * 98 * @param pidType the type of the PID. 99 * @param pid the PID of packets to stop to be descrambled. 100 * @param filter an optional filter instance to identify upper stream. 101 * @return result status of the operation. 102 */ 103 @Result removePid(@idType int pidType, int pid, @Nullable Filter filter)104 public int removePid(@PidType int pidType, int pid, @Nullable Filter filter) { 105 synchronized (mLock) { 106 TunerUtils.checkResourceState(TAG, mIsClosed); 107 return nativeRemovePid(pidType, pid, filter); 108 } 109 } 110 111 /** 112 * Set a key token to link descrambler to a key slot 113 * 114 * A descrambler instance can have only one key slot to link, but a key slot can hold a few 115 * keys for different purposes. 116 * 117 * @param keyToken the token to be used to link the key slot. 118 * @return result status of the operation. 119 */ 120 @Result setKeyToken(@onNull byte[] keyToken)121 public int setKeyToken(@NonNull byte[] keyToken) { 122 synchronized (mLock) { 123 TunerUtils.checkResourceState(TAG, mIsClosed); 124 Objects.requireNonNull(keyToken, "key token must not be null"); 125 return nativeSetKeyToken(keyToken); 126 } 127 } 128 129 /** 130 * Release the descrambler instance. 131 */ 132 @Override close()133 public void close() { 134 synchronized (mLock) { 135 if (mIsClosed) { 136 return; 137 } 138 int res = nativeClose(); 139 if (res != Tuner.RESULT_SUCCESS) { 140 TunerUtils.throwExceptionForResult(res, "Failed to close descrambler"); 141 } else { 142 mIsClosed = true; 143 } 144 } 145 } 146 147 } 148