aboutsummaryrefslogtreecommitdiff
path: root/tests/common/src/com/android/tv/input/TunerHelper.java
blob: 126d5027ca2bcc3b6acd1d0a8a69b2b28d4c8b34 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.tv.input;

import android.net.Uri;
import android.support.annotation.Nullable;
import android.util.Log;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * A class to manage fake tuners for the tune and the recording.
 */
public class TunerHelper {
    private static final String TAG = "TunerHelper";
    private static final boolean DEBUG = false;

    private final List<Tuner> mTuners = new ArrayList<>();
    private final int mTunerCount;

    public TunerHelper(int tunerCount) {
        mTunerCount = tunerCount;
    }

    /**
     * Checks whether there are available tuners for the recording.
     */
    public boolean tunerAvailableForRecording() {
        if (mTuners.size() < mTunerCount) {
            return true;
        }
        for (Tuner tuner : mTuners) {
            if (!tuner.recording) {
                return true;
            }
        }
        return false;
    }

    /**
     * Checks whether there is available tuner.
     * If there's available tuner, it is assigned to the channel.
     */
    public boolean tune(@Nullable Uri channelUri, boolean forRecording) {
        if (channelUri == null) {
            return false;
        }
        for (Tuner tuner : mTuners) {
            // Find available tuner which is used only for the recording.
            if (tuner.channelUri.equals(channelUri)) {
                if (!forRecording && !tuner.tuning) {
                    tuner.tuning = true;
                    return true;
                } else if (forRecording && !tuner.recording) {
                    tuner.recording = true;
                    return true;
                }
            }
        }
        if (mTuners.size() < mTunerCount) {
            // Assign new tuner.
            mTuners.add(new Tuner(channelUri, forRecording));
            return true;
        }
        Log.i(TAG, "No available tuners. tuner count: " + mTunerCount);
        return false;
    }

    /**
     * Releases the tuner which was being used for the tune.
     */
    public void stopTune(@Nullable Uri channelUri) {
        if (channelUri == null) {
            return;
        }
        Tuner candidate = null;
        Iterator<Tuner> iterator = mTuners.iterator();
        while (iterator.hasNext()) {
            Tuner tuner = iterator.next();
            if (tuner.channelUri.equals(channelUri) && tuner.tuning) {
                if (tuner.recording) {
                    // A tuner which is used both for the tune and recording is the candidate.
                    candidate = tuner;
                } else {
                    // Remove the tuner which is used only for the tune.
                    if (DEBUG) Log.d(TAG, "Removed tuner for tune");
                    iterator.remove();
                    return;
                }
            }
        }
        if (candidate != null) {
            candidate.tuning = false;
        }
    }

    /**
     * Releases the tuner which was being used for the recording.
     */
    public void stopRecording(@Nullable Uri channelUri) {
        if (channelUri == null) {
            return;
        }
        Tuner candidate = null;
        Iterator<Tuner> iterator = mTuners.iterator();
        while (iterator.hasNext()) {
            Tuner tuner = iterator.next();
            if (tuner.channelUri.equals(channelUri)) {
                if (tuner.recording) {
                    if (tuner.tuning) {
                        // A tuner which is used both for the tune and recording is the candidate.
                        candidate = tuner;
                    } else {
                        // Remove the tuner which is used only for the recording.
                        iterator.remove();
                        return;
                    }
                } else {
                    Log.w(TAG, "Tuner found for " + channelUri + ", but not used for recording");
                }
            }
        }
        if (candidate != null) {
            candidate.recording = false;
        }
    }

    private static class Tuner {
        public final Uri channelUri;
        public boolean tuning;
        public boolean recording;

        public Tuner (Uri channelUri, boolean forRecording) {
            this.channelUri = channelUri;
            this.tuning = !forRecording;
            this.recording = forRecording;
        }
    }
}