Home | History | Annotate | Download | only in source
      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.source;
     18 
     19 import android.content.Context;
     20 import android.support.annotation.VisibleForTesting;
     21 import com.android.tv.tuner.TunerHal;
     22 import com.android.tv.tuner.data.TunerChannel;
     23 import com.android.tv.tuner.data.nano.Channel;
     24 import com.android.tv.tuner.tvinput.EventDetector;
     25 import java.util.Map;
     26 import java.util.concurrent.ConcurrentHashMap;
     27 
     28 /**
     29  * Manages {@link DataSource} for playback and recording. The class hides handling of {@link
     30  * TunerHal} and {@link TsStreamer} from other classes. One TsDataSourceManager should be created
     31  * for per session.
     32  */
     33 public class TsDataSourceManager {
     34     private static final Object sLock = new Object();
     35     private static final Map<TsDataSource, TsStreamer> sTsStreamers = new ConcurrentHashMap<>();
     36 
     37     private static int sSequenceId;
     38 
     39     private final int mId;
     40     private final boolean mIsRecording;
     41     private final TunerTsStreamerManager mTunerStreamerManager =
     42             TunerTsStreamerManager.getInstance();
     43 
     44     private boolean mKeepTuneStatus;
     45 
     46     /**
     47      * Creates TsDataSourceManager to create and release {@link DataSource} which will be used for
     48      * playing and recording.
     49      *
     50      * @param isRecording {@code true} when for recording, {@code false} otherwise
     51      * @return {@link TsDataSourceManager}
     52      */
     53     public static TsDataSourceManager createSourceManager(boolean isRecording) {
     54         int id;
     55         synchronized (sLock) {
     56             id = ++sSequenceId;
     57         }
     58         return new TsDataSourceManager(id, isRecording);
     59     }
     60 
     61     private TsDataSourceManager(int id, boolean isRecording) {
     62         mId = id;
     63         mIsRecording = isRecording;
     64         mKeepTuneStatus = true;
     65     }
     66 
     67     /**
     68      * Creates or retrieves {@link TsDataSource} for playing or recording
     69      *
     70      * @param context a {@link Context} instance
     71      * @param channel to play or record
     72      * @param eventListener for program information which will be scanned from MPEG2-TS stream
     73      * @return {@link TsDataSource} which will provide the specified channel stream
     74      */
     75     public TsDataSource createDataSource(
     76             Context context, TunerChannel channel, EventDetector.EventListener eventListener) {
     77         if (channel.getType() == Channel.TunerType.TYPE_FILE) {
     78             // MPEG2 TS captured stream file recording is not supported.
     79             if (mIsRecording) {
     80                 return null;
     81             }
     82             FileTsStreamer streamer = new FileTsStreamer(eventListener, context);
     83             if (streamer.startStream(channel)) {
     84                 TsDataSource source = streamer.createDataSource();
     85                 sTsStreamers.put(source, streamer);
     86                 return source;
     87             }
     88             return null;
     89         }
     90         return mTunerStreamerManager.createDataSource(
     91                 context, channel, eventListener, mId, !mIsRecording && mKeepTuneStatus);
     92     }
     93 
     94     /**
     95      * Releases the specified {@link TsDataSource} and underlying {@link TunerHal}.
     96      *
     97      * @param source to release
     98      */
     99     public void releaseDataSource(TsDataSource source) {
    100         if (source instanceof TunerTsStreamer.TunerDataSource) {
    101             mTunerStreamerManager.releaseDataSource(source, mId, !mIsRecording && mKeepTuneStatus);
    102         } else if (source instanceof FileTsStreamer.FileDataSource) {
    103             FileTsStreamer streamer = (FileTsStreamer) sTsStreamers.get(source);
    104             if (streamer != null) {
    105                 sTsStreamers.remove(source);
    106                 streamer.stopStream();
    107             }
    108         }
    109     }
    110 
    111     /** Indicates that the current session has pending tunes. */
    112     public void setHasPendingTune() {
    113         mTunerStreamerManager.setHasPendingTune(mId);
    114     }
    115 
    116     /**
    117      * Indicates whether the underlying {@link TunerHal} should be kept or not when data source is
    118      * being released. TODO: If b/30750953 is fixed, we can remove this function.
    119      *
    120      * @param keepTuneStatus underlying {@link TunerHal} will be reused when data source releasing.
    121      */
    122     public void setKeepTuneStatus(boolean keepTuneStatus) {
    123         mKeepTuneStatus = keepTuneStatus;
    124     }
    125 
    126     /** Add tuner hal into TunerTsStreamerManager for test. */
    127     @VisibleForTesting
    128     public void addTunerHalForTest(TunerHal tunerHal) {
    129         mTunerStreamerManager.addTunerHal(tunerHal, mId);
    130     }
    131 
    132     /** Releases persistent resources. */
    133     public void release() {
    134         mTunerStreamerManager.release(mId);
    135     }
    136 }
    137