13083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn/* 23083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * Copyright (C) 2011 The Android Open Source Project 33083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * 43083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 53083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * you may not use this file except in compliance with the License. 63083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * You may obtain a copy of the License at 73083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * 83083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 93083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * 103083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 113083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 123083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * See the License for the specific language governing permissions and 143083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * limitations under the License. 153083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn */ 163083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 173083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackbornpackage android.support.v4.content; 183083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 193083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackbornimport java.util.ArrayList; 203083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackbornimport java.util.HashMap; 213083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackbornimport java.util.Set; 223083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 233083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackbornimport android.content.BroadcastReceiver; 243083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackbornimport android.content.Context; 253083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackbornimport android.content.Intent; 263083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackbornimport android.content.IntentFilter; 273083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackbornimport android.net.Uri; 283083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackbornimport android.os.Handler; 293083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackbornimport android.os.Message; 303083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackbornimport android.util.Log; 313083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 323083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn/** 333083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * Helper to register for and send broadcasts of Intents to local objects 343083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * within your process. This is has a number of advantages over sending 353083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * global broadcasts with {@link android.content.Context#sendBroadcast}: 363083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * <ul> 373083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * <li> You know that the data you are broadcasting won't leave your app, so 383083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * don't need to worry about leaking private data. 393083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * <li> It is not possible for other applications to send these broadcasts to 403083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * your app, so you don't need to worry about having security holes they can 413083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * exploit. 423083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * <li> It is more efficient than sending a global broadcast through the 433083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * system. 443083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * </ul> 453083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn */ 463083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackbornpublic class LocalBroadcastManager { 473083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn private static class ReceiverRecord { 483083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn final IntentFilter filter; 493083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn final BroadcastReceiver receiver; 503083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn boolean broadcasting; 513083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 523083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn ReceiverRecord(IntentFilter _filter, BroadcastReceiver _receiver) { 533083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn filter = _filter; 543083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn receiver = _receiver; 553083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 563083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 573083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn @Override 583083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn public String toString() { 593083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn StringBuilder builder = new StringBuilder(128); 603083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn builder.append("Receiver{"); 613083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn builder.append(receiver); 623083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn builder.append(" filter="); 633083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn builder.append(filter); 643083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn builder.append("}"); 653083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn return builder.toString(); 663083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 673083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 683083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 693083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn private static class BroadcastRecord { 703083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn final Intent intent; 713083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn final ArrayList<ReceiverRecord> receivers; 723083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 733083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn BroadcastRecord(Intent _intent, ArrayList<ReceiverRecord> _receivers) { 743083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn intent = _intent; 753083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn receivers = _receivers; 763083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 773083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 783083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 793083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn private static final String TAG = "LocalBroadcastManager"; 803083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn private static final boolean DEBUG = false; 813083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 823083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn private final Context mAppContext; 833083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 843083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn private final HashMap<BroadcastReceiver, ArrayList<IntentFilter>> mReceivers 853083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn = new HashMap<BroadcastReceiver, ArrayList<IntentFilter>>(); 863083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn private final HashMap<String, ArrayList<ReceiverRecord>> mActions 873083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn = new HashMap<String, ArrayList<ReceiverRecord>>(); 883083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 893083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn private final ArrayList<BroadcastRecord> mPendingBroadcasts 903083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn = new ArrayList<BroadcastRecord>(); 913083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 923083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn static final int MSG_EXEC_PENDING_BROADCASTS = 1; 933083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 943083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn private final Handler mHandler; 953083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 963083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn private static final Object mLock = new Object(); 973083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn private static LocalBroadcastManager mInstance; 983083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 993083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn public static LocalBroadcastManager getInstance(Context context) { 1003083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn synchronized (mLock) { 1013083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn if (mInstance == null) { 1023083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn mInstance = new LocalBroadcastManager(context.getApplicationContext()); 1033083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 1043083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn return mInstance; 1053083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 1063083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 1073083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 1083083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn private LocalBroadcastManager(Context context) { 1093083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn mAppContext = context; 1103083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn mHandler = new Handler(context.getMainLooper()) { 1113083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 1123083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn @Override 1133083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn public void handleMessage(Message msg) { 1143083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn switch (msg.what) { 1153083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn case MSG_EXEC_PENDING_BROADCASTS: 1163083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn executePendingBroadcasts(); 1173083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn break; 1183083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn default: 1193083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn super.handleMessage(msg); 1203083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 1213083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 1223083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn }; 1233083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 1243083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 1253083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn /** 1263083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * Register a receive for any local broadcasts that match the given IntentFilter. 1273083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * 1283083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * @param receiver The BroadcastReceiver to handle the broadcast. 1293083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * @param filter Selects the Intent broadcasts to be received. 1303083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * 1313083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * @see #unregisterReceiver 1323083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn */ 1333083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn public void registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { 1343083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn synchronized (mReceivers) { 1353083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn ReceiverRecord entry = new ReceiverRecord(filter, receiver); 1363083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn ArrayList<IntentFilter> filters = mReceivers.get(receiver); 1373083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn if (filters == null) { 1383083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn filters = new ArrayList<IntentFilter>(1); 1393083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn mReceivers.put(receiver, filters); 1403083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 1413083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn filters.add(filter); 1423083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn for (int i=0; i<filter.countActions(); i++) { 1433083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn String action = filter.getAction(i); 1443083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn ArrayList<ReceiverRecord> entries = mActions.get(action); 1453083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn if (entries == null) { 1463083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn entries = new ArrayList<ReceiverRecord>(1); 1473083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn mActions.put(action, entries); 1483083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 1493083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn entries.add(entry); 1503083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 1513083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 1523083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 1533083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 1543083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn /** 1553083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * Unregister a previously registered BroadcastReceiver. <em>All</em> 1563083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * filters that have been registered for this BroadcastReceiver will be 1573083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * removed. 1583083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * 1593083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * @param receiver The BroadcastReceiver to unregister. 1603083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * 1613083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * @see #registerReceiver 1623083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn */ 1633083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn public void unregisterReceiver(BroadcastReceiver receiver) { 1643083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn synchronized (mReceivers) { 1653083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn ArrayList<IntentFilter> filters = mReceivers.remove(receiver); 1663083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn if (filters == null) { 1673083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn return; 1683083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 1693083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn for (int i=0; i<filters.size(); i++) { 1703083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn IntentFilter filter = filters.get(i); 1713083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn for (int j=0; j<filter.countActions(); j++) { 1723083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn String action = filter.getAction(j); 1733083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn ArrayList<ReceiverRecord> receivers = mActions.get(action); 1743083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn if (receivers != null) { 1753083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn for (int k=0; k<receivers.size(); k++) { 1763083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn if (receivers.get(k).receiver == receiver) { 1773083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn receivers.remove(k); 1783083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn k--; 1793083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 1803083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 1813083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn if (receivers.size() <= 0) { 1823083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn mActions.remove(action); 1833083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 1843083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 1853083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 1863083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 1873083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 1883083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 1893083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 1903083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn /** 1913083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * Broadcast the given intent to all interested BroadcastReceivers. This 1923083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * call is asynchronous; it returns immediately, and you will continue 1933083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * executing while the receivers are run. 1943083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * 1953083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * @param intent The Intent to broadcast; all receivers matching this 1963083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * Intent will receive the broadcast. 1973083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * 1983083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * @see #registerReceiver 1993083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn */ 2003083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn public boolean sendBroadcast(Intent intent) { 2013083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn synchronized (mReceivers) { 2023083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn final String action = intent.getAction(); 2033083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn final String type = intent.resolveTypeIfNeeded( 2043083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn mAppContext.getContentResolver()); 2053083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn final Uri data = intent.getData(); 2063083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn final String scheme = intent.getScheme(); 2073083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn final Set<String> categories = intent.getCategories(); 2083083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 2093083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn final boolean debug = DEBUG || 2103083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 2113083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn if (debug) Log.v( 2123083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn TAG, "Resolving type " + type + " scheme " + scheme 2133083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn + " of intent " + intent); 2143083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 2153083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn ArrayList<ReceiverRecord> entries = mActions.get(intent.getAction()); 2163083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn if (entries != null) { 2173083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn if (debug) Log.v(TAG, "Action list: " + entries); 2183083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 2193083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn ArrayList<ReceiverRecord> receivers = null; 2203083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn for (int i=0; i<entries.size(); i++) { 2213083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn ReceiverRecord receiver = entries.get(i); 2223083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn if (debug) Log.v(TAG, "Matching against filter " + receiver.filter); 2233083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 2243083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn if (receiver.broadcasting) { 2253083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn if (debug) { 2263083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn Log.v(TAG, " Filter's target already added"); 2273083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 2283083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn continue; 2293083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 2303083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 2313083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn int match = receiver.filter.match(action, type, scheme, data, 2323083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn categories, "LocalBroadcastManager"); 2333083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn if (match >= 0) { 2343083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn if (debug) Log.v(TAG, " Filter matched! match=0x" + 2353083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn Integer.toHexString(match)); 2363083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn if (receivers == null) { 2373083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn receivers = new ArrayList<ReceiverRecord>(); 2383083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 2393083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn receivers.add(receiver); 2403083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn receiver.broadcasting = true; 2413083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } else { 2423083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn if (debug) { 2433083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn String reason; 2443083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn switch (match) { 2453083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn case IntentFilter.NO_MATCH_ACTION: reason = "action"; break; 2463083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn case IntentFilter.NO_MATCH_CATEGORY: reason = "category"; break; 2473083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn case IntentFilter.NO_MATCH_DATA: reason = "data"; break; 2483083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn case IntentFilter.NO_MATCH_TYPE: reason = "type"; break; 2493083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn default: reason = "unknown reason"; break; 2503083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 2513083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn Log.v(TAG, " Filter did not match: " + reason); 2523083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 2533083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 2543083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 2553083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 2563083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn if (receivers != null) { 2573083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn for (int i=0; i<receivers.size(); i++) { 2583083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn receivers.get(i).broadcasting = false; 2593083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 2603083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn mPendingBroadcasts.add(new BroadcastRecord(intent, receivers)); 2613083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn if (!mHandler.hasMessages(MSG_EXEC_PENDING_BROADCASTS)) { 2623083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn mHandler.sendEmptyMessage(MSG_EXEC_PENDING_BROADCASTS); 2633083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 2643083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn return true; 2653083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 2663083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 2673083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 2683083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn return false; 2693083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 2703083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 2713083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn /** 2723083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * Like {@link #sendBroadcast(Intent)}, but if there are any receivers for 2733083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * the Intent this function will block and immediately dispatch them before 2743083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn * returning. 2753083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn */ 2763083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn public void sendBroadcastSync(Intent intent) { 2773083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn if (sendBroadcast(intent)) { 2783083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn executePendingBroadcasts(); 2793083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 2803083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 2813083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn 2823083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn private void executePendingBroadcasts() { 2833083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn while (true) { 2843083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn BroadcastRecord[] brs = null; 2853083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn synchronized (mReceivers) { 2863083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn final int N = mPendingBroadcasts.size(); 2873083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn if (N <= 0) { 2883083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn return; 2893083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 2903083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn brs = new BroadcastRecord[N]; 2913083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn mPendingBroadcasts.toArray(brs); 2923083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn mPendingBroadcasts.clear(); 2933083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 2943083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn for (int i=0; i<brs.length; i++) { 2953083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn BroadcastRecord br = brs[i]; 2963083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn for (int j=0; j<br.receivers.size(); j++) { 2973083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn br.receivers.get(j).receiver.onReceive(mAppContext, br.intent); 2983083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 2993083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 3003083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 3013083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn } 3023083afddf1baabb57e801d2aa7d9c59e8b1e1c19Dianne Hackborn} 303