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