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 current TRM of the TunerHAL Demux information. 293 * 294 * <p><strong>Note:</strong> This update must happen before the first 295 * {@link #requestDemux(TunerDemuxRequest, int[])} and 296 * {@link #releaseDemux(int, int)} call. 297 * 298 * @param infos an array of the available {@link TunerDemuxInfo} information. 299 */ setDemuxInfoList(@onNull TunerDemuxInfo[] infos)300 public void setDemuxInfoList(@NonNull TunerDemuxInfo[] infos) { 301 try { 302 mService.setDemuxInfoList(infos); 303 } catch (RemoteException e) { 304 throw e.rethrowFromSystemServer(); 305 } 306 } 307 308 /** 309 * Updates the TRM of the current CAS information. 310 * 311 * <p><strong>Note:</strong> This update must happen before the first 312 * {@link #requestCasSession(CasSessionRequest, int[])} and {@link #releaseCasSession(int, int)} 313 * call. 314 * 315 * @param casSystemId id of the updating CAS system. 316 * @param maxSessionNum the max session number of the CAS system that is updated. 317 */ updateCasInfo(int casSystemId, int maxSessionNum)318 public void updateCasInfo(int casSystemId, int maxSessionNum) { 319 try { 320 mService.updateCasInfo(casSystemId, maxSessionNum); 321 } catch (RemoteException e) { 322 throw e.rethrowFromSystemServer(); 323 } 324 } 325 326 /** 327 * Updates the TRM of the current Lnb information. 328 * 329 * <p><strong>Note:</strong> This update must happen before the first 330 * {@link #requestLnb(TunerLnbRequest, int[])} and {@link #releaseLnb(int, int)} call. 331 * 332 * @param lnbIds ids of the updating lnbs. 333 */ setLnbInfoList(int[] lnbIds)334 public void setLnbInfoList(int[] lnbIds) { 335 try { 336 mService.setLnbInfoList(lnbIds); 337 } catch (RemoteException e) { 338 throw e.rethrowFromSystemServer(); 339 } 340 } 341 342 /** 343 * Grants the lock to the caller for public {@link Tuner} APIs 344 * 345 * <p>{@link Tuner} functions that call both [@link TunerResourceManager} APIs and 346 * grabs lock that are also used in {@link IResourcesReclaimListener#onReclaimResources()} 347 * must call this API before acquiring lock used in onReclaimResources(). 348 * 349 * <p>This API will block until it releases the lock or fails 350 * 351 * @param clientId The ID of the caller. 352 * 353 * @return true if the lock is granted. If false is returned, calling this API again is not 354 * guaranteed to work and may be unrecoverrable. (This should not happen.) 355 */ acquireLock(int clientId)356 public boolean acquireLock(int clientId) { 357 try { 358 return mService.acquireLock(clientId, Thread.currentThread().getId()); 359 } catch (RemoteException e) { 360 throw e.rethrowFromSystemServer(); 361 } 362 } 363 364 /** 365 * Releases the lock to the caller for public {@link Tuner} APIs 366 * 367 * <p>This API must be called in pair with {@link #acquireLock(int, int)} 368 * 369 * <p>This API will block until it releases the lock or fails 370 * 371 * @param clientId The ID of the caller. 372 * 373 * @return true if the lock is granted. If false is returned, calling this API again is not 374 * guaranteed to work and may be unrecoverrable. (This should not happen.) 375 */ releaseLock(int clientId)376 public boolean releaseLock(int clientId) { 377 try { 378 return mService.releaseLock(clientId); 379 } catch (RemoteException e) { 380 throw e.rethrowFromSystemServer(); 381 } 382 } 383 384 /** 385 * Requests a frontend resource. 386 * 387 * <p>There are three possible scenarios: 388 * <ul> 389 * <li>If there is frontend available, the API would send the id back. 390 * 391 * <li>If no Frontend is available but the current request info can show higher priority than 392 * other uses of Frontend, the API will send 393 * {@link IResourcesReclaimListener#onReclaimResources()} to the {@link Tuner}. Tuner would 394 * handle the resource reclaim on the holder of lower priority and notify the holder of its 395 * resource loss. 396 * 397 * <li>If no frontend can be granted, the API would return false. 398 * <ul> 399 * 400 * <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called 401 * before this request. 402 * 403 * @param request {@link TunerFrontendRequest} information of the current request. 404 * @param frontendHandle a one-element array to return the granted frontendHandle. If 405 * no frontend granted, this will return {@link #INVALID_RESOURCE_HANDLE}. 406 * 407 * @return true if there is frontend granted. 408 */ requestFrontend(@onNull TunerFrontendRequest request, @Nullable int[] frontendHandle)409 public boolean requestFrontend(@NonNull TunerFrontendRequest request, 410 @Nullable int[] frontendHandle) { 411 boolean result = false; 412 try { 413 result = mService.requestFrontend(request, frontendHandle); 414 } catch (RemoteException e) { 415 throw e.rethrowFromSystemServer(); 416 } 417 return result; 418 } 419 420 /** 421 * Sets the maximum usable frontends number of a given frontend type. It is used to enable or 422 * disable frontends when cable connection status is changed by user. 423 * 424 * @param frontendType the frontendType which the maximum usable number will be set for. 425 * @param maxNum the new maximum usable number. 426 * 427 * @return true if successful and false otherwise. 428 */ setMaxNumberOfFrontends(int frontendType, int maxNum)429 public boolean setMaxNumberOfFrontends(int frontendType, int maxNum) { 430 boolean result = false; 431 try { 432 result = mService.setMaxNumberOfFrontends(frontendType, maxNum); 433 } catch (RemoteException e) { 434 throw e.rethrowFromSystemServer(); 435 } 436 return result; 437 } 438 439 /** 440 * Get the maximum usable frontends number of a given frontend type. 441 * 442 * @param frontendType the frontendType which the maximum usable number will be queried for. 443 * 444 * @return the maximum usable number of the queried frontend type. Returns -1 when the 445 * frontendType is invalid 446 */ getMaxNumberOfFrontends(int frontendType)447 public int getMaxNumberOfFrontends(int frontendType) { 448 int result = -1; 449 try { 450 result = mService.getMaxNumberOfFrontends(frontendType); 451 } catch (RemoteException e) { 452 throw e.rethrowFromSystemServer(); 453 } 454 return result; 455 } 456 457 /** 458 * Requests from the client to share frontend with an existing client. 459 * 460 * <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called 461 * before this request. 462 * 463 * @param selfClientId the id of the client that sends the request. 464 * @param targetClientId the id of the client to share the frontend with. 465 */ shareFrontend(int selfClientId, int targetClientId)466 public void shareFrontend(int selfClientId, int targetClientId) { 467 try { 468 mService.shareFrontend(selfClientId, targetClientId); 469 } catch (RemoteException e) { 470 throw e.rethrowFromSystemServer(); 471 } 472 } 473 474 /** 475 * Transfers the ownership of shared resource. 476 * 477 * <p><strong>Note:</strong> Only the existing frontend sharee can be the new owner. 478 * 479 * @param resourceType the type of the resource to transfer the ownership for. 480 * @param currentOwnerId the id of the current owner client. 481 * @param newOwnerId the id of the new owner client. 482 * 483 * @return true if successful and false otherwise. 484 */ transferOwner(int resourceType, int currentOwnerId, int newOwnerId)485 public boolean transferOwner(int resourceType, int currentOwnerId, int newOwnerId) { 486 try { 487 return mService.transferOwner(resourceType, currentOwnerId, newOwnerId); 488 } catch (RemoteException e) { 489 throw e.rethrowFromSystemServer(); 490 } 491 } 492 493 /** 494 * Requests a Tuner Demux resource. 495 * 496 * <p>There are three possible scenarios: 497 * <ul> 498 * <li>If there is Demux available, the API would send the handle back. 499 * 500 * <li>If no Demux is available but the current request has a higher priority than other uses of 501 * demuxes, the API will send {@link IResourcesReclaimListener#onReclaimResources()} to the 502 * {@link Tuner}. Tuner would handle the resource reclaim on the holder of lower priority and 503 * notify the holder of its resource loss. 504 * 505 * <li>If no Demux system can be granted, the API would return false. 506 * <ul> 507 * 508 * @param request {@link TunerDemuxRequest} information of the current request. 509 * @param demuxHandle a one-element array to return the granted Demux handle. 510 * If no Demux granted, this will return {@link #INVALID_RESOURCE_HANDLE}. 511 * 512 * @return true if there is Demux granted. 513 */ requestDemux(@onNull TunerDemuxRequest request, @NonNull int[] demuxHandle)514 public boolean requestDemux(@NonNull TunerDemuxRequest request, @NonNull int[] demuxHandle) { 515 boolean result = false; 516 try { 517 result = mService.requestDemux(request, demuxHandle); 518 } catch (RemoteException e) { 519 throw e.rethrowFromSystemServer(); 520 } 521 return result; 522 } 523 524 /** 525 * Requests a Tuner Descrambler resource. 526 * 527 * <p>There are three possible scenarios: 528 * <ul> 529 * <li>If there is Descrambler available, the API would send the handle back. 530 * 531 * <li>If no Descrambler is available but the current request has a higher priority than other 532 * uses of descramblers, the API will send 533 * {@link IResourcesReclaimListener#onReclaimResources()} to the {@link Tuner}. Tuner would 534 * handle the resource reclaim on the holder of lower priority and notify the holder of its 535 * resource loss. 536 * 537 * <li>If no Descrambler system can be granted, the API would return false. 538 * <ul> 539 * 540 * @param request {@link TunerDescramblerRequest} information of the current request. 541 * @param descramblerHandle a one-element array to return the granted Descrambler handle. 542 * If no Descrambler granted, this will return 543 * {@link #INVALID_RESOURCE_HANDLE}. 544 * 545 * @return true if there is Descrambler granted. 546 */ requestDescrambler(@onNull TunerDescramblerRequest request, @NonNull int[] descramblerHandle)547 public boolean requestDescrambler(@NonNull TunerDescramblerRequest request, 548 @NonNull int[] descramblerHandle) { 549 boolean result = false; 550 try { 551 result = mService.requestDescrambler(request, descramblerHandle); 552 } catch (RemoteException e) { 553 throw e.rethrowFromSystemServer(); 554 } 555 return result; 556 } 557 558 /** 559 * Requests a CAS session resource. 560 * 561 * <p>There are three possible scenarios: 562 * <ul> 563 * <li>If there is Cas session available, the API would send the id back. 564 * 565 * <li>If no Cas system is available but the current request info can show higher priority than 566 * other uses of the cas sessions under the requested cas system, the API will send 567 * {@link IResourcesReclaimListener#onReclaimResources()} to the {@link Tuner}. Tuner would 568 * handle the resource reclaim on the holder of lower priority and notify the holder of its 569 * resource loss. 570 * 571 * <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this 572 * request. 573 * 574 * @param request {@link CasSessionRequest} information of the current request. 575 * @param casSessionHandle a one-element array to return the granted cas session handel. 576 * If no CAS granted, this will return {@link #INVALID_RESOURCE_HANDLE}. 577 * 578 * @return true if there is CAS session granted. 579 */ requestCasSession(@onNull CasSessionRequest request, @NonNull int[] casSessionHandle)580 public boolean requestCasSession(@NonNull CasSessionRequest request, 581 @NonNull int[] casSessionHandle) { 582 boolean result = false; 583 try { 584 result = mService.requestCasSession(request, casSessionHandle); 585 } catch (RemoteException e) { 586 throw e.rethrowFromSystemServer(); 587 } 588 return result; 589 } 590 591 /** 592 * Requests a CiCam resource. 593 * 594 * <p>There are three possible scenarios: 595 * <ul> 596 * <li>If there is CiCam available, the API would send the id back. 597 * 598 * <li>If no CiCam is available but the current request info can show higher priority than 599 * other uses of the CiCam, the API will send 600 * {@link IResourcesReclaimListener#onReclaimResources()} to the {@link Tuner}. Tuner would 601 * handle the resource reclaim on the holder of lower priority and notify the holder of its 602 * resource loss. 603 * 604 * <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this 605 * request. 606 * 607 * @param request {@link TunerCiCamRequest} information of the current request. 608 * @param ciCamHandle a one-element array to return the granted ciCam handle. 609 * If no ciCam granted, this will return {@link #INVALID_RESOURCE_HANDLE}. 610 * 611 * @return true if there is ciCam granted. 612 */ requestCiCam(TunerCiCamRequest request, int[] ciCamHandle)613 public boolean requestCiCam(TunerCiCamRequest request, int[] ciCamHandle) { 614 boolean result = false; 615 try { 616 result = mService.requestCiCam(request, ciCamHandle); 617 } catch (RemoteException e) { 618 throw e.rethrowFromSystemServer(); 619 } 620 return result; 621 } 622 623 /** 624 * Requests a Tuner Lnb resource. 625 * 626 * <p>There are three possible scenarios: 627 * <ul> 628 * <li>If there is Lnb available, the API would send the id back. 629 * 630 * <li>If no Lnb is available but the current request has a higher priority than other uses of 631 * lnbs, the API will send {@link IResourcesReclaimListener#onReclaimResources()} to the 632 * {@link Tuner}. Tuner would handle the resource reclaim on the holder of lower priority and 633 * notify the holder of its resource loss. 634 * 635 * <li>If no Lnb system can be granted, the API would return false. 636 * <ul> 637 * 638 * <p><strong>Note:</strong> {@link #setLnbInfoList(int[])} must be called before this request. 639 * 640 * @param request {@link TunerLnbRequest} information of the current request. 641 * @param lnbHandle a one-element array to return the granted Lnb handle. 642 * If no Lnb granted, this will return {@link #INVALID_RESOURCE_HANDLE}. 643 * 644 * @return true if there is Lnb granted. 645 */ requestLnb(@onNull TunerLnbRequest request, @NonNull int[] lnbHandle)646 public boolean requestLnb(@NonNull TunerLnbRequest request, @NonNull int[] lnbHandle) { 647 boolean result = false; 648 try { 649 result = mService.requestLnb(request, lnbHandle); 650 } catch (RemoteException e) { 651 throw e.rethrowFromSystemServer(); 652 } 653 return result; 654 } 655 656 /** 657 * Notifies the TRM that the given frontend has been released. 658 * 659 * <p>Client must call this whenever it releases a Tuner frontend. 660 * 661 * <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called 662 * before this release. 663 * 664 * @param frontendHandle the handle of the released frontend. 665 * @param clientId the id of the client that is releasing the frontend. 666 */ releaseFrontend(int frontendHandle, int clientId)667 public void releaseFrontend(int frontendHandle, int clientId) { 668 try { 669 mService.releaseFrontend(frontendHandle, clientId); 670 } catch (RemoteException e) { 671 throw e.rethrowFromSystemServer(); 672 } 673 } 674 675 /** 676 * Notifies the TRM that the Demux with the given handle has been released. 677 * 678 * <p>Client must call this whenever it releases an Demux. 679 * 680 * @param demuxHandle the handle of the released Tuner Demux. 681 * @param clientId the id of the client that is releasing the demux. 682 */ releaseDemux(int demuxHandle, int clientId)683 public void releaseDemux(int demuxHandle, int clientId) { 684 try { 685 mService.releaseDemux(demuxHandle, clientId); 686 } catch (RemoteException e) { 687 throw e.rethrowFromSystemServer(); 688 } 689 } 690 691 /** 692 * Notifies the TRM that the Descrambler with the given handle has been released. 693 * 694 * <p>Client must call this whenever it releases an Descrambler. 695 * 696 * @param descramblerHandle the handle of the released Tuner Descrambler. 697 * @param clientId the id of the client that is releasing the descrambler. 698 */ releaseDescrambler(int descramblerHandle, int clientId)699 public void releaseDescrambler(int descramblerHandle, int clientId) { 700 try { 701 mService.releaseDescrambler(descramblerHandle, clientId); 702 } catch (RemoteException e) { 703 throw e.rethrowFromSystemServer(); 704 } 705 } 706 707 /** 708 * Notifies the TRM that the given Cas session has been released. 709 * 710 * <p>Client must call this whenever it releases a Cas session. 711 * 712 * <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this 713 * release. 714 * 715 * @param casSessionHandle the handle of the released CAS session. 716 * @param clientId the id of the client that is releasing the cas session. 717 */ releaseCasSession(int casSessionHandle, int clientId)718 public void releaseCasSession(int casSessionHandle, int clientId) { 719 try { 720 mService.releaseCasSession(casSessionHandle, clientId); 721 } catch (RemoteException e) { 722 throw e.rethrowFromSystemServer(); 723 } 724 } 725 726 /** 727 * Notifies the TRM that the given CiCam has been released. 728 * 729 * <p>Client must call this whenever it releases a CiCam. 730 * 731 * <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this 732 * release. 733 * 734 * @param ciCamHandle the handle of the releasing CiCam. 735 * @param clientId the id of the client that is releasing the CiCam. 736 */ releaseCiCam(int ciCamHandle, int clientId)737 public void releaseCiCam(int ciCamHandle, int clientId) { 738 try { 739 mService.releaseCiCam(ciCamHandle, clientId); 740 } catch (RemoteException e) { 741 throw e.rethrowFromSystemServer(); 742 } 743 } 744 745 /** 746 * Notifies the TRM that the Lnb with the given id has been released. 747 * 748 * <p>Client must call this whenever it releases an Lnb. 749 * 750 * <p><strong>Note:</strong> {@link #setLnbInfoList(int[])} must be called before this release. 751 * 752 * @param lnbHandle the handle of the released Tuner Lnb. 753 * @param clientId the id of the client that is releasing the lnb. 754 */ releaseLnb(int lnbHandle, int clientId)755 public void releaseLnb(int lnbHandle, int clientId) { 756 try { 757 mService.releaseLnb(lnbHandle, clientId); 758 } catch (RemoteException e) { 759 throw e.rethrowFromSystemServer(); 760 } 761 } 762 763 /** 764 * Compare two clients' priority. 765 * 766 * @param challengerProfile the {@link ResourceClientProfile} of the challenger. 767 * @param holderProfile the {@link ResourceClientProfile} of the holder of the resource. 768 * 769 * @return true if the challenger has higher priority than the holder. 770 */ isHigherPriority(ResourceClientProfile challengerProfile, ResourceClientProfile holderProfile)771 public boolean isHigherPriority(ResourceClientProfile challengerProfile, 772 ResourceClientProfile holderProfile) { 773 try { 774 return mService.isHigherPriority(challengerProfile, holderProfile); 775 } catch (RemoteException e) { 776 throw e.rethrowFromSystemServer(); 777 } 778 } 779 780 /** 781 * Returns a priority for the given use case type and the client's foreground or background 782 * status. 783 * 784 * @param useCase the use case type of the client. When the given use case type is invalid, 785 * the default use case type will be used. {@see TvInputService#PriorityHintUseCaseType}. 786 * @param pid the pid of the client. When the pid is invalid, background status will be used as 787 * a client's status. Otherwise, client's app corresponding to the given session id will 788 * be used as a client. {@see TvInputService#onCreateSession(String, String)}. 789 * 790 * @return the client priority.. 791 */ getClientPriority(@vInputService.PriorityHintUseCaseType int useCase, int pid)792 public int getClientPriority(@TvInputService.PriorityHintUseCaseType int useCase, int pid) { 793 try { 794 return mService.getClientPriority(useCase, pid); 795 } catch (RemoteException e) { 796 throw e.rethrowFromSystemServer(); 797 } 798 } 799 800 /** 801 * Returns a config priority for the given use case type and the foreground or background 802 * status. 803 * 804 * @param useCase the use case type of the client. When the given use case type is invalid, 805 * the default use case type will be used. {@see TvInputService#PriorityHintUseCaseType}. 806 * @param isForeground {@code true} if foreground, {@code false} otherwise. 807 * 808 * @return the config priority. 809 * 810 * @hide 811 */ 812 @TestApi 813 @SuppressLint("ShowingMemberInHiddenClass") getConfigPriority(@vInputService.PriorityHintUseCaseType int useCase, boolean isForeground)814 public int getConfigPriority(@TvInputService.PriorityHintUseCaseType int useCase, 815 boolean isForeground) { 816 try { 817 return mService.getConfigPriority(useCase, isForeground); 818 } catch (RemoteException e) { 819 throw e.rethrowFromSystemServer(); 820 } 821 } 822 823 /** 824 * Interface used to receive events from TunerResourceManager. 825 */ 826 public abstract static class ResourcesReclaimListener { 827 /* 828 * To reclaim all the resources of the callack owner. 829 */ onReclaimResources()830 public abstract void onReclaimResources(); 831 } 832 } 833