19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.os; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** @hide */ 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class Broadcaster 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Broadcaster() 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sign up for notifications about something. 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * When this broadcaster pushes a message with senderWhat in the what field, 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * target will be sent a copy of that message with targetWhat in the what field. 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void request(int senderWhat, Handler target, int targetWhat) 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Registration r = null; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mReg == null) { 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r = new Registration(); 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.senderWhat = senderWhat; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.targets = new Handler[1]; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.targetWhats = new int[1]; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.targets[0] = target; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.targetWhats[0] = targetWhat; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReg = r; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.next = r; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.prev = r; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // find its place in the map 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Registration start = mReg; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r = start; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (r.senderWhat >= senderWhat) { 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r = r.next; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (r != start); 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int n; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (r.senderWhat != senderWhat) { 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we didn't find a senderWhat match, but r is right 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // after where it goes 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Registration reg = new Registration(); 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reg.senderWhat = senderWhat; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reg.targets = new Handler[1]; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reg.targetWhats = new int[1]; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reg.next = r; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reg.prev = r.prev; 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.prev.next = reg; 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.prev = reg; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (r == mReg && r.senderWhat > reg.senderWhat) { 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReg = reg; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r = reg; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n = 0; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n = r.targets.length; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Handler[] oldTargets = r.targets; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] oldWhats = r.targetWhats; 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // check for duplicates, and don't do it if we are dup. 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<n; i++) { 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (oldTargets[i] == target && oldWhats[i] == targetWhat) { 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.targets = new Handler[n+1]; 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(oldTargets, 0, r.targets, 0, n); 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.targetWhats = new int[n+1]; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(oldWhats, 0, r.targetWhats, 0, n); 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.targets[n] = target; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.targetWhats[n] = targetWhat; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregister for notifications for this senderWhat/target/targetWhat tuple. 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void cancelRequest(int senderWhat, Handler target, int targetWhat) 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Registration start = mReg; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Registration r = start; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (r == null) { 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (r.senderWhat >= senderWhat) { 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r = r.next; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (r != start); 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (r.senderWhat == senderWhat) { 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Handler[] targets = r.targets; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] whats = r.targetWhats; 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int oldLen = targets.length; 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<oldLen; i++) { 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (targets[i] == target && whats[i] == targetWhat) { 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.targets = new Handler[oldLen-1]; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.targetWhats = new int[oldLen-1]; 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i > 0) { 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(targets, 0, r.targets, 0, i); 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(whats, 0, r.targetWhats, 0, i); 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int remainingLen = oldLen-i-1; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (remainingLen != 0) { 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(targets, i+1, r.targets, i, 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project remainingLen); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(whats, i+1, r.targetWhats, i, 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project remainingLen); 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For debugging purposes, print the registrations to System.out 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void dumpRegistrations() 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Registration start = mReg; 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.out.println("Broadcaster " + this + " {"); 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (start != null) { 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Registration r = start; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.out.println(" senderWhat=" + r.senderWhat); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int n = r.targets.length; 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<n; i++) { 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.out.println(" [" + r.targetWhats[i] 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + "] " + r.targets[i]); 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r = r.next; 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (r != start); 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.out.println("}"); 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Send out msg. Anyone who has registered via the request() method will be 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * sent the message. 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void broadcast(Message msg) 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mReg == null) { 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int senderWhat = msg.what; 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Registration start = mReg; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Registration r = start; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (r.senderWhat >= senderWhat) { 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r = r.next; 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (r != start); 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (r.senderWhat == senderWhat) { 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Handler[] targets = r.targets; 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] whats = r.targetWhats; 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int n = targets.length; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<n; i++) { 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Handler target = targets[i]; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message m = Message.obtain(); 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m.copyFrom(msg); 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m.what = whats[i]; 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project target.sendMessage(m); 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class Registration 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Registration next; 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Registration prev; 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int senderWhat; 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Handler[] targets; 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] targetWhats; 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Registration mReg; 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 213