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.media.tv.tunerresourcemanager.CasSessionRequest;
20 import android.media.tv.tunerresourcemanager.IResourcesReclaimListener;
21 import android.media.tv.tunerresourcemanager.ResourceClientProfile;
22 import android.media.tv.tunerresourcemanager.TunerCiCamRequest;
23 import android.media.tv.tunerresourcemanager.TunerDemuxInfo;
24 import android.media.tv.tunerresourcemanager.TunerDemuxRequest;
25 import android.media.tv.tunerresourcemanager.TunerDescramblerRequest;
26 import android.media.tv.tunerresourcemanager.TunerFrontendInfo;
27 import android.media.tv.tunerresourcemanager.TunerFrontendRequest;
28 import android.media.tv.tunerresourcemanager.TunerLnbRequest;
29 
30 /**
31  * Interface of the Tuner Resource Manager. It manages resources used by TV Tuners.
32  * <p>Resources include:
33  * <ul>
34  * <li>TunerFrontend {@link android.media.tv.tuner.frontend}.
35  * <li>TunerLnb {@link android.media.tv.tuner.Lnb}.
36  * <li>MediaCas {@link android.media.MediaCas}.
37  * <li>TvInputHardware {@link android.media.tv.TvInputHardwareInfo}.
38  * <ul>
39  *
40  * <p>Expected workflow is:
41  * <ul>
42  * <li>Tuner Java/MediaCas/TIF update resources of the current device with TRM.
43  * <li>Client registers its profile through {@link #registerClientProfile(ResourceClientProfile,
44  * IResourcesReclaimListener, int[])}.
45  * <li>Client requests resources through request APIs.
46  * <li>If the resource needs to be handed to a higher priority client from a lower priority
47  * one, TRM calls IResourcesReclaimListener registered by the lower priority client to release
48  * the resource.
49  * <ul>
50  *
51  * @hide
52  */
53 interface ITunerResourceManager {
54     /*
55      * This API is used by the client to register their profile with the Tuner Resource manager.
56      *
57      * <p>The profile contains information that can show the base priority score of the client.
58      *
59      * @param profile {@link ResourceClientProfile} profile of the current client
60      * @param listener {@link IResourcesReclaimListener} a callback to
61      *                 reclaim clients' resources when needed.
62      * @param clientId returns a clientId from the resource manager when the
63      *                 the client registers its profile.
64      */
registerClientProfile(in ResourceClientProfile profile, IResourcesReclaimListener listener, out int[] clientId)65     void registerClientProfile(in ResourceClientProfile profile,
66         IResourcesReclaimListener listener, out int[] clientId);
67 
68     /*
69      * This API is used by the client to unregister their profile with the Tuner Resource manager.
70      *
71      * @param clientId the client id that needs to be unregistered.
72      */
unregisterClientProfile(in int clientId)73     void unregisterClientProfile(in int clientId);
74 
75     /*
76      * Updates a registered client's priority and niceValue.
77      *
78      * @param clientId the id of the client that is updating its profile.
79      * @param priority the priority that the client would like to update to.
80      * @param niceValue the nice value that the client would like to update to.
81      *
82      * @return true if the update is successful.
83      */
updateClientPriority(in int clientId, in int priority, in int niceValue)84     boolean updateClientPriority(in int clientId, in int priority, in int niceValue);
85 
86     /*
87      * Checks if there is any unused frontend resource of the specified type.
88      *
89      * @param frontendType the specific type of frontend resource to be checked for.
90      *
91      * @return true if there is any unused resource of the specified type.
92      */
hasUnusedFrontend(in int frontendType)93     boolean hasUnusedFrontend(in int frontendType);
94 
95     /*
96      * Checks if the client has the lowest priority among the clients that are holding
97      * the frontend resource of the specified type.
98      *
99      * <p> When this function returns false, it means that there is at least one client with the
100      * strictly lower priority (than clientId) that is reclaimable by the system.
101      *
102      * @param clientId The client ID to be checked the priority for.
103      * @param frontendType The specific frontend type to be checked for.
104      *
105      * @return false if there is another client holding the frontend resource of the specified type
106      * that can be reclaimed. Otherwise true.
107      */
isLowestPriority(in int clientId, in int frontendType)108     boolean isLowestPriority(in int clientId, in int frontendType);
109 
110     /*
111      * Updates the available Frontend resources information on the current device.
112      *
113      * <p><strong>Note:</strong> This update must happen before the first
114      * {@link #requestFrontend(TunerFrontendRequest,int[])} and {@link #releaseFrontend(int, int)}
115      * call.
116      *
117      * @param infos an array of the available {@link TunerFrontendInfo} information.
118      */
setFrontendInfoList(in TunerFrontendInfo[] infos)119     void setFrontendInfoList(in TunerFrontendInfo[] infos);
120 
121     /*
122      * Updates the available Cas resource information on the current device.
123      *
124      * <p><strong>Note:</strong> This update must happen before the first
125      * {@link #requestCasSession(CasSessionRequest, int[])} and {@link #releaseCasSession(int, int)}
126      * call.
127      *
128      * @param casSystemId id of the updating CAS system.
129      * @param maxSessionNum the max session number of the CAS system that is updated.
130      */
updateCasInfo(in int casSystemId, in int maxSessionNum)131     void updateCasInfo(in int casSystemId, in int maxSessionNum);
132 
133     /*
134      * Updates the available Demux resources information on the current device.
135      *
136      * <p><strong>Note:</strong> This update must happen before the first
137      * {@link #requestDemux(TunerDemux,int[])} and {@link #releaseDemux(int, int)}
138      * call.
139      *
140      * @param infos an array of the available {@link TunerDemux} information.
141      */
setDemuxInfoList(in TunerDemuxInfo[] infos)142     void setDemuxInfoList(in TunerDemuxInfo[] infos);
143 
144     /*
145      * Updates the available Lnb resource information on the current device.
146      *
147      * <p><strong>Note:</strong> This update must happen before the first
148      * {@link #requestLnb(TunerLnbRequest, int[])} and {@link #releaseLnb(int, int)} call.
149      *
150      * @param lnbIds ids of the updating lnbs.
151      */
setLnbInfoList(in int[] lnbIds)152     void setLnbInfoList(in int[] lnbIds);
153 
154     /*
155      * This API is used by the Tuner framework to request a frontend from the TunerHAL.
156      *
157      * <p>There are two cases:
158      * <ul>
159      * <li>If the desiredId is not {@link TunerFrontendRequest#DEFAULT_DESIRED_ID}
160      * <li><li>If the desired frontend with the given frontendType is available, the API would send
161      * the id back.
162      * <li><li>If the desired frontend with the given frontendType is in use but the current request
163      * info can show higher priority than other uses of Frontend, the API will send
164      * {@link IResourcesReclaimListener#onReclaimResources()} to the {@link Tuner}. Tuner would
165      * handle the resource reclaim on the holder of lower priority and notify the holder of its
166      * resource loss.
167      * <li><li>If no frontend can be granted, the API would return false.
168      * <ul>
169      *
170      * <li>If the desiredId is {@link TunerFrontendRequest#DEFAULT_DESIRED_ID}
171      * <li><li>If there is frontend available, the API would send the id back.
172      * <li><li>If no Frontend is available but the current request info can show higher priority
173      * than other uses of Frontend, the API will send
174      * {@link IResourcesReclaimListener#onReclaimResources()} to the {@link Tuner}. Tuner would
175      * handle the resource reclaim on the holder of lower priority and notify the holder of its
176      * resource loss.
177      * <li><li>If no frontend can be granted, the API would return false.
178      * <ul>
179      *
180      * <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called
181      * before this request.
182      *
183      * @param request {@link TunerFrontendRequest} information of the current request.
184      * @param frontendHandle a one-element array to return the granted frontendHandle.
185      *
186      * @return true if there is frontend granted.
187      */
requestFrontend(in TunerFrontendRequest request, out int[] frontendHandle)188     boolean requestFrontend(in TunerFrontendRequest request, out int[] frontendHandle);
189 
190     /*
191      * Sets the maximum usable frontends number of a given frontend type. It is used to enable or
192      * disable frontends when cable connection status is changed by user.
193      *
194      * @param frontendType the frontendType which the maximum usable number will be set for.
195      * @param maxNumber the new maximum usable number.
196      *
197      * @return true if  successful and false otherwise.
198      */
setMaxNumberOfFrontends(in int frontendType, in int maxNum)199     boolean setMaxNumberOfFrontends(in int frontendType, in int maxNum);
200 
201     /*
202      * Get the maximum usable frontends number of a given frontend type.
203      *
204      * @param frontendType the frontendType which the maximum usable number will be queried for.
205      *
206      * @return the maximum usable number of the queried frontend type. Returns -1 when the
207      *         frontendType is invalid
208      */
getMaxNumberOfFrontends(in int frontendType)209     int getMaxNumberOfFrontends(in int frontendType);
210 
211     /*
212      * Requests to share frontend with an existing client.
213      *
214      * <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called
215      * before this request.
216      *
217      * @param selfClientId the id of the client that sends the request.
218      * @param targetClientId the id of the client to share the frontend with.
219      */
shareFrontend(in int selfClientId, in int targetClientId)220     void shareFrontend(in int selfClientId, in int targetClientId);
221 
222     /*
223      * Transfers the ownership of the shared resource.
224      *
225      * <p><strong>Note:</strong> Only the existing frontend sharee can be the new owner.
226      *
227      * @param resourceType the type of resource to transfer the ownership for.
228      * @param currentOwnerId the id of the current owner client.
229      * @param newOwnerId the id of the new owner client.
230      *
231      * @return true if successful. false otherwise.
232      */
transferOwner(in int resourceType, in int currentOwnerId, in int newOwnerId)233     boolean transferOwner(in int resourceType, in int currentOwnerId, in int newOwnerId);
234 
235     /*
236      * This API is used by the Tuner framework to request an available demux from the TunerHAL.
237      *
238      * <p>There are three possible scenarios:
239      * <ul>
240      * <li>If there is demux available, the API would send the handle back.
241      *
242      * <li>If no Demux is available but the current request info can show higher priority than
243      * other uses of demuxes, the API will send
244      * {@link IResourcesReclaimListener#onReclaimResources()} to the {@link Tuner}. Tuner would
245      * handle the resource reclaim on the holder of lower priority and notify the holder of its
246      * resource loss.
247      *
248      * <li>If no demux can be granted, the API would return false.
249      * <ul>
250      *
251      * @param request {@link TunerDemuxRequest} information of the current request.
252      * @param demuxHandle a one-element array to return the granted demux handle.
253      *
254      * @return true if there is demux granted.
255      */
requestDemux(in TunerDemuxRequest request, out int[] demuxHandle)256     boolean requestDemux(in TunerDemuxRequest request, out int[] demuxHandle);
257 
258     /*
259      * This API is used by the Tuner framework to request an available descrambler from the
260      * TunerHAL.
261      *
262      * <p>There are three possible scenarios:
263      * <ul>
264      * <li>If there is descrambler available, the API would send the handle back.
265      *
266      * <li>If no Descrambler is available but the current request info can show higher priority than
267      * other uses of Descrambler, the API will send
268      * {@link IResourcesReclaimListener#onReclaimResources()} to the {@link Tuner}. Tuner would
269      * handle the resource reclaim on the holder of lower priority and notify the holder of its
270      * resource loss.
271      *
272      * <li>If no Descrambler can be granted, the API would return false.
273      * <ul>
274      *
275      * @param request {@link TunerDescramblerRequest} information of the current request.
276      * @param descramblerHandle a one-element array to return the granted descrambler handle.
277      *
278      * @return true if there is Descrambler granted.
279      */
requestDescrambler(in TunerDescramblerRequest request, out int[] descramblerHandle)280     boolean requestDescrambler(in TunerDescramblerRequest request, out int[] descramblerHandle);
281 
282     /*
283      * This API is used by the Tuner framework to request an available Cas session. This session
284      * needs to be under the CAS system with the id indicated in the {@code request}.
285      *
286      * <p>There are three possible scenarios:
287      * <ul>
288      * <li>If there is Cas session available, the API would send the id back.
289      *
290      * <li>If no Cas session is available but the current request info can show higher priority than
291      * other uses of the sessions under the requested CAS system, the API will send
292      * {@link ITunerResourceManagerCallback#onReclaimResources()} to the {@link Tuner}. Tuner would
293      * handle the resource reclaim on the holder of lower priority and notify the holder of its
294      * resource loss.
295      *
296      * <li>If no Cas session can be granted, the API would return false.
297      * <ul>
298      *
299      * <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this request.
300      *
301      * @param request {@link CasSessionRequest} information of the current request.
302      * @param casSessionHandle a one-element array to return the granted cas session handle.
303      *
304      * @return true if there is CAS session granted.
305      */
requestCasSession(in CasSessionRequest request, out int[] casSessionHandle)306     boolean requestCasSession(in CasSessionRequest request, out int[] casSessionHandle);
307 
308     /*
309      * This API is used by the Tuner framework to request an available CuCam.
310      *
311      * <p>There are three possible scenarios:
312      * <ul>
313      * <li>If there is CiCam available, the API would send the handle back.
314      *
315      * <li>If no CiCma is available but the current request info can show higher priority than
316      * other uses of the ciCam, the API will send
317      * {@link ITunerResourceManagerCallback#onReclaimResources()} to the {@link Tuner}. Tuner would
318      * handle the resource reclaim on the holder of lower priority and notify the holder of its
319      * resource loss.
320      *
321      * <li>If no CiCam can be granted, the API would return false.
322      * <ul>
323      *
324      * <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this request.
325      *
326      * @param request {@link TunerCiCamRequest} information of the current request.
327      * @param ciCamHandle a one-element array to return the granted ciCam handle.
328      *
329      * @return true if there is CiCam granted.
330      */
requestCiCam(in TunerCiCamRequest request, out int[] ciCamHandle)331     boolean requestCiCam(in TunerCiCamRequest request, out int[] ciCamHandle);
332 
333     /*
334      * This API is used by the Tuner framework to request an available Lnb from the TunerHAL.
335      *
336      * <p>There are three possible scenarios:
337      * <ul>
338      * <li>If there is Lnb available, the API would send the id back.
339      *
340      * <li>If no Lnb is available but the current request has a higher priority than other uses of
341      * lnbs, the API will send {@link ITunerResourceManagerCallback#onReclaimResources()} to the
342      * {@link Tuner}. Tuner would handle the resource reclaim on the holder of lower priority and
343      * notify the holder of its resource loss.
344      *
345      * <li>If no Lnb system can be granted, the API would return false.
346      * <ul>
347      *
348      * <p><strong>Note:</strong> {@link #setLnbInfos(int[])} must be called before this request.
349      *
350      * @param request {@link TunerLnbRequest} information of the current request.
351      * @param lnbHandle a one-element array to return the granted Lnb handle.
352      *
353      * @return true if there is Lnb granted.
354      */
requestLnb(in TunerLnbRequest request, out int[] lnbHandle)355     boolean requestLnb(in TunerLnbRequest request, out int[] lnbHandle);
356 
357     /*
358      * Notifies the TRM that the given frontend has been released.
359      *
360      * <p>Client must call this whenever it releases a Tuner frontend.
361      *
362      * <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called
363      * before this release.
364      *
365      * @param frontendHandle the handle of the released frontend.
366      * @param clientId the id of the client that is releasing the frontend.
367      */
releaseFrontend(in int frontendHandle, int clientId)368     void releaseFrontend(in int frontendHandle, int clientId);
369 
370     /*
371      * Notifies the TRM that the Demux with the given handle was released.
372      *
373      * <p>Client must call this whenever it releases a demux.
374      *
375      * @param demuxHandle the handle of the released Tuner Demux.
376      * @param clientId the id of the client that is releasing the demux.
377      */
releaseDemux(in int demuxHandle, int clientId)378     void releaseDemux(in int demuxHandle, int clientId);
379 
380     /*
381      * Notifies the TRM that the Descrambler with the given handle was released.
382      *
383      * <p>Client must call this whenever it releases a descrambler.
384      *
385      * @param descramblerHandle the handle of the released Tuner Descrambler.
386      * @param clientId the id of the client that is releasing the descrambler.
387      */
releaseDescrambler(in int descramblerHandle, int clientId)388     void releaseDescrambler(in int descramblerHandle, int clientId);
389 
390     /*
391      * Notifies the TRM that the given Cas session has been released.
392      *
393      * <p>Client must call this whenever it releases a Cas session.
394      *
395      * <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this release.
396      *
397      * @param casSessionHandle the handle of the released CAS session.
398      * @param clientId the id of the client that is releasing the cas session.
399      */
releaseCasSession(in int casSessionHandle, int clientId)400     void releaseCasSession(in int casSessionHandle, int clientId);
401 
402     /**
403      * Notifies the TRM that the given CiCam has been released.
404      *
405      * <p>Client must call this whenever it releases a CiCam.
406      *
407      * <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this
408      * release.
409      *
410      * @param ciCamHandle the handle of the releasing CiCam.
411      * @param clientId the id of the client that is releasing the CiCam.
412      */
releaseCiCam(in int ciCamHandle, int clientId)413     void releaseCiCam(in int ciCamHandle, int clientId);
414 
415     /*
416      * Notifies the TRM that the Lnb with the given handle was released.
417      *
418      * <p>Client must call this whenever it releases an Lnb.
419      *
420      * <p><strong>Note:</strong> {@link #setLnbInfos(int[])} must be called before this release.
421      *
422      * @param lnbHandle the handle of the released Tuner Lnb.
423      * @param clientId the id of the client that is releasing the lnb.
424      */
releaseLnb(in int lnbHandle, int clientId)425     void releaseLnb(in int lnbHandle, int clientId);
426 
427     /*
428      * Compare two clients' priority.
429      *
430      * @param challengerProfile the {@link ResourceClientProfile} of the challenger.
431      * @param holderProfile the {@link ResourceClientProfile} of the holder of the resource.
432      *
433      * @return true if the challenger has higher priority than the holder.
434      */
isHigherPriority(in ResourceClientProfile challengerProfile, in ResourceClientProfile holderProfile)435     boolean isHigherPriority(in ResourceClientProfile challengerProfile,
436             in ResourceClientProfile holderProfile);
437 
438     /*
439      * Stores Frontend resource map for the later restore.
440      *
441      * <p>This is API is only for testing purpose and should be used in pair with
442      * restoreResourceMap(), which allows testing of {@link Tuner} APIs
443      * that behave differently based on different sets of resource map.
444      *
445      * @param resourceType The resource type to store the map for.
446      */
storeResourceMap(in int resourceType)447     void storeResourceMap(in int resourceType);
448 
449     /*
450      * Clears the frontend resource map.
451      *
452      * <p>This is API is only for testing purpose and should be called right after
453      * storeResourceMap(), so TRMService#removeFrontendResource() does not
454      * get called in TRMService#setFrontendInfoListInternal() for custom frontend
455      * resource map creation.
456      *
457      * @param resourceType The resource type to clear the map for.
458      */
clearResourceMap(in int resourceType)459     void clearResourceMap(in int resourceType);
460 
461     /*
462      * Restores Frontend resource map if it was stored before.
463      *
464      * <p>This is API is only for testing purpose and should be used in pair with
465      * storeResourceMap(), which allows testing of {@link Tuner} APIs
466      * that behave differently based on different sets of resource map.
467      *
468      * @param resourceType The resource type to restore the map for.
469      */
restoreResourceMap(in int resourceType)470     void restoreResourceMap(in int resourceType);
471 
472     /**
473      * Grants the lock to the caller for public {@link Tuner} APIs
474      *
475      * <p>{@link Tuner} functions that call both [@link TunerResourceManager} APIs and
476      * grabs lock that are also used in {@link IResourcesReclaimListener#onReclaimResources()}
477      * must call this API before acquiring lock used in onReclaimResources().
478      *
479      * <p>This API will block until it releases the lock or fails
480      *
481      * @param clientId The ID of the caller.
482      *
483      * @return true if the lock is granted. If false is returned, calling this API again is not
484      * guaranteed to work and may be unrecoverrable. (This should not happen.)
485      */
acquireLock(in int clientId, in long clientThreadId)486     boolean acquireLock(in int clientId, in long clientThreadId);
487 
488     /**
489      * Releases the lock to the caller for public {@link Tuner} APIs
490      *
491      * <p>This API must be called in pair with {@link #acquireLock(int, int)}
492      *
493      * <p>This API will block until it releases the lock or fails
494      *
495      * @param clientId The ID of the caller.
496      *
497      * @return true if the lock is granted. If false is returned, calling this API again is not
498      * guaranteed to work and may be unrecoverrable. (This should not happen.)
499      */
releaseLock(in int clientId)500     boolean releaseLock(in int clientId);
501 
502     /**
503      * Returns a priority for the given use case type and the client's foreground or background
504      * status.
505      *
506      * @param useCase the use case type of the client. When the given use case type is invalid,
507      *        the default use case type will be used. {@see TvInputService#PriorityHintUseCaseType}.
508      * @param pid the pid of the client. When the pid is invalid, background status will be used as
509      *        a client's status. Otherwise, client's app corresponding to the given session id will
510      *        be used as a client. {@see TvInputService#onCreateSession(String, String)}.
511      *
512      * @return the client priority..
513      */
getClientPriority(int useCase, int pid)514     int getClientPriority(int useCase, int pid);
515 
516     /**
517      * Returns a config priority for the given use case type and the foreground or background
518      * status.
519      *
520      * @param useCase the use case type of the client. When the given use case type is invalid,
521      *        the default use case type will be used. {@see TvInputService#PriorityHintUseCaseType}.
522      * @param isForeground {@code true} if foreground, {@code false} otherwise.
523      *
524      * @return the config priority.
525      */
getConfigPriority(int useCase, boolean isForeground)526     int getConfigPriority(int useCase, boolean isForeground);
527 }
528