1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 * except in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 * KIND, either express or implied. See the License for the specific language governing 12 * permissions and limitations under the License. 13 */ 14 15 package com.android.systemui; 16 17 import static org.mockito.ArgumentMatchers.any; 18 import static org.mockito.ArgumentMatchers.anyInt; 19 import static org.mockito.ArgumentMatchers.eq; 20 import static org.mockito.Mockito.mock; 21 import static org.mockito.Mockito.never; 22 import static org.mockito.Mockito.spy; 23 import static org.mockito.Mockito.timeout; 24 import static org.mockito.Mockito.verify; 25 26 import android.content.BroadcastReceiver; 27 import android.content.ComponentName; 28 import android.content.ContentProvider; 29 import android.content.ContentResolver; 30 import android.content.Context; 31 import android.content.Intent; 32 import android.content.IntentFilter; 33 import android.net.Uri; 34 import android.platform.test.annotations.DisableFlags; 35 import android.platform.test.annotations.EnableFlags; 36 import android.platform.test.flag.junit.FlagsParameterization; 37 38 import androidx.test.filters.SmallTest; 39 40 import com.android.settingslib.SliceBroadcastRelay; 41 import com.android.systemui.broadcast.BroadcastDispatcher; 42 import com.android.systemui.util.concurrency.FakeExecutor; 43 import com.android.systemui.util.time.FakeSystemClock; 44 45 import org.junit.Before; 46 import org.junit.Test; 47 import org.junit.runner.RunWith; 48 import org.junit.runners.Parameterized; 49 import org.mockito.ArgumentCaptor; 50 import org.mockito.Mock; 51 import org.mockito.MockitoAnnotations; 52 53 import java.util.List; 54 55 @RunWith(Parameterized.class) 56 @SmallTest 57 public class SliceBroadcastRelayHandlerTest extends SysuiTestCase { 58 59 @Parameterized.Parameters(name = "{0}") getFlags()60 public static List<FlagsParameterization> getFlags() { 61 return FlagsParameterization.allCombinationsOf( 62 Flags.FLAG_SLICE_BROADCAST_RELAY_IN_BACKGROUND); 63 } 64 65 private static final String TEST_ACTION = "com.android.systemui.action.TEST_ACTION"; 66 private final FakeExecutor mBackgroundExecutor = new FakeExecutor(new FakeSystemClock()); 67 68 private SliceBroadcastRelayHandler mRelayHandler; 69 private Context mSpyContext; 70 @Mock 71 private BroadcastDispatcher mBroadcastDispatcher; 72 73 SliceBroadcastRelayHandlerTest(FlagsParameterization flags)74 public SliceBroadcastRelayHandlerTest(FlagsParameterization flags) { 75 mSetFlagsRule.setFlagsParameterization(flags); 76 } 77 78 @Before setup()79 public void setup() { 80 MockitoAnnotations.initMocks(this); 81 mSpyContext = spy(mContext); 82 83 mRelayHandler = new SliceBroadcastRelayHandler(mSpyContext, mBroadcastDispatcher, 84 mBackgroundExecutor); 85 } 86 87 @Test testRegister()88 public void testRegister() { 89 Uri testUri = new Uri.Builder() 90 .scheme(ContentResolver.SCHEME_CONTENT) 91 .authority("something") 92 .path("test") 93 .build(); 94 95 Intent intent = new Intent(SliceBroadcastRelay.ACTION_REGISTER); 96 intent.putExtra(SliceBroadcastRelay.EXTRA_URI, ContentProvider.maybeAddUserId(testUri, 0)); 97 intent.putExtra(SliceBroadcastRelay.EXTRA_RECEIVER, 98 new ComponentName(mContext.getPackageName(), Receiver.class.getName())); 99 IntentFilter value = new IntentFilter(TEST_ACTION); 100 intent.putExtra(SliceBroadcastRelay.EXTRA_FILTER, value); 101 intent.putExtra(SliceBroadcastRelay.EXTRA_URI, testUri); 102 103 mRelayHandler.handleIntent(intent); 104 mBackgroundExecutor.runAllReady(); 105 verify(mSpyContext).registerReceiver(any(), eq(value), anyInt()); 106 } 107 108 @Test testUnregister()109 public void testUnregister() { 110 Uri testUri = new Uri.Builder() 111 .scheme(ContentResolver.SCHEME_CONTENT) 112 .authority("something") 113 .path("test") 114 .build(); 115 116 Intent intent = new Intent(SliceBroadcastRelay.ACTION_REGISTER); 117 intent.putExtra(SliceBroadcastRelay.EXTRA_URI, ContentProvider.maybeAddUserId(testUri, 0)); 118 intent.putExtra(SliceBroadcastRelay.EXTRA_RECEIVER, 119 new ComponentName(mContext.getPackageName(), Receiver.class.getName())); 120 IntentFilter value = new IntentFilter(TEST_ACTION); 121 intent.putExtra(SliceBroadcastRelay.EXTRA_FILTER, value); 122 123 mRelayHandler.handleIntent(intent); 124 mBackgroundExecutor.runAllReady(); 125 ArgumentCaptor<BroadcastReceiver> relay = ArgumentCaptor.forClass(BroadcastReceiver.class); 126 verify(mSpyContext).registerReceiver(relay.capture(), eq(value), anyInt()); 127 128 intent = new Intent(SliceBroadcastRelay.ACTION_UNREGISTER); 129 intent.putExtra(SliceBroadcastRelay.EXTRA_URI, ContentProvider.maybeAddUserId(testUri, 0)); 130 mRelayHandler.handleIntent(intent); 131 mBackgroundExecutor.runAllReady(); 132 verify(mSpyContext).unregisterReceiver(eq(relay.getValue())); 133 } 134 135 @Test testUnregisterWithoutRegister()136 public void testUnregisterWithoutRegister() { 137 Uri testUri = new Uri.Builder() 138 .scheme(ContentResolver.SCHEME_CONTENT) 139 .authority("something") 140 .path("test") 141 .build(); 142 143 Intent intent = new Intent(SliceBroadcastRelay.ACTION_UNREGISTER); 144 intent.putExtra(SliceBroadcastRelay.EXTRA_URI, ContentProvider.maybeAddUserId(testUri, 0)); 145 mRelayHandler.handleIntent(intent); 146 mBackgroundExecutor.runAllReady(); 147 // No crash 148 } 149 150 @Test testRelay()151 public void testRelay() { 152 Receiver.sReceiver = mock(BroadcastReceiver.class); 153 Uri testUri = new Uri.Builder() 154 .scheme(ContentResolver.SCHEME_CONTENT) 155 .authority("something") 156 .path("test") 157 .build(); 158 Intent intent = new Intent(SliceBroadcastRelay.ACTION_REGISTER); 159 intent.putExtra(SliceBroadcastRelay.EXTRA_URI, ContentProvider.maybeAddUserId(testUri, 0)); 160 intent.putExtra(SliceBroadcastRelay.EXTRA_RECEIVER, 161 new ComponentName(mContext.getPackageName(), Receiver.class.getName())); 162 IntentFilter value = new IntentFilter(TEST_ACTION); 163 intent.putExtra(SliceBroadcastRelay.EXTRA_FILTER, value); 164 165 mRelayHandler.handleIntent(intent); 166 mBackgroundExecutor.runAllReady(); 167 ArgumentCaptor<BroadcastReceiver> relay = ArgumentCaptor.forClass(BroadcastReceiver.class); 168 verify(mSpyContext).registerReceiver(relay.capture(), eq(value), anyInt()); 169 relay.getValue().onReceive(mSpyContext, new Intent(TEST_ACTION)); 170 171 verify(Receiver.sReceiver, timeout(2000)).onReceive(any(), any()); 172 } 173 174 @Test 175 @DisableFlags(Flags.FLAG_SLICE_BROADCAST_RELAY_IN_BACKGROUND) testRegisteredWithDispatcher_onMainThread()176 public void testRegisteredWithDispatcher_onMainThread() { 177 mRelayHandler.start(); 178 mBackgroundExecutor.runAllReady(); 179 180 verify(mBroadcastDispatcher) 181 .registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class)); 182 verify(mSpyContext, never()) 183 .registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class)); 184 } 185 186 @Test 187 @EnableFlags(Flags.FLAG_SLICE_BROADCAST_RELAY_IN_BACKGROUND) testRegisteredWithDispatcher_onBackgroundThread()188 public void testRegisteredWithDispatcher_onBackgroundThread() { 189 mRelayHandler.start(); 190 mBackgroundExecutor.runAllReady(); 191 192 verify(mBroadcastDispatcher) 193 .registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class), 194 eq(mBackgroundExecutor)); 195 verify(mSpyContext, never()) 196 .registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class)); 197 } 198 199 public static class Receiver extends BroadcastReceiver { 200 private static BroadcastReceiver sReceiver; 201 202 @Override onReceive(Context context, Intent intent)203 public void onReceive(Context context, Intent intent) { 204 if (sReceiver != null) sReceiver.onReceive(context, intent); 205 } 206 } 207 208 }