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 50 public BroadcastInterceptor(BroadcastReceiver receiver, IntentFilter filter) { 51 mReceiver = receiver; 52 mFilter = filter; 53 } 54 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 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 80 public BroadcastInterceptingContext(Context base) { 81 super(base); 82 } 83 84 public Future<Intent> nextBroadcastIntent(String action) { 85 return nextBroadcastIntent(new IntentFilter(action)); 86 } 87 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 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 105 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, 106 String broadcastPermission, Handler scheduler) { 107 return registerReceiver(receiver, filter); 108 } 109 110 @Override 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 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 137 public void sendBroadcast(Intent intent, String receiverPermission) { 138 sendBroadcast(intent); 139 } 140 141 @Override 142 public void sendBroadcastAsUser(Intent intent, UserHandle user) { 143 sendBroadcast(intent); 144 } 145 146 @Override 147 public void sendBroadcastAsUser(Intent intent, UserHandle user, 148 String receiverPermission) { 149 sendBroadcast(intent); 150 } 151 152 @Override 153 public void sendStickyBroadcast(Intent intent) { 154 sendBroadcast(intent); 155 } 156 157 @Override 158 public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) { 159 sendBroadcast(intent); 160 } 161 162 @Override 163 public void removeStickyBroadcast(Intent intent) { 164 // ignored 165 } 166 } 167