• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 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.os;
18 
19 import android.compat.annotation.UnsupportedAppUsage;
20 
21 /** @hide */
22 public class Broadcaster
23 {
24     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Broadcaster()25     public Broadcaster()
26     {
27     }
28 
29     /**
30      *  Sign up for notifications about something.
31      *
32      *  When this broadcaster pushes a message with senderWhat in the what field,
33      *  target will be sent a copy of that message with targetWhat in the what field.
34      */
35     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
request(int senderWhat, Handler target, int targetWhat)36     public void request(int senderWhat, Handler target, int targetWhat)
37     {
38         synchronized (this) {
39             Registration r = null;
40             if (mReg == null) {
41                 r = new Registration();
42                 r.senderWhat = senderWhat;
43                 r.targets = new Handler[1];
44                 r.targetWhats = new int[1];
45                 r.targets[0] = target;
46                 r.targetWhats[0] = targetWhat;
47                 mReg = r;
48                 r.next = r;
49                 r.prev = r;
50             } else {
51                 // find its place in the map
52                 Registration start = mReg;
53                 r = start;
54                 do {
55                     if (r.senderWhat >= senderWhat) {
56                         break;
57                     }
58                     r = r.next;
59                 } while (r != start);
60                 int n;
61                 if (r.senderWhat != senderWhat) {
62                     // we didn't find a senderWhat match, but r is right
63                     // after where it goes
64                     Registration reg = new Registration();
65                     reg.senderWhat = senderWhat;
66                     reg.targets = new Handler[1];
67                     reg.targetWhats = new int[1];
68                     reg.next = r;
69                     reg.prev = r.prev;
70                     r.prev.next = reg;
71                     r.prev = reg;
72 
73                     if (r == mReg && r.senderWhat > reg.senderWhat) {
74                         mReg = reg;
75                     }
76 
77                     r = reg;
78                     n = 0;
79                 } else {
80                     n = r.targets.length;
81                     Handler[] oldTargets = r.targets;
82                     int[] oldWhats = r.targetWhats;
83                     // check for duplicates, and don't do it if we are dup.
84                     for (int i=0; i<n; i++) {
85                         if (oldTargets[i] == target && oldWhats[i] == targetWhat) {
86                             return;
87                         }
88                     }
89                     r.targets = new Handler[n+1];
90                     System.arraycopy(oldTargets, 0, r.targets, 0, n);
91                     r.targetWhats = new int[n+1];
92                     System.arraycopy(oldWhats, 0, r.targetWhats, 0, n);
93                 }
94                 r.targets[n] = target;
95                 r.targetWhats[n] = targetWhat;
96             }
97         }
98     }
99 
100     /**
101      * Unregister for notifications for this senderWhat/target/targetWhat tuple.
102      */
103     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
cancelRequest(int senderWhat, Handler target, int targetWhat)104     public void cancelRequest(int senderWhat, Handler target, int targetWhat)
105     {
106         synchronized (this) {
107             Registration start = mReg;
108             Registration r = start;
109 
110             if (r == null) {
111                 return;
112             }
113 
114             do {
115                 if (r.senderWhat >= senderWhat) {
116                     break;
117                 }
118                 r = r.next;
119             } while (r != start);
120 
121             if (r.senderWhat == senderWhat) {
122                 Handler[] targets = r.targets;
123                 int[] whats = r.targetWhats;
124                 int oldLen = targets.length;
125                 for (int i=0; i<oldLen; i++) {
126                     if (targets[i] == target && whats[i] == targetWhat) {
127                         r.targets = new Handler[oldLen-1];
128                         r.targetWhats = new int[oldLen-1];
129                         if (i > 0) {
130                             System.arraycopy(targets, 0, r.targets, 0, i);
131                             System.arraycopy(whats, 0, r.targetWhats, 0, i);
132                         }
133 
134                         int remainingLen = oldLen-i-1;
135                         if (remainingLen != 0) {
136                             System.arraycopy(targets, i+1, r.targets, i,
137                                     remainingLen);
138                             System.arraycopy(whats, i+1, r.targetWhats, i,
139                                     remainingLen);
140                         }
141                         break;
142                     }
143                 }
144             }
145         }
146     }
147 
148     /**
149      * For debugging purposes, print the registrations to System.out
150      */
dumpRegistrations()151     public void dumpRegistrations()
152     {
153         synchronized (this) {
154             Registration start = mReg;
155             System.out.println("Broadcaster " + this + " {");
156             if (start != null) {
157                 Registration r = start;
158                 do {
159                     System.out.println("    senderWhat=" + r.senderWhat);
160                     int n = r.targets.length;
161                     for (int i=0; i<n; i++) {
162                         System.out.println("        [" + r.targetWhats[i]
163                                         + "] " + r.targets[i]);
164                     }
165                     r = r.next;
166                 } while (r != start);
167             }
168             System.out.println("}");
169         }
170     }
171 
172     /**
173      * Send out msg.  Anyone who has registered via the request() method will be
174      * sent the message.
175      */
176     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
broadcast(Message msg)177     public void broadcast(Message msg)
178     {
179         synchronized (this) {
180             if (mReg == null) {
181                 return;
182             }
183 
184             int senderWhat = msg.what;
185             Registration start = mReg;
186             Registration r = start;
187             do {
188                 if (r.senderWhat >= senderWhat) {
189                     break;
190                 }
191                 r = r.next;
192             } while (r != start);
193             if (r.senderWhat == senderWhat) {
194                 Handler[] targets = r.targets;
195                 int[] whats = r.targetWhats;
196                 int n = targets.length;
197                 for (int i=0; i<n; i++) {
198                     Handler target = targets[i];
199                     Message m = Message.obtain();
200                     m.copyFrom(msg);
201                     m.what = whats[i];
202                     target.sendMessage(m);
203                 }
204             }
205         }
206     }
207 
208     private class Registration
209     {
210         Registration next;
211         Registration prev;
212 
213         int senderWhat;
214         Handler[] targets;
215         int[] targetWhats;
216     }
217     private Registration mReg;
218 }
219