1 /* 2 * Copyright 2022 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 package com.android.app.cts.broadcasts.helper; 17 18 import android.app.Service; 19 import android.content.BroadcastReceiver; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.IntentFilter; 23 import android.os.Bundle; 24 import android.os.IBinder; 25 import android.os.Process; 26 import android.os.SystemClock; 27 import android.util.ArrayMap; 28 import android.util.ArraySet; 29 import android.util.Log; 30 31 import androidx.annotation.GuardedBy; 32 33 import com.android.app.cts.broadcasts.BroadcastReceipt; 34 import com.android.app.cts.broadcasts.ICommandReceiver; 35 36 import java.util.ArrayList; 37 import java.util.Arrays; 38 import java.util.List; 39 40 public class TestService extends Service { 41 private static final String TAG = "TestService"; 42 43 @GuardedBy("mReceivedBroadcasts") 44 private static final ArrayMap<String, ArrayList<BroadcastReceipt>> sReceivedBroadcasts = 45 new ArrayMap<>(); 46 47 @GuardedBy("mRegisteredReceivers") 48 private static final ArraySet<BroadcastReceiver> sRegisteredReceivers = new ArraySet<>(); 49 50 @Override onBind(Intent intent)51 public IBinder onBind(Intent intent) { 52 return new CommandReceiver(); 53 } 54 registerReceiver(Context context, BroadcastReceiver receiver, IntentFilter filter, int flags)55 void registerReceiver(Context context, BroadcastReceiver receiver, 56 IntentFilter filter, int flags) { 57 context.registerReceiver(receiver, filter, flags); 58 synchronized (sRegisteredReceivers) { 59 sRegisteredReceivers.add(receiver); 60 } 61 } 62 unregisterReceiver(Context context, BroadcastReceiver receiver)63 void unregisterReceiver(Context context, BroadcastReceiver receiver) { 64 context.unregisterReceiver(receiver); 65 synchronized (sRegisteredReceivers) { 66 sRegisteredReceivers.remove(receiver); 67 } 68 } 69 70 private class CommandReceiver extends ICommandReceiver.Stub { 71 @Override sendBroadcast(Intent intent, Bundle options)72 public void sendBroadcast(Intent intent, Bundle options) { 73 TestService.this.sendBroadcast(intent, null /* receiverPermission */, options); 74 } 75 76 @Override monitorBroadcasts(IntentFilter filter, String cookie)77 public void monitorBroadcasts(IntentFilter filter, String cookie) { 78 registerReceiver(TestService.this.getApplicationContext(), new BroadcastReceiver() { 79 @Override 80 public void onReceive(Context context, Intent intent) { 81 Log.d(TAG, "Received broadcast: " + intent + " for " + cookie); 82 synchronized (sReceivedBroadcasts) { 83 ArrayList<BroadcastReceipt> receivedBroadcasts = sReceivedBroadcasts.get( 84 cookie); 85 if (receivedBroadcasts == null) { 86 receivedBroadcasts = new ArrayList(); 87 sReceivedBroadcasts.put(cookie, receivedBroadcasts); 88 } 89 receivedBroadcasts.add(BroadcastReceipt.create( 90 SystemClock.elapsedRealtime(), intent)); 91 } 92 } 93 }, filter, Context.RECEIVER_EXPORTED); 94 } 95 96 @Override getReceivedBroadcasts(String cookie)97 public List<BroadcastReceipt> getReceivedBroadcasts(String cookie) { 98 synchronized (sReceivedBroadcasts) { 99 final ArrayList<BroadcastReceipt> receivedBroadcasts = 100 sReceivedBroadcasts.get(cookie); 101 return receivedBroadcasts == null ? new ArrayList<>() : receivedBroadcasts; 102 } 103 } 104 listToString(List<T> list)105 private <T> String listToString(List<T> list) { 106 return list == null ? null : Arrays.toString(list.toArray()); 107 } 108 109 @Override clearCookie(String cookie)110 public void clearCookie(String cookie) { 111 synchronized (sReceivedBroadcasts) { 112 sReceivedBroadcasts.remove(cookie); 113 } 114 } 115 116 @Override getPid()117 public int getPid() { 118 return Process.myPid(); 119 } 120 121 @Override tearDown()122 public void tearDown() { 123 synchronized (sReceivedBroadcasts) { 124 sReceivedBroadcasts.clear(); 125 } 126 synchronized (sRegisteredReceivers) { 127 for (int i = sRegisteredReceivers.size() - 1; i >= 0; --i) { 128 TestService.this.getApplicationContext().unregisterReceiver( 129 sRegisteredReceivers.valueAt(i)); 130 sRegisteredReceivers.removeAt(i); 131 } 132 } 133 } 134 } 135 } 136 137