1 /* 2 * Copyright (C) 2016 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 com.android.tv.tuner.hdhomerun; 18 19 import android.content.Context; 20 import android.content.SharedPreferences; 21 import android.preference.PreferenceManager; 22 import android.support.annotation.WorkerThread; 23 import android.util.Log; 24 import java.util.HashSet; 25 import java.util.Set; 26 27 /** 28 * A class to manage tuner resources of HDHomeRun devices. It handles tuner resource acquisition and 29 * release. 30 */ 31 class HdHomeRunTunerManager { 32 private static final String TAG = "HdHomeRunTunerManager"; 33 private static final boolean DEBUG = false; 34 35 private static final String PREF_KEY_SCANNED_DEVICE_ID = "scanned_device_id"; 36 37 private static HdHomeRunTunerManager sInstance; 38 39 private final Set<HdHomeRunDevice> mHdHomeRunDevices = new HashSet<>(); 40 private final Set<HdHomeRunDevice> mUsedDevices = new HashSet<>(); 41 HdHomeRunTunerManager()42 private HdHomeRunTunerManager() {} 43 44 /** Returns the instance of this manager. */ getInstance()45 public static synchronized HdHomeRunTunerManager getInstance() { 46 if (sInstance == null) { 47 sInstance = new HdHomeRunTunerManager(); 48 } 49 return sInstance; 50 } 51 52 /** Returns number of tuners. */ 53 @WorkerThread getTunerCount()54 synchronized int getTunerCount() { 55 updateDevicesLocked(null); 56 if (DEBUG) Log.d(TAG, "getTunerCount: " + mHdHomeRunDevices.size()); 57 return mHdHomeRunDevices.size(); 58 } 59 60 /** Creates an HDHomeRun device. If there is no available one, returns {@code null}. */ 61 @WorkerThread acquireDevice(Context context)62 synchronized HdHomeRunDevice acquireDevice(Context context) { 63 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); 64 int scannedDeviceId = sp.getInt(PREF_KEY_SCANNED_DEVICE_ID, 0); 65 updateDevicesLocked(scannedDeviceId == 0 ? null : scannedDeviceId); 66 if (DEBUG) Log.d(TAG, "createDevice: device count = " + mHdHomeRunDevices.size()); 67 HdHomeRunDevice availableDevice = null; 68 // Use the device used for scanning first since other devices might have different line-up. 69 if (scannedDeviceId != 0) { 70 for (HdHomeRunDevice device : mHdHomeRunDevices) { 71 if (!mUsedDevices.contains(device) && scannedDeviceId == device.getDeviceId()) { 72 if (!HdHomeRunInterface.isDeviceAvailable( 73 device.getDeviceId(), device.getIpAddress(), device.getTunerIndex())) { 74 if (DEBUG) Log.d(TAG, "Device not available: " + device); 75 continue; 76 } 77 availableDevice = device; 78 break; 79 } 80 } 81 } 82 if (availableDevice == null) { 83 for (HdHomeRunDevice device : mHdHomeRunDevices) { 84 if (!mUsedDevices.contains(device)) { 85 if (!HdHomeRunInterface.isDeviceAvailable( 86 device.getDeviceId(), device.getIpAddress(), device.getTunerIndex())) { 87 if (DEBUG) Log.d(TAG, "Device not available: " + device); 88 continue; 89 } 90 availableDevice = device; 91 break; 92 } 93 } 94 } 95 if (availableDevice != null) { 96 if (DEBUG) Log.d(TAG, "created device " + availableDevice); 97 mUsedDevices.add(availableDevice); 98 return availableDevice; 99 } 100 return null; 101 } 102 103 /** Releases a created device by {@link #acquireDevice(Context)}. */ releaseDevice(HdHomeRunDevice device)104 synchronized void releaseDevice(HdHomeRunDevice device) { 105 if (DEBUG) Log.d(TAG, "releaseDevice: " + device); 106 mUsedDevices.remove(device); 107 } 108 109 /** 110 * Marks the device associated to this instance as a scanned device. Scanned device has higher 111 * priority among multiple HDHomeRun devices. 112 */ markAsScannedDevice(Context context, HdHomeRunDevice device)113 static void markAsScannedDevice(Context context, HdHomeRunDevice device) { 114 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); 115 sp.edit().putInt(PREF_KEY_SCANNED_DEVICE_ID, device.getDeviceId()).apply(); 116 } 117 updateDevicesLocked(Integer deviceId)118 private void updateDevicesLocked(Integer deviceId) { 119 mHdHomeRunDevices.clear(); 120 mHdHomeRunDevices.addAll(HdHomeRunInterface.scanDevices(deviceId)); 121 } 122 } 123