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.hardware.tv.tuner.V1_0.Constants; 24 import android.media.tv.tuner.Tuner.Result; 25 26 import java.lang.annotation.Retention; 27 import java.lang.annotation.RetentionPolicy; 28 import java.util.concurrent.Executor; 29 30 /** 31 * LNB (low-noise block downconverter) for satellite tuner. 32 * 33 * A Tuner LNB (low-noise block downconverter) is used by satellite frontend to receive the 34 * microwave signal from the satellite, amplify it, and downconvert the frequency to a lower 35 * frequency. 36 * 37 * @hide 38 */ 39 @SystemApi 40 public class Lnb implements AutoCloseable { 41 /** @hide */ 42 @IntDef(prefix = "VOLTAGE_", 43 value = {VOLTAGE_NONE, VOLTAGE_5V, VOLTAGE_11V, VOLTAGE_12V, VOLTAGE_13V, VOLTAGE_14V, 44 VOLTAGE_15V, VOLTAGE_18V, VOLTAGE_19V}) 45 @Retention(RetentionPolicy.SOURCE) 46 public @interface Voltage {} 47 48 /** 49 * LNB power voltage not set. 50 */ 51 public static final int VOLTAGE_NONE = Constants.LnbVoltage.NONE; 52 /** 53 * LNB power voltage 5V. 54 */ 55 public static final int VOLTAGE_5V = Constants.LnbVoltage.VOLTAGE_5V; 56 /** 57 * LNB power voltage 11V. 58 */ 59 public static final int VOLTAGE_11V = Constants.LnbVoltage.VOLTAGE_11V; 60 /** 61 * LNB power voltage 12V. 62 */ 63 public static final int VOLTAGE_12V = Constants.LnbVoltage.VOLTAGE_12V; 64 /** 65 * LNB power voltage 13V. 66 */ 67 public static final int VOLTAGE_13V = Constants.LnbVoltage.VOLTAGE_13V; 68 /** 69 * LNB power voltage 14V. 70 */ 71 public static final int VOLTAGE_14V = Constants.LnbVoltage.VOLTAGE_14V; 72 /** 73 * LNB power voltage 15V. 74 */ 75 public static final int VOLTAGE_15V = Constants.LnbVoltage.VOLTAGE_15V; 76 /** 77 * LNB power voltage 18V. 78 */ 79 public static final int VOLTAGE_18V = Constants.LnbVoltage.VOLTAGE_18V; 80 /** 81 * LNB power voltage 19V. 82 */ 83 public static final int VOLTAGE_19V = Constants.LnbVoltage.VOLTAGE_19V; 84 85 /** @hide */ 86 @IntDef(prefix = "TONE_", 87 value = {TONE_NONE, TONE_CONTINUOUS}) 88 @Retention(RetentionPolicy.SOURCE) 89 public @interface Tone {} 90 91 /** 92 * LNB tone mode not set. 93 */ 94 public static final int TONE_NONE = Constants.LnbTone.NONE; 95 /** 96 * LNB continuous tone mode. 97 */ 98 public static final int TONE_CONTINUOUS = Constants.LnbTone.CONTINUOUS; 99 100 /** @hide */ 101 @IntDef(prefix = "POSITION_", 102 value = {POSITION_UNDEFINED, POSITION_A, POSITION_B}) 103 @Retention(RetentionPolicy.SOURCE) 104 public @interface Position {} 105 106 /** 107 * LNB position is not defined. 108 */ 109 public static final int POSITION_UNDEFINED = Constants.LnbPosition.UNDEFINED; 110 /** 111 * Position A of two-band LNBs 112 */ 113 public static final int POSITION_A = Constants.LnbPosition.POSITION_A; 114 /** 115 * Position B of two-band LNBs 116 */ 117 public static final int POSITION_B = Constants.LnbPosition.POSITION_B; 118 119 /** @hide */ 120 @Retention(RetentionPolicy.SOURCE) 121 @IntDef(prefix = "EVENT_TYPE_", 122 value = {EVENT_TYPE_DISEQC_RX_OVERFLOW, EVENT_TYPE_DISEQC_RX_TIMEOUT, 123 EVENT_TYPE_DISEQC_RX_PARITY_ERROR, EVENT_TYPE_LNB_OVERLOAD}) 124 public @interface EventType {} 125 126 /** 127 * Outgoing Diseqc message overflow. 128 */ 129 public static final int EVENT_TYPE_DISEQC_RX_OVERFLOW = 130 Constants.LnbEventType.DISEQC_RX_OVERFLOW; 131 /** 132 * Outgoing Diseqc message isn't delivered on time. 133 */ 134 public static final int EVENT_TYPE_DISEQC_RX_TIMEOUT = 135 Constants.LnbEventType.DISEQC_RX_TIMEOUT; 136 /** 137 * Incoming Diseqc message has parity error. 138 */ 139 public static final int EVENT_TYPE_DISEQC_RX_PARITY_ERROR = 140 Constants.LnbEventType.DISEQC_RX_PARITY_ERROR; 141 /** 142 * LNB is overload. 143 */ 144 public static final int EVENT_TYPE_LNB_OVERLOAD = Constants.LnbEventType.LNB_OVERLOAD; 145 146 private static final String TAG = "Lnb"; 147 148 int mId; 149 LnbCallback mCallback; 150 Executor mExecutor; 151 Tuner mTuner; 152 153 nativeSetVoltage(int voltage)154 private native int nativeSetVoltage(int voltage); nativeSetTone(int tone)155 private native int nativeSetTone(int tone); nativeSetSatellitePosition(int position)156 private native int nativeSetSatellitePosition(int position); nativeSendDiseqcMessage(byte[] message)157 private native int nativeSendDiseqcMessage(byte[] message); nativeClose()158 private native int nativeClose(); 159 160 private long mNativeContext; 161 162 private Boolean mIsClosed = false; 163 private final Object mLock = new Object(); 164 Lnb(int id)165 private Lnb(int id) { 166 mId = id; 167 } 168 setCallback(Executor executor, @Nullable LnbCallback callback, Tuner tuner)169 void setCallback(Executor executor, @Nullable LnbCallback callback, Tuner tuner) { 170 mCallback = callback; 171 mExecutor = executor; 172 mTuner = tuner; 173 } 174 onEvent(int eventType)175 private void onEvent(int eventType) { 176 if (mExecutor != null && mCallback != null) { 177 mExecutor.execute(() -> mCallback.onEvent(eventType)); 178 } 179 } 180 onDiseqcMessage(byte[] diseqcMessage)181 private void onDiseqcMessage(byte[] diseqcMessage) { 182 if (mExecutor != null && mCallback != null) { 183 mExecutor.execute(() -> mCallback.onDiseqcMessage(diseqcMessage)); 184 } 185 } 186 isClosed()187 /* package */ boolean isClosed() { 188 synchronized (mLock) { 189 return mIsClosed; 190 } 191 } 192 193 /** 194 * Sets the LNB's power voltage. 195 * 196 * @param voltage the power voltage constant the Lnb to use. 197 * @return result status of the operation. 198 */ 199 @Result setVoltage(@oltage int voltage)200 public int setVoltage(@Voltage int voltage) { 201 synchronized (mLock) { 202 TunerUtils.checkResourceState(TAG, mIsClosed); 203 return nativeSetVoltage(voltage); 204 } 205 } 206 207 /** 208 * Sets the LNB's tone mode. 209 * 210 * @param tone the tone mode the Lnb to use. 211 * @return result status of the operation. 212 */ 213 @Result setTone(@one int tone)214 public int setTone(@Tone int tone) { 215 synchronized (mLock) { 216 TunerUtils.checkResourceState(TAG, mIsClosed); 217 return nativeSetTone(tone); 218 } 219 } 220 221 /** 222 * Selects the LNB's position. 223 * 224 * @param position the position the Lnb to use. 225 * @return result status of the operation. 226 */ 227 @Result setSatellitePosition(@osition int position)228 public int setSatellitePosition(@Position int position) { 229 synchronized (mLock) { 230 TunerUtils.checkResourceState(TAG, mIsClosed); 231 return nativeSetSatellitePosition(position); 232 } 233 } 234 235 /** 236 * Sends DiSEqC (Digital Satellite Equipment Control) message. 237 * 238 * The response message from the device comes back through callback onDiseqcMessage. 239 * 240 * @param message a byte array of data for DiSEqC message which is specified by EUTELSAT Bus 241 * Functional Specification Version 4.2. 242 * 243 * @return result status of the operation. 244 */ 245 @Result sendDiseqcMessage(@onNull byte[] message)246 public int sendDiseqcMessage(@NonNull byte[] message) { 247 synchronized (mLock) { 248 TunerUtils.checkResourceState(TAG, mIsClosed); 249 return nativeSendDiseqcMessage(message); 250 } 251 } 252 253 /** 254 * Releases the LNB instance. 255 */ close()256 public void close() { 257 synchronized (mLock) { 258 if (mIsClosed) { 259 return; 260 } 261 int res = nativeClose(); 262 if (res != Tuner.RESULT_SUCCESS) { 263 TunerUtils.throwExceptionForResult(res, "Failed to close LNB"); 264 } else { 265 mIsClosed = true; 266 mTuner.releaseLnb(); 267 } 268 } 269 } 270 } 271