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