diff options
Diffstat (limited to 'core/java/android/os/Broadcaster.java')
-rw-r--r-- | core/java/android/os/Broadcaster.java | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/core/java/android/os/Broadcaster.java b/core/java/android/os/Broadcaster.java new file mode 100644 index 0000000..96dc61a --- /dev/null +++ b/core/java/android/os/Broadcaster.java @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os; + +/** @hide */ +public class Broadcaster +{ + public Broadcaster() + { + } + + /** + * Sign up for notifications about something. + * + * When this broadcaster pushes a message with senderWhat in the what field, + * target will be sent a copy of that message with targetWhat in the what field. + */ + public void request(int senderWhat, Handler target, int targetWhat) + { + synchronized (this) { + Registration r = null; + if (mReg == null) { + r = new Registration(); + r.senderWhat = senderWhat; + r.targets = new Handler[1]; + r.targetWhats = new int[1]; + r.targets[0] = target; + r.targetWhats[0] = targetWhat; + mReg = r; + r.next = r; + r.prev = r; + } else { + // find its place in the map + Registration start = mReg; + r = start; + do { + if (r.senderWhat >= senderWhat) { + break; + } + r = r.next; + } while (r != start); + int n; + if (r.senderWhat != senderWhat) { + // we didn't find a senderWhat match, but r is right + // after where it goes + Registration reg = new Registration(); + reg.senderWhat = senderWhat; + reg.targets = new Handler[1]; + reg.targetWhats = new int[1]; + reg.next = r; + reg.prev = r.prev; + r.prev.next = reg; + r.prev = reg; + + if (r == mReg && r.senderWhat > reg.senderWhat) { + mReg = reg; + } + + r = reg; + n = 0; + } else { + n = r.targets.length; + Handler[] oldTargets = r.targets; + int[] oldWhats = r.targetWhats; + // check for duplicates, and don't do it if we are dup. + for (int i=0; i<n; i++) { + if (oldTargets[i] == target && oldWhats[i] == targetWhat) { + return; + } + } + r.targets = new Handler[n+1]; + System.arraycopy(oldTargets, 0, r.targets, 0, n); + r.targetWhats = new int[n+1]; + System.arraycopy(oldWhats, 0, r.targetWhats, 0, n); + } + r.targets[n] = target; + r.targetWhats[n] = targetWhat; + } + } + } + + /** + * Unregister for notifications for this senderWhat/target/targetWhat tuple. + */ + public void cancelRequest(int senderWhat, Handler target, int targetWhat) + { + synchronized (this) { + Registration start = mReg; + Registration r = start; + + if (r == null) { + return; + } + + do { + if (r.senderWhat >= senderWhat) { + break; + } + r = r.next; + } while (r != start); + + if (r.senderWhat == senderWhat) { + Handler[] targets = r.targets; + int[] whats = r.targetWhats; + int oldLen = targets.length; + for (int i=0; i<oldLen; i++) { + if (targets[i] == target && whats[i] == targetWhat) { + r.targets = new Handler[oldLen-1]; + r.targetWhats = new int[oldLen-1]; + if (i > 0) { + System.arraycopy(targets, 0, r.targets, 0, i); + System.arraycopy(whats, 0, r.targetWhats, 0, i); + } + + int remainingLen = oldLen-i-1; + if (remainingLen != 0) { + System.arraycopy(targets, i+1, r.targets, i, + remainingLen); + System.arraycopy(whats, i+1, r.targetWhats, i, + remainingLen); + } + break; + } + } + } + } + } + + /** + * For debugging purposes, print the registrations to System.out + */ + public void dumpRegistrations() + { + synchronized (this) { + Registration start = mReg; + System.out.println("Broadcaster " + this + " {"); + if (start != null) { + Registration r = start; + do { + System.out.println(" senderWhat=" + r.senderWhat); + int n = r.targets.length; + for (int i=0; i<n; i++) { + System.out.println(" [" + r.targetWhats[i] + + "] " + r.targets[i]); + } + r = r.next; + } while (r != start); + } + System.out.println("}"); + } + } + + /** + * Send out msg. Anyone who has registered via the request() method will be + * sent the message. + */ + public void broadcast(Message msg) + { + synchronized (this) { + if (mReg == null) { + return; + } + + int senderWhat = msg.what; + Registration start = mReg; + Registration r = start; + do { + if (r.senderWhat >= senderWhat) { + break; + } + r = r.next; + } while (r != start); + if (r.senderWhat == senderWhat) { + Handler[] targets = r.targets; + int[] whats = r.targetWhats; + int n = targets.length; + for (int i=0; i<n; i++) { + Handler target = targets[i]; + Message m = Message.obtain(); + m.copyFrom(msg); + m.what = whats[i]; + target.sendMessage(m); + } + } + } + } + + private class Registration + { + Registration next; + Registration prev; + + int senderWhat; + Handler[] targets; + int[] targetWhats; + } + private Registration mReg; +} |