1 /*
2  * Copyright (C) 2015 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.dvr;
18 
19 import android.annotation.TargetApi;
20 import android.content.Context;
21 import android.media.tv.TvInputInfo;
22 import android.media.tv.TvInputManager;
23 import android.media.tv.TvRecordingClient;
24 import android.os.Build;
25 import android.os.Handler;
26 import android.support.annotation.Nullable;
27 import android.support.annotation.VisibleForTesting;
28 import android.support.v4.util.ArrayMap;
29 import android.util.Log;
30 
31 import com.android.tv.common.SoftPreconditions;
32 import com.android.tv.common.feature.CommonFeatures;
33 import com.android.tv.data.Channel;
34 
35 /**
36  * Manages Dvr Sessions.
37  * Responsible for:
38  * <ul>
39  *     <li>Manage DvrSession</li>
40  *     <li>Manage capabilities (conflict)</li>
41  * </ul>
42  */
43 @TargetApi(Build.VERSION_CODES.N)
44 public class DvrSessionManager extends TvInputManager.TvInputCallback {
45     //consider moving all of this to TvInputManagerHelper
46     private final static String TAG = "DvrSessionManager";
47     private static final boolean DEBUG = false;
48 
49     private final Context mContext;
50     private final TvInputManager mTvInputManager;
51     private final ArrayMap<String, TvInputInfo> mRecordingTvInputs = new ArrayMap<>();
52 
DvrSessionManager(Context context)53     public DvrSessionManager(Context context) {
54         this(context, (TvInputManager) context.getSystemService(Context.TV_INPUT_SERVICE),
55                 new Handler());
56     }
57 
58     @VisibleForTesting
DvrSessionManager(Context context, TvInputManager tvInputManager, Handler handler)59     DvrSessionManager(Context context, TvInputManager tvInputManager, Handler handler) {
60         SoftPreconditions.checkFeatureEnabled(context, CommonFeatures.DVR, TAG);
61         mTvInputManager = tvInputManager;
62         mContext = context.getApplicationContext();
63         for (TvInputInfo info : tvInputManager.getTvInputList()) {
64             if (DEBUG) {
65                 Log.d(TAG, info + " canRecord=" + info.canRecord() + " tunerCount=" + info
66                         .getTunerCount());
67             }
68             if (info.canRecord()) {
69                 mRecordingTvInputs.put(info.getId(), info);
70             }
71         }
72         tvInputManager.registerCallback(this, handler);
73 
74     }
75 
createTvRecordingClient(String tag, TvRecordingClient.RecordingCallback callback, Handler handler)76     public TvRecordingClient createTvRecordingClient(String tag,
77             TvRecordingClient.RecordingCallback callback, Handler handler) {
78         return new TvRecordingClient(mContext, tag, callback, handler);
79     }
80 
canAcquireDvrSession(String inputId, Channel channel)81     public boolean canAcquireDvrSession(String inputId, Channel channel) {
82         // TODO(DVR): implement checking tuner count etc.
83         TvInputInfo info = mRecordingTvInputs.get(inputId);
84         return info != null;
85     }
86 
releaseTvRecordingClient(TvRecordingClient recordingClient)87     public void releaseTvRecordingClient(TvRecordingClient recordingClient) {
88         recordingClient.release();
89     }
90 
91     @Override
onInputAdded(String inputId)92     public void onInputAdded(String inputId) {
93         super.onInputAdded(inputId);
94         TvInputInfo info = mTvInputManager.getTvInputInfo(inputId);
95         if (DEBUG) {
96             Log.d(TAG, "onInputAdded " + info.toString() + " canRecord=" + info.canRecord()
97                     + " tunerCount=" + info.getTunerCount());
98         }
99         if (info.canRecord()) {
100             mRecordingTvInputs.put(inputId, info);
101         }
102     }
103 
104     @Override
onInputRemoved(String inputId)105     public void onInputRemoved(String inputId) {
106         super.onInputRemoved(inputId);
107         if (DEBUG) Log.d(TAG, "onInputRemoved " + inputId);
108         mRecordingTvInputs.remove(inputId);
109     }
110 
111     @Override
onInputUpdated(String inputId)112     public void onInputUpdated(String inputId) {
113         super.onInputUpdated(inputId);
114         TvInputInfo info = mTvInputManager.getTvInputInfo(inputId);
115         if (DEBUG) {
116             Log.d(TAG, "onInputUpdated " + info.toString() + " canRecord=" + info.canRecord()
117                     + " tunerCount=" + info.getTunerCount());
118         }
119         if (info.canRecord()) {
120             mRecordingTvInputs.put(inputId, info);
121         } else {
122             mRecordingTvInputs.remove(inputId);
123         }
124     }
125 
126     @Nullable
getTvInputInfo(String inputId)127     public TvInputInfo getTvInputInfo(String inputId) {
128         return mRecordingTvInputs.get(inputId);
129     }
130 }
131