213 lines
7.0 KiB
Java
213 lines
7.0 KiB
Java
|
/*
|
||
|
* 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;
|
||
|
}
|