Home | History | Annotate | Download | only in test
      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.internal.util.test;
     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.Bundle;
     25 import android.os.Handler;
     26 import android.os.UserHandle;
     27 
     28 import java.util.ArrayList;
     29 import java.util.Iterator;
     30 import java.util.List;
     31 import java.util.concurrent.ExecutionException;
     32 import java.util.concurrent.Future;
     33 import java.util.concurrent.FutureTask;
     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 = new ArrayList<>();
     45 
     46     public abstract class FutureIntent extends FutureTask<Intent> {
     47         public FutureIntent() {
     48             super(
     49                 () -> { throw new IllegalStateException("Cannot happen"); }
     50             );
     51         }
     52 
     53         public void assertNotReceived()
     54                 throws InterruptedException, ExecutionException {
     55             assertNotReceived(5, TimeUnit.SECONDS);
     56         }
     57 
     58         public abstract void assertNotReceived(long timeout, TimeUnit unit)
     59                 throws InterruptedException, ExecutionException;
     60     }
     61 
     62     public class BroadcastInterceptor extends FutureIntent {
     63         private final BroadcastReceiver mReceiver;
     64         private final IntentFilter mFilter;
     65 
     66         public BroadcastInterceptor(BroadcastReceiver receiver, IntentFilter filter) {
     67             mReceiver = receiver;
     68             mFilter = filter;
     69         }
     70 
     71         public boolean dispatchBroadcast(Intent intent) {
     72             if (mFilter.match(getContentResolver(), intent, false, TAG) > 0) {
     73                 if (mReceiver != null) {
     74                     final Context context = BroadcastInterceptingContext.this;
     75                     mReceiver.onReceive(context, intent);
     76                     return false;
     77                 } else {
     78                     set(intent);
     79                     return true;
     80                 }
     81             } else {
     82                 return false;
     83             }
     84         }
     85 
     86         @Override
     87         public Intent get() throws InterruptedException, ExecutionException {
     88             try {
     89                 return get(5, TimeUnit.SECONDS);
     90             } catch (TimeoutException e) {
     91                 throw new RuntimeException(e);
     92             }
     93         }
     94 
     95         @Override
     96         public void assertNotReceived()
     97             throws InterruptedException, ExecutionException {
     98             assertNotReceived(5, TimeUnit.SECONDS);
     99         }
    100 
    101         public void assertNotReceived(long timeout, TimeUnit unit)
    102                 throws InterruptedException, ExecutionException {
    103             try {
    104                 final Intent intent = get(timeout, unit);
    105                 throw new AssertionError("Received intent: " + intent);
    106             } catch (TimeoutException e) {
    107             }
    108         }
    109     }
    110 
    111     public BroadcastInterceptingContext(Context base) {
    112         super(base);
    113     }
    114 
    115     public FutureIntent nextBroadcastIntent(String action) {
    116         return nextBroadcastIntent(new IntentFilter(action));
    117     }
    118 
    119     public FutureIntent nextBroadcastIntent(IntentFilter filter) {
    120         final BroadcastInterceptor interceptor = new BroadcastInterceptor(null, filter);
    121         synchronized (mInterceptors) {
    122             mInterceptors.add(interceptor);
    123         }
    124         return interceptor;
    125     }
    126 
    127     @Override
    128     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
    129         synchronized (mInterceptors) {
    130             mInterceptors.add(new BroadcastInterceptor(receiver, filter));
    131         }
    132         return null;
    133     }
    134 
    135     @Override
    136     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
    137             String broadcastPermission, Handler scheduler) {
    138         return registerReceiver(receiver, filter);
    139     }
    140 
    141     @Override
    142     public void unregisterReceiver(BroadcastReceiver receiver) {
    143         synchronized (mInterceptors) {
    144             final Iterator<BroadcastInterceptor> i = mInterceptors.iterator();
    145             while (i.hasNext()) {
    146                 final BroadcastInterceptor interceptor = i.next();
    147                 if (receiver.equals(interceptor.mReceiver)) {
    148                     i.remove();
    149                 }
    150             }
    151         }
    152     }
    153 
    154     @Override
    155     public void sendBroadcast(Intent intent) {
    156         synchronized (mInterceptors) {
    157             final Iterator<BroadcastInterceptor> i = mInterceptors.iterator();
    158             while (i.hasNext()) {
    159                 final BroadcastInterceptor interceptor = i.next();
    160                 if (interceptor.dispatchBroadcast(intent)) {
    161                     i.remove();
    162                 }
    163             }
    164         }
    165     }
    166 
    167     @Override
    168     public void sendBroadcast(Intent intent, String receiverPermission) {
    169         sendBroadcast(intent);
    170     }
    171 
    172     @Override
    173     public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) {
    174         sendBroadcast(intent);
    175     }
    176 
    177     @Override
    178     public void sendBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user,
    179             String[] receiverPermissions) {
    180         sendBroadcast(intent);
    181     }
    182 
    183     @Override
    184     public void sendBroadcastAsUser(Intent intent, UserHandle user) {
    185         sendBroadcast(intent);
    186     }
    187 
    188     @Override
    189     public void sendBroadcastAsUser(Intent intent, UserHandle user,
    190             String receiverPermission) {
    191         sendBroadcast(intent);
    192     }
    193 
    194     @Override
    195     public void sendStickyBroadcast(Intent intent) {
    196         sendBroadcast(intent);
    197     }
    198 
    199     @Override
    200     public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
    201         sendBroadcast(intent);
    202     }
    203 
    204     @Override
    205     public void sendStickyBroadcastAsUser(Intent intent, UserHandle user, Bundle options) {
    206         sendBroadcast(intent);
    207     }
    208 
    209     @Override
    210     public void removeStickyBroadcast(Intent intent) {
    211         // ignored
    212     }
    213 }
    214