• 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.ui.settings;
18 
19 import static com.android.adservices.service.FlagsConstants.KEY_CONSENT_SOURCE_OF_TRUTH;
20 import static com.android.adservices.service.FlagsConstants.KEY_DISABLE_FLEDGE_ENROLLMENT_CHECK;
21 import static com.android.adservices.service.FlagsConstants.KEY_ENABLE_APPSEARCH_CONSENT_DATA;
22 import static com.android.adservices.service.FlagsConstants.KEY_FLEDGE_CUSTOM_AUDIENCE_SERVICE_KILL_SWITCH;
23 import static com.android.adservices.service.FlagsConstants.KEY_FLEDGE_SCHEDULE_CUSTOM_AUDIENCE_UPDATE_ENABLED;
24 import static com.android.adservices.service.FlagsConstants.KEY_GA_UX_FEATURE_ENABLED;
25 import static com.android.adservices.service.FlagsConstants.KEY_UI_DIALOGS_FEATURE_ENABLED;
26 
27 import static com.google.common.truth.Truth.assertThat;
28 
29 import android.content.ComponentName;
30 import android.content.Context;
31 import android.content.Intent;
32 import android.os.Build;
33 import android.os.Process;
34 
35 import androidx.test.core.app.ApplicationProvider;
36 import androidx.test.platform.app.InstrumentationRegistry;
37 import androidx.test.uiautomator.By;
38 import androidx.test.uiautomator.UiDevice;
39 import androidx.test.uiautomator.UiObject2;
40 import androidx.test.uiautomator.UiObjectNotFoundException;
41 import androidx.test.uiautomator.Until;
42 
43 import com.android.adservices.LogUtil;
44 import com.android.adservices.api.R;
45 import com.android.adservices.common.AdservicesTestHelper;
46 import com.android.adservices.common.annotations.DisableGlobalKillSwitch;
47 import com.android.adservices.common.annotations.SetAllLogcatTags;
48 import com.android.adservices.common.annotations.SetCompatModeFlags;
49 import com.android.adservices.service.Flags;
50 import com.android.adservices.shared.testing.annotations.RequiresSdkLevelAtLeastT;
51 import com.android.adservices.shared.testing.annotations.SetFlagEnabled;
52 import com.android.adservices.shared.testing.annotations.SetIntegerFlag;
53 import com.android.adservices.ui.util.AdservicesSettingsUiTestCase;
54 import com.android.adservices.ui.util.ApkTestUtil;
55 import com.android.compatibility.common.util.ShellUtils;
56 
57 import org.junit.After;
58 import org.junit.Before;
59 import org.junit.Ignore;
60 import org.junit.Test;
61 
62 @DisableGlobalKillSwitch
63 @SetAllLogcatTags
64 @SetCompatModeFlags
65 public final class AppConsentSettingsUiAutomatorTest extends AdservicesSettingsUiTestCase {
66     private static final String TEST_APP_NAME = "com.example.adservices.samples.ui.consenttestapp";
67     private static final String TEST_APP_APK_PATH =
68             "/data/local/tmp/cts/install/" + TEST_APP_NAME + ".apk";
69     private static final String TEST_APP_ACTIVITY_NAME = TEST_APP_NAME + ".MainActivity";
70     private static final ComponentName COMPONENT =
71             new ComponentName(TEST_APP_NAME, TEST_APP_ACTIVITY_NAME);
72 
73     private static final String PRIVACY_SANDBOX_PACKAGE = "android.adservices.ui.SETTINGS";
74     private static final String PRIVACY_SANDBOX_TEST_PACKAGE = "android.test.adservices.ui.MAIN";
75     private static final int LAUNCH_TIMEOUT = 5000;
76     private static UiDevice sDevice;
77 
78     private int mUserId;
79 
80     private String mTestName;
81 
82     @Before
setup()83     public void setup() throws UiObjectNotFoundException {
84         mTestName = getTestName();
85         mUserId = Process.myUserHandle().getIdentifier();
86         LogUtil.d("work on user id %d", mUserId);
87 
88         String installMessage =
89                 ShellUtils.runShellCommand(
90                         "pm install -r --user %d %s", mUserId, TEST_APP_APK_PATH);
91         assertThat(installMessage).contains("Success");
92 
93         // Initialize UiDevice instance
94         sDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
95 
96         // Start from the home screen
97         sDevice.pressHome();
98     }
99 
100     @After
teardown()101     public void teardown() {
102         ApkTestUtil.takeScreenshot(sDevice, getClass().getSimpleName() + "_" + mTestName + "_");
103 
104         AdservicesTestHelper.killAdservicesProcess(mContext);
105 
106         // Note aosp_x86 requires --user 0 to uninstall though arm doesn't.
107         ShellUtils.runShellCommand("pm uninstall --user %d %s", mUserId, TEST_APP_NAME);
108     }
109 
110     // TODO: Remove this blank test along with the other @Ignore. b/268351419
111     @Test
placeholderTest()112     public void placeholderTest() {
113         // As this class is the only test class in the test module and need to be @Ignore for the
114         // moment, add a blank test to help presubmit to pass.
115         assertThat(true).isTrue();
116     }
117 
118     @Test
119     @RequiresSdkLevelAtLeastT
120     @Ignore("Flaky test. (b/268351419)")
consentSystemServerOnlyTest()121     public void consentSystemServerOnlyTest() throws InterruptedException {
122         // System server is not available on S-, skip this test for S-
123         appConsentTest(0, false);
124     }
125 
126     @Test
127     @Ignore("Flaky test. (b/268351419)")
consentPpApiOnlyTest()128     public void consentPpApiOnlyTest() throws InterruptedException {
129         appConsentTest(1, false);
130     }
131 
132     @Test
133     @RequiresSdkLevelAtLeastT
134     @Ignore("Flaky test. (b/268351419)")
consentSystemServerAndPpApiTest()135     public void consentSystemServerAndPpApiTest() throws InterruptedException {
136         // System server is not available on S-, skip this test for S-
137         appConsentTest(2, false);
138     }
139 
140     @Test
141     @SetFlagEnabled(KEY_ENABLE_APPSEARCH_CONSENT_DATA)
142     @SetIntegerFlag(name = KEY_CONSENT_SOURCE_OF_TRUTH, value = 3)
143     @Ignore("Flaky test. (b/268351419)")
consentAppSearchOnlyTest()144     public void consentAppSearchOnlyTest() throws InterruptedException {
145         appConsentTest(Flags.APPSEARCH_ONLY, false);
146     }
147 
148     @Test
149     @SetFlagEnabled(KEY_ENABLE_APPSEARCH_CONSENT_DATA)
150     @SetIntegerFlag(name = KEY_CONSENT_SOURCE_OF_TRUTH, value = 3)
151     @Ignore("Flaky test. (b/268351419)")
consentAppSearchOnlyDialogsOnTest()152     public void consentAppSearchOnlyDialogsOnTest() throws InterruptedException {
153         appConsentTest(Flags.APPSEARCH_ONLY, true);
154     }
155 
156     @Test
157     @RequiresSdkLevelAtLeastT
158     @Ignore("Flaky test. (b/268351419)")
consentSystemServerOnlyDialogsOnTest()159     public void consentSystemServerOnlyDialogsOnTest() throws InterruptedException {
160         // System server is not available on S-, skip this test for S-
161         appConsentTest(0, true);
162     }
163 
164     @Test
165     @Ignore("Flaky test. (b/268351419)")
consentPpApiOnlyDialogsOnTest()166     public void consentPpApiOnlyDialogsOnTest() throws InterruptedException {
167         appConsentTest(1, true);
168     }
169 
170     @Test
171     @RequiresSdkLevelAtLeastT
172     @Ignore("Flaky test. (b/268351419)")
consentSystemServerAndPpApiDialogsOnTest()173     public void consentSystemServerAndPpApiDialogsOnTest() throws InterruptedException {
174         // System server is not available on S-, skip this test for S-
175         appConsentTest(2, true);
176     }
177 
setPpApiConsentToGiven()178     private void setPpApiConsentToGiven() {
179         // launch app
180         launchSettingApp();
181 
182         UiObject2 mainSwitch = ApkTestUtil.getConsentSwitch(sDevice);
183         assertThat(mainSwitch).isNotNull();
184 
185         if (!mainSwitch.isChecked()) {
186             mainSwitch.click();
187         }
188     }
189 
launchSettingApp()190     private void launchSettingApp() {
191         String privacySandboxUi;
192         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
193             privacySandboxUi = PRIVACY_SANDBOX_TEST_PACKAGE;
194         } else {
195             privacySandboxUi = PRIVACY_SANDBOX_PACKAGE;
196         }
197         Context context = ApplicationProvider.getApplicationContext();
198         Intent intent = new Intent(privacySandboxUi);
199         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
200         context.startActivity(intent);
201 
202         // Wait for the app to appear
203         sDevice.wait(Until.hasObject(By.pkg(privacySandboxUi).depth(0)), LAUNCH_TIMEOUT);
204     }
205 
appConsentTest(int consentSourceOfTruth, boolean dialogsOn)206     private void appConsentTest(int consentSourceOfTruth, boolean dialogsOn)
207             throws InterruptedException {
208         flags.setFlag(KEY_CONSENT_SOURCE_OF_TRUTH, consentSourceOfTruth);
209         flags.setFlag(KEY_UI_DIALOGS_FEATURE_ENABLED, dialogsOn);
210 
211         AdservicesTestHelper.killAdservicesProcess(mContext);
212 
213         // Wait for launcher
214         final String launcherPackage = sDevice.getLauncherPackageName();
215         assertThat(launcherPackage).isNotNull();
216         sDevice.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), LAUNCH_TIMEOUT);
217 
218         flags.setFlag(KEY_GA_UX_FEATURE_ENABLED, false);
219 
220         setPpApiConsentToGiven();
221 
222         // Initiate test app consent.
223         initiateTestAppConsent();
224 
225         // open apps view
226         launchSettingApp();
227         ApkTestUtil.scrollToAndClick(sDevice, R.string.settingsUI_apps_title);
228 
229         blockAppConsent(dialogsOn);
230 
231         unblockAppConsent(dialogsOn);
232 
233         assertThat(ApkTestUtil.getElement(sDevice, R.string.settingsUI_block_app_title))
234                 .isNotNull();
235 
236         resetAppConsent(dialogsOn);
237 
238         assertThat(ApkTestUtil.getElement(sDevice, R.string.settingsUI_block_app_title, 0))
239                 .isNull();
240         assertThat(ApkTestUtil.getElement(sDevice, R.string.settingsUI_blocked_apps_title, 0))
241                 .isNull();
242         assertThat(ApkTestUtil.getElement(sDevice, R.string.settingsUI_apps_view_no_apps_text, 0))
243                 .isNotNull();
244     }
245 
unblockAppConsent(boolean dialogsOn)246     private void unblockAppConsent(boolean dialogsOn) {
247         ApkTestUtil.scrollToAndClick(sDevice, R.string.settingsUI_blocked_apps_title);
248         ApkTestUtil.scrollToAndClick(sDevice, R.string.settingsUI_unblock_app_title);
249 
250         if (dialogsOn) {
251             // click unblock
252             UiObject2 dialogTitle =
253                     ApkTestUtil.getElement(sDevice, R.string.settingsUI_dialog_unblock_app_message);
254             UiObject2 positiveText =
255                     ApkTestUtil.getElement(
256                             sDevice, R.string.settingsUI_dialog_unblock_app_positive_text);
257             assertThat(dialogTitle).isNotNull();
258             assertThat(positiveText).isNotNull();
259 
260             // confirm
261             positiveText.click();
262         }
263 
264         assertThat(
265                         ApkTestUtil.getElement(
266                                 sDevice,
267                                 R.string.settingsUI_apps_view_no_blocked_apps_text))
268                 .isNotNull();
269         sDevice.pressBack();
270     }
271 
resetAppConsent(boolean dialogsOn)272     private void resetAppConsent(boolean dialogsOn) {
273         ApkTestUtil.scrollToAndClick(sDevice, R.string.settingsUI_reset_apps_title);
274 
275         if (dialogsOn) {
276             UiObject2 dialogTitle =
277                     ApkTestUtil.getElement(sDevice, R.string.settingsUI_dialog_reset_app_message);
278             UiObject2 positiveText =
279                     ApkTestUtil.getElement(
280                             sDevice, R.string.settingsUI_dialog_reset_app_positive_text);
281             assertThat(dialogTitle).isNotNull();
282             assertThat(positiveText).isNotNull();
283 
284             // confirm
285             positiveText.click();
286         }
287     }
288 
blockAppConsent(boolean dialogsOn)289     private void blockAppConsent(boolean dialogsOn) {
290         ApkTestUtil.scrollToAndClick(sDevice, R.string.settingsUI_block_app_title);
291 
292         if (dialogsOn) {
293             UiObject2 dialogTitle =
294                     ApkTestUtil.getElement(sDevice, R.string.settingsUI_dialog_block_app_message);
295             UiObject2 positiveText =
296                     ApkTestUtil.getElement(
297                             sDevice, R.string.settingsUI_dialog_block_app_positive_text);
298             assertThat(dialogTitle).isNotNull();
299             assertThat(positiveText).isNotNull();
300             positiveText.click();
301         }
302     }
303 
initiateTestAppConsent()304     private void initiateTestAppConsent() throws InterruptedException {
305         String installMessage = ShellUtils.runShellCommand("pm install -r " + TEST_APP_APK_PATH);
306         assertThat(installMessage).contains("Success");
307 
308         flags.setFlag(KEY_FLEDGE_CUSTOM_AUDIENCE_SERVICE_KILL_SWITCH, false);
309         flags.setFlag(KEY_FLEDGE_SCHEDULE_CUSTOM_AUDIENCE_UPDATE_ENABLED, true);
310         flags.setFlag(KEY_DISABLE_FLEDGE_ENROLLMENT_CHECK, true);
311         flags.setPpapiAppAllowList("*");
312 
313         Intent intent = new Intent().setComponent(COMPONENT);
314         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
315         mContext.startActivity(intent);
316 
317         sDevice.wait(Until.hasObject(By.pkg(TEST_APP_NAME).depth(0)), LAUNCH_TIMEOUT);
318 
319         Thread.sleep(1000);
320 
321         ShellUtils.runShellCommand(
322                 "am force-stop com.example.adservices.samples.ui.consenttestapp");
323     }
324 }
325