• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package android.media.tv.tunerresourcemanager;
18 
19 import android.annotation.CallbackExecutor;
20 import android.annotation.IntDef;
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.annotation.RequiresFeature;
24 import android.annotation.SuppressLint;
25 import android.annotation.SystemService;
26 import android.annotation.TestApi;
27 import android.content.Context;
28 import android.content.pm.PackageManager;
29 import android.media.tv.TvInputService;
30 import android.os.Binder;
31 import android.os.RemoteException;
32 import android.util.Log;
33 
34 import java.lang.annotation.Retention;
35 import java.lang.annotation.RetentionPolicy;
36 import java.util.concurrent.Executor;
37 
38 /**
39  * Interface of the Tuner Resource Manager(TRM). It manages resources used by TV Tuners.
40  * <p>Resources include:
41  * <ul>
42  * <li>TunerFrontend {@link android.media.tv.tuner.frontend}.
43  * <li>TunerLnb {@link android.media.tv.tuner.Lnb}.
44  * <li>MediaCas {@link android.media.MediaCas}.
45  * <ul>
46  *
47  * <p>Expected workflow is:
48  * <ul>
49  * <li>Tuner Java/MediaCas/TIF update resources of the current device with TRM.
50  * <li>Client registers its profile through {@link #registerClientProfile(ResourceClientProfile,
51  * Executor, ResourcesReclaimListener, int[])}.
52  * <li>Client requests resources through request APIs.
53  * <li>If the resource needs to be handed to a higher priority client from a lower priority
54  * one, TRM calls IResourcesReclaimListener registered by the lower priority client to release
55  * the resource.
56  * <ul>
57  *
58  * <p>TRM also exposes its priority comparison algorithm as a helping method to other services.
59  * {@see #isHigherPriority(ResourceClientProfile, ResourceClientProfile)}.
60  *
61  * @hide
62  */
63 @RequiresFeature(PackageManager.FEATURE_LIVE_TV)
64 @SystemService(Context.TV_TUNER_RESOURCE_MGR_SERVICE)
65 public class TunerResourceManager {
66     private static final String TAG = "TunerResourceManager";
67     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
68 
69     public static final int INVALID_RESOURCE_HANDLE = -1;
70     public static final int INVALID_OWNER_ID = -1;
71     /**
72      * Tuner resource type to help generate resource handle
73      */
74     @IntDef({
75         TUNER_RESOURCE_TYPE_FRONTEND,
76         TUNER_RESOURCE_TYPE_DEMUX,
77         TUNER_RESOURCE_TYPE_DESCRAMBLER,
78         TUNER_RESOURCE_TYPE_LNB,
79         TUNER_RESOURCE_TYPE_CAS_SESSION,
80         TUNER_RESOURCE_TYPE_FRONTEND_CICAM,
81         TUNER_RESOURCE_TYPE_MAX,
82      })
83     @Retention(RetentionPolicy.SOURCE)
84     public @interface TunerResourceType {}
85 
86     public static final int TUNER_RESOURCE_TYPE_FRONTEND = 0;
87     public static final int TUNER_RESOURCE_TYPE_DEMUX = 1;
88     public static final int TUNER_RESOURCE_TYPE_DESCRAMBLER = 2;
89     public static final int TUNER_RESOURCE_TYPE_LNB = 3;
90     public static final int TUNER_RESOURCE_TYPE_CAS_SESSION = 4;
91     public static final int TUNER_RESOURCE_TYPE_FRONTEND_CICAM = 5;
92     public static final int TUNER_RESOURCE_TYPE_MAX = 6;
93 
94     private final ITunerResourceManager mService;
95     private final int mUserId;
96 
97     /**
98      * @hide
99      */
TunerResourceManager(ITunerResourceManager service, int userId)100     public TunerResourceManager(ITunerResourceManager service, int userId) {
101         mService = service;
102         mUserId = userId;
103     }
104 
105     /**
106      * This API is used by the client to register their profile with the Tuner Resource manager.
107      *
108      * <p>The profile contains information that can show the base priority score of the client.
109      *
110      * @param profile {@link ResourceClientProfile} profile of the current client. Undefined use
111      *                case would cause IllegalArgumentException.
112      * @param executor the executor on which the listener would be invoked.
113      * @param listener {@link ResourcesReclaimListener} callback to reclaim clients' resources when
114      *                 needed.
115      * @param clientId returned a clientId from the resource manager when the
116      *                 the client registeres.
117      * @throws IllegalArgumentException when {@code profile} contains undefined use case.
118      */
registerClientProfile(@onNull ResourceClientProfile profile, @NonNull @CallbackExecutor Executor executor, @NonNull ResourcesReclaimListener listener, @NonNull int[] clientId)119     public void registerClientProfile(@NonNull ResourceClientProfile profile,
120                         @NonNull @CallbackExecutor Executor executor,
121                         @NonNull ResourcesReclaimListener listener,
122                         @NonNull int[] clientId) {
123         // TODO: throw new IllegalArgumentException("Unknown client use case")
124         // when the use case is not defined.
125         try {
126             mService.registerClientProfile(profile,
127                     new IResourcesReclaimListener.Stub() {
128                     @Override
129                 public void onReclaimResources() {
130                         final long identity = Binder.clearCallingIdentity();
131                         try {
132                             executor.execute(() -> listener.onReclaimResources());
133                         } finally {
134                             Binder.restoreCallingIdentity(identity);
135                         }
136                     }
137                 }, clientId);
138         } catch (RemoteException e) {
139             throw e.rethrowFromSystemServer();
140         }
141     }
142 
143     /**
144      * This API is used by the client to unregister their profile with the
145      * Tuner Resource manager.
146      *
147      * @param clientId the client id that needs to be unregistered.
148      */
unregisterClientProfile(int clientId)149     public void unregisterClientProfile(int clientId) {
150         try {
151             mService.unregisterClientProfile(clientId);
152         } catch (RemoteException e) {
153             throw e.rethrowFromSystemServer();
154         }
155     }
156 
157     /**
158      * This API is used by client to update its registered {@link ResourceClientProfile}.
159      *
160      * <p>We recommend creating a new tuner instance for different use cases instead of using this
161      * API since different use cases may need different resources.
162      *
163      * <p>If TIS updates use case, it needs to ensure underneath resources are exchangeable between
164      * two different use cases.
165      *
166      * <p>Only the arbitrary priority and niceValue are allowed to be updated.
167      *
168      * @param clientId the id of the client that is updating its profile.
169      * @param priority the priority that the client would like to update to.
170      * @param niceValue the nice value that the client would like to update to.
171      *
172      * @return true if the update is successful.
173      */
updateClientPriority(int clientId, int priority, int niceValue)174     public boolean updateClientPriority(int clientId, int priority, int niceValue) {
175         boolean result = false;
176         try {
177             result = mService.updateClientPriority(clientId, priority, niceValue);
178         } catch (RemoteException e) {
179             throw e.rethrowFromSystemServer();
180         }
181         return result;
182     }
183 
184     /**
185      * Checks if there is an unused frontend resource available.
186      *
187      * @param frontendType The frontend type for the query to be done for.
188      */
hasUnusedFrontend(int frontendType)189     public boolean hasUnusedFrontend(int frontendType) {
190         boolean result = false;
191         try {
192             result = mService.hasUnusedFrontend(frontendType);
193         } catch (RemoteException e) {
194             throw e.rethrowFromSystemServer();
195         }
196         return result;
197     }
198 
199     /**
200      * Checks if the client has the lowest priority among the clients that are holding
201      * the frontend resource of the specified type.
202      *
203      * <p> When this function returns false, it means that there is at least one client with the
204      * strictly lower priority (than clientId) that is reclaimable by the system.
205      *
206      * @param clientId The client ID to be checked the priority for.
207      * @param frontendType The specific frontend type to be checked for.
208      *
209      * @return false if there is another client holding the frontend resource of the specified type
210      * that can be reclaimed. Otherwise true.
211      */
isLowestPriority(int clientId, int frontendType)212     public boolean isLowestPriority(int clientId, int frontendType) {
213         boolean result = false;
214         try {
215             result = mService.isLowestPriority(clientId, frontendType);
216         } catch (RemoteException e) {
217             throw e.rethrowFromSystemServer();
218         }
219         return result;
220     }
221 
222     /**
223      * Stores the frontend resource map if it was stored before.
224      *
225      * <p>This API is only for testing purpose and should be used in pair with
226      * restoreResourceMap(), which allows testing of {@link Tuner} APIs
227      * that behave differently based on different sets of resource map.
228      *
229      * @param resourceType The resource type to store the map for.
230      */
storeResourceMap(int resourceType)231     public void storeResourceMap(int resourceType) {
232         try {
233             mService.storeResourceMap(resourceType);
234         } catch (RemoteException e) {
235             throw e.rethrowFromSystemServer();
236         }
237     }
238 
239     /**
240      * Clears the frontend resource map.
241      *
242      * <p>This API is only for testing purpose and should be called right after
243      * storeResourceMap(), so TRMService#removeFrontendResource() does not
244      * get called in TRMService#setFrontendInfoListInternal() for custom frontend
245      * resource map creation.
246      *
247      * @param resourceType The resource type to clear the map for.
248      */
clearResourceMap(int resourceType)249     public void clearResourceMap(int resourceType) {
250         try {
251             mService.clearResourceMap(resourceType);
252         } catch (RemoteException e) {
253             throw e.rethrowFromSystemServer();
254         }
255     }
256 
257     /**
258      * Restores Frontend resource map for the later restore.
259      *
260      * <p>This API is only for testing purpose and should be used in pair with
261      * storeResourceMap(), which allows testing of {@link Tuner} APIs
262      * that behave differently based on different sets of resource map.
263      *
264      * @param resourceType The resource type to restore the map for.
265      */
restoreResourceMap(int resourceType)266     public void restoreResourceMap(int resourceType) {
267         try {
268             mService.restoreResourceMap(resourceType);
269         } catch (RemoteException e) {
270             throw e.rethrowFromSystemServer();
271         }
272     }
273 
274     /**
275      * Updates the current TRM of the TunerHAL Frontend information.
276      *
277      * <p><strong>Note:</strong> This update must happen before the first
278      * {@link #requestFrontend(TunerFrontendRequest, int[])} and
279      * {@link #releaseFrontend(int, int)} call.
280      *
281      * @param infos an array of the available {@link TunerFrontendInfo} information.
282      */
setFrontendInfoList(@onNull TunerFrontendInfo[] infos)283     public void setFrontendInfoList(@NonNull TunerFrontendInfo[] infos) {
284         try {
285             mService.setFrontendInfoList(infos);
286         } catch (RemoteException e) {
287             throw e.rethrowFromSystemServer();
288         }
289     }
290 
291     /**
292      * Updates the TRM of the current CAS information.
293      *
294      * <p><strong>Note:</strong> This update must happen before the first
295      * {@link #requestCasSession(CasSessionRequest, int[])} and {@link #releaseCasSession(int, int)}
296      * call.
297      *
298      * @param casSystemId id of the updating CAS system.
299      * @param maxSessionNum the max session number of the CAS system that is updated.
300      */
updateCasInfo(int casSystemId, int maxSessionNum)301     public void updateCasInfo(int casSystemId, int maxSessionNum) {
302         try {
303             mService.updateCasInfo(casSystemId, maxSessionNum);
304         } catch (RemoteException e) {
305             throw e.rethrowFromSystemServer();
306         }
307     }
308 
309     /**
310      * Updates the TRM of the current Lnb information.
311      *
312      * <p><strong>Note:</strong> This update must happen before the first
313      * {@link #requestLnb(TunerLnbRequest, int[])} and {@link #releaseLnb(int, int)} call.
314      *
315      * @param lnbIds ids of the updating lnbs.
316      */
setLnbInfoList(int[] lnbIds)317     public void setLnbInfoList(int[] lnbIds) {
318         try {
319             mService.setLnbInfoList(lnbIds);
320         } catch (RemoteException e) {
321             throw e.rethrowFromSystemServer();
322         }
323     }
324 
325     /**
326      * Grants the lock to the caller for public {@link Tuner} APIs
327      *
328      * <p>{@link Tuner} functions that call both [@link TunerResourceManager} APIs and
329      * grabs lock that are also used in {@link IResourcesReclaimListener#onReclaimResources()}
330      * must call this API before acquiring lock used in onReclaimResources().
331      *
332      * <p>This API will block until it releases the lock or fails
333      *
334      * @param clientId The ID of the caller.
335      *
336      * @return true if the lock is granted. If false is returned, calling this API again is not
337      * guaranteed to work and may be unrecoverrable. (This should not happen.)
338      */
acquireLock(int clientId)339     public boolean acquireLock(int clientId) {
340         try {
341             return mService.acquireLock(clientId, Thread.currentThread().getId());
342         } catch (RemoteException e) {
343             throw e.rethrowFromSystemServer();
344         }
345     }
346 
347     /**
348      * Releases the lock to the caller for public {@link Tuner} APIs
349      *
350      * <p>This API must be called in pair with {@link #acquireLock(int, int)}
351      *
352      * <p>This API will block until it releases the lock or fails
353      *
354      * @param clientId The ID of the caller.
355      *
356      * @return true if the lock is granted. If false is returned, calling this API again is not
357      * guaranteed to work and may be unrecoverrable. (This should not happen.)
358      */
releaseLock(int clientId)359     public boolean releaseLock(int clientId) {
360         try {
361             return mService.releaseLock(clientId);
362         } catch (RemoteException e) {
363             throw e.rethrowFromSystemServer();
364         }
365     }
366 
367     /**
368      * Requests a frontend resource.
369      *
370      * <p>There are three possible scenarios:
371      * <ul>
372      * <li>If there is frontend available, the API would send the id back.
373      *
374      * <li>If no Frontend is available but the current request info can show higher priority than
375      * other uses of Frontend, the API will send
376      * {@link IResourcesReclaimListener#onReclaimResources()} to the {@link Tuner}. Tuner would
377      * handle the resource reclaim on the holder of lower priority and notify the holder of its
378      * resource loss.
379      *
380      * <li>If no frontend can be granted, the API would return false.
381      * <ul>
382      *
383      * <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called
384      * before this request.
385      *
386      * @param request {@link TunerFrontendRequest} information of the current request.
387      * @param frontendHandle a one-element array to return the granted frontendHandle. If
388      *                       no frontend granted, this will return {@link #INVALID_RESOURCE_HANDLE}.
389      *
390      * @return true if there is frontend granted.
391      */
requestFrontend(@onNull TunerFrontendRequest request, @Nullable int[] frontendHandle)392     public boolean requestFrontend(@NonNull TunerFrontendRequest request,
393                 @Nullable int[] frontendHandle) {
394         boolean result = false;
395         try {
396             result = mService.requestFrontend(request, frontendHandle);
397         } catch (RemoteException e) {
398             throw e.rethrowFromSystemServer();
399         }
400         return result;
401     }
402 
403     /**
404      * Sets the maximum usable frontends number of a given frontend type. It is used to enable or
405      * disable frontends when cable connection status is changed by user.
406      *
407      * @param frontendType the frontendType which the maximum usable number will be set for.
408      * @param maxNum the new maximum usable number.
409      *
410      * @return true if  successful and false otherwise.
411      */
setMaxNumberOfFrontends(int frontendType, int maxNum)412     public boolean setMaxNumberOfFrontends(int frontendType, int maxNum) {
413         boolean result = false;
414         try {
415             result = mService.setMaxNumberOfFrontends(frontendType, maxNum);
416         } catch (RemoteException e) {
417             throw e.rethrowFromSystemServer();
418         }
419         return result;
420     }
421 
422     /**
423      * Get the maximum usable frontends number of a given frontend type.
424      *
425      * @param frontendType the frontendType which the maximum usable number will be queried for.
426      *
427      * @return the maximum usable number of the queried frontend type. Returns -1 when the
428      *         frontendType is invalid
429      */
getMaxNumberOfFrontends(int frontendType)430     public int getMaxNumberOfFrontends(int frontendType) {
431         int result = -1;
432         try {
433             result = mService.getMaxNumberOfFrontends(frontendType);
434         } catch (RemoteException e) {
435             throw e.rethrowFromSystemServer();
436         }
437         return result;
438     }
439 
440     /**
441      * Requests from the client to share frontend with an existing client.
442      *
443      * <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called
444      * before this request.
445      *
446      * @param selfClientId the id of the client that sends the request.
447      * @param targetClientId the id of the client to share the frontend with.
448      */
shareFrontend(int selfClientId, int targetClientId)449     public void shareFrontend(int selfClientId, int targetClientId) {
450         try {
451             mService.shareFrontend(selfClientId, targetClientId);
452         } catch (RemoteException e) {
453             throw e.rethrowFromSystemServer();
454         }
455     }
456 
457     /**
458      * Transfers the ownership of shared resource.
459      *
460      * <p><strong>Note:</strong> Only the existing frontend sharee can be the new owner.
461      *
462      * @param resourceType the type of the resource to transfer the ownership for.
463      * @param currentOwnerId the id of the current owner client.
464      * @param newOwnerId the id of the new owner client.
465      *
466      * @return true if successful and false otherwise.
467      */
transferOwner(int resourceType, int currentOwnerId, int newOwnerId)468     public boolean transferOwner(int resourceType, int currentOwnerId, int newOwnerId) {
469         try {
470             return mService.transferOwner(resourceType, currentOwnerId, newOwnerId);
471         } catch (RemoteException e) {
472             throw e.rethrowFromSystemServer();
473         }
474     }
475 
476     /**
477      * Requests a Tuner Demux resource.
478      *
479      * <p>There are three possible scenarios:
480      * <ul>
481      * <li>If there is Demux available, the API would send the handle back.
482      *
483      * <li>If no Demux is available but the current request has a higher priority than other uses of
484      * demuxes, the API will send {@link IResourcesReclaimListener#onReclaimResources()} to the
485      * {@link Tuner}. Tuner would handle the resource reclaim on the holder of lower priority and
486      * notify the holder of its resource loss.
487      *
488      * <li>If no Demux system can be granted, the API would return false.
489      * <ul>
490      *
491      * @param request {@link TunerDemuxRequest} information of the current request.
492      * @param demuxHandle a one-element array to return the granted Demux handle.
493      *                    If no Demux granted, this will return {@link #INVALID_RESOURCE_HANDLE}.
494      *
495      * @return true if there is Demux granted.
496      */
requestDemux(@onNull TunerDemuxRequest request, @NonNull int[] demuxHandle)497     public boolean requestDemux(@NonNull TunerDemuxRequest request, @NonNull int[] demuxHandle) {
498         boolean result = false;
499         try {
500             result = mService.requestDemux(request, demuxHandle);
501         } catch (RemoteException e) {
502             throw e.rethrowFromSystemServer();
503         }
504         return result;
505     }
506 
507     /**
508      * Requests a Tuner Descrambler resource.
509      *
510      * <p>There are three possible scenarios:
511      * <ul>
512      * <li>If there is Descrambler available, the API would send the handle back.
513      *
514      * <li>If no Descrambler is available but the current request has a higher priority than other
515      * uses of descramblers, the API will send
516      * {@link IResourcesReclaimListener#onReclaimResources()} to the {@link Tuner}. Tuner would
517      * handle the resource reclaim on the holder of lower priority and notify the holder of its
518      * resource loss.
519      *
520      * <li>If no Descrambler system can be granted, the API would return false.
521      * <ul>
522      *
523      * @param request {@link TunerDescramblerRequest} information of the current request.
524      * @param descramblerHandle a one-element array to return the granted Descrambler handle.
525      *                          If no Descrambler granted, this will return
526      *                          {@link #INVALID_RESOURCE_HANDLE}.
527      *
528      * @return true if there is Descrambler granted.
529      */
requestDescrambler(@onNull TunerDescramblerRequest request, @NonNull int[] descramblerHandle)530     public boolean requestDescrambler(@NonNull TunerDescramblerRequest request,
531                 @NonNull int[] descramblerHandle) {
532         boolean result = false;
533         try {
534             result = mService.requestDescrambler(request, descramblerHandle);
535         } catch (RemoteException e) {
536             throw e.rethrowFromSystemServer();
537         }
538         return result;
539     }
540 
541     /**
542      * Requests a CAS session resource.
543      *
544      * <p>There are three possible scenarios:
545      * <ul>
546      * <li>If there is Cas session available, the API would send the id back.
547      *
548      * <li>If no Cas system is available but the current request info can show higher priority than
549      * other uses of the cas sessions under the requested cas system, the API will send
550      * {@link IResourcesReclaimListener#onReclaimResources()} to the {@link Tuner}. Tuner would
551      * handle the resource reclaim on the holder of lower priority and notify the holder of its
552      * resource loss.
553      *
554      * <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this
555      * request.
556      *
557      * @param request {@link CasSessionRequest} information of the current request.
558      * @param casSessionHandle a one-element array to return the granted cas session handel.
559      *                         If no CAS granted, this will return {@link #INVALID_RESOURCE_HANDLE}.
560      *
561      * @return true if there is CAS session granted.
562      */
requestCasSession(@onNull CasSessionRequest request, @NonNull int[] casSessionHandle)563     public boolean requestCasSession(@NonNull CasSessionRequest request,
564                 @NonNull int[] casSessionHandle) {
565         boolean result = false;
566         try {
567             result = mService.requestCasSession(request, casSessionHandle);
568         } catch (RemoteException e) {
569             throw e.rethrowFromSystemServer();
570         }
571         return result;
572     }
573 
574     /**
575      * Requests a CiCam resource.
576      *
577      * <p>There are three possible scenarios:
578      * <ul>
579      * <li>If there is CiCam available, the API would send the id back.
580      *
581      * <li>If no CiCam is available but the current request info can show higher priority than
582      * other uses of the CiCam, the API will send
583      * {@link IResourcesReclaimListener#onReclaimResources()} to the {@link Tuner}. Tuner would
584      * handle the resource reclaim on the holder of lower priority and notify the holder of its
585      * resource loss.
586      *
587      * <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this
588      * request.
589      *
590      * @param request {@link TunerCiCamRequest} information of the current request.
591      * @param ciCamHandle a one-element array to return the granted ciCam handle.
592      *                    If no ciCam granted, this will return {@link #INVALID_RESOURCE_HANDLE}.
593      *
594      * @return true if there is ciCam granted.
595      */
requestCiCam(TunerCiCamRequest request, int[] ciCamHandle)596     public boolean requestCiCam(TunerCiCamRequest request, int[] ciCamHandle) {
597         boolean result = false;
598         try {
599             result = mService.requestCiCam(request, ciCamHandle);
600         } catch (RemoteException e) {
601             throw e.rethrowFromSystemServer();
602         }
603         return result;
604     }
605 
606     /**
607      * Requests a Tuner Lnb resource.
608      *
609      * <p>There are three possible scenarios:
610      * <ul>
611      * <li>If there is Lnb available, the API would send the id back.
612      *
613      * <li>If no Lnb is available but the current request has a higher priority than other uses of
614      * lnbs, the API will send {@link IResourcesReclaimListener#onReclaimResources()} to the
615      * {@link Tuner}. Tuner would handle the resource reclaim on the holder of lower priority and
616      * notify the holder of its resource loss.
617      *
618      * <li>If no Lnb system can be granted, the API would return false.
619      * <ul>
620      *
621      * <p><strong>Note:</strong> {@link #setLnbInfoList(int[])} must be called before this request.
622      *
623      * @param request {@link TunerLnbRequest} information of the current request.
624      * @param lnbHandle a one-element array to return the granted Lnb handle.
625      *                  If no Lnb granted, this will return {@link #INVALID_RESOURCE_HANDLE}.
626      *
627      * @return true if there is Lnb granted.
628      */
requestLnb(@onNull TunerLnbRequest request, @NonNull int[] lnbHandle)629     public boolean requestLnb(@NonNull TunerLnbRequest request, @NonNull int[] lnbHandle) {
630         boolean result = false;
631         try {
632             result = mService.requestLnb(request, lnbHandle);
633         } catch (RemoteException e) {
634             throw e.rethrowFromSystemServer();
635         }
636         return result;
637     }
638 
639     /**
640      * Notifies the TRM that the given frontend has been released.
641      *
642      * <p>Client must call this whenever it releases a Tuner frontend.
643      *
644      * <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called
645      * before this release.
646      *
647      * @param frontendHandle the handle of the released frontend.
648      * @param clientId the id of the client that is releasing the frontend.
649      */
releaseFrontend(int frontendHandle, int clientId)650     public void releaseFrontend(int frontendHandle, int clientId) {
651         try {
652             mService.releaseFrontend(frontendHandle, clientId);
653         } catch (RemoteException e) {
654             throw e.rethrowFromSystemServer();
655         }
656     }
657 
658     /**
659      * Notifies the TRM that the Demux with the given handle has been released.
660      *
661      * <p>Client must call this whenever it releases an Demux.
662      *
663      * @param demuxHandle the handle of the released Tuner Demux.
664      * @param clientId the id of the client that is releasing the demux.
665      */
releaseDemux(int demuxHandle, int clientId)666     public void releaseDemux(int demuxHandle, int clientId) {
667         try {
668             mService.releaseDemux(demuxHandle, clientId);
669         } catch (RemoteException e) {
670             throw e.rethrowFromSystemServer();
671         }
672     }
673 
674     /**
675      * Notifies the TRM that the Descrambler with the given handle has been released.
676      *
677      * <p>Client must call this whenever it releases an Descrambler.
678      *
679      * @param descramblerHandle the handle of the released Tuner Descrambler.
680      * @param clientId the id of the client that is releasing the descrambler.
681      */
releaseDescrambler(int descramblerHandle, int clientId)682     public void releaseDescrambler(int descramblerHandle, int clientId) {
683         try {
684             mService.releaseDescrambler(descramblerHandle, clientId);
685         } catch (RemoteException e) {
686             throw e.rethrowFromSystemServer();
687         }
688     }
689 
690     /**
691      * Notifies the TRM that the given Cas session has been released.
692      *
693      * <p>Client must call this whenever it releases a Cas session.
694      *
695      * <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this
696      * release.
697      *
698      * @param casSessionHandle the handle of the released CAS session.
699      * @param clientId the id of the client that is releasing the cas session.
700      */
releaseCasSession(int casSessionHandle, int clientId)701     public void releaseCasSession(int casSessionHandle, int clientId) {
702         try {
703             mService.releaseCasSession(casSessionHandle, clientId);
704         } catch (RemoteException e) {
705             throw e.rethrowFromSystemServer();
706         }
707     }
708 
709     /**
710      * Notifies the TRM that the given CiCam has been released.
711      *
712      * <p>Client must call this whenever it releases a CiCam.
713      *
714      * <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this
715      * release.
716      *
717      * @param ciCamHandle the handle of the releasing CiCam.
718      * @param clientId the id of the client that is releasing the CiCam.
719      */
releaseCiCam(int ciCamHandle, int clientId)720     public void releaseCiCam(int ciCamHandle, int clientId) {
721         try {
722             mService.releaseCiCam(ciCamHandle, clientId);
723         } catch (RemoteException e) {
724             throw e.rethrowFromSystemServer();
725         }
726     }
727 
728     /**
729      * Notifies the TRM that the Lnb with the given id has been released.
730      *
731      * <p>Client must call this whenever it releases an Lnb.
732      *
733      * <p><strong>Note:</strong> {@link #setLnbInfoList(int[])} must be called before this release.
734      *
735      * @param lnbHandle the handle of the released Tuner Lnb.
736      * @param clientId the id of the client that is releasing the lnb.
737      */
releaseLnb(int lnbHandle, int clientId)738     public void releaseLnb(int lnbHandle, int clientId) {
739         try {
740             mService.releaseLnb(lnbHandle, clientId);
741         } catch (RemoteException e) {
742             throw e.rethrowFromSystemServer();
743         }
744     }
745 
746     /**
747      * Compare two clients' priority.
748      *
749      * @param challengerProfile the {@link ResourceClientProfile} of the challenger.
750      * @param holderProfile the {@link ResourceClientProfile} of the holder of the resource.
751      *
752      * @return true if the challenger has higher priority than the holder.
753      */
isHigherPriority(ResourceClientProfile challengerProfile, ResourceClientProfile holderProfile)754     public boolean isHigherPriority(ResourceClientProfile challengerProfile,
755             ResourceClientProfile holderProfile) {
756         try {
757             return mService.isHigherPriority(challengerProfile, holderProfile);
758         } catch (RemoteException e) {
759             throw e.rethrowFromSystemServer();
760         }
761     }
762 
763     /**
764      * Returns a priority for the given use case type and the client's foreground or background
765      * status.
766      *
767      * @param useCase the use case type of the client. When the given use case type is invalid,
768      *        the default use case type will be used. {@see TvInputService#PriorityHintUseCaseType}.
769      * @param pid the pid of the client. When the pid is invalid, background status will be used as
770      *        a client's status. Otherwise, client's app corresponding to the given session id will
771      *        be used as a client. {@see TvInputService#onCreateSession(String, String)}.
772      *
773      * @return the client priority..
774      */
getClientPriority(@vInputService.PriorityHintUseCaseType int useCase, int pid)775     public int getClientPriority(@TvInputService.PriorityHintUseCaseType int useCase, int pid) {
776         try {
777             return mService.getClientPriority(useCase, pid);
778         } catch (RemoteException e) {
779             throw e.rethrowFromSystemServer();
780         }
781     }
782 
783     /**
784      * Returns a config priority for the given use case type and the foreground or background
785      * status.
786      *
787      * @param useCase the use case type of the client. When the given use case type is invalid,
788      *        the default use case type will be used. {@see TvInputService#PriorityHintUseCaseType}.
789      * @param isForeground {@code true} if foreground, {@code false} otherwise.
790      *
791      * @return the config priority.
792      *
793      * @hide
794      */
795     @TestApi
796     @SuppressLint("ShowingMemberInHiddenClass")
getConfigPriority(@vInputService.PriorityHintUseCaseType int useCase, boolean isForeground)797     public int getConfigPriority(@TvInputService.PriorityHintUseCaseType int useCase,
798             boolean isForeground) {
799         try {
800             return mService.getConfigPriority(useCase, isForeground);
801         } catch (RemoteException e) {
802             throw e.rethrowFromSystemServer();
803         }
804     }
805 
806     /**
807      * Interface used to receive events from TunerResourceManager.
808      */
809     public abstract static class ResourcesReclaimListener {
810         /*
811          * To reclaim all the resources of the callack owner.
812          */
onReclaimResources()813         public abstract void onReclaimResources();
814     }
815 }
816