Home | History | Annotate | Download | only in input
      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.input;
     18 
     19 import android.net.Uri;
     20 import android.support.annotation.Nullable;
     21 import android.util.Log;
     22 import java.util.ArrayList;
     23 import java.util.Iterator;
     24 import java.util.List;
     25 
     26 /** A class to manage fake tuners for the tune and the recording. */
     27 public class TunerHelper {
     28     private static final String TAG = "TunerHelper";
     29     private static final boolean DEBUG = false;
     30 
     31     private final List<Tuner> mTuners = new ArrayList<>();
     32     private final int mTunerCount;
     33 
     34     public TunerHelper(int tunerCount) {
     35         mTunerCount = tunerCount;
     36     }
     37 
     38     /** Checks whether there are available tuners for the recording. */
     39     public boolean tunerAvailableForRecording() {
     40         if (mTuners.size() < mTunerCount) {
     41             return true;
     42         }
     43         for (Tuner tuner : mTuners) {
     44             if (!tuner.recording) {
     45                 return true;
     46             }
     47         }
     48         return false;
     49     }
     50 
     51     /**
     52      * Checks whether there is available tuner. If there's available tuner, it is assigned to the
     53      * channel.
     54      */
     55     public boolean tune(@Nullable Uri channelUri, boolean forRecording) {
     56         if (channelUri == null) {
     57             return false;
     58         }
     59         for (Tuner tuner : mTuners) {
     60             // Find available tuner which is used only for the recording.
     61             if (tuner.channelUri.equals(channelUri)) {
     62                 if (!forRecording && !tuner.tuning) {
     63                     tuner.tuning = true;
     64                     return true;
     65                 } else if (forRecording && !tuner.recording) {
     66                     tuner.recording = true;
     67                     return true;
     68                 }
     69             }
     70         }
     71         if (mTuners.size() < mTunerCount) {
     72             // Assign new tuner.
     73             mTuners.add(new Tuner(channelUri, forRecording));
     74             return true;
     75         }
     76         Log.i(TAG, "No available tuners. tuner count: " + mTunerCount);
     77         return false;
     78     }
     79 
     80     /** Releases the tuner which was being used for the tune. */
     81     public void stopTune(@Nullable Uri channelUri) {
     82         if (channelUri == null) {
     83             return;
     84         }
     85         Tuner candidate = null;
     86         Iterator<Tuner> iterator = mTuners.iterator();
     87         while (iterator.hasNext()) {
     88             Tuner tuner = iterator.next();
     89             if (tuner.channelUri.equals(channelUri) && tuner.tuning) {
     90                 if (tuner.recording) {
     91                     // A tuner which is used both for the tune and recording is the candidate.
     92                     candidate = tuner;
     93                 } else {
     94                     // Remove the tuner which is used only for the tune.
     95                     if (DEBUG) Log.d(TAG, "Removed tuner for tune");
     96                     iterator.remove();
     97                     return;
     98                 }
     99             }
    100         }
    101         if (candidate != null) {
    102             candidate.tuning = false;
    103         }
    104     }
    105 
    106     /** Releases the tuner which was being used for the recording. */
    107     public void stopRecording(@Nullable Uri channelUri) {
    108         if (channelUri == null) {
    109             return;
    110         }
    111         Tuner candidate = null;
    112         Iterator<Tuner> iterator = mTuners.iterator();
    113         while (iterator.hasNext()) {
    114             Tuner tuner = iterator.next();
    115             if (tuner.channelUri.equals(channelUri)) {
    116                 if (tuner.recording) {
    117                     if (tuner.tuning) {
    118                         // A tuner which is used both for the tune and recording is the candidate.
    119                         candidate = tuner;
    120                     } else {
    121                         // Remove the tuner which is used only for the recording.
    122                         iterator.remove();
    123                         return;
    124                     }
    125                 } else {
    126                     Log.w(TAG, "Tuner found for " + channelUri + ", but not used for recording");
    127                 }
    128             }
    129         }
    130         if (candidate != null) {
    131             candidate.recording = false;
    132         }
    133     }
    134 
    135     private static class Tuner {
    136         public final Uri channelUri;
    137         public boolean tuning;
    138         public boolean recording;
    139 
    140         public Tuner(Uri channelUri, boolean forRecording) {
    141             this.channelUri = channelUri;
    142             this.tuning = !forRecording;
    143             this.recording = forRecording;
    144         }
    145     }
    146 }
    147