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.eq; 22 import static org.mockito.Mockito.doNothing; 23 import static org.mockito.Mockito.doReturn; 24 import static org.mockito.Mockito.mock; 25 import static org.mockito.Mockito.never; 26 import static org.mockito.Mockito.spy; 27 import static org.mockito.Mockito.times; 28 import static org.mockito.Mockito.verify; 29 30 import android.content.Context; 31 import android.content.Intent; 32 import android.content.pm.PackageManager; 33 import android.os.IBinder; 34 35 import androidx.test.core.app.ApplicationProvider; 36 37 import com.android.adservices.common.AdServicesExtendedMockitoTestCase; 38 import com.android.adservices.service.FlagsFactory; 39 import com.android.adservices.service.common.PackageChangedReceiver; 40 import com.android.adservices.service.consent.AdServicesApiConsent; 41 import com.android.adservices.service.consent.AdServicesApiType; 42 import com.android.adservices.service.consent.ConsentManager; 43 import com.android.adservices.service.measurement.MeasurementServiceImpl; 44 import com.android.compatibility.common.util.TestUtils; 45 import com.android.dx.mockito.inline.extended.ExtendedMockito; 46 import com.android.modules.utils.testing.ExtendedMockitoRule.SpyStatic; 47 48 import org.junit.Test; 49 import org.mockito.Mock; 50 51 /** Unit test for {@link com.android.adservices.measurement.MeasurementService}. */ 52 @SpyStatic(ConsentManager.class) 53 @SpyStatic(FlagsFactory.class) 54 @SpyStatic(PackageChangedReceiver.class) 55 public final class MeasurementServiceTest extends AdServicesExtendedMockitoTestCase { 56 @Mock private ConsentManager mMockConsentManager; 57 @Mock private MeasurementServiceImpl mSpyServiceImpl; 58 private MeasurementService mSpyService; 59 60 /** Test kill switch off with consent given */ 61 @Test testBindableMeasurementService_killSwitchOff_gaUxEnabled_consentGiven()62 public void testBindableMeasurementService_killSwitchOff_gaUxEnabled_consentGiven() 63 throws Exception { 64 runWithMocks( 65 /* killSwitchOff */ false, 66 /* consentNotifiedState */ 67 /* consentGiven */ true, 68 () -> { 69 // Execute 70 final IBinder binder = onCreateAndOnBindService(); 71 72 // Verification 73 assertNotNull(binder); 74 verify(mMockConsentManager, never()).getConsent(); 75 verify(mMockConsentManager, times(1)) 76 .getConsent(eq(AdServicesApiType.MEASUREMENTS)); 77 ExtendedMockito.verify( 78 () -> PackageChangedReceiver.enableReceiver(any(Context.class), any())); 79 assertJobScheduled(/* timesCalled */ 1); 80 }); 81 } 82 83 /** Test kill switch off with consent revoked */ 84 @Test testBindableMeasurementService_killSwitchOff_gaUxEnabled_consentRevoked()85 public void testBindableMeasurementService_killSwitchOff_gaUxEnabled_consentRevoked() 86 throws Exception { 87 runWithMocks( 88 /* killSwitchOff */ false, 89 /* consentNotifiedState */ 90 /* consentRevoked */ false, 91 () -> { 92 // Execute 93 final IBinder binder = onCreateAndOnBindService(); 94 95 // Verification 96 assertNotNull(binder); 97 verify(mMockConsentManager, never()).getConsent(); 98 verify(mMockConsentManager, times(1)) 99 .getConsent(eq(AdServicesApiType.MEASUREMENTS)); 100 assertJobScheduled(/* timesCalled */ 0); 101 }); 102 } 103 104 /** Test kill switch on */ 105 @Test testBindableMeasurementService_killSwitchOn_gaUxEnabled()106 public void testBindableMeasurementService_killSwitchOn_gaUxEnabled() throws Exception { 107 runWithMocks( 108 /* killSwitchOn */ true, 109 /* consentGiven */ true, 110 () -> { 111 // Execute 112 final IBinder binder = onCreateAndOnBindService(); 113 114 // Verification 115 assertNull(binder); 116 verify(mMockConsentManager, never()).getConsent(); 117 verify(mMockConsentManager, never()).getConsent(any()); 118 assertJobScheduled(/* timesCalled */ 0); 119 }); 120 } 121 getIntentForMeasurementService()122 private Intent getIntentForMeasurementService() { 123 return new Intent(ApplicationProvider.getApplicationContext(), MeasurementService.class); 124 } 125 onCreateAndOnBindService()126 private IBinder onCreateAndOnBindService() { 127 doReturn(mock(PackageManager.class)).when(mSpyService).getPackageManager(); 128 mSpyService.onCreate(); 129 return mSpyService.onBind(getIntentForMeasurementService()); 130 } 131 runWithMocks( boolean killSwitchStatus, boolean consentStatus, TestUtils.RunnableWithThrow execute)132 private void runWithMocks( 133 boolean killSwitchStatus, boolean consentStatus, TestUtils.RunnableWithThrow execute) 134 throws Exception { 135 mSpyService = spy(new MeasurementService(mSpyServiceImpl)); 136 doReturn(!killSwitchStatus).when(mMockFlags).getMeasurementEnabled(); 137 138 doNothing().when(mSpyServiceImpl).schedulePeriodicJobs(any()); 139 ExtendedMockito.doReturn(mMockFlags).when(FlagsFactory::getFlags); 140 ExtendedMockito.doReturn(mMockConsentManager).when(ConsentManager::getInstance); 141 142 final AdServicesApiConsent mockConsent = mock(AdServicesApiConsent.class); 143 doReturn(consentStatus).when(mockConsent).isGiven(); 144 145 doReturn(mockConsent) 146 .when(mMockConsentManager) 147 .getConsent(eq(AdServicesApiType.MEASUREMENTS)); 148 149 ExtendedMockito.doReturn(true) 150 .when(() -> PackageChangedReceiver.enableReceiver(any(Context.class), any())); 151 152 // Execute 153 execute.run(); 154 } 155 assertJobScheduled(int timesCalled)156 private void assertJobScheduled(int timesCalled) { 157 verify(mSpyServiceImpl, times(timesCalled)).schedulePeriodicJobs(any()); 158 } 159 } 160