blob: 13657ab7f02d697039ea03007c39da9ee8a129dd [file] [log] [blame]
Jeff Sharkey9599cc52011-05-22 14:59:31 -07001/*
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;
Dianne Hackborne0e413e2015-12-09 17:22:26 -080024import android.os.Bundle;
Jeff Sharkey9599cc52011-05-22 14:59:31 -070025import android.os.Handler;
Jeff Sharkey3671b1e2013-01-31 17:22:26 -080026import android.os.UserHandle;
Jeff Sharkey9599cc52011-05-22 14:59:31 -070027
28import com.google.common.collect.Lists;
29import com.google.common.util.concurrent.AbstractFuture;
30
31import java.util.Iterator;
32import java.util.List;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -070033import java.util.concurrent.ExecutionException;
Jeff Sharkey9599cc52011-05-22 14:59:31 -070034import java.util.concurrent.Future;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -070035import java.util.concurrent.TimeUnit;
36import java.util.concurrent.TimeoutException;
Jeff Sharkey9599cc52011-05-22 14:59:31 -070037
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 }
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -070070
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 }
Jeff Sharkey9599cc52011-05-22 14:59:31 -070079 }
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
Jeff Sharkey3671b1e2013-01-31 17:22:26 -0800138 public void sendBroadcast(Intent intent, String receiverPermission) {
139 sendBroadcast(intent);
140 }
141
142 @Override
Fyodor Kupolovd4fd8c72015-07-13 19:19:25 -0700143 public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) {
144 sendBroadcast(intent);
145 }
146
147 @Override
Jeff Sharkey3671b1e2013-01-31 17:22:26 -0800148 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
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700159 public void sendStickyBroadcast(Intent intent) {
160 sendBroadcast(intent);
161 }
162
163 @Override
Jeff Sharkey3671b1e2013-01-31 17:22:26 -0800164 public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700165 sendBroadcast(intent);
166 }
167
168 @Override
Dianne Hackborne0e413e2015-12-09 17:22:26 -0800169 public void sendStickyBroadcastAsUser(Intent intent, UserHandle user, Bundle options) {
170 sendBroadcast(intent);
171 }
172
173 @Override
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700174 public void removeStickyBroadcast(Intent intent) {
175 // ignored
176 }
177}