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 17package com.android.server; 18 19import android.content.BroadcastReceiver; 20import android.content.Context; 21import android.content.ContextWrapper; 22import android.content.Intent; 23import android.content.IntentFilter; 24import android.os.Bundle; 25import android.os.Handler; 26import android.os.UserHandle; 27 28import com.google.common.collect.Lists; 29import com.google.common.util.concurrent.AbstractFuture; 30 31import java.util.Iterator; 32import java.util.List; 33import java.util.concurrent.ExecutionException; 34import java.util.concurrent.Future; 35import java.util.concurrent.TimeUnit; 36import java.util.concurrent.TimeoutException; 37 38/** 39 * {@link ContextWrapper} that can attach listeners for upcoming 40 * {@link Context#sendBroadcast(Intent)}. 41 */ 42public class BroadcastInterceptingContext extends ContextWrapper { 43 private static final String TAG = "WatchingContext"; 44 45 private final List<BroadcastInterceptor> mInterceptors = Lists.newArrayList(); 46 47 public class BroadcastInterceptor extends AbstractFuture<Intent> { 48 private final BroadcastReceiver mReceiver; 49 private final IntentFilter mFilter; 50 51 public BroadcastInterceptor(BroadcastReceiver receiver, IntentFilter filter) { 52 mReceiver = receiver; 53 mFilter = filter; 54 } 55 56 public boolean dispatchBroadcast(Intent intent) { 57 if (mFilter.match(getContentResolver(), intent, false, TAG) > 0) { 58 if (mReceiver != null) { 59 final Context context = BroadcastInterceptingContext.this; 60 mReceiver.onReceive(context, intent); 61 return false; 62 } else { 63 set(intent); 64 return true; 65 } 66 } else { 67 return false; 68 } 69 } 70 71 @Override 72 public Intent get() throws InterruptedException, ExecutionException { 73 try { 74 return get(5, TimeUnit.SECONDS); 75 } catch (TimeoutException e) { 76 throw new RuntimeException(e); 77 } 78 } 79 } 80 81 public BroadcastInterceptingContext(Context base) { 82 super(base); 83 } 84 85 public Future<Intent> nextBroadcastIntent(String action) { 86 return nextBroadcastIntent(new IntentFilter(action)); 87 } 88 89 public Future<Intent> nextBroadcastIntent(IntentFilter filter) { 90 final BroadcastInterceptor interceptor = new BroadcastInterceptor(null, filter); 91 synchronized (mInterceptors) { 92 mInterceptors.add(interceptor); 93 } 94 return interceptor; 95 } 96 97 @Override 98 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { 99 synchronized (mInterceptors) { 100 mInterceptors.add(new BroadcastInterceptor(receiver, filter)); 101 } 102 return null; 103 } 104 105 @Override 106 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, 107 String broadcastPermission, Handler scheduler) { 108 return registerReceiver(receiver, filter); 109 } 110 111 @Override 112 public void unregisterReceiver(BroadcastReceiver receiver) { 113 synchronized (mInterceptors) { 114 final Iterator<BroadcastInterceptor> i = mInterceptors.iterator(); 115 while (i.hasNext()) { 116 final BroadcastInterceptor interceptor = i.next(); 117 if (receiver.equals(interceptor.mReceiver)) { 118 i.remove(); 119 } 120 } 121 } 122 } 123 124 @Override 125 public void sendBroadcast(Intent intent) { 126 synchronized (mInterceptors) { 127 final Iterator<BroadcastInterceptor> i = mInterceptors.iterator(); 128 while (i.hasNext()) { 129 final BroadcastInterceptor interceptor = i.next(); 130 if (interceptor.dispatchBroadcast(intent)) { 131 i.remove(); 132 } 133 } 134 } 135 } 136 137 @Override 138 public void sendBroadcast(Intent intent, String receiverPermission) { 139 sendBroadcast(intent); 140 } 141 142 @Override 143 public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) { 144 sendBroadcast(intent); 145 } 146 147 @Override 148 public void sendBroadcastAsUser(Intent intent, UserHandle user) { 149 sendBroadcast(intent); 150 } 151 152 @Override 153 public void sendBroadcastAsUser(Intent intent, UserHandle user, 154 String receiverPermission) { 155 sendBroadcast(intent); 156 } 157 158 @Override 159 public void sendStickyBroadcast(Intent intent) { 160 sendBroadcast(intent); 161 } 162 163 @Override 164 public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) { 165 sendBroadcast(intent); 166 } 167 168 @Override 169 public void sendStickyBroadcastAsUser(Intent intent, UserHandle user, Bundle options) { 170 sendBroadcast(intent); 171 } 172 173 @Override 174 public void removeStickyBroadcast(Intent intent) { 175 // ignored 176 } 177} 178