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
17package com.android.tv.dvr;
18
19import android.annotation.TargetApi;
20import android.content.Context;
21import android.media.tv.TvInputInfo;
22import android.media.tv.TvInputManager;
23import android.media.tv.TvRecordingClient;
24import android.os.Build;
25import android.os.Handler;
26import android.support.annotation.Nullable;
27import android.support.annotation.VisibleForTesting;
28import android.support.v4.util.ArrayMap;
29import android.util.Log;
30
31import com.android.tv.common.SoftPreconditions;
32import com.android.tv.common.feature.CommonFeatures;
33import 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)
44public 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
53    public DvrSessionManager(Context context) {
54        this(context, (TvInputManager) context.getSystemService(Context.TV_INPUT_SERVICE),
55                new Handler());
56    }
57
58    @VisibleForTesting
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
76    public TvRecordingClient createTvRecordingClient(String tag,
77            TvRecordingClient.RecordingCallback callback, Handler handler) {
78        return new TvRecordingClient(mContext, tag, callback, handler);
79    }
80
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
87    public void releaseTvRecordingClient(TvRecordingClient recordingClient) {
88        recordingClient.release();
89    }
90
91    @Override
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
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
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
127    public TvInputInfo getTvInputInfo(String inputId) {
128        return mRecordingTvInputs.get(inputId);
129    }
130}
131