1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server; 18 19 import android.content.BroadcastReceiver; 20 import android.content.Context; 21 import android.content.ContextWrapper; 22 import android.content.Intent; 23 import android.content.IntentFilter; 24 import android.os.Handler; 25 import android.os.UserHandle; 26 27 import com.google.common.collect.Lists; 28 import com.google.common.util.concurrent.AbstractFuture; 29 30 import java.util.Iterator; 31 import java.util.List; 32 import java.util.concurrent.ExecutionException; 33 import java.util.concurrent.Future; 34 import java.util.concurrent.TimeUnit; 35 import java.util.concurrent.TimeoutException; 36 37 /** 38 * {@link ContextWrapper} that can attach listeners for upcoming 39 * {@link Context#sendBroadcast(Intent)}. 40 */ 41 public class BroadcastInterceptingContext extends ContextWrapper { 42 private static final String TAG = "WatchingContext"; 43 44 private final List<BroadcastInterceptor> mInterceptors = Lists.newArrayList(); 45 46 public class BroadcastInterceptor extends AbstractFuture<Intent> { 47 private final BroadcastReceiver mReceiver; 48 private final IntentFilter mFilter; 49 BroadcastInterceptor(BroadcastReceiver receiver, IntentFilter filter)50 public BroadcastInterceptor(BroadcastReceiver receiver, IntentFilter filter) { 51 mReceiver = receiver; 52 mFilter = filter; 53 } 54 dispatchBroadcast(Intent intent)55 public boolean dispatchBroadcast(Intent intent) { 56 if (mFilter.match(getContentResolver(), intent, false, TAG) > 0) { 57 if (mReceiver != null) { 58 final Context context = BroadcastInterceptingContext.this; 59 mReceiver.onReceive(context, intent); 60 return false; 61 } else { 62 set(intent); 63 return true; 64 } 65 } else { 66 return false; 67 } 68 } 69 70 @Override get()71 public Intent get() throws InterruptedException, ExecutionException { 72 try { 73 return get(5, TimeUnit.SECONDS); 74 } catch (TimeoutException e) { 75 throw new RuntimeException(e); 76 } 77 } 78 } 79 BroadcastInterceptingContext(Context base)80 public BroadcastInterceptingContext(Context base) { 81 super(base); 82 } 83 nextBroadcastIntent(String action)84 public Future<Intent> nextBroadcastIntent(String action) { 85 return nextBroadcastIntent(new IntentFilter(action)); 86 } 87 nextBroadcastIntent(IntentFilter filter)88 public Future<Intent> nextBroadcastIntent(IntentFilter filter) { 89 final BroadcastInterceptor interceptor = new BroadcastInterceptor(null, filter); 90 synchronized (mInterceptors) { 91 mInterceptors.add(interceptor); 92 } 93 return interceptor; 94 } 95 96 @Override registerReceiver(BroadcastReceiver receiver, IntentFilter filter)97 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { 98 synchronized (mInterceptors) { 99 mInterceptors.add(new BroadcastInterceptor(receiver, filter)); 100 } 101 return null; 102 } 103 104 @Override registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)105 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, 106 String broadcastPermission, Handler scheduler) { 107 return registerReceiver(receiver, filter); 108 } 109 110 @Override unregisterReceiver(BroadcastReceiver receiver)111 public void unregisterReceiver(BroadcastReceiver receiver) { 112 synchronized (mInterceptors) { 113 final Iterator<BroadcastInterceptor> i = mInterceptors.iterator(); 114 while (i.hasNext()) { 115 final BroadcastInterceptor interceptor = i.next(); 116 if (receiver.equals(interceptor.mReceiver)) { 117 i.remove(); 118 } 119 } 120 } 121 } 122 123 @Override sendBroadcast(Intent intent)124 public void sendBroadcast(Intent intent) { 125 synchronized (mInterceptors) { 126 final Iterator<BroadcastInterceptor> i = mInterceptors.iterator(); 127 while (i.hasNext()) { 128 final BroadcastInterceptor interceptor = i.next(); 129 if (interceptor.dispatchBroadcast(intent)) { 130 i.remove(); 131 } 132 } 133 } 134 } 135 136 @Override sendBroadcast(Intent intent, String receiverPermission)137 public void sendBroadcast(Intent intent, String receiverPermission) { 138 sendBroadcast(intent); 139 } 140 141 @Override sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions)142 public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) { 143 sendBroadcast(intent); 144 } 145 146 @Override sendBroadcastAsUser(Intent intent, UserHandle user)147 public void sendBroadcastAsUser(Intent intent, UserHandle user) { 148 sendBroadcast(intent); 149 } 150 151 @Override sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission)152 public void sendBroadcastAsUser(Intent intent, UserHandle user, 153 String receiverPermission) { 154 sendBroadcast(intent); 155 } 156 157 @Override sendStickyBroadcast(Intent intent)158 public void sendStickyBroadcast(Intent intent) { 159 sendBroadcast(intent); 160 } 161 162 @Override sendStickyBroadcastAsUser(Intent intent, UserHandle user)163 public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) { 164 sendBroadcast(intent); 165 } 166 167 @Override removeStickyBroadcast(Intent intent)168 public void removeStickyBroadcast(Intent intent) { 169 // ignored 170 } 171 } 172