/* * 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; }