1 /*
2  * Copyright (C) 2022 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 com.android.telephony.qns;
18 
19 import android.os.Handler;
20 
21 import java.util.ArrayList;
22 
23 /** @hide */
24 class QnsRegistrantList {
25     protected final ArrayList<QnsRegistrant> mRegistrants;
26 
27     /** constructor */
QnsRegistrantList()28     QnsRegistrantList() {
29         mRegistrants = new ArrayList<>();
30     }
31 
32     /**
33      * Add each element for the registrant.
34      *
35      * @param h handler
36      * @param what message to be delivered
37      * @param obj object
38      */
add(Handler h, int what, Object obj)39     synchronized void add(Handler h, int what, Object obj) {
40         add(new QnsRegistrant(h, what, obj));
41     }
42 
43     /**
44      * Add each element for the registrant. does not allow duplicated handler
45      *
46      * @param h handler
47      * @param what message to be delivered
48      * @param obj object
49      */
addUnique(Handler h, int what, Object obj)50     synchronized void addUnique(Handler h, int what, Object obj) {
51         // if the handler is already in the registrant list, remove it
52         remove(h);
53         add(new QnsRegistrant(h, what, obj));
54     }
55 
56     /**
57      * Add the registrant.
58      *
59      * @param r registrant.
60      */
add(QnsRegistrant r)61     synchronized void add(QnsRegistrant r) {
62         removeCleared();
63         mRegistrants.add(r);
64     }
65 
66     /** Remove cleared registrant in list */
removeCleared()67     synchronized void removeCleared() {
68         for (int i = mRegistrants.size() - 1; i >= 0; i--) {
69             QnsRegistrant r = mRegistrants.get(i);
70 
71             if (r.mRefH == null) {
72                 mRegistrants.remove(i);
73             }
74         }
75     }
76 
77     /** Remove all registrant */
removeAll()78     synchronized void removeAll() {
79         mRegistrants.clear();
80     }
81 
82     /**
83      * Returns size of Registrant.
84      *
85      * @return size
86      */
size()87     synchronized int size() {
88         return mRegistrants.size();
89     }
90 
91     /**
92      * Returns Object from the list
93      *
94      * @param index index
95      * @return Object
96      */
get(int index)97     synchronized Object get(int index) {
98         return mRegistrants.get(index);
99     }
100 
internalNotifyRegistrants(Object result, Throwable exception)101     private synchronized void internalNotifyRegistrants(Object result, Throwable exception) {
102         for (QnsRegistrant registrant : mRegistrants) {
103             registrant.internalNotifyRegistrant(result, exception);
104         }
105     }
106 
107     /** notify registrant */
notifyRegistrants()108     void notifyRegistrants() {
109         internalNotifyRegistrants(null, null);
110     }
111 
112     /**
113      * notify registrant with given object
114      *
115      * @param result object
116      */
notifyResult(Object result)117     void notifyResult(Object result) {
118         internalNotifyRegistrants(result, null);
119     }
120 
121     /**
122      * notify registrant
123      *
124      * @param ar QnsAsyncResult to be notified
125      */
notifyRegistrants(QnsAsyncResult ar)126     void notifyRegistrants(QnsAsyncResult ar) {
127         internalNotifyRegistrants(ar.mResult, ar.mException);
128     }
129 
130     /**
131      * remove handler in list
132      *
133      * @param h handler
134      */
remove(Handler h)135     synchronized void remove(Handler h) {
136         for (QnsRegistrant r : mRegistrants) {
137             Handler rh;
138 
139             rh = r.getHandler();
140 
141             /* Clean up both the requested registrant and
142              * any now-collected registrants
143              */
144             if (rh == null || rh == h) {
145                 r.clear();
146             }
147         }
148 
149         removeCleared();
150     }
151 }
152