1 /*
2  * Copyright 2020 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 package com.android.server.tv.tunerresourcemanager;
17 
18 import static com.google.common.truth.Truth.assertThat;
19 
20 import static org.mockito.Mockito.spy;
21 import static org.mockito.Mockito.when;
22 
23 import android.content.Context;
24 import android.content.ContextWrapper;
25 import android.media.tv.ITvInputManager;
26 import android.media.tv.TvInputManager;
27 import android.media.tv.TvInputService;
28 import android.media.tv.tuner.filter.Filter;
29 import android.media.tv.tuner.frontend.FrontendSettings;
30 import android.media.tv.tunerresourcemanager.CasSessionRequest;
31 import android.media.tv.tunerresourcemanager.IResourcesReclaimListener;
32 import android.media.tv.tunerresourcemanager.ResourceClientProfile;
33 import android.media.tv.tunerresourcemanager.TunerCiCamRequest;
34 import android.media.tv.tunerresourcemanager.TunerDemuxInfo;
35 import android.media.tv.tunerresourcemanager.TunerDemuxRequest;
36 import android.media.tv.tunerresourcemanager.TunerDescramblerRequest;
37 import android.media.tv.tunerresourcemanager.TunerFrontendInfo;
38 import android.media.tv.tunerresourcemanager.TunerFrontendRequest;
39 import android.media.tv.tunerresourcemanager.TunerLnbRequest;
40 import android.media.tv.tunerresourcemanager.TunerResourceManager;
41 import android.platform.test.annotations.Presubmit;
42 
43 import androidx.test.InstrumentationRegistry;
44 import androidx.test.filters.SmallTest;
45 
46 import com.google.common.truth.Correspondence;
47 
48 import org.junit.Before;
49 import org.junit.Test;
50 import org.junit.runner.RunWith;
51 import org.junit.runners.JUnit4;
52 import org.mockito.Mock;
53 import org.mockito.MockitoAnnotations;
54 
55 import java.util.Arrays;
56 import java.util.HashSet;
57 import java.util.Map;
58 
59 /**
60  * Tests for {@link TunerResourceManagerService} class.
61  */
62 @SmallTest
63 @Presubmit
64 @RunWith(JUnit4.class)
65 public class TunerResourceManagerServiceTest {
66     private static final String TAG = "TunerResourceManagerServiceTest";
67     private Context mContextSpy;
68     @Mock private ITvInputManager mITvInputManagerMock;
69     private TunerResourceManagerService mTunerResourceManagerService;
70     private boolean mIsForeground;
71 
72     private static final class TestResourcesReclaimListener extends IResourcesReclaimListener.Stub {
73         boolean mReclaimed;
74 
75         @Override
onReclaimResources()76         public void onReclaimResources() {
77             mReclaimed = true;
78         }
79 
isReclaimed()80         public boolean isReclaimed() {
81             return mReclaimed;
82         }
83     }
84 
85     // A correspondence to compare a FrontendResource and a TunerFrontendInfo.
86     private static final Correspondence<FrontendResource, TunerFrontendInfo> FR_TFI_COMPARE =
87             Correspondence.from((FrontendResource actual, TunerFrontendInfo expected) -> {
88                 if (actual == null || expected == null) {
89                     return (actual == null) && (expected == null);
90                 }
91 
92                 return actual.getHandle() == expected.handle
93                         && actual.getType() == expected.type
94                         && actual.getExclusiveGroupId() == expected.exclusiveGroupId;
95             },  "is correctly configured from ");
96 
97     @Before
setUp()98     public void setUp() throws Exception {
99         MockitoAnnotations.initMocks(this);
100         TvInputManager tvInputManager = new TvInputManager(mITvInputManagerMock, 0);
101         mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
102         when(mContextSpy.getSystemService(Context.TV_INPUT_SERVICE)).thenReturn(tvInputManager);
103         mTunerResourceManagerService = new TunerResourceManagerService(mContextSpy) {
104             @Override
105             protected boolean checkIsForeground(int pid) {
106                 return mIsForeground;
107             }
108         };
109         mTunerResourceManagerService.onStart(true /*isForTesting*/);
110     }
111 
112     @Test
setFrontendListTest_addFrontendResources_noExclusiveGroupId()113     public void setFrontendListTest_addFrontendResources_noExclusiveGroupId() {
114         // Init frontend resources.
115         TunerFrontendInfo[] infos = new TunerFrontendInfo[2];
116         infos[0] =
117                 tunerFrontendInfo(0 /*handle*/, FrontendSettings.TYPE_DVBT, 0 /*exclusiveGroupId*/);
118         infos[1] =
119                 tunerFrontendInfo(1 /*handle*/, FrontendSettings.TYPE_DVBT, 1 /*exclusiveGroupId*/);
120         mTunerResourceManagerService.setFrontendInfoListInternal(infos);
121 
122         Map<Integer, FrontendResource> resources =
123                 mTunerResourceManagerService.getFrontendResources();
124         for (int id = 0; id < infos.length; id++) {
125             assertThat(resources.get(infos[id].handle)
126                     .getExclusiveGroupMemberFeHandles().size()).isEqualTo(0);
127         }
128         for (int id = 0; id < infos.length; id++) {
129             assertThat(resources.get(infos[id].handle)
130                     .getExclusiveGroupMemberFeHandles().size()).isEqualTo(0);
131         }
132         assertThat(resources.values()).comparingElementsUsing(FR_TFI_COMPARE)
133                 .containsExactlyElementsIn(Arrays.asList(infos));
134     }
135 
136     @Test
setFrontendListTest_addFrontendResources_underTheSameExclusiveGroupId()137     public void setFrontendListTest_addFrontendResources_underTheSameExclusiveGroupId() {
138         // Init frontend resources.
139         TunerFrontendInfo[] infos = new TunerFrontendInfo[4];
140         infos[0] =
141                 tunerFrontendInfo(0 /*handle*/, FrontendSettings.TYPE_DVBT, 0 /*exclusiveGroupId*/);
142         infos[1] =
143                 tunerFrontendInfo(1 /*handle*/, FrontendSettings.TYPE_DVBT, 1 /*exclusiveGroupId*/);
144         infos[2] =
145                 tunerFrontendInfo(2 /*handle*/, FrontendSettings.TYPE_DVBS, 1 /*exclusiveGroupId*/);
146         infos[3] =
147                 tunerFrontendInfo(3 /*handle*/, FrontendSettings.TYPE_ATSC, 1 /*exclusiveGroupId*/);
148         mTunerResourceManagerService.setFrontendInfoListInternal(infos);
149 
150         Map<Integer, FrontendResource> resources =
151                 mTunerResourceManagerService.getFrontendResources();
152         assertThat(resources.values()).comparingElementsUsing(FR_TFI_COMPARE)
153                 .containsExactlyElementsIn(Arrays.asList(infos));
154 
155         assertThat(resources.get(0).getExclusiveGroupMemberFeHandles()).isEmpty();
156         assertThat(resources.get(1).getExclusiveGroupMemberFeHandles()).containsExactly(2, 3);
157         assertThat(resources.get(2).getExclusiveGroupMemberFeHandles()).containsExactly(1, 3);
158         assertThat(resources.get(3).getExclusiveGroupMemberFeHandles()).containsExactly(1, 2);
159     }
160 
161     @Test
setFrontendListTest_updateExistingFrontendResources()162     public void setFrontendListTest_updateExistingFrontendResources() {
163         // Init frontend resources.
164         TunerFrontendInfo[] infos = new TunerFrontendInfo[2];
165         infos[0] =
166                 tunerFrontendInfo(0 /*handle*/, FrontendSettings.TYPE_DVBT, 1 /*exclusiveGroupId*/);
167         infos[1] =
168                 tunerFrontendInfo(1 /*handle*/, FrontendSettings.TYPE_DVBS, 1 /*exclusiveGroupId*/);
169 
170         mTunerResourceManagerService.setFrontendInfoListInternal(infos);
171         Map<Integer, FrontendResource> resources0 =
172                 mTunerResourceManagerService.getFrontendResources();
173 
174         mTunerResourceManagerService.setFrontendInfoListInternal(infos);
175         Map<Integer, FrontendResource> resources1 =
176                 mTunerResourceManagerService.getFrontendResources();
177 
178         assertThat(resources0).isEqualTo(resources1);
179     }
180 
181     @Test
setFrontendListTest_removeFrontendResources_noExclusiveGroupId()182     public void setFrontendListTest_removeFrontendResources_noExclusiveGroupId() {
183         // Init frontend resources.
184         TunerFrontendInfo[] infos0 = new TunerFrontendInfo[3];
185         infos0[0] =
186                 tunerFrontendInfo(0 /*handle*/, FrontendSettings.TYPE_DVBT, 0 /*exclusiveGroupId*/);
187         infos0[1] =
188                 tunerFrontendInfo(1 /*handle*/, FrontendSettings.TYPE_DVBT, 1 /*exclusiveGroupId*/);
189         infos0[2] =
190                 tunerFrontendInfo(2 /*handle*/, FrontendSettings.TYPE_DVBS, 2 /*exclusiveGroupId*/);
191         mTunerResourceManagerService.setFrontendInfoListInternal(infos0);
192 
193         TunerFrontendInfo[] infos1 = new TunerFrontendInfo[1];
194         infos1[0] =
195                 tunerFrontendInfo(1 /*handle*/, FrontendSettings.TYPE_DVBT, 1 /*exclusiveGroupId*/);
196         mTunerResourceManagerService.setFrontendInfoListInternal(infos1);
197 
198         Map<Integer, FrontendResource> resources =
199                 mTunerResourceManagerService.getFrontendResources();
200         for (int id = 0; id < infos1.length; id++) {
201             assertThat(resources.get(infos1[id].handle)
202                     .getExclusiveGroupMemberFeHandles().size()).isEqualTo(0);
203         }
204         assertThat(resources.values()).comparingElementsUsing(FR_TFI_COMPARE)
205                 .containsExactlyElementsIn(Arrays.asList(infos1));
206     }
207 
208     @Test
setFrontendListTest_removeFrontendResources_underTheSameExclusiveGroupId()209     public void setFrontendListTest_removeFrontendResources_underTheSameExclusiveGroupId() {
210         // Init frontend resources.
211         TunerFrontendInfo[] infos0 = new TunerFrontendInfo[3];
212         infos0[0] =
213                 tunerFrontendInfo(0 /*handle*/, FrontendSettings.TYPE_DVBT, 0 /*exclusiveGroupId*/);
214         infos0[1] =
215                 tunerFrontendInfo(1 /*handle*/, FrontendSettings.TYPE_DVBT, 1 /*exclusiveGroupId*/);
216         infos0[2] =
217                 tunerFrontendInfo(2 /*handle*/, FrontendSettings.TYPE_DVBS, 1 /*exclusiveGroupId*/);
218         mTunerResourceManagerService.setFrontendInfoListInternal(infos0);
219 
220         TunerFrontendInfo[] infos1 = new TunerFrontendInfo[1];
221         infos1[0] =
222                 tunerFrontendInfo(1 /*handle*/, FrontendSettings.TYPE_DVBT, 1 /*exclusiveGroupId*/);
223         mTunerResourceManagerService.setFrontendInfoListInternal(infos1);
224 
225         Map<Integer, FrontendResource> resources =
226                 mTunerResourceManagerService.getFrontendResources();
227         for (int id = 0; id < infos1.length; id++) {
228             assertThat(resources.get(infos1[id].handle)
229                     .getExclusiveGroupMemberFeHandles().size()).isEqualTo(0);
230         }
231         assertThat(resources.values()).comparingElementsUsing(FR_TFI_COMPARE)
232                 .containsExactlyElementsIn(Arrays.asList(infos1));
233     }
234 
235     @Test
requestFrontendTest_ClientNotRegistered()236     public void requestFrontendTest_ClientNotRegistered() {
237         TunerFrontendInfo[] infos0 = new TunerFrontendInfo[1];
238         infos0[0] =
239                 tunerFrontendInfo(0 /*id*/, FrontendSettings.TYPE_DVBT, 0 /*exclusiveGroupId*/);
240         mTunerResourceManagerService.setFrontendInfoListInternal(infos0);
241         TunerFrontendRequest request =
242                 tunerFrontendRequest(0 /*clientId*/, FrontendSettings.TYPE_DVBT);
243         int[] frontendHandle = new int[1];
244         assertThat(mTunerResourceManagerService
245                 .requestFrontendInternal(request, frontendHandle)).isFalse();
246         assertThat(frontendHandle[0]).isEqualTo(TunerResourceManager.INVALID_RESOURCE_HANDLE);
247     }
248 
249     @Test
requestFrontendTest_NoFrontendWithGiveTypeAvailable()250     public void requestFrontendTest_NoFrontendWithGiveTypeAvailable() {
251         ResourceClientProfile profile = resourceClientProfile("0" /*sessionId*/,
252                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
253         int[] clientId = new int[1];
254         mTunerResourceManagerService.registerClientProfileInternal(
255                 profile, null /*listener*/, clientId);
256         assertThat(clientId[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
257 
258         // Init frontend resources.
259         TunerFrontendInfo[] infos = new TunerFrontendInfo[1];
260         infos[0] =
261                 tunerFrontendInfo(0 /*handle*/, FrontendSettings.TYPE_DVBS, 0 /*exclusiveGroupId*/);
262         mTunerResourceManagerService.setFrontendInfoListInternal(infos);
263 
264         TunerFrontendRequest request =
265                 tunerFrontendRequest(clientId[0] /*clientId*/, FrontendSettings.TYPE_DVBT);
266         int[] frontendHandle = new int[1];
267         assertThat(mTunerResourceManagerService
268                 .requestFrontendInternal(request, frontendHandle)).isFalse();
269         assertThat(frontendHandle[0]).isEqualTo(TunerResourceManager.INVALID_RESOURCE_HANDLE);
270     }
271 
272     @Test
requestFrontendTest_FrontendWithNoExclusiveGroupAvailable()273     public void requestFrontendTest_FrontendWithNoExclusiveGroupAvailable() {
274         ResourceClientProfile profile = resourceClientProfile("0" /*sessionId*/,
275                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
276         int[] clientId = new int[1];
277         mTunerResourceManagerService.registerClientProfileInternal(
278                 profile, null /*listener*/, clientId);
279         assertThat(clientId[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
280 
281         // Init frontend resources.
282         TunerFrontendInfo[] infos = new TunerFrontendInfo[3];
283         infos[0] = tunerFrontendInfo(
284                 0 /*handle*/,
285                 FrontendSettings.TYPE_DVBT,
286                 0 /*exclusiveGroupId*/);
287         infos[1] = tunerFrontendInfo(
288                 1 /*handle*/,
289                 FrontendSettings.TYPE_DVBT,
290                 1 /*exclusiveGroupId*/);
291         infos[2] = tunerFrontendInfo(
292                 2 /*handle*/,
293                 FrontendSettings.TYPE_DVBS,
294                 1 /*exclusiveGroupId*/);
295         mTunerResourceManagerService.setFrontendInfoListInternal(infos);
296 
297         TunerFrontendRequest request =
298                 tunerFrontendRequest(clientId[0] /*clientId*/, FrontendSettings.TYPE_DVBT);
299         int[] frontendHandle = new int[1];
300         assertThat(mTunerResourceManagerService
301                 .requestFrontendInternal(request, frontendHandle)).isTrue();
302         assertThat(frontendHandle[0]).isEqualTo(0);
303     }
304 
305     @Test
requestFrontendTest_FrontendWithExclusiveGroupAvailable()306     public void requestFrontendTest_FrontendWithExclusiveGroupAvailable() {
307         ResourceClientProfile profile0 = resourceClientProfile("0" /*sessionId*/,
308                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
309         ResourceClientProfile profile1 = resourceClientProfile("1" /*sessionId*/,
310                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
311         int[] clientId0 = new int[1];
312         int[] clientId1 = new int[1];
313         mTunerResourceManagerService.registerClientProfileInternal(
314                 profile0, null /*listener*/, clientId0);
315         mTunerResourceManagerService.registerClientProfileInternal(
316                 profile1, null /*listener*/, clientId1);
317         assertThat(clientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
318         assertThat(clientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
319 
320         // Init frontend resources.
321         TunerFrontendInfo[] infos = new TunerFrontendInfo[3];
322         infos[0] = tunerFrontendInfo(
323                 0 /*handle*/,
324                 FrontendSettings.TYPE_DVBT,
325                 0 /*exclusiveGroupId*/);
326         infos[1] = tunerFrontendInfo(
327                 1 /*handle*/,
328                 FrontendSettings.TYPE_DVBT,
329                 1 /*exclusiveGroupId*/);
330         infos[2] = tunerFrontendInfo(
331                 2 /*handle*/,
332                 FrontendSettings.TYPE_DVBS,
333                 1 /*exclusiveGroupId*/);
334         mTunerResourceManagerService.setFrontendInfoListInternal(infos);
335 
336         int[] frontendHandle = new int[1];
337         TunerFrontendRequest request =
338                 tunerFrontendRequest(clientId1[0] /*clientId*/, FrontendSettings.TYPE_DVBT);
339         assertThat(mTunerResourceManagerService
340                 .requestFrontendInternal(request, frontendHandle)).isTrue();
341         assertThat(frontendHandle[0]).isEqualTo(infos[0].handle);
342 
343         request =
344                 tunerFrontendRequest(clientId0[0] /*clientId*/, FrontendSettings.TYPE_DVBT);
345         assertThat(mTunerResourceManagerService
346                 .requestFrontendInternal(request, frontendHandle)).isTrue();
347         assertThat(frontendHandle[0]).isEqualTo(infos[1].handle);
348         assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].handle).isInUse())
349                 .isTrue();
350         assertThat(mTunerResourceManagerService.getFrontendResource(infos[2].handle).isInUse())
351                 .isTrue();
352     }
353 
354     @Test
requestFrontendTest_NoFrontendAvailable_RequestWithLowerPriority()355     public void requestFrontendTest_NoFrontendAvailable_RequestWithLowerPriority() {
356         // Register clients
357         ResourceClientProfile[] profiles = new ResourceClientProfile[2];
358         profiles[0] = resourceClientProfile("0" /*sessionId*/,
359                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
360         profiles[1] = resourceClientProfile("1" /*sessionId*/,
361                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
362         int[] clientPriorities = {100, 50};
363         int[] clientId0 = new int[1];
364         int[] clientId1 = new int[1];
365         TestResourcesReclaimListener listener = new TestResourcesReclaimListener();
366 
367         mTunerResourceManagerService.registerClientProfileInternal(
368                 profiles[0], listener, clientId0);
369         assertThat(clientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
370         mTunerResourceManagerService.updateClientPriorityInternal(
371                 clientId0[0], clientPriorities[0], 0/*niceValue*/);
372         mTunerResourceManagerService.registerClientProfileInternal(
373                 profiles[1], new TestResourcesReclaimListener(), clientId1);
374         assertThat(clientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
375         mTunerResourceManagerService.updateClientPriorityInternal(
376                 clientId1[0], clientPriorities[1], 0/*niceValue*/);
377 
378         // Init frontend resources.
379         TunerFrontendInfo[] infos = new TunerFrontendInfo[2];
380         infos[0] =
381                 tunerFrontendInfo(0 /*handle*/, FrontendSettings.TYPE_DVBT, 1 /*exclusiveGroupId*/);
382         infos[1] =
383                 tunerFrontendInfo(1 /*handle*/, FrontendSettings.TYPE_DVBS, 1 /*exclusiveGroupId*/);
384         mTunerResourceManagerService.setFrontendInfoListInternal(infos);
385 
386         TunerFrontendRequest request =
387                 tunerFrontendRequest(clientId0[0] /*clientId*/, FrontendSettings.TYPE_DVBT);
388         int[] frontendHandle = new int[1];
389         assertThat(mTunerResourceManagerService
390                 .requestFrontendInternal(request, frontendHandle)).isTrue();
391 
392         request =
393                 tunerFrontendRequest(clientId1[0] /*clientId*/, FrontendSettings.TYPE_DVBT);
394         assertThat(mTunerResourceManagerService
395                 .requestFrontendInternal(request, frontendHandle)).isFalse();
396         assertThat(listener.isReclaimed()).isFalse();
397 
398         request =
399                 tunerFrontendRequest(clientId1[0] /*clientId*/, FrontendSettings.TYPE_DVBS);
400         assertThat(mTunerResourceManagerService
401                 .requestFrontendInternal(request, frontendHandle)).isFalse();
402         assertThat(listener.isReclaimed()).isFalse();
403     }
404 
405     @Test
requestFrontendTest_NoFrontendAvailable_RequestWithHigherPriority()406     public void requestFrontendTest_NoFrontendAvailable_RequestWithHigherPriority() {
407         // Register clients
408         ResourceClientProfile[] profiles = new ResourceClientProfile[2];
409         profiles[0] = resourceClientProfile("0" /*sessionId*/,
410                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
411         profiles[1] = resourceClientProfile("1" /*sessionId*/,
412                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
413         int[] clientPriorities = {100, 500};
414         int[] clientId0 = new int[1];
415         int[] clientId1 = new int[1];
416         TestResourcesReclaimListener listener = new TestResourcesReclaimListener();
417         mTunerResourceManagerService.registerClientProfileInternal(
418                 profiles[0], listener, clientId0);
419         assertThat(clientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
420         mTunerResourceManagerService.updateClientPriorityInternal(
421                 clientId0[0], clientPriorities[0], 0/*niceValue*/);
422         mTunerResourceManagerService.registerClientProfileInternal(
423                 profiles[1], new TestResourcesReclaimListener(), clientId1);
424         assertThat(clientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
425         mTunerResourceManagerService.updateClientPriorityInternal(
426                 clientId1[0], clientPriorities[1], 0/*niceValue*/);
427 
428         // Init frontend resources.
429         TunerFrontendInfo[] infos = new TunerFrontendInfo[2];
430         infos[0] =
431                 tunerFrontendInfo(0 /*handle*/, FrontendSettings.TYPE_DVBT, 1 /*exclusiveGroupId*/);
432         infos[1] =
433                 tunerFrontendInfo(1 /*handle*/, FrontendSettings.TYPE_DVBS, 1 /*exclusiveGroupId*/);
434         mTunerResourceManagerService.setFrontendInfoListInternal(infos);
435 
436         TunerFrontendRequest request =
437                 tunerFrontendRequest(clientId0[0] /*clientId*/, FrontendSettings.TYPE_DVBT);
438         int[] frontendHandle = new int[1];
439         assertThat(mTunerResourceManagerService
440                 .requestFrontendInternal(request, frontendHandle)).isTrue();
441         assertThat(frontendHandle[0]).isEqualTo(infos[0].handle);
442         assertThat(mTunerResourceManagerService.getClientProfile(clientId0[0])
443                 .getInUseFrontendHandles()).isEqualTo(new HashSet<Integer>(Arrays.asList(
444                         infos[0].handle, infos[1].handle)));
445 
446         request =
447                 tunerFrontendRequest(clientId1[0] /*clientId*/, FrontendSettings.TYPE_DVBS);
448         assertThat(mTunerResourceManagerService
449                 .requestFrontendInternal(request, frontendHandle)).isTrue();
450         assertThat(frontendHandle[0]).isEqualTo(infos[1].handle);
451         assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].handle)
452                 .isInUse()).isTrue();
453         assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].handle)
454                 .isInUse()).isTrue();
455         assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].handle)
456                 .getOwnerClientId()).isEqualTo(clientId1[0]);
457         assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].handle)
458                 .getOwnerClientId()).isEqualTo(clientId1[0]);
459         assertThat(listener.isReclaimed()).isTrue();
460     }
461 
462     @Test
releaseFrontendTest_UnderTheSameExclusiveGroup()463     public void releaseFrontendTest_UnderTheSameExclusiveGroup() {
464         // Register clients
465         ResourceClientProfile[] profiles = new ResourceClientProfile[1];
466         profiles[0] = resourceClientProfile("0" /*sessionId*/,
467                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
468         int[] clientId = new int[1];
469         TestResourcesReclaimListener listener = new TestResourcesReclaimListener();
470         mTunerResourceManagerService.registerClientProfileInternal(profiles[0], listener, clientId);
471         assertThat(clientId[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
472 
473         // Init frontend resources.
474         TunerFrontendInfo[] infos = new TunerFrontendInfo[2];
475         infos[0] =
476                 tunerFrontendInfo(0 /*handle*/, FrontendSettings.TYPE_DVBT, 1 /*exclusiveGroupId*/);
477         infos[1] =
478                 tunerFrontendInfo(1 /*handle*/, FrontendSettings.TYPE_DVBS, 1 /*exclusiveGroupId*/);
479         mTunerResourceManagerService.setFrontendInfoListInternal(infos);
480 
481         TunerFrontendRequest request =
482                 tunerFrontendRequest(clientId[0] /*clientId*/, FrontendSettings.TYPE_DVBT);
483         int[] frontendHandle = new int[1];
484         assertThat(mTunerResourceManagerService
485                 .requestFrontendInternal(request, frontendHandle)).isTrue();
486         assertThat(frontendHandle[0]).isEqualTo(infos[0].handle);
487         assertThat(mTunerResourceManagerService
488                 .getFrontendResource(infos[1].handle).isInUse()).isTrue();
489 
490         // Release frontend
491         mTunerResourceManagerService.releaseFrontendInternal(mTunerResourceManagerService
492                 .getFrontendResource(frontendHandle[0]), clientId[0]);
493         assertThat(mTunerResourceManagerService
494                 .getFrontendResource(frontendHandle[0]).isInUse()).isFalse();
495         assertThat(mTunerResourceManagerService
496                 .getFrontendResource(infos[1].handle).isInUse()).isFalse();
497         assertThat(mTunerResourceManagerService
498                 .getClientProfile(clientId[0]).getInUseFrontendHandles().size()).isEqualTo(0);
499     }
500 
501     @Test
requestCasTest_NoCasAvailable_RequestWithHigherPriority()502     public void requestCasTest_NoCasAvailable_RequestWithHigherPriority() {
503         // Register clients
504         ResourceClientProfile[] profiles = new ResourceClientProfile[2];
505         profiles[0] = resourceClientProfile("0" /*sessionId*/,
506                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
507         profiles[1] = resourceClientProfile("1" /*sessionId*/,
508                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
509         int[] clientPriorities = {100, 500};
510         int[] clientId0 = new int[1];
511         int[] clientId1 = new int[1];
512         TestResourcesReclaimListener listener = new TestResourcesReclaimListener();
513         mTunerResourceManagerService.registerClientProfileInternal(
514                 profiles[0], listener, clientId0);
515         assertThat(clientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
516         mTunerResourceManagerService.updateClientPriorityInternal(
517                 clientId0[0], clientPriorities[0], 0/*niceValue*/);
518         mTunerResourceManagerService.registerClientProfileInternal(
519                 profiles[1], new TestResourcesReclaimListener(), clientId1);
520         assertThat(clientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
521         mTunerResourceManagerService.updateClientPriorityInternal(
522                 clientId1[0], clientPriorities[1], 0/*niceValue*/);
523 
524         // Init cas resources.
525         mTunerResourceManagerService.updateCasInfoInternal(1 /*casSystemId*/, 2 /*maxSessionNum*/);
526 
527         CasSessionRequest request = casSessionRequest(clientId0[0], 1 /*casSystemId*/);
528         int[] casSessionHandle = new int[1];
529         // Request for 2 cas sessions.
530         assertThat(mTunerResourceManagerService
531                 .requestCasSessionInternal(request, casSessionHandle)).isTrue();
532         assertThat(mTunerResourceManagerService
533                 .requestCasSessionInternal(request, casSessionHandle)).isTrue();
534         assertThat(mTunerResourceManagerService.getResourceIdFromHandle(casSessionHandle[0]))
535                 .isEqualTo(1);
536         assertThat(mTunerResourceManagerService.getClientProfile(clientId0[0])
537                 .getInUseCasSystemId()).isEqualTo(1);
538         assertThat(mTunerResourceManagerService.getCasResource(1)
539                 .getOwnerClientIds()).isEqualTo(new HashSet<Integer>(Arrays.asList(clientId0[0])));
540         assertThat(mTunerResourceManagerService.getCasResource(1).isFullyUsed()).isTrue();
541 
542         request = casSessionRequest(clientId1[0], 1);
543         assertThat(mTunerResourceManagerService
544                 .requestCasSessionInternal(request, casSessionHandle)).isTrue();
545         assertThat(mTunerResourceManagerService.getResourceIdFromHandle(casSessionHandle[0]))
546                 .isEqualTo(1);
547         assertThat(mTunerResourceManagerService.getClientProfile(clientId1[0])
548                 .getInUseCasSystemId()).isEqualTo(1);
549         assertThat(mTunerResourceManagerService.getClientProfile(clientId0[0])
550                 .getInUseCasSystemId()).isEqualTo(ClientProfile.INVALID_RESOURCE_ID);
551         assertThat(mTunerResourceManagerService.getCasResource(1)
552                 .getOwnerClientIds()).isEqualTo(new HashSet<Integer>(Arrays.asList(clientId1[0])));
553         assertThat(mTunerResourceManagerService.getCasResource(1).isFullyUsed()).isFalse();
554         assertThat(listener.isReclaimed()).isTrue();
555     }
556 
557     @Test
requestCiCamTest_NoCiCamAvailable_RequestWithHigherPriority()558     public void requestCiCamTest_NoCiCamAvailable_RequestWithHigherPriority() {
559         // Register clients
560         ResourceClientProfile[] profiles = new ResourceClientProfile[2];
561         profiles[0] = resourceClientProfile("0" /*sessionId*/,
562                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
563         profiles[1] = resourceClientProfile("1" /*sessionId*/,
564                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
565         int[] clientPriorities = {100, 500};
566         int[] clientId0 = new int[1];
567         int[] clientId1 = new int[1];
568         TestResourcesReclaimListener listener = new TestResourcesReclaimListener();
569         mTunerResourceManagerService.registerClientProfileInternal(
570                 profiles[0], listener, clientId0);
571         assertThat(clientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
572         mTunerResourceManagerService.updateClientPriorityInternal(
573                 clientId0[0], clientPriorities[0], 0/*niceValue*/);
574         mTunerResourceManagerService.registerClientProfileInternal(
575                 profiles[1], new TestResourcesReclaimListener(), clientId1);
576         assertThat(clientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
577         mTunerResourceManagerService.updateClientPriorityInternal(
578                 clientId1[0], clientPriorities[1], 0/*niceValue*/);
579 
580         // Init cicam/cas resources.
581         mTunerResourceManagerService.updateCasInfoInternal(1 /*casSystemId*/, 2 /*maxSessionNum*/);
582 
583         TunerCiCamRequest request = tunerCiCamRequest(clientId0[0], 1 /*ciCamId*/);
584         int[] ciCamHandle = new int[1];
585         // Request for 2 ciCam sessions.
586         assertThat(mTunerResourceManagerService
587                 .requestCiCamInternal(request, ciCamHandle)).isTrue();
588         assertThat(mTunerResourceManagerService
589                 .requestCiCamInternal(request, ciCamHandle)).isTrue();
590         assertThat(mTunerResourceManagerService.getResourceIdFromHandle(ciCamHandle[0]))
591                 .isEqualTo(1);
592         assertThat(mTunerResourceManagerService.getClientProfile(clientId0[0])
593                 .getInUseCiCamId()).isEqualTo(1);
594         assertThat(mTunerResourceManagerService.getCiCamResource(1)
595                 .getOwnerClientIds()).isEqualTo(new HashSet<Integer>(Arrays.asList(clientId0[0])));
596         assertThat(mTunerResourceManagerService.getCiCamResource(1).isFullyUsed()).isTrue();
597 
598         request = tunerCiCamRequest(clientId1[0], 1);
599         assertThat(mTunerResourceManagerService
600                 .requestCiCamInternal(request, ciCamHandle)).isTrue();
601         assertThat(mTunerResourceManagerService.getResourceIdFromHandle(ciCamHandle[0]))
602                 .isEqualTo(1);
603         assertThat(mTunerResourceManagerService.getClientProfile(clientId1[0])
604                 .getInUseCiCamId()).isEqualTo(1);
605         assertThat(mTunerResourceManagerService.getClientProfile(clientId0[0])
606                 .getInUseCiCamId()).isEqualTo(ClientProfile.INVALID_RESOURCE_ID);
607         assertThat(mTunerResourceManagerService.getCiCamResource(1)
608                 .getOwnerClientIds()).isEqualTo(new HashSet<Integer>(Arrays.asList(clientId1[0])));
609         assertThat(mTunerResourceManagerService.getCiCamResource(1).isFullyUsed()).isFalse();
610         assertThat(listener.isReclaimed()).isTrue();
611     }
612 
613     @Test
releaseCasTest()614     public void releaseCasTest() {
615         // Register clients
616         ResourceClientProfile[] profiles = new ResourceClientProfile[1];
617         profiles[0] = resourceClientProfile("0" /*sessionId*/,
618                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
619         int[] clientId = new int[1];
620         TestResourcesReclaimListener listener = new TestResourcesReclaimListener();
621         mTunerResourceManagerService.registerClientProfileInternal(profiles[0], listener, clientId);
622         assertThat(clientId[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
623 
624         // Init cas resources.
625         mTunerResourceManagerService.updateCasInfoInternal(1 /*casSystemId*/, 2 /*maxSessionNum*/);
626 
627         CasSessionRequest request = casSessionRequest(clientId[0], 1 /*casSystemId*/);
628         int[] casSessionHandle = new int[1];
629         // Request for 1 cas sessions.
630         assertThat(mTunerResourceManagerService
631                 .requestCasSessionInternal(request, casSessionHandle)).isTrue();
632         assertThat(mTunerResourceManagerService.getResourceIdFromHandle(casSessionHandle[0]))
633                 .isEqualTo(1);
634         assertThat(mTunerResourceManagerService.getClientProfile(clientId[0])
635                 .getInUseCasSystemId()).isEqualTo(1);
636         assertThat(mTunerResourceManagerService.getCasResource(1)
637                 .getOwnerClientIds()).isEqualTo(new HashSet<Integer>(Arrays.asList(clientId[0])));
638         assertThat(mTunerResourceManagerService.getCasResource(1).isFullyUsed()).isFalse();
639 
640         // Release cas
641         mTunerResourceManagerService.releaseCasSessionInternal(mTunerResourceManagerService
642                 .getCasResource(1), clientId[0]);
643         assertThat(mTunerResourceManagerService.getClientProfile(clientId[0])
644                 .getInUseCasSystemId()).isEqualTo(ClientProfile.INVALID_RESOURCE_ID);
645         assertThat(mTunerResourceManagerService.getCasResource(1).isFullyUsed()).isFalse();
646         assertThat(mTunerResourceManagerService.getCasResource(1)
647                 .getOwnerClientIds()).isEmpty();
648     }
649 
650     @Test
releaseCiCamTest()651     public void releaseCiCamTest() {
652         // Register clients
653         ResourceClientProfile[] profiles = new ResourceClientProfile[1];
654         profiles[0] = resourceClientProfile("0" /*sessionId*/,
655                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
656         int[] clientId = new int[1];
657         TestResourcesReclaimListener listener = new TestResourcesReclaimListener();
658         mTunerResourceManagerService.registerClientProfileInternal(profiles[0], listener, clientId);
659         assertThat(clientId[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
660 
661         // Init cas resources.
662         mTunerResourceManagerService.updateCasInfoInternal(1 /*casSystemId*/, 2 /*maxSessionNum*/);
663 
664         TunerCiCamRequest request = tunerCiCamRequest(clientId[0], 1 /*ciCamId*/);
665         int[] ciCamHandle = new int[1];
666         // Request for 1 ciCam sessions.
667         assertThat(mTunerResourceManagerService
668                 .requestCiCamInternal(request, ciCamHandle)).isTrue();
669         assertThat(mTunerResourceManagerService.getResourceIdFromHandle(ciCamHandle[0]))
670                 .isEqualTo(1);
671         assertThat(mTunerResourceManagerService.getClientProfile(clientId[0])
672                 .getInUseCiCamId()).isEqualTo(1);
673         assertThat(mTunerResourceManagerService.getCiCamResource(1)
674                 .getOwnerClientIds()).isEqualTo(new HashSet<Integer>(Arrays.asList(clientId[0])));
675         assertThat(mTunerResourceManagerService.getCiCamResource(1).isFullyUsed()).isFalse();
676 
677         // Release ciCam
678         mTunerResourceManagerService.releaseCiCamInternal(mTunerResourceManagerService
679                 .getCiCamResource(1), clientId[0]);
680         assertThat(mTunerResourceManagerService.getClientProfile(clientId[0])
681                 .getInUseCiCamId()).isEqualTo(ClientProfile.INVALID_RESOURCE_ID);
682         assertThat(mTunerResourceManagerService.getCiCamResource(1).isFullyUsed()).isFalse();
683         assertThat(mTunerResourceManagerService.getCiCamResource(1)
684                 .getOwnerClientIds()).isEmpty();
685     }
686 
687     @Test
requestLnbTest_NoLnbAvailable_RequestWithHigherPriority()688     public void requestLnbTest_NoLnbAvailable_RequestWithHigherPriority() {
689         // Register clients
690         ResourceClientProfile[] profiles = new ResourceClientProfile[2];
691         profiles[0] = resourceClientProfile("0" /*sessionId*/,
692                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
693         profiles[1] = resourceClientProfile("1" /*sessionId*/,
694                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
695         int[] clientPriorities = {100, 500};
696         int[] clientId0 = new int[1];
697         int[] clientId1 = new int[1];
698         TestResourcesReclaimListener listener = new TestResourcesReclaimListener();
699         mTunerResourceManagerService.registerClientProfileInternal(
700                 profiles[0], listener, clientId0);
701         assertThat(clientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
702         mTunerResourceManagerService.updateClientPriorityInternal(
703                 clientId0[0], clientPriorities[0], 0/*niceValue*/);
704         mTunerResourceManagerService.registerClientProfileInternal(
705                 profiles[1], new TestResourcesReclaimListener(), clientId1);
706         assertThat(clientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
707         mTunerResourceManagerService.updateClientPriorityInternal(
708                 clientId1[0], clientPriorities[1], 0/*niceValue*/);
709 
710         // Init lnb resources.
711         int[] lnbHandles = {1};
712         mTunerResourceManagerService.setLnbInfoListInternal(lnbHandles);
713 
714         TunerLnbRequest request = new TunerLnbRequest();
715         request.clientId = clientId0[0];
716         int[] lnbHandle = new int[1];
717         assertThat(mTunerResourceManagerService
718                 .requestLnbInternal(request, lnbHandle)).isTrue();
719         assertThat(lnbHandle[0]).isEqualTo(lnbHandles[0]);
720         assertThat(mTunerResourceManagerService.getClientProfile(clientId0[0]).getInUseLnbHandles())
721                 .isEqualTo(new HashSet<Integer>(Arrays.asList(lnbHandles[0])));
722 
723         request = new TunerLnbRequest();
724         request.clientId = clientId1[0];
725 
726         assertThat(mTunerResourceManagerService
727                 .requestLnbInternal(request, lnbHandle)).isTrue();
728         assertThat(lnbHandle[0]).isEqualTo(lnbHandles[0]);
729         assertThat(mTunerResourceManagerService.getLnbResource(lnbHandles[0])
730                 .isInUse()).isTrue();
731         assertThat(mTunerResourceManagerService.getLnbResource(lnbHandles[0])
732                 .getOwnerClientId()).isEqualTo(clientId1[0]);
733         assertThat(listener.isReclaimed()).isTrue();
734         assertThat(mTunerResourceManagerService.getClientProfile(clientId0[0])
735                 .getInUseLnbHandles().size()).isEqualTo(0);
736     }
737 
738     @Test
releaseLnbTest()739     public void releaseLnbTest() {
740         // Register clients
741         ResourceClientProfile[] profiles = new ResourceClientProfile[1];
742         profiles[0] = resourceClientProfile("0" /*sessionId*/,
743                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
744         int[] clientId = new int[1];
745         TestResourcesReclaimListener listener = new TestResourcesReclaimListener();
746         mTunerResourceManagerService.registerClientProfileInternal(profiles[0], listener, clientId);
747         assertThat(clientId[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
748 
749         // Init lnb resources.
750         int[] lnbHandles = {0};
751         mTunerResourceManagerService.setLnbInfoListInternal(lnbHandles);
752 
753         TunerLnbRequest request = new TunerLnbRequest();
754         request.clientId = clientId[0];
755         int[] lnbHandle = new int[1];
756         assertThat(mTunerResourceManagerService
757                 .requestLnbInternal(request, lnbHandle)).isTrue();
758         assertThat(lnbHandle[0]).isEqualTo(lnbHandles[0]);
759 
760         // Release lnb
761         mTunerResourceManagerService.releaseLnbInternal(mTunerResourceManagerService
762                 .getLnbResource(lnbHandle[0]));
763         assertThat(mTunerResourceManagerService
764                 .getLnbResource(lnbHandle[0]).isInUse()).isFalse();
765         assertThat(mTunerResourceManagerService
766                 .getClientProfile(clientId[0]).getInUseLnbHandles().size()).isEqualTo(0);
767     }
768 
769     @Test
unregisterClientTest_usingFrontend()770     public void unregisterClientTest_usingFrontend() {
771         // Register client
772         ResourceClientProfile profile = resourceClientProfile("0" /*sessionId*/,
773                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
774         int[] clientId = new int[1];
775         mTunerResourceManagerService.registerClientProfileInternal(
776                 profile, null /*listener*/, clientId);
777         assertThat(clientId[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
778 
779         // Init frontend resources.
780         TunerFrontendInfo[] infos = new TunerFrontendInfo[2];
781         infos[0] =
782                 tunerFrontendInfo(0 /*handle*/, FrontendSettings.TYPE_DVBT, 1 /*exclusiveGroupId*/);
783         infos[1] =
784                 tunerFrontendInfo(1 /*handle*/, FrontendSettings.TYPE_DVBS, 1 /*exclusiveGroupId*/);
785         mTunerResourceManagerService.setFrontendInfoListInternal(infos);
786 
787         TunerFrontendRequest request =
788                 tunerFrontendRequest(clientId[0] /*clientId*/, FrontendSettings.TYPE_DVBT);
789         int[] frontendHandle = new int[1];
790         assertThat(mTunerResourceManagerService
791                 .requestFrontendInternal(request, frontendHandle)).isTrue();
792         assertThat(frontendHandle[0]).isEqualTo(infos[0].handle);
793         assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].handle)
794                 .isInUse()).isTrue();
795         assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].handle)
796                 .isInUse()).isTrue();
797 
798         // Unregister client when using frontend
799         mTunerResourceManagerService.unregisterClientProfileInternal(clientId[0]);
800         assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].handle)
801                 .isInUse()).isFalse();
802         assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].handle)
803                 .isInUse()).isFalse();
804         assertThat(mTunerResourceManagerService.checkClientExists(clientId[0])).isFalse();
805 
806     }
807 
808     @Test
requestDemuxTest()809     public void requestDemuxTest() {
810         // Register client
811         ResourceClientProfile profile0 = resourceClientProfile("0" /*sessionId*/,
812                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
813         ResourceClientProfile profile1 = resourceClientProfile("1" /*sessionId*/,
814                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
815         int[] clientId0 = new int[1];
816         mTunerResourceManagerService.registerClientProfileInternal(
817                 profile0, null /*listener*/, clientId0);
818         assertThat(clientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
819 
820         TunerDemuxInfo[] infos = new TunerDemuxInfo[3];
821         infos[0] = tunerDemuxInfo(0 /* handle */, Filter.TYPE_TS | Filter.TYPE_IP);
822         infos[1] = tunerDemuxInfo(1 /* handle */, Filter.TYPE_TLV);
823         infos[2] = tunerDemuxInfo(2 /* handle */, Filter.TYPE_TS);
824         mTunerResourceManagerService.setDemuxInfoListInternal(infos);
825 
826         int[] demuxHandle0 = new int[1];
827         // first with undefined type (should be the first one with least # of caps)
828         TunerDemuxRequest request = tunerDemuxRequest(clientId0[0], Filter.TYPE_UNDEFINED);
829         assertThat(mTunerResourceManagerService.requestDemuxInternal(request, demuxHandle0))
830                 .isTrue();
831         assertThat(demuxHandle0[0]).isEqualTo(1);
832         DemuxResource dr = mTunerResourceManagerService.getDemuxResource(demuxHandle0[0]);
833         mTunerResourceManagerService.releaseDemuxInternal(dr);
834 
835         // now with non-supported type (ALP)
836         request.desiredFilterTypes = Filter.TYPE_ALP;
837         demuxHandle0[0] = -1;
838         assertThat(mTunerResourceManagerService.requestDemuxInternal(request, demuxHandle0))
839                 .isFalse();
840         assertThat(demuxHandle0[0]).isEqualTo(-1);
841 
842         // now with TS (should be the one with least # of caps that supports TS)
843         request.desiredFilterTypes = Filter.TYPE_TS;
844         assertThat(mTunerResourceManagerService.requestDemuxInternal(request, demuxHandle0))
845                 .isTrue();
846         assertThat(demuxHandle0[0]).isEqualTo(2);
847 
848         // request for another TS
849         int[] clientId1 = new int[1];
850         mTunerResourceManagerService.registerClientProfileInternal(
851                 profile1, null /*listener*/, clientId1);
852         assertThat(clientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
853         int[] demuxHandle1 = new int[1];
854         TunerDemuxRequest request1 = tunerDemuxRequest(clientId1[0], Filter.TYPE_TS);
855         assertThat(mTunerResourceManagerService.requestDemuxInternal(request1, demuxHandle1))
856                 .isTrue();
857         assertThat(demuxHandle1[0]).isEqualTo(0);
858         assertThat(mTunerResourceManagerService.getResourceIdFromHandle(demuxHandle1[0]))
859                 .isEqualTo(0);
860 
861         // release demuxes
862         dr = mTunerResourceManagerService.getDemuxResource(demuxHandle0[0]);
863         mTunerResourceManagerService.releaseDemuxInternal(dr);
864         dr = mTunerResourceManagerService.getDemuxResource(demuxHandle1[0]);
865         mTunerResourceManagerService.releaseDemuxInternal(dr);
866     }
867 
868     @Test
requestDemuxTest_ResourceReclaim()869     public void requestDemuxTest_ResourceReclaim() {
870         // Register clients
871         ResourceClientProfile profile0 = resourceClientProfile("0" /*sessionId*/,
872                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
873         ResourceClientProfile profile1 = resourceClientProfile("1" /*sessionId*/,
874                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_SCAN);
875         ResourceClientProfile profile2 = resourceClientProfile("2" /*sessionId*/,
876                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_SCAN);
877         int[] clientId0 = new int[1];
878         int[] clientId1 = new int[1];
879         int[] clientId2 = new int[1];
880         TestResourcesReclaimListener listener0 = new TestResourcesReclaimListener();
881         TestResourcesReclaimListener listener1 = new TestResourcesReclaimListener();
882         TestResourcesReclaimListener listener2 = new TestResourcesReclaimListener();
883 
884         mTunerResourceManagerService.registerClientProfileInternal(
885                 profile0, listener0, clientId0);
886         assertThat(clientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
887         mTunerResourceManagerService.registerClientProfileInternal(
888                 profile1, listener1, clientId1);
889         assertThat(clientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
890         mTunerResourceManagerService.registerClientProfileInternal(
891                 profile2, listener2, clientId1);
892         assertThat(clientId2[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
893 
894         // Init demux resources.
895         TunerDemuxInfo[] infos = new TunerDemuxInfo[2];
896         infos[0] = tunerDemuxInfo(0 /*handle*/, Filter.TYPE_TS | Filter.TYPE_IP);
897         infos[1] = tunerDemuxInfo(1 /*handle*/, Filter.TYPE_TS);
898         mTunerResourceManagerService.setDemuxInfoListInternal(infos);
899 
900         // let clientId0(prio:100) request for IP - should succeed
901         TunerDemuxRequest request0 = tunerDemuxRequest(clientId0[0], Filter.TYPE_IP);
902         int[] demuxHandle0 = new int[1];
903         assertThat(mTunerResourceManagerService
904                 .requestDemuxInternal(request0, demuxHandle0)).isTrue();
905         assertThat(demuxHandle0[0]).isEqualTo(0);
906 
907         // let clientId1(prio:50) request for IP - should fail
908         TunerDemuxRequest request1 = tunerDemuxRequest(clientId1[0], Filter.TYPE_IP);
909         int[] demuxHandle1 = new int[1];
910         demuxHandle1[0] = -1;
911         assertThat(mTunerResourceManagerService
912                 .requestDemuxInternal(request1, demuxHandle1)).isFalse();
913         assertThat(listener0.isReclaimed()).isFalse();
914         assertThat(demuxHandle1[0]).isEqualTo(-1);
915 
916         // let clientId1(prio:50) request for TS - should succeed
917         request1.desiredFilterTypes = Filter.TYPE_TS;
918         assertThat(mTunerResourceManagerService
919                 .requestDemuxInternal(request1, demuxHandle1)).isTrue();
920         assertThat(demuxHandle1[0]).isEqualTo(1);
921         assertThat(listener0.isReclaimed()).isFalse();
922 
923         // now release demux for the clientId0 (higher priority) and request demux
924         DemuxResource dr = mTunerResourceManagerService.getDemuxResource(demuxHandle0[0]);
925         mTunerResourceManagerService.releaseDemuxInternal(dr);
926 
927         // let clientId2(prio:50) request for TS - should succeed
928         TunerDemuxRequest request2 = tunerDemuxRequest(clientId2[0], Filter.TYPE_TS);
929         int[] demuxHandle2 = new int[1];
930         assertThat(mTunerResourceManagerService
931                 .requestDemuxInternal(request2, demuxHandle2)).isTrue();
932         assertThat(demuxHandle2[0]).isEqualTo(0);
933         assertThat(listener1.isReclaimed()).isFalse();
934 
935         // let clientId0(prio:100) request for TS - should reclaim from clientId2
936         // , who has the smaller caps
937         request0.desiredFilterTypes = Filter.TYPE_TS;
938         assertThat(mTunerResourceManagerService
939                 .requestDemuxInternal(request0, demuxHandle0)).isTrue();
940         assertThat(listener1.isReclaimed()).isFalse();
941         assertThat(listener2.isReclaimed()).isTrue();
942     }
943 
944     @Test
requestDescramblerTest()945     public void requestDescramblerTest() {
946         // Register client
947         ResourceClientProfile profile = resourceClientProfile("0" /*sessionId*/,
948                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
949         int[] clientId = new int[1];
950         mTunerResourceManagerService.registerClientProfileInternal(
951                 profile, null /*listener*/, clientId);
952         assertThat(clientId[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
953 
954         int[] desHandle = new int[1];
955         TunerDescramblerRequest request = new TunerDescramblerRequest();
956         request.clientId = clientId[0];
957         assertThat(mTunerResourceManagerService.requestDescramblerInternal(request, desHandle))
958                 .isTrue();
959         assertThat(mTunerResourceManagerService.getResourceIdFromHandle(desHandle[0])).isEqualTo(0);
960     }
961 
962     @Test
isHigherPriorityTest()963     public void isHigherPriorityTest() {
964         mIsForeground = false;
965         ResourceClientProfile backgroundPlaybackProfile =
966                 resourceClientProfile(null /*sessionId*/,
967                         TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
968         ResourceClientProfile backgroundRecordProfile =
969                 resourceClientProfile(null /*sessionId*/,
970                         TvInputService.PRIORITY_HINT_USE_CASE_TYPE_RECORD);
971         int backgroundPlaybackPriority = mTunerResourceManagerService.getClientPriority(
972                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK, mIsForeground);
973         int backgroundRecordPriority = mTunerResourceManagerService.getClientPriority(
974                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_RECORD, mIsForeground);
975         assertThat(mTunerResourceManagerService.isHigherPriorityInternal(backgroundPlaybackProfile,
976                 backgroundRecordProfile)).isEqualTo(
977                         (backgroundPlaybackPriority > backgroundRecordPriority));
978     }
979 
980     @Test
shareFrontendTest_FrontendWithExclusiveGroupReadyToShare()981     public void shareFrontendTest_FrontendWithExclusiveGroupReadyToShare() {
982         /**** Register Clients and Set Priority ****/
983 
984         // Int array to save the returned client ids
985         int[] ownerClientId0 = new int[1];
986         int[] ownerClientId1 = new int[1];
987         int[] shareClientId0 = new int[1];
988         int[] shareClientId1 = new int[1];
989 
990         // Predefined client profiles
991         ResourceClientProfile[] ownerProfiles = new ResourceClientProfile[2];
992         ResourceClientProfile[] shareProfiles = new ResourceClientProfile[2];
993         ownerProfiles[0] = resourceClientProfile(
994                 "0" /*sessionId*/,
995                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_LIVE);
996         ownerProfiles[1] = resourceClientProfile(
997                 "1" /*sessionId*/,
998                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_LIVE);
999         shareProfiles[0] = resourceClientProfile(
1000                 "2" /*sessionId*/,
1001                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_RECORD);
1002         shareProfiles[1] = resourceClientProfile(
1003                 "3" /*sessionId*/,
1004                 TvInputService.PRIORITY_HINT_USE_CASE_TYPE_RECORD);
1005 
1006         // Predefined client reclaim listeners
1007         TestResourcesReclaimListener ownerListener0 = new TestResourcesReclaimListener();
1008         TestResourcesReclaimListener shareListener0 = new TestResourcesReclaimListener();
1009         TestResourcesReclaimListener ownerListener1 = new TestResourcesReclaimListener();
1010         TestResourcesReclaimListener shareListener1 = new TestResourcesReclaimListener();
1011         // Register clients and validate the returned client ids
1012         mTunerResourceManagerService
1013                 .registerClientProfileInternal(ownerProfiles[0], ownerListener0, ownerClientId0);
1014         mTunerResourceManagerService
1015                 .registerClientProfileInternal(shareProfiles[0], shareListener0, shareClientId0);
1016         mTunerResourceManagerService
1017                 .registerClientProfileInternal(ownerProfiles[1], ownerListener1, ownerClientId1);
1018         mTunerResourceManagerService
1019                 .registerClientProfileInternal(shareProfiles[1], shareListener1, shareClientId1);
1020         assertThat(ownerClientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
1021         assertThat(shareClientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
1022         assertThat(ownerClientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
1023         assertThat(shareClientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
1024 
1025         mTunerResourceManagerService.updateClientPriorityInternal(
1026                 ownerClientId0[0],
1027                 100/*priority*/,
1028                 0/*niceValue*/);
1029         mTunerResourceManagerService.updateClientPriorityInternal(
1030                 shareClientId0[0],
1031                 200/*priority*/,
1032                 0/*niceValue*/);
1033         mTunerResourceManagerService.updateClientPriorityInternal(
1034                 ownerClientId1[0],
1035                 300/*priority*/,
1036                 0/*niceValue*/);
1037         mTunerResourceManagerService.updateClientPriorityInternal(
1038                 shareClientId1[0],
1039                 400/*priority*/,
1040                 0/*niceValue*/);
1041         mTunerResourceManagerService.updateClientPriorityInternal(
1042                 shareClientId1[0],
1043                 -1/*invalid priority*/,
1044                 0/*niceValue*/);
1045         assertThat(mTunerResourceManagerService
1046                 .getClientProfile(shareClientId1[0])
1047                 .getPriority())
1048                 .isEqualTo(400);
1049 
1050         /**** Init Frontend Resources ****/
1051 
1052         // Predefined frontend info
1053         TunerFrontendInfo[] infos = new TunerFrontendInfo[2];
1054         infos[0] = tunerFrontendInfo(
1055                 0 /*handle*/,
1056                 FrontendSettings.TYPE_DVBT,
1057                 1 /*exclusiveGroupId*/);
1058         infos[1] = tunerFrontendInfo(
1059                 1 /*handle*/,
1060                 FrontendSettings.TYPE_DVBS,
1061                 1 /*exclusiveGroupId*/);
1062 
1063         /**** Init Lnb Resources ****/
1064         int[] lnbHandles = {1};
1065         mTunerResourceManagerService.setLnbInfoListInternal(lnbHandles);
1066 
1067         // Update frontend list in TRM
1068         mTunerResourceManagerService.setFrontendInfoListInternal(infos);
1069 
1070         /**** Request Frontend ****/
1071 
1072         // Predefined frontend request and array to save returned frontend handle
1073         int[] frontendHandle = new int[1];
1074         TunerFrontendRequest request = tunerFrontendRequest(
1075                 ownerClientId0[0] /*clientId*/,
1076                 FrontendSettings.TYPE_DVBT);
1077 
1078         // Request call and validate granted resource and internal mapping
1079         assertThat(mTunerResourceManagerService
1080                 .requestFrontendInternal(request, frontendHandle))
1081                 .isTrue();
1082         assertThat(frontendHandle[0]).isEqualTo(infos[0].handle);
1083         assertThat(mTunerResourceManagerService
1084                 .getClientProfile(ownerClientId0[0])
1085                 .getInUseFrontendHandles())
1086                 .isEqualTo(new HashSet<Integer>(Arrays.asList(
1087                         infos[0].handle,
1088                         infos[1].handle)));
1089 
1090         /**** Share Frontend ****/
1091 
1092         // Share frontend call and validate the internal mapping
1093         mTunerResourceManagerService.shareFrontendInternal(
1094                 shareClientId0[0]/*selfClientId*/,
1095                 ownerClientId0[0]/*targetClientId*/);
1096         mTunerResourceManagerService.shareFrontendInternal(
1097                 shareClientId1[0]/*selfClientId*/,
1098                 ownerClientId0[0]/*targetClientId*/);
1099         // Verify fe in use status
1100         assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].handle)
1101                 .isInUse()).isTrue();
1102         assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].handle)
1103                 .isInUse()).isTrue();
1104         // Verify fe owner status
1105         assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].handle)
1106                 .getOwnerClientId()).isEqualTo(ownerClientId0[0]);
1107         assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].handle)
1108                 .getOwnerClientId()).isEqualTo(ownerClientId0[0]);
1109         // Verify share fe client status in the primary owner client
1110         assertThat(mTunerResourceManagerService.getClientProfile(ownerClientId0[0])
1111                 .getShareFeClientIds())
1112                 .isEqualTo(new HashSet<Integer>(Arrays.asList(
1113                         shareClientId0[0],
1114                         shareClientId1[0])));
1115         // Verify in use frontend list in all the primary owner and share owner clients
1116         assertThat(mTunerResourceManagerService
1117                 .getClientProfile(ownerClientId0[0])
1118                 .getInUseFrontendHandles())
1119                 .isEqualTo(new HashSet<Integer>(Arrays.asList(
1120                         infos[0].handle,
1121                         infos[1].handle)));
1122         assertThat(mTunerResourceManagerService
1123                 .getClientProfile(shareClientId0[0])
1124                 .getInUseFrontendHandles())
1125                 .isEqualTo(new HashSet<Integer>(Arrays.asList(
1126                         infos[0].handle,
1127                         infos[1].handle)));
1128         assertThat(mTunerResourceManagerService
1129                 .getClientProfile(shareClientId1[0])
1130                 .getInUseFrontendHandles())
1131                 .isEqualTo(new HashSet<Integer>(Arrays.asList(
1132                         infos[0].handle,
1133                         infos[1].handle)));
1134 
1135         /**** Remove Frontend Share Owner ****/
1136 
1137         // Unregister the second share fe client
1138         mTunerResourceManagerService.unregisterClientProfileInternal(shareClientId1[0]);
1139 
1140         // Validate the internal mapping
1141         assertThat(mTunerResourceManagerService.getClientProfile(ownerClientId0[0])
1142                 .getShareFeClientIds())
1143                 .isEqualTo(new HashSet<Integer>(Arrays.asList(
1144                         shareClientId0[0])));
1145         assertThat(mTunerResourceManagerService
1146                 .getClientProfile(ownerClientId0[0])
1147                 .getInUseFrontendHandles())
1148                 .isEqualTo(new HashSet<Integer>(Arrays.asList(
1149                         infos[0].handle,
1150                         infos[1].handle)));
1151         assertThat(mTunerResourceManagerService
1152                 .getClientProfile(shareClientId0[0])
1153                 .getInUseFrontendHandles())
1154                 .isEqualTo(new HashSet<Integer>(Arrays.asList(
1155                         infos[0].handle,
1156                         infos[1].handle)));
1157 
1158         /**** Request Shared Frontend with Higher Priority Client ****/
1159 
1160         // Predefined second frontend request
1161         request = tunerFrontendRequest(
1162                 ownerClientId1[0] /*clientId*/,
1163                 FrontendSettings.TYPE_DVBT);
1164 
1165         // Second request call
1166         assertThat(mTunerResourceManagerService
1167                 .requestFrontendInternal(request, frontendHandle))
1168                 .isTrue();
1169 
1170         // Validate granted resource and internal mapping
1171         assertThat(frontendHandle[0]).isEqualTo(infos[0].handle);
1172         assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].handle)
1173                 .getOwnerClientId()).isEqualTo(ownerClientId1[0]);
1174         assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].handle)
1175                 .getOwnerClientId()).isEqualTo(ownerClientId1[0]);
1176         assertThat(mTunerResourceManagerService
1177                 .getClientProfile(ownerClientId1[0])
1178                 .getInUseFrontendHandles())
1179                 .isEqualTo(new HashSet<Integer>(Arrays.asList(
1180                         infos[0].handle,
1181                         infos[1].handle)));
1182         assertThat(mTunerResourceManagerService
1183                 .getClientProfile(ownerClientId0[0])
1184                 .getInUseFrontendHandles()
1185                 .isEmpty())
1186                 .isTrue();
1187         assertThat(mTunerResourceManagerService
1188                 .getClientProfile(shareClientId0[0])
1189                 .getInUseFrontendHandles()
1190                 .isEmpty())
1191                 .isTrue();
1192         assertThat(mTunerResourceManagerService
1193                 .getClientProfile(ownerClientId0[0])
1194                 .getShareFeClientIds()
1195                 .isEmpty())
1196                 .isTrue();
1197         assertThat(ownerListener0.isReclaimed()).isTrue();
1198         assertThat(shareListener0.isReclaimed()).isTrue();
1199 
1200         /**** Release Frontend Resource From Primary Owner ****/
1201 
1202         // Reshare the frontend
1203         mTunerResourceManagerService.shareFrontendInternal(
1204                 shareClientId0[0]/*selfClientId*/,
1205                 ownerClientId1[0]/*targetClientId*/);
1206 
1207         // Release the frontend resource from the primary owner
1208         mTunerResourceManagerService.releaseFrontendInternal(mTunerResourceManagerService
1209                 .getFrontendResource(infos[0].handle), ownerClientId1[0]);
1210 
1211         // Validate the internal mapping
1212         assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].handle)
1213                 .isInUse()).isFalse();
1214         assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].handle)
1215                 .isInUse()).isFalse();
1216         // Verify client status
1217         assertThat(mTunerResourceManagerService
1218                 .getClientProfile(ownerClientId1[0])
1219                 .getInUseFrontendHandles()
1220                 .isEmpty())
1221                 .isTrue();
1222         assertThat(mTunerResourceManagerService
1223                 .getClientProfile(shareClientId0[0])
1224                 .getInUseFrontendHandles()
1225                 .isEmpty())
1226                 .isTrue();
1227         assertThat(mTunerResourceManagerService
1228                 .getClientProfile(ownerClientId1[0])
1229                 .getShareFeClientIds()
1230                 .isEmpty())
1231                 .isTrue();
1232 
1233         /**** Unregister Primary Owner when the Share owner owns an Lnb ****/
1234 
1235         // Predefined Lnb request and handle array
1236         TunerLnbRequest requestLnb = new TunerLnbRequest();
1237         requestLnb.clientId = shareClientId0[0];
1238         int[] lnbHandle = new int[1];
1239 
1240         // Request for an Lnb
1241         assertThat(mTunerResourceManagerService
1242                 .requestLnbInternal(requestLnb, lnbHandle))
1243                 .isTrue();
1244 
1245         // Request and share the frontend resource again
1246         assertThat(mTunerResourceManagerService
1247                 .requestFrontendInternal(request, frontendHandle))
1248                 .isTrue();
1249         mTunerResourceManagerService.shareFrontendInternal(
1250                 shareClientId0[0]/*selfClientId*/,
1251                 ownerClientId1[0]/*targetClientId*/);
1252 
1253         // Unregister the primary owner of the shared frontend
1254         mTunerResourceManagerService.unregisterClientProfileInternal(ownerClientId1[0]);
1255 
1256         // Validate the internal mapping
1257         assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].handle)
1258                 .isInUse()).isFalse();
1259         assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].handle)
1260                 .isInUse()).isFalse();
1261         // Verify client status
1262         assertThat(mTunerResourceManagerService
1263                 .getClientProfile(shareClientId0[0])
1264                 .getInUseFrontendHandles()
1265                 .isEmpty())
1266                 .isTrue();
1267         assertThat(mTunerResourceManagerService
1268                 .getClientProfile(shareClientId0[0])
1269                 .getInUseLnbHandles())
1270                 .isEqualTo(new HashSet<Integer>(Arrays.asList(
1271                         lnbHandles[0])));
1272     }
1273 
tunerFrontendInfo( int handle, int frontendType, int exclusiveGroupId)1274     private TunerFrontendInfo tunerFrontendInfo(
1275             int handle, int frontendType, int exclusiveGroupId) {
1276         TunerFrontendInfo info = new TunerFrontendInfo();
1277         info.handle = handle;
1278         info.type = frontendType;
1279         info.exclusiveGroupId = exclusiveGroupId;
1280         return info;
1281     }
1282 
tunerFrontendRequest(int clientId, int frontendType)1283     private TunerFrontendRequest tunerFrontendRequest(int clientId, int frontendType) {
1284         TunerFrontendRequest request = new TunerFrontendRequest();
1285         request.clientId = clientId;
1286         request.frontendType = frontendType;
1287         return request;
1288     }
1289 
resourceClientProfile(String sessionId, int useCase)1290     private ResourceClientProfile resourceClientProfile(String sessionId, int useCase) {
1291         ResourceClientProfile profile = new ResourceClientProfile();
1292         profile.tvInputSessionId = sessionId;
1293         profile.useCase = useCase;
1294         return profile;
1295     }
1296 
casSessionRequest(int clientId, int casSystemId)1297     private CasSessionRequest casSessionRequest(int clientId, int casSystemId) {
1298         CasSessionRequest request = new CasSessionRequest();
1299         request.clientId = clientId;
1300         request.casSystemId = casSystemId;
1301         return request;
1302     }
1303 
tunerCiCamRequest(int clientId, int ciCamId)1304     private TunerCiCamRequest tunerCiCamRequest(int clientId, int ciCamId) {
1305         TunerCiCamRequest request = new TunerCiCamRequest();
1306         request.clientId = clientId;
1307         request.ciCamId = ciCamId;
1308         return request;
1309     }
1310 
tunerDemuxInfo(int handle, int supportedFilterTypes)1311     private TunerDemuxInfo tunerDemuxInfo(int handle, int supportedFilterTypes) {
1312         TunerDemuxInfo info = new TunerDemuxInfo();
1313         info.handle = handle;
1314         info.filterTypes = supportedFilterTypes;
1315         return info;
1316     }
1317 
tunerDemuxRequest(int clientId, int desiredFilterTypes)1318     private TunerDemuxRequest tunerDemuxRequest(int clientId, int desiredFilterTypes) {
1319         TunerDemuxRequest request = new TunerDemuxRequest();
1320         request.clientId = clientId;
1321         request.desiredFilterTypes = desiredFilterTypes;
1322         return request;
1323     }
1324 }
1325