1 /* 2 * Copyright (C) 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 17 package com.android.settings.safetycenter; 18 19 import static android.safetycenter.SafetyCenterManager.ACTION_REFRESH_SAFETY_SOURCES; 20 import static android.safetycenter.SafetyCenterManager.EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID; 21 import static android.safetycenter.SafetyCenterManager.EXTRA_REFRESH_SAFETY_SOURCE_IDS; 22 import static android.safetycenter.SafetyEvent.SAFETY_EVENT_TYPE_DEVICE_REBOOTED; 23 import static android.safetycenter.SafetyEvent.SAFETY_EVENT_TYPE_REFRESH_REQUESTED; 24 import static com.google.common.truth.Truth.assertThat; 25 import static org.mockito.ArgumentMatchers.any; 26 import static org.mockito.Mockito.never; 27 import static org.mockito.Mockito.times; 28 import static org.mockito.Mockito.verify; 29 import static org.mockito.Mockito.when; 30 31 import android.content.Context; 32 import android.content.Intent; 33 import android.os.Flags; 34 import android.platform.test.flag.junit.SetFlagsRule; 35 import android.safetycenter.SafetyEvent; 36 import android.safetycenter.SafetySourceData; 37 38 import androidx.test.core.app.ApplicationProvider; 39 import androidx.test.ext.junit.runners.AndroidJUnit4; 40 41 import com.android.internal.widget.LockPatternUtils; 42 import com.android.settings.privatespace.PrivateSpaceSafetySource; 43 import com.android.settings.testutils.FakeFeatureFactory; 44 45 import org.junit.After; 46 import org.junit.Before; 47 import org.junit.Rule; 48 import org.junit.Test; 49 import org.junit.runner.RunWith; 50 import org.mockito.ArgumentCaptor; 51 import org.mockito.Mock; 52 import org.mockito.MockitoAnnotations; 53 54 import java.util.Arrays; 55 import java.util.List; 56 57 @RunWith(AndroidJUnit4.class) 58 public class SafetySourceBroadcastReceiverTest { 59 60 private static final String REFRESH_BROADCAST_ID = "REFRESH_BROADCAST_ID"; 61 62 private Context mApplicationContext; 63 64 @Mock private SafetyCenterManagerWrapper mSafetyCenterManagerWrapper; 65 66 @Mock private LockPatternUtils mLockPatternUtils; 67 @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); 68 69 @Before setUp()70 public void setUp() { 71 MockitoAnnotations.initMocks(this); 72 mApplicationContext = ApplicationProvider.getApplicationContext(); 73 final FakeFeatureFactory featureFactory = FakeFeatureFactory.setupForTest(); 74 when(featureFactory.securityFeatureProvider.getLockPatternUtils(mApplicationContext)) 75 .thenReturn(mLockPatternUtils); 76 SafetyCenterManagerWrapper.sInstance = mSafetyCenterManagerWrapper; 77 } 78 79 @After tearDown()80 public void tearDown() { 81 SafetyCenterManagerWrapper.sInstance = null; 82 } 83 84 @Test onReceive_onRefresh_whenSafetyCenterIsDisabled_doesNotSetData()85 public void onReceive_onRefresh_whenSafetyCenterIsDisabled_doesNotSetData() { 86 when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(false); 87 Intent intent = 88 new Intent() 89 .setAction(ACTION_REFRESH_SAFETY_SOURCES) 90 .putExtra( 91 EXTRA_REFRESH_SAFETY_SOURCE_IDS, 92 new String[] {LockScreenSafetySource.SAFETY_SOURCE_ID}) 93 .putExtra(EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID, REFRESH_BROADCAST_ID); 94 95 new SafetySourceBroadcastReceiver().onReceive(mApplicationContext, intent); 96 97 verify(mSafetyCenterManagerWrapper, never()) 98 .setSafetySourceData(any(), any(), any(), any()); 99 } 100 101 @Test onReceive_onRefresh_whenSafetyCenterIsEnabled_withNoIntentAction_doesNotSetData()102 public void onReceive_onRefresh_whenSafetyCenterIsEnabled_withNoIntentAction_doesNotSetData() { 103 when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true); 104 Intent intent = 105 new Intent() 106 .putExtra( 107 EXTRA_REFRESH_SAFETY_SOURCE_IDS, 108 new String[] {LockScreenSafetySource.SAFETY_SOURCE_ID}) 109 .putExtra(EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID, REFRESH_BROADCAST_ID); 110 111 new SafetySourceBroadcastReceiver().onReceive(mApplicationContext, intent); 112 113 verify(mSafetyCenterManagerWrapper, never()) 114 .setSafetySourceData(any(), any(), any(), any()); 115 } 116 117 @Test onReceive_onRefresh_whenSafetyCenterIsEnabled_withNullSourceIds_doesNotSetData()118 public void onReceive_onRefresh_whenSafetyCenterIsEnabled_withNullSourceIds_doesNotSetData() { 119 when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true); 120 Intent intent = 121 new Intent() 122 .setAction(ACTION_REFRESH_SAFETY_SOURCES) 123 .putExtra(EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID, REFRESH_BROADCAST_ID); 124 125 new SafetySourceBroadcastReceiver().onReceive(mApplicationContext, intent); 126 127 verify(mSafetyCenterManagerWrapper, never()) 128 .setSafetySourceData(any(), any(), any(), any()); 129 } 130 131 @Test onReceive_onRefresh_whenSafetyCenterIsEnabled_withNoSourceIds_doesNotSetData()132 public void onReceive_onRefresh_whenSafetyCenterIsEnabled_withNoSourceIds_doesNotSetData() { 133 when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true); 134 Intent intent = 135 new Intent() 136 .setAction(ACTION_REFRESH_SAFETY_SOURCES) 137 .putExtra(EXTRA_REFRESH_SAFETY_SOURCE_IDS, new String[] {}) 138 .putExtra(EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID, REFRESH_BROADCAST_ID); 139 140 new SafetySourceBroadcastReceiver().onReceive(mApplicationContext, intent); 141 142 verify(mSafetyCenterManagerWrapper, never()) 143 .setSafetySourceData(any(), any(), any(), any()); 144 } 145 146 @Test onReceive_onRefresh_whenSafetyCenterIsEnabled_withNoBroadcastId_doesNotSetData()147 public void onReceive_onRefresh_whenSafetyCenterIsEnabled_withNoBroadcastId_doesNotSetData() { 148 when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true); 149 Intent intent = 150 new Intent() 151 .setAction(ACTION_REFRESH_SAFETY_SOURCES) 152 .putExtra( 153 EXTRA_REFRESH_SAFETY_SOURCE_IDS, 154 new String[] {LockScreenSafetySource.SAFETY_SOURCE_ID}); 155 156 new SafetySourceBroadcastReceiver().onReceive(mApplicationContext, intent); 157 158 verify(mSafetyCenterManagerWrapper, never()) 159 .setSafetySourceData(any(), any(), any(), any()); 160 } 161 162 @Test onReceive_onRefresh_setsRefreshEvent()163 public void onReceive_onRefresh_setsRefreshEvent() { 164 when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true); 165 Intent intent = 166 new Intent() 167 .setAction(ACTION_REFRESH_SAFETY_SOURCES) 168 .putExtra( 169 EXTRA_REFRESH_SAFETY_SOURCE_IDS, 170 new String[] {LockScreenSafetySource.SAFETY_SOURCE_ID}) 171 .putExtra(EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID, REFRESH_BROADCAST_ID); 172 173 new SafetySourceBroadcastReceiver().onReceive(mApplicationContext, intent); 174 ArgumentCaptor<SafetyEvent> captor = ArgumentCaptor.forClass(SafetyEvent.class); 175 verify(mSafetyCenterManagerWrapper, times(1)) 176 .setSafetySourceData(any(), any(), any(), captor.capture()); 177 178 assertThat(captor.getValue()) 179 .isEqualTo( 180 new SafetyEvent.Builder(SAFETY_EVENT_TYPE_REFRESH_REQUESTED) 181 .setRefreshBroadcastId(REFRESH_BROADCAST_ID) 182 .build()); 183 } 184 185 @Test onReceive_onRefresh_withLockscreenSourceId_setsLockscreenData()186 public void onReceive_onRefresh_withLockscreenSourceId_setsLockscreenData() { 187 when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true); 188 Intent intent = 189 new Intent() 190 .setAction(ACTION_REFRESH_SAFETY_SOURCES) 191 .putExtra( 192 EXTRA_REFRESH_SAFETY_SOURCE_IDS, 193 new String[] {LockScreenSafetySource.SAFETY_SOURCE_ID}) 194 .putExtra(EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID, REFRESH_BROADCAST_ID); 195 196 new SafetySourceBroadcastReceiver().onReceive(mApplicationContext, intent); 197 ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class); 198 verify(mSafetyCenterManagerWrapper, times(1)) 199 .setSafetySourceData(any(), captor.capture(), any(), any()); 200 201 assertThat(captor.getValue()).isEqualTo(LockScreenSafetySource.SAFETY_SOURCE_ID); 202 } 203 204 @Test onReceive_onRefresh_withBiometricsSourceId_setsBiometricData()205 public void onReceive_onRefresh_withBiometricsSourceId_setsBiometricData() { 206 when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true); 207 Intent intent = 208 new Intent() 209 .setAction(ACTION_REFRESH_SAFETY_SOURCES) 210 .putExtra( 211 EXTRA_REFRESH_SAFETY_SOURCE_IDS, 212 new String[] {BiometricsSafetySource.SAFETY_SOURCE_ID}) 213 .putExtra(EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID, REFRESH_BROADCAST_ID); 214 215 new SafetySourceBroadcastReceiver().onReceive(mApplicationContext, intent); 216 ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class); 217 verify(mSafetyCenterManagerWrapper, times(1)) 218 .setSafetySourceData(any(), captor.capture(), any(), any()); 219 220 assertThat(captor.getValue()).isEqualTo(BiometricsSafetySource.SAFETY_SOURCE_ID); 221 } 222 223 /** 224 * Tests that on receiving the refresh broadcast request with the PS source id, the PS data 225 * is set. 226 */ 227 @Test onReceive_onRefresh_withPrivateSpaceSourceId_setsPrivateSpaceData()228 public void onReceive_onRefresh_withPrivateSpaceSourceId_setsPrivateSpaceData() { 229 when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true); 230 Intent intent = 231 new Intent() 232 .setAction(ACTION_REFRESH_SAFETY_SOURCES) 233 .putExtra( 234 EXTRA_REFRESH_SAFETY_SOURCE_IDS, 235 new String[] {PrivateSpaceSafetySource.SAFETY_SOURCE_ID}) 236 .putExtra(EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID, REFRESH_BROADCAST_ID); 237 238 new SafetySourceBroadcastReceiver().onReceive(mApplicationContext, intent); 239 ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class); 240 verify(mSafetyCenterManagerWrapper, times(1)) 241 .setSafetySourceData(any(), captor.capture(), any(), any()); 242 243 assertThat(captor.getValue()).isEqualTo(PrivateSpaceSafetySource.SAFETY_SOURCE_ID); 244 } 245 246 /** Tests that the PS source sets null data when it's disabled. */ 247 @Test onReceive_onRefresh_withPrivateSpaceFeatureDisabled_setsNullData()248 public void onReceive_onRefresh_withPrivateSpaceFeatureDisabled_setsNullData() { 249 when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true); 250 mSetFlagsRule.disableFlags(Flags.FLAG_ALLOW_PRIVATE_PROFILE, 251 android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES); 252 253 Intent intent = 254 new Intent() 255 .setAction(ACTION_REFRESH_SAFETY_SOURCES) 256 .putExtra( 257 EXTRA_REFRESH_SAFETY_SOURCE_IDS, 258 new String[] {PrivateSpaceSafetySource.SAFETY_SOURCE_ID}) 259 .putExtra(EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID, REFRESH_BROADCAST_ID); 260 261 new SafetySourceBroadcastReceiver().onReceive(mApplicationContext, intent); 262 ArgumentCaptor<SafetySourceData> captor = ArgumentCaptor.forClass(SafetySourceData.class); 263 verify(mSafetyCenterManagerWrapper, times(1)) 264 .setSafetySourceData(any(), any(), captor.capture(), any()); 265 266 assertThat(captor.getValue()).isEqualTo(null); 267 } 268 269 @Test onReceive_onBootCompleted_setsBootCompleteEvent()270 public void onReceive_onBootCompleted_setsBootCompleteEvent() { 271 when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true); 272 Intent intent = new Intent().setAction(Intent.ACTION_BOOT_COMPLETED); 273 274 new SafetySourceBroadcastReceiver().onReceive(mApplicationContext, intent); 275 ArgumentCaptor<SafetyEvent> captor = ArgumentCaptor.forClass(SafetyEvent.class); 276 verify(mSafetyCenterManagerWrapper, times(3)) 277 .setSafetySourceData(any(), any(), any(), captor.capture()); 278 279 SafetyEvent bootEvent = new SafetyEvent.Builder(SAFETY_EVENT_TYPE_DEVICE_REBOOTED).build(); 280 assertThat(captor.getAllValues()) 281 .containsExactlyElementsIn(Arrays.asList(bootEvent, bootEvent, bootEvent)); 282 } 283 284 @Test onReceive_onBootCompleted_sendsAllSafetySourcesData()285 public void onReceive_onBootCompleted_sendsAllSafetySourcesData() { 286 when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true); 287 Intent intent = new Intent().setAction(Intent.ACTION_BOOT_COMPLETED); 288 289 new SafetySourceBroadcastReceiver().onReceive(mApplicationContext, intent); 290 ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class); 291 verify(mSafetyCenterManagerWrapper, times(3)) 292 .setSafetySourceData(any(), captor.capture(), any(), any()); 293 List<String> safetySourceIdList = captor.getAllValues(); 294 295 assertThat(safetySourceIdList.stream().anyMatch( 296 id -> id.equals(LockScreenSafetySource.SAFETY_SOURCE_ID))).isTrue(); 297 assertThat(safetySourceIdList.stream().anyMatch( 298 id -> id.equals(BiometricsSafetySource.SAFETY_SOURCE_ID))).isTrue(); 299 assertThat(safetySourceIdList.stream().anyMatch( 300 id -> id.equals(PrivateSpaceSafetySource.SAFETY_SOURCE_ID))).isTrue(); 301 } 302 } 303