• 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 
17 package com.android.adservices.tests.permissions;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.junit.Assert.assertThrows;
22 
23 import android.adservices.adselection.AdSelectionConfig;
24 import android.adservices.adselection.AdSelectionConfigFixture;
25 import android.adservices.adselection.ReportImpressionRequest;
26 import android.adservices.clients.adselection.AdSelectionClient;
27 import android.adservices.clients.customaudience.AdvertisingCustomAudienceClient;
28 import android.adservices.clients.topics.AdvertisingTopicsClient;
29 import android.adservices.common.AdTechIdentifier;
30 import android.adservices.customaudience.CustomAudience;
31 import android.adservices.topics.GetTopicsResponse;
32 import android.content.Context;
33 import android.net.Uri;
34 
35 import androidx.test.core.app.ApplicationProvider;
36 import androidx.test.ext.junit.runners.AndroidJUnit4;
37 
38 import com.android.adservices.common.AdservicesTestHelper;
39 import com.android.adservices.common.CompatAdServicesTestUtils;
40 import com.android.adservices.service.js.JSScriptEngine;
41 import com.android.compatibility.common.util.ShellUtils;
42 import com.android.modules.utils.build.SdkLevel;
43 
44 import org.junit.After;
45 import org.junit.Assume;
46 import org.junit.Before;
47 import org.junit.Test;
48 import org.junit.runner.RunWith;
49 
50 import java.util.concurrent.ExecutionException;
51 import java.util.concurrent.Executor;
52 import java.util.concurrent.Executors;
53 
54 @RunWith(AndroidJUnit4.class)
55 // TODO: Add tests for measurement (b/238194122).
56 public class PermissionsValidTest {
57     private static final Executor CALLBACK_EXECUTOR = Executors.newCachedThreadPool();
58     private static final Context sContext = ApplicationProvider.getApplicationContext();
59     private static final String PERMISSION_NOT_REQUESTED =
60             "Caller is not authorized to call this API. Permission was not requested.";
61 
62     private String mPreviousAppAllowList;
63 
64     @Before
setup()65     public void setup() {
66         // Skip the test if it runs on unsupported platforms
67         Assume.assumeTrue(AdservicesTestHelper.isDeviceSupported());
68 
69         if (!SdkLevel.isAtLeastT()) {
70             mPreviousAppAllowList =
71                     CompatAdServicesTestUtils.getAndOverridePpapiAppAllowList(
72                             sContext.getPackageName());
73             CompatAdServicesTestUtils.setFlags();
74             // TODO: Remove after EngProd figures out why setprop commands from AndroidTest
75             //  .ExtServices.xml are not executing in post-submit (b/276909363)
76             setAdditionalFlags();
77         }
78     }
79 
80     @After
tearDown()81     public void tearDown() throws Exception {
82         if (!AdservicesTestHelper.isDeviceSupported()) {
83             return;
84         }
85 
86         if (!SdkLevel.isAtLeastT()) {
87             CompatAdServicesTestUtils.setPpapiAppAllowList(mPreviousAppAllowList);
88             CompatAdServicesTestUtils.resetFlagsToDefault();
89             // TODO: Remove after EngProd figures out why setprop commands from AndroidTest
90             //  .ExtServices.xml are not executing in post-submit (b/276909363)
91             resetAdditionalFlags();
92         }
93     }
94 
setAdditionalFlags()95     private void setAdditionalFlags() {
96         ShellUtils.runShellCommand("setprop debug.adservices.consent_manager_debug_mode true");
97         ShellUtils.runShellCommand("setprop debug.adservices.disable_fledge_enrollment_check true");
98         ShellUtils.runShellCommand("setprop debug.adservices.disable_topics_enrollment_check true");
99         // TODO: Investigate why this is needed (b/276916172)
100         ShellUtils.runShellCommand("device_config put adservices ppapi_app_signature_allow_list *");
101     }
102 
resetAdditionalFlags()103     private void resetAdditionalFlags() {
104         ShellUtils.runShellCommand("setprop debug.adservices.consent_manager_debug_mode null");
105         ShellUtils.runShellCommand("setprop debug.adservices.disable_fledge_enrollment_check null");
106         ShellUtils.runShellCommand("setprop debug.adservices.disable_topics_enrollment_check null");
107         ShellUtils.runShellCommand(
108                 "device_config put adservices ppapi_app_signature_allow_list null");
109     }
110 
111     @Test
testValidPermissions_topics()112     public void testValidPermissions_topics() throws Exception {
113         AdvertisingTopicsClient advertisingTopicsClient1 =
114                 new AdvertisingTopicsClient.Builder()
115                         .setContext(sContext)
116                         .setSdkName("sdk1")
117                         .setExecutor(CALLBACK_EXECUTOR)
118                         .build();
119 
120         GetTopicsResponse sdk1Result = advertisingTopicsClient1.getTopics().get();
121         // Not getting an error here indicates that permissions are valid. The valid case is also
122         // tested in TopicsManagerTest.
123         assertThat(sdk1Result.getTopics()).isEmpty();
124     }
125 
126     @Test
testValidPermissions_fledgeJoinCustomAudience()127     public void testValidPermissions_fledgeJoinCustomAudience()
128             throws ExecutionException, InterruptedException {
129         AdvertisingCustomAudienceClient customAudienceClient =
130                 new AdvertisingCustomAudienceClient.Builder()
131                         .setContext(sContext)
132                         .setExecutor(CALLBACK_EXECUTOR)
133                         .build();
134 
135         CustomAudience customAudience =
136                 new CustomAudience.Builder()
137                         .setBuyer(AdTechIdentifier.fromString("test.com"))
138                         .setName("exampleCustomAudience")
139                         .setDailyUpdateUri(Uri.parse("https://test.com/daily-update"))
140                         .setBiddingLogicUri(Uri.parse("https://test.com/bidding-logic"))
141                         .build();
142 
143         customAudienceClient.joinCustomAudience(customAudience).get();
144     }
145 
146     @Test
testValidPermissions_selectAds_adSelectionConfig()147     public void testValidPermissions_selectAds_adSelectionConfig() {
148         Assume.assumeTrue(JSScriptEngine.AvailabilityChecker.isJSSandboxAvailable());
149         AdSelectionConfig adSelectionConfig = AdSelectionConfigFixture.anAdSelectionConfig();
150 
151         AdSelectionClient mAdSelectionClient =
152                 new AdSelectionClient.Builder()
153                         .setContext(sContext)
154                         .setExecutor(CALLBACK_EXECUTOR)
155                         .build();
156 
157         ExecutionException exception =
158                 assertThrows(
159                         ExecutionException.class,
160                         () -> mAdSelectionClient.selectAds(adSelectionConfig).get());
161         // We only need to get past the permissions check for this test to be valid
162         assertThat(exception.getMessage()).isNotEqualTo(PERMISSION_NOT_REQUESTED);
163     }
164 
165     @Test
testValidPermissions_reportImpression()166     public void testValidPermissions_reportImpression() {
167         Assume.assumeTrue(JSScriptEngine.AvailabilityChecker.isJSSandboxAvailable());
168         AdSelectionConfig adSelectionConfig = AdSelectionConfigFixture.anAdSelectionConfig();
169 
170         long adSelectionId = 1;
171 
172         AdSelectionClient mAdSelectionClient =
173                 new AdSelectionClient.Builder()
174                         .setContext(sContext)
175                         .setExecutor(CALLBACK_EXECUTOR)
176                         .build();
177 
178         ReportImpressionRequest request =
179                 new ReportImpressionRequest(adSelectionId, adSelectionConfig);
180 
181         ExecutionException exception =
182                 assertThrows(
183                         ExecutionException.class,
184                         () -> mAdSelectionClient.reportImpression(request).get());
185         // We only need to get past the permissions check for this test to be valid
186         assertThat(exception.getMessage()).isNotEqualTo(PERMISSION_NOT_REQUESTED);
187     }
188     // TODO(b/274723533): Uncomment after un-hiding the API
189     /*
190     @Test
191     public void testValidPermissions_reportInteraction() {
192         long adSelectionId = 1;
193         String interactionKey = "click";
194         String interactionData = "{\"key\":\"value\"}";
195 
196         AdSelectionClient mAdSelectionClient =
197                 new AdSelectionClient.Builder()
198                         .setContext(sContext)
199                         .setExecutor(CALLBACK_EXECUTOR)
200                         .build();
201 
202         ReportInteractionRequest request =
203                 new ReportInteractionRequest(
204                         adSelectionId,
205                         interactionKey,
206                         interactionData,
207                         ReportInteractionRequest.FLAG_REPORTING_DESTINATION_BUYER
208                                 | ReportInteractionRequest.FLAG_REPORTING_DESTINATION_SELLER);
209 
210         ExecutionException exception =
211                 assertThrows(
212                         ExecutionException.class,
213                         () -> mAdSelectionClient.reportInteraction(request).get());
214         // We only need to get past the permissions check for this test to be valid
215         assertThat(exception.getMessage()).isNotEqualTo(PERMISSION_NOT_REQUESTED);
216     }
217     */
218 
219     // TODO(b/221876775): Unhide for frequency cap mainline promotion
220     /*
221     @Test
222     public void testValidPermissions_updateAdCounterHistogram() {
223         long adSelectionId = 1;
224 
225         AdSelectionClient mAdSelectionClient =
226                 new AdSelectionClient.Builder()
227                         .setContext(sContext)
228                         .setExecutor(CALLBACK_EXECUTOR)
229                         .build();
230 
231         UpdateAdCounterHistogramRequest request =
232                 new UpdateAdCounterHistogramRequest.Builder()
233                         .setAdSelectionId(adSelectionId)
234                         .setAdEventType(FrequencyCapFilters.AD_EVENT_TYPE_IMPRESSION)
235                         .setCallerAdTech(AdTechIdentifier.fromString("test.com"))
236                         .build();
237         ExecutionException exception =
238                 assertThrows(
239                         ExecutionException.class,
240                         () -> mAdSelectionClient.updateAdCounterHistogram(request).get());
241 
242         // We only need to get past the permissions check for this test to be valid
243         assertThat(exception.getMessage()).isNotEqualTo(PERMISSION_NOT_REQUESTED);
244     }
245     */
246 
247     @Test
testValidPermissions_fledgeLeaveCustomAudience()248     public void testValidPermissions_fledgeLeaveCustomAudience()
249             throws ExecutionException, InterruptedException {
250         AdvertisingCustomAudienceClient customAudienceClient =
251                 new AdvertisingCustomAudienceClient.Builder()
252                         .setContext(sContext)
253                         .setExecutor(CALLBACK_EXECUTOR)
254                         .build();
255 
256         customAudienceClient
257                 .leaveCustomAudience(
258                         AdTechIdentifier.fromString("test.com"), "exampleCustomAudience")
259                 .get();
260     }
261 }
262