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 package com.android.server.tv.tunerresourcemanager;
17 
18 import android.media.tv.tunerresourcemanager.TunerResourceManager;
19 
20 import java.util.HashSet;
21 import java.util.Set;
22 
23 /**
24   * A client profile object used by the Tuner Resource Manager to record the registered clients'
25   * information.
26   *
27   * @hide
28   */
29 public final class ClientProfile {
30 
31     public static final int INVALID_GROUP_ID = -1;
32     public static final int INVALID_RESOURCE_ID = -1;
33 
34     /**
35      * Client id sent to the client when registering with
36      * {@link #registerClientProfile(ResourceClientProfile, TunerResourceManagerCallback, int[])}
37      */
38     private final int mId;
39 
40     /**
41      * see {@link ResourceClientProfile}
42      */
43     private final String mTvInputSessionId;
44 
45     /**
46      * see {@link ResourceClientProfile}
47      */
48     private final int mUseCase;
49 
50     /**
51      * Process id queried from {@link TvInputManager#getPid(String)}.
52      */
53     private final int mProcessId;
54 
55     /**
56      * All the clients that share the same resource would be under the same group id.
57      *
58      * <p>If a client's resource is to be reclaimed, all other clients under the same group id
59      * also lose their resources.
60      */
61     private int mGroupId = INVALID_GROUP_ID;
62     /**
63      * Optional nice value for TRM to reduce client’s priority.
64      */
65     private int mNiceValue;
66 
67     /**
68      * The handle of the primary frontend resource
69      */
70     private int mPrimaryUsingFrontendHandle = TunerResourceManager.INVALID_RESOURCE_HANDLE;
71 
72     /**
73      * List of the frontend handles that are used by the current client.
74      */
75     private Set<Integer> mUsingFrontendHandles = new HashSet<>();
76 
77     /**
78      * List of the client ids that share frontend with the current client.
79      */
80     private Set<Integer> mShareFeClientIds = new HashSet<>();
81 
82     private Set<Integer> mUsingDemuxHandles = new HashSet<>();
83 
84     /**
85      * List of the Lnb handles that are used by the current client.
86      */
87     private Set<Integer> mUsingLnbHandles = new HashSet<>();
88 
89     /**
90      * List of the Cas system ids that are used by the current client.
91      */
92     private int mUsingCasSystemId = INVALID_RESOURCE_ID;
93 
94     /**
95      * CiCam id that is used by the client.
96      */
97     private int mUsingCiCamId = INVALID_RESOURCE_ID;
98 
99     /**
100      * If the priority is overwritten through
101      * {@link TunerResourceManagerService#setPriority(int, int)}.
102      */
103     private boolean mIsPriorityOverwritten = false;
104 
105     /**
106      * Optional arbitrary priority value given by the client.
107      *
108      * <p>This value can override the default priorotiy calculated from
109      * the client profile.
110      */
111     private int mPriority;
112 
ClientProfile(Builder builder)113     private ClientProfile(Builder builder) {
114         this.mId = builder.mId;
115         this.mTvInputSessionId = builder.mTvInputSessionId;
116         this.mUseCase = builder.mUseCase;
117         this.mProcessId = builder.mProcessId;
118     }
119 
getId()120     public int getId() {
121         return mId;
122     }
123 
getTvInputSessionId()124     public String getTvInputSessionId() {
125         return mTvInputSessionId;
126     }
127 
getUseCase()128     public int getUseCase() {
129         return mUseCase;
130     }
131 
getProcessId()132     public int getProcessId() {
133         return mProcessId;
134     }
135 
136     /**
137      * If the client priority is overwrttien.
138      */
isPriorityOverwritten()139     public boolean isPriorityOverwritten() {
140         return mIsPriorityOverwritten;
141     }
142 
getGroupId()143     public int getGroupId() {
144         return mGroupId;
145     }
146 
getPriority()147     public int getPriority() {
148         return mPriority - mNiceValue;
149     }
150 
setGroupId(int groupId)151     public void setGroupId(int groupId) {
152         mGroupId = groupId;
153     }
154 
setPriority(int priority)155     public void setPriority(int priority) {
156         if (priority < 0) {
157             return;
158         }
159         mPriority = priority;
160     }
161 
162     /**
163      * Overwrite the client priority.
164      */
overwritePriority(int priority)165     public void overwritePriority(int priority) {
166         if (priority < 0) {
167             return;
168         }
169         mIsPriorityOverwritten = true;
170         mPriority = priority;
171     }
172 
setNiceValue(int niceValue)173     public void setNiceValue(int niceValue) {
174         mNiceValue = niceValue;
175     }
176 
177     /**
178      * Set when the client starts to use a frontend.
179      *
180      * @param frontendHandle being used.
181      */
useFrontend(int frontendHandle)182     public void useFrontend(int frontendHandle) {
183         mUsingFrontendHandles.add(frontendHandle);
184     }
185 
186     /**
187      * Set the primary frontend used by the client
188      *
189      * @param frontendHandle being used.
190      */
setPrimaryFrontend(int frontendHandle)191     public void setPrimaryFrontend(int frontendHandle) {
192         mPrimaryUsingFrontendHandle = frontendHandle;
193     }
194 
195     /**
196      * Get the primary frontend used by the client
197      */
getPrimaryFrontend()198     public int getPrimaryFrontend() {
199         return mPrimaryUsingFrontendHandle;
200     }
201 
202     /**
203      * Update the set of client that share frontend with the current client.
204      *
205      * @param clientId the client to share the fe with the current client.
206      */
shareFrontend(int clientId)207     public void shareFrontend(int clientId) {
208         mShareFeClientIds.add(clientId);
209     }
210 
211     /**
212      * Remove the given client id from the share frontend client id set.
213      *
214      * @param clientId the client to stop sharing the fe with the current client.
215      */
stopSharingFrontend(int clientId)216     public void stopSharingFrontend(int clientId) {
217         mShareFeClientIds.remove(clientId);
218     }
219 
getInUseFrontendHandles()220     public Set<Integer> getInUseFrontendHandles() {
221         return mUsingFrontendHandles;
222     }
223 
getShareFeClientIds()224     public Set<Integer> getShareFeClientIds() {
225         return mShareFeClientIds;
226     }
227 
228     /**
229      * Called when the client released a frontend.
230      */
releaseFrontend()231     public void releaseFrontend() {
232         mUsingFrontendHandles.clear();
233         mShareFeClientIds.clear();
234         mPrimaryUsingFrontendHandle = TunerResourceManager.INVALID_RESOURCE_HANDLE;
235     }
236 
237     /**
238      * Set when the client starts to use a Demux.
239      *
240      * @param demuxHandle the demux being used.
241      */
useDemux(int demuxHandle)242     public void useDemux(int demuxHandle) {
243         mUsingDemuxHandles.add(demuxHandle);
244     }
245 
246     /**
247      * Get the set of demux handles in use.
248      */
getInUseDemuxHandles()249     public Set<Integer> getInUseDemuxHandles() {
250         return mUsingDemuxHandles;
251     }
252 
253     /**
254      * Called when the client released a Demux.
255      *
256      * @param demuxHandle the demux handl being released.
257      */
releaseDemux(int demuxHandle)258     public void releaseDemux(int demuxHandle) {
259         mUsingDemuxHandles.remove(demuxHandle);
260     }
261 
262     /**
263      * Set when the client starts to use an Lnb.
264      *
265      * @param lnbHandle being used.
266      */
useLnb(int lnbHandle)267     public void useLnb(int lnbHandle) {
268         mUsingLnbHandles.add(lnbHandle);
269     }
270 
getInUseLnbHandles()271     public Set<Integer> getInUseLnbHandles() {
272         return mUsingLnbHandles;
273     }
274 
275     /**
276      * Called when the client released an lnb.
277      *
278      * @param lnbHandle being released.
279      */
releaseLnb(int lnbHandle)280     public void releaseLnb(int lnbHandle) {
281         mUsingLnbHandles.remove(lnbHandle);
282     }
283 
284     /**
285      * Set when the client starts to use a Cas system.
286      *
287      * @param casSystemId cas being used.
288      */
useCas(int casSystemId)289     public void useCas(int casSystemId) {
290         mUsingCasSystemId = casSystemId;
291     }
292 
getInUseCasSystemId()293     public int getInUseCasSystemId() {
294         return mUsingCasSystemId;
295     }
296 
297     /**
298      * Called when the client released a Cas System.
299      */
releaseCas()300     public void releaseCas() {
301         mUsingCasSystemId = INVALID_RESOURCE_ID;
302     }
303 
304     /**
305      * Set when the client starts to connect to a CiCam.
306      *
307      * @param ciCamId ciCam being used.
308      */
useCiCam(int ciCamId)309     public void useCiCam(int ciCamId) {
310         mUsingCiCamId = ciCamId;
311     }
312 
getInUseCiCamId()313     public int getInUseCiCamId() {
314         return mUsingCiCamId;
315     }
316 
317     /**
318      * Called when the client disconnect to a CiCam.
319      */
releaseCiCam()320     public void releaseCiCam() {
321         mUsingCiCamId = INVALID_RESOURCE_ID;
322     }
323 
324     /**
325      * Called to reclaim all the resources being used by the current client.
326      */
reclaimAllResources()327     public void reclaimAllResources() {
328         mUsingFrontendHandles.clear();
329         mShareFeClientIds.clear();
330         mPrimaryUsingFrontendHandle = TunerResourceManager.INVALID_RESOURCE_HANDLE;
331         mUsingLnbHandles.clear();
332         mUsingCasSystemId = INVALID_RESOURCE_ID;
333         mUsingCiCamId = INVALID_RESOURCE_ID;
334     }
335 
336     @Override
toString()337     public String toString() {
338         return "ClientProfile[id=" + this.mId + ", tvInputSessionId=" + this.mTvInputSessionId
339                 + ", useCase=" + this.mUseCase + ", processId=" + this.mProcessId + "]";
340     }
341 
342     /**
343     * Builder class for {@link ClientProfile}.
344     */
345     public static class Builder {
346         private final int mId;
347         private String mTvInputSessionId;
348         private int mUseCase;
349         private int mProcessId;
350 
Builder(int id)351         Builder(int id) {
352             this.mId = id;
353         }
354 
355         /**
356           * Builder for {@link ClientProfile}.
357           *
358           * @param useCase the useCase of the client.
359           */
useCase(int useCase)360         public Builder useCase(int useCase) {
361             this.mUseCase = useCase;
362             return this;
363         }
364 
365         /**
366           * Builder for {@link ClientProfile}.
367           *
368           * @param tvInputSessionId the id of the tv input session.
369           */
tvInputSessionId(String tvInputSessionId)370         public Builder tvInputSessionId(String tvInputSessionId) {
371             this.mTvInputSessionId = tvInputSessionId;
372             return this;
373         }
374 
375         /**
376           * Builder for {@link ClientProfile}.
377           *
378           * @param processId the id of process.
379           */
processId(int processId)380         public Builder processId(int processId) {
381             this.mProcessId = processId;
382             return this;
383         }
384 
385         /**
386           * Build a {@link ClientProfile}.
387           *
388           * @return {@link ClientProfile}.
389           */
build()390         public ClientProfile build() {
391             ClientProfile clientProfile = new ClientProfile(this);
392             return clientProfile;
393         }
394     }
395 }
396