diff options
Diffstat (limited to 'src/com/android/tv/tuner/DvbTunerHal.java')
-rw-r--r-- | src/com/android/tv/tuner/DvbTunerHal.java | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/src/com/android/tv/tuner/DvbTunerHal.java b/src/com/android/tv/tuner/DvbTunerHal.java new file mode 100644 index 00000000..ea977230 --- /dev/null +++ b/src/com/android/tv/tuner/DvbTunerHal.java @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.tv.tuner; + +import android.content.Context; +import android.os.ParcelFileDescriptor; +import android.util.Log; +import com.android.tv.tuner.DvbDeviceAccessor.DvbDeviceInfoWrapper; + +import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; + +/** + * A class to handle a hardware Linux DVB API supported tuner device. + */ +public class DvbTunerHal extends TunerHal { + + private static final Object sLock = new Object(); + // @GuardedBy("sLock") + private static final SortedSet<DvbDeviceInfoWrapper> sUsedDvbDevices = new TreeSet<>(); + + private final DvbDeviceAccessor mDvbDeviceAccessor; + private DvbDeviceInfoWrapper mDvbDeviceInfo; + + protected DvbTunerHal(Context context) { + super(context); + mDvbDeviceAccessor = new DvbDeviceAccessor(context); + } + + @Override + protected boolean openFirstAvailable() { + List<DvbDeviceInfoWrapper> deviceInfoList = mDvbDeviceAccessor.getDvbDeviceList(); + if (deviceInfoList == null || deviceInfoList.isEmpty()) { + Log.e(TAG, "There's no dvb device attached"); + return false; + } + synchronized (sLock) { + for (DvbDeviceInfoWrapper deviceInfo : deviceInfoList) { + if (!sUsedDvbDevices.contains(deviceInfo)) { + if (DEBUG) Log.d(TAG, "Available device info: " + deviceInfo); + mDvbDeviceInfo = deviceInfo; + sUsedDvbDevices.add(deviceInfo); + getDeliverySystemTypeFromDevice(); + return true; + } + } + } + Log.e(TAG, "There's no available dvb devices"); + return false; + } + + /** + * Acquires the tuner device. The requested device will be locked to the current instance if + * it's not acquired by others. + * + * @param deviceInfo a tuner device to open + * @return {@code true} if the operation was successful, {@code false} otherwise + */ + protected boolean open(DvbDeviceInfoWrapper deviceInfo) { + if (deviceInfo == null) { + Log.e(TAG, "Device info should not be null"); + return false; + } + if (mDvbDeviceInfo != null) { + Log.e(TAG, "Already acquired"); + return false; + } + List<DvbDeviceInfoWrapper> deviceInfoList = mDvbDeviceAccessor.getDvbDeviceList(); + if (deviceInfoList == null || deviceInfoList.isEmpty()) { + Log.e(TAG, "There's no dvb device attached"); + return false; + } + for (DvbDeviceInfoWrapper deviceInfoWrapper : deviceInfoList) { + if (deviceInfoWrapper.compareTo(deviceInfo) == 0) { + synchronized (sLock) { + if (sUsedDvbDevices.contains(deviceInfo)) { + Log.e(TAG, deviceInfo + " is already taken"); + return false; + } + sUsedDvbDevices.add(deviceInfo); + } + if (DEBUG) Log.d(TAG, "Available device info: " + deviceInfo); + mDvbDeviceInfo = deviceInfo; + return true; + } + } + Log.e(TAG, "There's no such dvb device attached"); + return false; + } + + @Override + public void close() { + if (mDvbDeviceInfo != null) { + if (isStreaming()) { + stopTune(); + } + nativeFinalize(mDvbDeviceInfo.getId()); + synchronized (sLock) { + sUsedDvbDevices.remove(mDvbDeviceInfo); + } + mDvbDeviceInfo = null; + } + } + + @Override + protected boolean isDeviceOpen() { + return (mDvbDeviceInfo != null); + } + + @Override + protected long getDeviceId() { + if (mDvbDeviceInfo != null) { + return mDvbDeviceInfo.getId(); + } + return -1; + } + + @Override + protected int openDvbFrontEndFd() { + if (mDvbDeviceInfo != null) { + ParcelFileDescriptor descriptor = mDvbDeviceAccessor.openDvbDevice( + mDvbDeviceInfo, DvbDeviceAccessor.DVB_DEVICE_FRONTEND); + if (descriptor != null) { + return descriptor.detachFd(); + } + } + return -1; + } + + @Override + protected int openDvbDemuxFd() { + if (mDvbDeviceInfo != null) { + ParcelFileDescriptor descriptor = mDvbDeviceAccessor.openDvbDevice( + mDvbDeviceInfo, DvbDeviceAccessor.DVB_DEVICE_DEMUX); + if (descriptor != null) { + return descriptor.detachFd(); + } + } + return -1; + } + + @Override + protected int openDvbDvrFd() { + if (mDvbDeviceInfo != null) { + ParcelFileDescriptor descriptor = mDvbDeviceAccessor.openDvbDevice( + mDvbDeviceInfo, DvbDeviceAccessor.DVB_DEVICE_DVR); + if (descriptor != null) { + return descriptor.detachFd(); + } + } + return -1; + } + + /** + * Gets the number of USB tuner devices currently present. + */ + public static int getNumberOfDevices(Context context) { + try { + return (new DvbDeviceAccessor(context)).getNumOfDvbDevices(); + } catch (Exception e) { + return 0; + } + } +} |