summaryrefslogtreecommitdiffstats
path: root/core/java/android/os/Broadcaster.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/os/Broadcaster.java')
-rw-r--r--core/java/android/os/Broadcaster.java212
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;
+}