[go: nahoru, domu]

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