• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.data.enrollment.EnrollmentDao;
39 import com.android.adservices.download.MddJobService;
40 import com.android.adservices.service.Flags;
41 import com.android.adservices.service.FlagsFactory;
42 import com.android.adservices.service.common.AppImportanceFilter;
43 import com.android.adservices.service.common.PackageChangedReceiver;
44 import com.android.adservices.service.consent.AdServicesApiConsent;
45 import com.android.adservices.service.consent.AdServicesApiType;
46 import com.android.adservices.service.consent.ConsentManager;
47 import com.android.adservices.service.enrollment.EnrollmentData;
48 import com.android.adservices.service.measurement.DeleteExpiredJobService;
49 import com.android.adservices.service.measurement.DeleteUninstalledJobService;
50 import com.android.adservices.service.measurement.MeasurementImpl;
51 import com.android.adservices.service.measurement.attribution.AttributionJobService;
52 import com.android.adservices.service.measurement.registration.AsyncRegistrationQueueJobService;
53 import com.android.adservices.service.measurement.reporting.AggregateFallbackReportingJobService;
54 import com.android.adservices.service.measurement.reporting.AggregateReportingJobService;
55 import com.android.adservices.service.measurement.reporting.EventFallbackReportingJobService;
56 import com.android.adservices.service.measurement.reporting.EventReportingJobService;
57 import com.android.compatibility.common.util.TestUtils;
58 import com.android.dx.mockito.inline.extended.ExtendedMockito;
59 
60 import org.junit.Before;
61 import org.junit.Test;
62 import org.mockito.Mock;
63 import org.mockito.MockitoAnnotations;
64 import org.mockito.MockitoSession;
65 import org.mockito.quality.Strictness;
66 
67 import java.util.List;
68 
69 /** Unit test for {@link com.android.adservices.measurement.MeasurementService}. */
70 public class MeasurementServiceTest {
71     @Mock ConsentManager mMockConsentManager;
72     @Mock Flags mMockFlags;
73     @Mock MeasurementImpl mMockMeasurementImpl;
74     @Mock EnrollmentDao mMockEnrollmentDao;
75     @Mock AppImportanceFilter mMockAppImportanceFilter;
76 
77     private static final EnrollmentData ENROLLMENT =
78             new EnrollmentData.Builder()
79                     .setEnrollmentId("E1")
80                     .setCompanyId("1001")
81                     .setSdkNames("sdk1")
82                     .setAttributionSourceRegistrationUrl(List.of("https://test.com/source"))
83                     .setAttributionTriggerRegistrationUrl(List.of("https://test.com/trigger"))
84                     .setAttributionReportingUrl(List.of("https://test.com"))
85                     .setRemarketingResponseBasedRegistrationUrl(List.of("https://test.com"))
86                     .setEncryptionKeyUrl(List.of("https://test.com/keys"))
87                     .build();
88 
89     /** Setup for tests */
90     @Before
setup()91     public void setup() {
92         MockitoAnnotations.initMocks(this);
93     }
94 
95     /** Test kill switch off with consent given */
96     @Test
testBindableMeasurementService_killSwitchOff_gaUxDisabled_consentGiven()97     public void testBindableMeasurementService_killSwitchOff_gaUxDisabled_consentGiven()
98             throws Exception {
99         runWithMocks(
100                 /* killSwitchOff */ false,
101                 /* consentGiven */ true,
102                 /* isGaUxEnabled */ false,
103                 () -> {
104                     // Execute
105                     final IBinder binder = onCreateAndOnBindService();
106 
107                     // Verification
108                     assertNotNull(binder);
109                     verify(mMockConsentManager, times(1)).getConsent();
110                     ExtendedMockito.verify(
111                             () -> PackageChangedReceiver.enableReceiver(any(Context.class), any()));
112                     assertJobScheduled(/* timesCalled */ 1);
113                 });
114     }
115 
116     /** Test kill switch off with consent revoked */
117     @Test
testBindableMeasurementService_killSwitchOff_gaUxDisabled_consentRevoked()118     public void testBindableMeasurementService_killSwitchOff_gaUxDisabled_consentRevoked()
119             throws Exception {
120         runWithMocks(
121                 /* killSwitchOff */ false,
122                 /* consentRevoked */ false,
123                 /* isGaUxEnabled */ false,
124                 () -> {
125                     // Execute
126                     final IBinder binder = onCreateAndOnBindService();
127 
128                     // Verification
129                     assertNotNull(binder);
130                     verify(mMockConsentManager, times(1)).getConsent();
131                     assertJobScheduled(/* timesCalled */ 0);
132                 });
133     }
134 
135     /** Test kill switch on */
136     @Test
testBindableMeasurementService_killSwitchOn_gaUxDisabled()137     public void testBindableMeasurementService_killSwitchOn_gaUxDisabled() throws Exception {
138         runWithMocks(
139                 /* killSwitchOn */ true,
140                 /* consentGiven */ true,
141                 /* isGaUxEnabled */ false,
142                 () -> {
143                     // Execute
144                     final IBinder binder = onCreateAndOnBindService();
145 
146                     // Verification
147                     assertNull(binder);
148                     verify(mMockConsentManager, never()).getConsent();
149                     assertJobScheduled(/* timesCalled */ 0);
150                 });
151     }
152 
153     /** Test kill switch off with consent given */
154     @Test
testBindableMeasurementService_killSwitchOff_gaUxEnabled_consentGiven()155     public void testBindableMeasurementService_killSwitchOff_gaUxEnabled_consentGiven()
156             throws Exception {
157         runWithMocks(
158                 /* killSwitchOff */ false,
159                 /* consentGiven */ true,
160                 /* isGaUxEnabled */ true,
161                 () -> {
162                     // Execute
163                     final IBinder binder = onCreateAndOnBindService();
164 
165                     // Verification
166                     assertNotNull(binder);
167                     verify(mMockConsentManager, never()).getConsent();
168                     verify(mMockConsentManager, times(1))
169                             .getConsent(eq(AdServicesApiType.MEASUREMENTS));
170                     ExtendedMockito.verify(
171                             () -> PackageChangedReceiver.enableReceiver(any(Context.class), any()));
172                     assertJobScheduled(/* timesCalled */ 1);
173                 });
174     }
175 
176     /** Test kill switch off with consent revoked */
177     @Test
testBindableMeasurementService_killSwitchOff_gaUxEnabled_consentRevoked()178     public void testBindableMeasurementService_killSwitchOff_gaUxEnabled_consentRevoked()
179             throws Exception {
180         runWithMocks(
181                 /* killSwitchOff */ false,
182                 /* consentRevoked */ false,
183                 /* isGaUxEnabled */ true,
184                 () -> {
185                     // Execute
186                     final IBinder binder = onCreateAndOnBindService();
187 
188                     // Verification
189                     assertNotNull(binder);
190                     verify(mMockConsentManager, never()).getConsent();
191                     verify(mMockConsentManager, times(1))
192                             .getConsent(eq(AdServicesApiType.MEASUREMENTS));
193                     assertJobScheduled(/* timesCalled */ 0);
194                 });
195     }
196 
197     /** Test kill switch on */
198     @Test
testBindableMeasurementService_killSwitchOn_gaUxEnabled()199     public void testBindableMeasurementService_killSwitchOn_gaUxEnabled() throws Exception {
200         runWithMocks(
201                 /* killSwitchOn */ true,
202                 /* consentGiven */ true,
203                 /* isGaUxEnabled */ false,
204                 () -> {
205                     // Execute
206                     final IBinder binder = onCreateAndOnBindService();
207 
208                     // Verification
209                     assertNull(binder);
210                     verify(mMockConsentManager, never()).getConsent();
211                     verify(mMockConsentManager, never()).getConsent(any());
212                     assertJobScheduled(/* timesCalled */ 0);
213                 });
214     }
215 
getIntentForMeasurementService()216     private Intent getIntentForMeasurementService() {
217         return new Intent(ApplicationProvider.getApplicationContext(), MeasurementService.class);
218     }
219 
onCreateAndOnBindService()220     private IBinder onCreateAndOnBindService() {
221         MeasurementService spyMeasurementService = spy(new MeasurementService());
222         doReturn(mock(PackageManager.class)).when(spyMeasurementService).getPackageManager();
223         spyMeasurementService.onCreate();
224         return spyMeasurementService.onBind(getIntentForMeasurementService());
225     }
226 
runWithMocks( boolean killSwitchStatus, boolean consentStatus, boolean isGaUxEnabled, TestUtils.RunnableWithThrow execute)227     private void runWithMocks(
228             boolean killSwitchStatus,
229             boolean consentStatus,
230             boolean isGaUxEnabled,
231             TestUtils.RunnableWithThrow execute)
232             throws Exception {
233         // Start a mockitoSession to mock static method
234         final MockitoSession session =
235                 ExtendedMockito.mockitoSession()
236                         .spyStatic(AggregateReportingJobService.class)
237                         .spyStatic(AggregateFallbackReportingJobService.class)
238                         .spyStatic(AppImportanceFilter.class)
239                         .spyStatic(AttributionJobService.class)
240                         .spyStatic(ConsentManager.class)
241                         .spyStatic(EnrollmentDao.class)
242                         .spyStatic(EventReportingJobService.class)
243                         .spyStatic(PackageChangedReceiver.class)
244                         .spyStatic(EventFallbackReportingJobService.class)
245                         .spyStatic(DeleteExpiredJobService.class)
246                         .spyStatic(DeleteUninstalledJobService.class)
247                         .spyStatic(MddJobService.class)
248                         .spyStatic(FlagsFactory.class)
249                         .spyStatic(MeasurementImpl.class)
250                         .spyStatic(AsyncRegistrationQueueJobService.class)
251                         .strictness(Strictness.LENIENT)
252                         .startMocking();
253         try {
254             doReturn(killSwitchStatus).when(mMockFlags).getMeasurementKillSwitch();
255             doReturn(isGaUxEnabled).when(mMockFlags).getGaUxFeatureEnabled();
256 
257             ExtendedMockito.doReturn(mMockFlags).when(FlagsFactory::getFlags);
258 
259             ExtendedMockito.doReturn(mMockConsentManager)
260                     .when(() -> ConsentManager.getInstance(any()));
261 
262             final AdServicesApiConsent mockConsent = mock(AdServicesApiConsent.class);
263             doReturn(consentStatus).when(mockConsent).isGiven();
264 
265             if (isGaUxEnabled) {
266                 doReturn(mockConsent)
267                         .when(mMockConsentManager)
268                         .getConsent(eq(AdServicesApiType.MEASUREMENTS));
269             } else {
270                 doReturn(mockConsent).when(mMockConsentManager).getConsent();
271             }
272 
273             ExtendedMockito.doReturn(mMockEnrollmentDao)
274                     .when(() -> EnrollmentDao.getInstance(any()));
275             doReturn(ENROLLMENT)
276                     .when(mMockEnrollmentDao)
277                     .getEnrollmentDataFromMeasurementUrl(any());
278 
279             ExtendedMockito.doReturn(mMockMeasurementImpl)
280                     .when(() -> MeasurementImpl.getInstance(any()));
281 
282             ExtendedMockito.doReturn(mMockAppImportanceFilter)
283                     .when(() -> AppImportanceFilter.create(any(), anyInt(), any()));
284 
285             ExtendedMockito.doReturn(true)
286                     .when(() -> PackageChangedReceiver.enableReceiver(any(Context.class), any()));
287             ExtendedMockito.doNothing()
288                     .when(() -> AggregateReportingJobService.scheduleIfNeeded(any(), anyBoolean()));
289             ExtendedMockito.doNothing()
290                     .when(
291                             () ->
292                                     AggregateFallbackReportingJobService.scheduleIfNeeded(
293                                             any(), anyBoolean()));
294             ExtendedMockito.doNothing()
295                     .when(() -> AttributionJobService.scheduleIfNeeded(any(), anyBoolean()));
296 
297             ExtendedMockito.doNothing()
298                     .when(() -> EventReportingJobService.scheduleIfNeeded(any(), anyBoolean()));
299             ExtendedMockito.doNothing()
300                     .when(
301                             () ->
302                                     EventFallbackReportingJobService.scheduleIfNeeded(
303                                             any(), anyBoolean()));
304             ExtendedMockito.doNothing()
305                     .when(() -> DeleteExpiredJobService.scheduleIfNeeded(any(), anyBoolean()));
306             ExtendedMockito.doNothing()
307                     .when(() -> DeleteUninstalledJobService.scheduleIfNeeded(any(), anyBoolean()));
308             ExtendedMockito.doReturn(true)
309                     .when(() -> MddJobService.scheduleIfNeeded(any(), anyBoolean()));
310             ExtendedMockito.doNothing()
311                     .when(
312                             () ->
313                                     AsyncRegistrationQueueJobService.scheduleIfNeeded(
314                                             any(), anyBoolean()));
315 
316             // Execute
317             execute.run();
318         } finally {
319             session.finishMocking();
320         }
321     }
322 
assertJobScheduled(int timesCalled)323     private void assertJobScheduled(int timesCalled) {
324         ExtendedMockito.verify(
325                 () -> AggregateReportingJobService.scheduleIfNeeded(any(), anyBoolean()),
326                 times(timesCalled));
327         ExtendedMockito.verify(
328                 () -> AggregateFallbackReportingJobService.scheduleIfNeeded(any(), anyBoolean()),
329                 times(timesCalled));
330         ExtendedMockito.verify(
331                 () -> AttributionJobService.scheduleIfNeeded(any(), anyBoolean()),
332                 times(timesCalled));
333         ExtendedMockito.verify(
334                 () -> EventReportingJobService.scheduleIfNeeded(any(), anyBoolean()),
335                 times(timesCalled));
336         ExtendedMockito.verify(
337                 () -> EventFallbackReportingJobService.scheduleIfNeeded(any(), anyBoolean()),
338                 times(timesCalled));
339         ExtendedMockito.verify(
340                 () -> DeleteExpiredJobService.scheduleIfNeeded(any(), anyBoolean()),
341                 times(timesCalled));
342         ExtendedMockito.verify(
343                 () -> DeleteUninstalledJobService.scheduleIfNeeded(any(), anyBoolean()),
344                 times(timesCalled));
345         ExtendedMockito.verify(
346                 () -> MddJobService.scheduleIfNeeded(any(), anyBoolean()), times(timesCalled));
347         ExtendedMockito.verify(
348                 () -> AsyncRegistrationQueueJobService.scheduleIfNeeded(any(), anyBoolean()),
349                 times(timesCalled));
350     }
351 }
352