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 package com.android.adservices.measurement; 17 18 import static org.junit.Assert.assertNotNull; 19 import static org.junit.Assert.assertNull; 20 import static org.mockito.ArgumentMatchers.any; 21 import static org.mockito.ArgumentMatchers.anyBoolean; 22 import static org.mockito.ArgumentMatchers.anyInt; 23 import static org.mockito.ArgumentMatchers.eq; 24 import static org.mockito.Mockito.doReturn; 25 import static org.mockito.Mockito.mock; 26 import static org.mockito.Mockito.never; 27 import static org.mockito.Mockito.spy; 28 import static org.mockito.Mockito.times; 29 import static org.mockito.Mockito.verify; 30 31 import android.content.Context; 32 import android.content.Intent; 33 import android.content.pm.PackageManager; 34 import android.os.IBinder; 35 36 import androidx.test.core.app.ApplicationProvider; 37 38 import com.android.adservices.common.AdServicesExtendedMockitoTestCase; 39 import com.android.adservices.data.enrollment.EnrollmentDao; 40 import com.android.adservices.download.MddJob; 41 import com.android.adservices.service.Flags; 42 import com.android.adservices.service.FlagsFactory; 43 import com.android.adservices.service.common.AppImportanceFilter; 44 import com.android.adservices.service.common.PackageChangedReceiver; 45 import com.android.adservices.service.consent.AdServicesApiConsent; 46 import com.android.adservices.service.consent.AdServicesApiType; 47 import com.android.adservices.service.consent.ConsentManager; 48 import com.android.adservices.service.devapi.DevContextFilter; 49 import com.android.adservices.service.encryptionkey.EncryptionKeyJobService; 50 import com.android.adservices.service.enrollment.EnrollmentData; 51 import com.android.adservices.service.measurement.DeleteExpiredJobService; 52 import com.android.adservices.service.measurement.DeleteUninstalledJobService; 53 import com.android.adservices.service.measurement.MeasurementImpl; 54 import com.android.adservices.service.measurement.attribution.AttributionFallbackJobService; 55 import com.android.adservices.service.measurement.attribution.AttributionJobService; 56 import com.android.adservices.service.measurement.registration.AsyncRegistrationFallbackJob; 57 import com.android.adservices.service.measurement.registration.AsyncRegistrationQueueJobService; 58 import com.android.adservices.service.measurement.reporting.AggregateFallbackReportingJobService; 59 import com.android.adservices.service.measurement.reporting.AggregateReportingJobService; 60 import com.android.adservices.service.measurement.reporting.DebugReportingFallbackJobService; 61 import com.android.adservices.service.measurement.reporting.EventFallbackReportingJobService; 62 import com.android.adservices.service.measurement.reporting.EventReportingJobService; 63 import com.android.adservices.service.measurement.reporting.VerboseDebugReportingFallbackJobService; 64 import com.android.adservices.service.ui.data.UxStatesManager; 65 import com.android.compatibility.common.util.TestUtils; 66 import com.android.dx.mockito.inline.extended.ExtendedMockito; 67 import com.android.modules.utils.testing.ExtendedMockitoRule.SpyStatic; 68 69 import org.junit.Test; 70 import org.mockito.Mock; 71 72 import java.util.List; 73 74 /** Unit test for {@link com.android.adservices.measurement.MeasurementService}. */ 75 @SpyStatic(AggregateReportingJobService.class) 76 @SpyStatic(AggregateFallbackReportingJobService.class) 77 @SpyStatic(AppImportanceFilter.class) 78 @SpyStatic(AttributionJobService.class) 79 @SpyStatic(AttributionFallbackJobService.class) 80 @SpyStatic(ConsentManager.class) 81 @SpyStatic(UxStatesManager.class) 82 @SpyStatic(DevContextFilter.class) 83 @SpyStatic(EnrollmentDao.class) 84 @SpyStatic(EventReportingJobService.class) 85 @SpyStatic(PackageChangedReceiver.class) 86 @SpyStatic(EventFallbackReportingJobService.class) 87 @SpyStatic(DeleteExpiredJobService.class) 88 @SpyStatic(DeleteUninstalledJobService.class) 89 @SpyStatic(MddJob.class) 90 @SpyStatic(EncryptionKeyJobService.class) 91 @SpyStatic(FlagsFactory.class) 92 @SpyStatic(MeasurementImpl.class) 93 @SpyStatic(AsyncRegistrationQueueJobService.class) 94 @SpyStatic(AsyncRegistrationFallbackJob.class) 95 @SpyStatic(VerboseDebugReportingFallbackJobService.class) 96 @SpyStatic(DebugReportingFallbackJobService.class) 97 public final class MeasurementServiceTest extends AdServicesExtendedMockitoTestCase { 98 @Mock private ConsentManager mMockConsentManager; 99 @Mock private DevContextFilter mDevContextFilter; 100 @Mock private Flags mMockFlags; 101 @Mock private MeasurementImpl mMockMeasurementImpl; 102 @Mock private EnrollmentDao mMockEnrollmentDao; 103 @Mock private AppImportanceFilter mMockAppImportanceFilter; 104 105 private static final EnrollmentData ENROLLMENT = 106 new EnrollmentData.Builder() 107 .setEnrollmentId("E1") 108 .setEnrolledAPIs("PRIVACY_SANDBOX_API_ATTRIBUTION_REPORTING") 109 .setSdkNames("sdk1") 110 .setAttributionSourceRegistrationUrl(List.of("https://test.com/source")) 111 .setAttributionTriggerRegistrationUrl(List.of("https://test.com/trigger")) 112 .setAttributionReportingUrl(List.of("https://test.com")) 113 .setRemarketingResponseBasedRegistrationUrl(List.of("https://test.com")) 114 .setEncryptionKeyUrl("https://test.com/keys") 115 .build(); 116 117 /** Test kill switch off with consent given */ 118 @Test testBindableMeasurementService_killSwitchOff_gaUxEnabled_consentGiven()119 public void testBindableMeasurementService_killSwitchOff_gaUxEnabled_consentGiven() 120 throws Exception { 121 runWithMocks( 122 /* killSwitchOff */ false, 123 /* consentNotifiedState */ 124 /* consentGiven */ true, 125 () -> { 126 // Execute 127 final IBinder binder = onCreateAndOnBindService(); 128 129 // Verification 130 assertNotNull(binder); 131 verify(mMockConsentManager, never()).getConsent(); 132 verify(mMockConsentManager, times(1)) 133 .getConsent(eq(AdServicesApiType.MEASUREMENTS)); 134 ExtendedMockito.verify( 135 () -> PackageChangedReceiver.enableReceiver(any(Context.class), any())); 136 assertJobScheduled(/* timesCalled */ 1); 137 }); 138 } 139 140 /** Test kill switch off with consent revoked */ 141 @Test testBindableMeasurementService_killSwitchOff_gaUxEnabled_consentRevoked()142 public void testBindableMeasurementService_killSwitchOff_gaUxEnabled_consentRevoked() 143 throws Exception { 144 runWithMocks( 145 /* killSwitchOff */ false, 146 /* consentNotifiedState */ 147 /* consentRevoked */ false, 148 () -> { 149 // Execute 150 final IBinder binder = onCreateAndOnBindService(); 151 152 // Verification 153 assertNotNull(binder); 154 verify(mMockConsentManager, never()).getConsent(); 155 verify(mMockConsentManager, times(1)) 156 .getConsent(eq(AdServicesApiType.MEASUREMENTS)); 157 assertJobScheduled(/* timesCalled */ 0); 158 }); 159 } 160 161 /** Test kill switch on */ 162 @Test testBindableMeasurementService_killSwitchOn_gaUxEnabled()163 public void testBindableMeasurementService_killSwitchOn_gaUxEnabled() throws Exception { 164 runWithMocks( 165 /* killSwitchOn */ true, 166 /* consentGiven */ true, 167 () -> { 168 // Execute 169 final IBinder binder = onCreateAndOnBindService(); 170 171 // Verification 172 assertNull(binder); 173 verify(mMockConsentManager, never()).getConsent(); 174 verify(mMockConsentManager, never()).getConsent(any()); 175 assertJobScheduled(/* timesCalled */ 0); 176 }); 177 } 178 getIntentForMeasurementService()179 private Intent getIntentForMeasurementService() { 180 return new Intent(ApplicationProvider.getApplicationContext(), MeasurementService.class); 181 } 182 onCreateAndOnBindService()183 private IBinder onCreateAndOnBindService() { 184 MeasurementService spyMeasurementService = spy(new MeasurementService()); 185 doReturn(mock(PackageManager.class)).when(spyMeasurementService).getPackageManager(); 186 spyMeasurementService.onCreate(); 187 return spyMeasurementService.onBind(getIntentForMeasurementService()); 188 } 189 runWithMocks( boolean killSwitchStatus, boolean consentStatus, TestUtils.RunnableWithThrow execute)190 private void runWithMocks( 191 boolean killSwitchStatus, boolean consentStatus, TestUtils.RunnableWithThrow execute) 192 throws Exception { 193 doReturn(!killSwitchStatus).when(mMockFlags).getMeasurementEnabled(); 194 195 ExtendedMockito.doReturn(mMockFlags).when(FlagsFactory::getFlags); 196 ExtendedMockito.doReturn(mMockConsentManager).when(() -> ConsentManager.getInstance()); 197 ExtendedMockito.doReturn(mDevContextFilter) 198 .when(() -> DevContextFilter.create(any(Context.class))); 199 200 final AdServicesApiConsent mockConsent = mock(AdServicesApiConsent.class); 201 doReturn(consentStatus).when(mockConsent).isGiven(); 202 203 doReturn(mockConsent) 204 .when(mMockConsentManager) 205 .getConsent(eq(AdServicesApiType.MEASUREMENTS)); 206 207 ExtendedMockito.doReturn(mMockEnrollmentDao).when(() -> EnrollmentDao.getInstance()); 208 doReturn(ENROLLMENT).when(mMockEnrollmentDao).getEnrollmentDataFromMeasurementUrl(any()); 209 ExtendedMockito.doReturn(mMockMeasurementImpl) 210 .when(() -> MeasurementImpl.getInstance(any())); 211 212 ExtendedMockito.doReturn(mMockAppImportanceFilter) 213 .when(() -> AppImportanceFilter.create(any(), anyInt(), any())); 214 215 ExtendedMockito.doReturn(true) 216 .when(() -> PackageChangedReceiver.enableReceiver(any(Context.class), any())); 217 ExtendedMockito.doNothing() 218 .when(() -> AggregateReportingJobService.scheduleIfNeeded(any(), anyBoolean())); 219 ExtendedMockito.doNothing() 220 .when( 221 () -> 222 AggregateFallbackReportingJobService.scheduleIfNeeded( 223 any(), anyBoolean())); 224 ExtendedMockito.doNothing() 225 .when(() -> AttributionJobService.scheduleIfNeeded(any(), anyBoolean())); 226 ExtendedMockito.doNothing() 227 .when(() -> AttributionFallbackJobService.scheduleIfNeeded(any(), anyBoolean())); 228 ExtendedMockito.doNothing() 229 .when(() -> EventReportingJobService.scheduleIfNeeded(any(), anyBoolean())); 230 ExtendedMockito.doNothing() 231 .when(() -> EventFallbackReportingJobService.scheduleIfNeeded(any(), anyBoolean())); 232 ExtendedMockito.doNothing() 233 .when(() -> DeleteExpiredJobService.scheduleIfNeeded(any(), anyBoolean())); 234 ExtendedMockito.doNothing() 235 .when(() -> DeleteUninstalledJobService.scheduleIfNeeded(any(), anyBoolean())); 236 ExtendedMockito.doNothing().when(MddJob::scheduleAllMddJobs); 237 ExtendedMockito.doReturn(true) 238 .when(() -> EncryptionKeyJobService.scheduleIfNeeded(any(), anyBoolean())); 239 ExtendedMockito.doNothing() 240 .when(() -> AsyncRegistrationQueueJobService.scheduleIfNeeded(any(), anyBoolean())); 241 ExtendedMockito.doNothing().when(AsyncRegistrationFallbackJob::schedule); 242 ExtendedMockito.doNothing() 243 .when( 244 () -> 245 VerboseDebugReportingFallbackJobService.scheduleIfNeeded( 246 any(), anyBoolean())); 247 ExtendedMockito.doNothing() 248 .when(() -> DebugReportingFallbackJobService.scheduleIfNeeded(any(), anyBoolean())); 249 // Execute 250 execute.run(); 251 } 252 assertJobScheduled(int timesCalled)253 private void assertJobScheduled(int timesCalled) { 254 ExtendedMockito.verify( 255 () -> AggregateReportingJobService.scheduleIfNeeded(any(), anyBoolean()), 256 times(timesCalled)); 257 ExtendedMockito.verify( 258 () -> AggregateFallbackReportingJobService.scheduleIfNeeded(any(), anyBoolean()), 259 times(timesCalled)); 260 ExtendedMockito.verify( 261 () -> AttributionJobService.scheduleIfNeeded(any(), anyBoolean()), 262 times(timesCalled)); 263 ExtendedMockito.verify( 264 () -> AttributionFallbackJobService.scheduleIfNeeded(any(), anyBoolean()), 265 times(timesCalled)); 266 ExtendedMockito.verify( 267 () -> EventReportingJobService.scheduleIfNeeded(any(), anyBoolean()), 268 times(timesCalled)); 269 ExtendedMockito.verify( 270 () -> EventFallbackReportingJobService.scheduleIfNeeded(any(), anyBoolean()), 271 times(timesCalled)); 272 ExtendedMockito.verify( 273 () -> DeleteExpiredJobService.scheduleIfNeeded(any(), anyBoolean()), 274 times(timesCalled)); 275 ExtendedMockito.verify( 276 () -> DeleteUninstalledJobService.scheduleIfNeeded(any(), anyBoolean()), 277 times(timesCalled)); 278 ExtendedMockito.verify(MddJob::scheduleAllMddJobs, times(timesCalled)); 279 ExtendedMockito.verify( 280 () -> EncryptionKeyJobService.scheduleIfNeeded(any(), anyBoolean()), 281 times(timesCalled)); 282 ExtendedMockito.verify( 283 () -> AsyncRegistrationQueueJobService.scheduleIfNeeded(any(), anyBoolean()), 284 times(timesCalled)); 285 ExtendedMockito.verify(AsyncRegistrationFallbackJob::schedule, times(timesCalled)); 286 ExtendedMockito.verify( 287 () -> VerboseDebugReportingFallbackJobService.scheduleIfNeeded(any(), anyBoolean()), 288 times(timesCalled)); 289 ExtendedMockito.verify( 290 () -> DebugReportingFallbackJobService.scheduleIfNeeded(any(), anyBoolean()), 291 times(timesCalled)); 292 } 293 } 294