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