1 /*
2  * Copyright (C) 2017 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 android.autofillservice.cts.commontests;
18 
19 import static android.autofillservice.cts.testcore.Helper.DEVICE_CONFIG_AUTOFILL_DIALOG_HINTS;
20 import static android.autofillservice.cts.testcore.Helper.getContext;
21 import static android.autofillservice.cts.testcore.InstrumentedAutoFillService.SERVICE_NAME;
22 import static android.content.Context.CLIPBOARD_SERVICE;
23 
24 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
25 
26 import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
27 
28 import static org.junit.Assume.assumeFalse;
29 
30 import android.app.PendingIntent;
31 import android.autofillservice.cts.R;
32 import android.autofillservice.cts.activities.AbstractAutoFillActivity;
33 import android.autofillservice.cts.activities.AugmentedAuthActivity;
34 import android.autofillservice.cts.activities.AuthenticationActivity;
35 import android.autofillservice.cts.activities.LoginActivity;
36 import android.autofillservice.cts.activities.LoginImportantForCredentialManagerActivity;
37 import android.autofillservice.cts.activities.LoginMixedImportantForCredentialManagerActivity;
38 import android.autofillservice.cts.activities.PreSimpleSaveActivity;
39 import android.autofillservice.cts.activities.SimpleSaveActivity;
40 import android.autofillservice.cts.testcore.AutofillActivityTestRule;
41 import android.autofillservice.cts.testcore.AutofillLoggingTestRule;
42 import android.autofillservice.cts.testcore.AutofillTestWatcher;
43 import android.autofillservice.cts.testcore.Helper;
44 import android.autofillservice.cts.testcore.InlineUiBot;
45 import android.autofillservice.cts.testcore.InstrumentedAutoFillService;
46 import android.autofillservice.cts.testcore.InstrumentedAutoFillService.Replier;
47 import android.autofillservice.cts.testcore.UiBot;
48 import android.content.ClipboardManager;
49 import android.content.Context;
50 import android.content.Intent;
51 import android.content.pm.PackageManager;
52 import android.platform.test.flag.junit.CheckFlagsRule;
53 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
54 import android.provider.DeviceConfig;
55 import android.provider.Settings;
56 import android.service.autofill.InlinePresentation;
57 import android.util.Log;
58 import android.view.autofill.AutofillFeatureFlags;
59 import android.view.autofill.AutofillManager;
60 import android.widget.RemoteViews;
61 
62 import androidx.annotation.NonNull;
63 import androidx.test.InstrumentationRegistry;
64 import androidx.test.ext.junit.runners.AndroidJUnit4;
65 
66 import com.android.compatibility.common.util.DeviceConfigStateChangerRule;
67 import com.android.compatibility.common.util.DisableAnimationRule;
68 import com.android.compatibility.common.util.RequiredFeatureRule;
69 import com.android.compatibility.common.util.RetryRule;
70 import com.android.compatibility.common.util.SafeCleanerRule;
71 import com.android.compatibility.common.util.SettingsStateKeeperRule;
72 import com.android.compatibility.common.util.TestNameUtils;
73 import com.android.cts.mockime.ImeSettings;
74 import com.android.cts.mockime.MockImeSessionRule;
75 
76 import org.junit.AfterClass;
77 import org.junit.Before;
78 import org.junit.BeforeClass;
79 import org.junit.ClassRule;
80 import org.junit.Rule;
81 import org.junit.rules.RuleChain;
82 import org.junit.rules.TestRule;
83 import org.junit.runner.Description;
84 import org.junit.runner.RunWith;
85 import org.junit.runners.model.Statement;
86 
87 /**
88  * Placeholder for the base class for all integration tests:
89  *
90  * <ul>
91  *   <li>{@link AutoActivityLaunch}
92  *   <li>{@link ManualActivityLaunch}
93  * </ul>
94  *
95  * <p>These classes provide the common infrastructure such as:
96  *
97  * <ul>
98  *   <li>Preserving the autofill service settings.
99  *   <li>Cleaning up test state.
100  *   <li>Wrapping the test under autofill-specific test rules.
101  *   <li>Launching the activity used by the test.
102  * </ul>
103  */
104 public final class AutoFillServiceTestCase {
105 
106     /**
107      * Base class for all test cases that use an {@link AutofillActivityTestRule} to
108      * launch the activity.
109      */
110     // Must be public because of @ClassRule
111     public abstract static class AutoActivityLaunch<A extends AbstractAutoFillActivity>
112             extends BaseTestCase {
113 
114         /**
115          * Returns if inline suggestion is enabled.
116          */
isInlineMode()117         protected boolean isInlineMode() {
118             return false;
119         }
120 
getInlineUiBot()121         protected static InlineUiBot getInlineUiBot() {
122             return new InlineUiBot(getContext());
123         }
124 
getDropdownUiBot()125         protected static UiBot getDropdownUiBot() {
126             return sDefaultUiBot;
127         }
128 
129         @ClassRule
130         public static final SettingsStateKeeperRule sPublicServiceSettingsKeeper =
131                 sTheRealServiceSettingsKeeper;
132 
AutoActivityLaunch()133         protected AutoActivityLaunch() {
134             super(sDefaultUiBot);
135         }
AutoActivityLaunch(UiBot uiBot)136         protected AutoActivityLaunch(UiBot uiBot) {
137             super(uiBot);
138         }
139 
140         @Override
getMainTestRule()141         protected TestRule getMainTestRule() {
142             // Tries to set the orientation, noop if nothing happens
143             getDropdownUiBot().maybeSetScreenOrientation(UiBot.PORTRAIT);
144             return getActivityRule();
145         }
146 
147         /**
148          * Gets the rule to launch the main activity for this test.
149          *
150          * <p><b>Note: </b>the rule must be either lazily generated or a static singleton, otherwise
151          * this method could return {@code null} when the rule chain that uses it is constructed.
152          *
153          */
getActivityRule()154         protected abstract @NonNull AutofillActivityTestRule<A> getActivityRule();
155 
launchActivity(@onNull Intent intent)156         protected @NonNull A launchActivity(@NonNull Intent intent) {
157             return getActivityRule().launchActivity(intent);
158         }
159 
getActivity()160         protected @NonNull A getActivity() {
161             return getActivityRule().getActivity();
162         }
163     }
164 
165     /**
166      * Base class for all test cases that don't require an {@link AutofillActivityTestRule}.
167      */
168     // Must be public because of @ClassRule
169     public abstract static class ManualActivityLaunch extends BaseTestCase {
170 
171         @ClassRule
172         public static final SettingsStateKeeperRule sPublicServiceSettingsKeeper =
173                 sTheRealServiceSettingsKeeper;
174 
ManualActivityLaunch()175         protected ManualActivityLaunch() {
176             this(sDefaultUiBot);
177         }
178 
ManualActivityLaunch(@onNull UiBot uiBot)179         protected ManualActivityLaunch(@NonNull UiBot uiBot) {
180             super(uiBot);
181         }
182 
183         @Override
getMainTestRule()184         protected TestRule getMainTestRule() {
185             // TODO: create a NoOpTestRule on common code
186             return new TestRule() {
187 
188                 @Override
189                 public Statement apply(Statement base, Description description) {
190                     // Returns a no-op statements
191                     return new Statement() {
192                         @Override
193                         public void evaluate() throws Throwable {
194                             base.evaluate();
195                         }
196                     };
197                 }
198             };
199         }
200 
201         protected SimpleSaveActivity startSimpleSaveActivity() throws Exception {
202             final Intent intent = new Intent(mContext, SimpleSaveActivity.class)
203                     .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
204             mContext.startActivity(intent);
205             mUiBot.assertShownByRelativeId(SimpleSaveActivity.ID_LABEL);
206             return SimpleSaveActivity.getInstance();
207         }
208 
209         protected PreSimpleSaveActivity startPreSimpleSaveActivity() throws Exception {
210             final Intent intent = new Intent(mContext, PreSimpleSaveActivity.class)
211                     .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
212             mContext.startActivity(intent);
213             mUiBot.assertShownByRelativeId(PreSimpleSaveActivity.ID_PRE_LABEL);
214             return PreSimpleSaveActivity.getInstance();
215         }
216 
217         protected LoginActivity startLoginActivity() throws Exception {
218             final Intent intent = new Intent(mContext, LoginActivity.class)
219                     .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
220             mContext.startActivity(intent);
221             mUiBot.waitForIdleSync();
222             mUiBot.assertShownByRelativeId(Helper.ID_USERNAME_LABEL);
223             return LoginActivity.getCurrentActivity();
224         }
225 
226         protected LoginImportantForCredentialManagerActivity
227                     startLoginImportantForCredentialManagerActivity(boolean useAutofillHint)
228                 throws Exception {
229             final Intent intent =
230                     new Intent(mContext, LoginImportantForCredentialManagerActivity.class)
231                         .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
232                         .putExtra("useAutofillHint", useAutofillHint);
233             mContext.startActivity(intent);
234             mUiBot.assertShownByRelativeId(Helper.ID_USERNAME_LABEL);
235             return LoginImportantForCredentialManagerActivity.getCurrentActivity();
236         }
237 
238         protected LoginMixedImportantForCredentialManagerActivity
239                 startLoginMixedImportantForCredentialManagerActivity(boolean useAutofillHInt)
240                 throws Exception {
241             final Intent intent =
242                     new Intent(mContext, LoginMixedImportantForCredentialManagerActivity.class)
243                         .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
244                         .putExtra("useAutofillHint", useAutofillHInt);
245             mContext.startActivity(intent);
246             mUiBot.assertShownByRelativeId(Helper.ID_USERNAME_LABEL);
247             return LoginMixedImportantForCredentialManagerActivity.getCurrentActivity();
248         }
249     }
250 
251     @RunWith(AndroidJUnit4.class)
252     // Must be public because of @ClassRule
253     public abstract static class BaseTestCase {
254 
255         private static final String TAG = "AutoFillServiceTestCase";
256 
257         protected static final Replier sReplier = InstrumentedAutoFillService.getReplier();
258 
259         protected static final Context sContext = getInstrumentation().getTargetContext();
260 
261         // Hack because JUnit requires that @ClassRule instance belong to a public class.
262         protected static final SettingsStateKeeperRule sTheRealServiceSettingsKeeper =
263                 new SettingsStateKeeperRule(sContext, Settings.Secure.AUTOFILL_SERVICE) {
264             @Override
265             protected void preEvaluate(Description description) {
266                 TestNameUtils.setCurrentTestClass(description.getClassName());
267             }
268 
269             @Override
270             protected void postEvaluate(Description description) {
271                 TestNameUtils.setCurrentTestClass(null);
272             }
273         };
274 
275         public static final MockImeSessionRule sMockImeSessionRule = new MockImeSessionRule(
276                 InstrumentationRegistry.getTargetContext(),
277                 InstrumentationRegistry.getInstrumentation().getUiAutomation(),
278                 new ImeSettings.Builder().setInlineSuggestionsEnabled(true)
279                         .setInlineSuggestionViewContentDesc(InlineUiBot.SUGGESTION_STRIP_DESC));
280 
281         private final AutofillTestWatcher mTestWatcher = new AutofillTestWatcher();
282 
283         private final RetryRule mRetryRule =
284                 new RetryRule(getNumberRetries(), () -> {
285                     // Between testing and retries, clean all launched activities to avoid
286                     // exception:
287                     //     Could not launch intent Intent { ... } within 45 seconds.
288                     mTestWatcher.cleanAllActivities();
289                     cleanAllActivities();
290                 });
291 
292         @Rule
293         public final CheckFlagsRule mCheckFlagsRule =
294                 DeviceFlagsValueProvider.createCheckFlagsRule();
295 
296         private final AutofillLoggingTestRule mLoggingRule = new AutofillLoggingTestRule(TAG);
297 
298         protected final SafeCleanerRule mSafeCleanerRule = new SafeCleanerRule()
299                 .setDumper(mLoggingRule)
300                 .run(() -> sReplier.assertNoUnhandledFillRequests())
301                 .run(() -> sReplier.assertNoUnhandledSaveRequests())
302                 .add(() -> {
303                     return sReplier.getExceptions();
304                 });
305 
306         /**
307          * Disable animation for UiAutomator because animation will cause the UiAutomator
308          * got a wrong position and then tests failed due to click on the wrong position.
309          *
310          * This is annotated as @ClassRule instead of @Rule, to save time of disabling and
311          * re-enabling animation for each test method.
312          */
313         @ClassRule
314         public static DisableAnimationRule sDisableAnimationRule = new DisableAnimationRule();
315 
316         @Rule
317         public final RuleChain mLookAllTheseRules = RuleChain
318                 //
319                 // requiredFeatureRule should be first so the test can be skipped right away
320                 .outerRule(getRequiredFeaturesRule())
321                 //
322                 // mTestWatcher should always be one the first rules, as it defines the name of the
323                 // test being ran and finishes dangling activities at the end
324                 .around(mTestWatcher)
325                 //
326                 // sMockImeSessionRule make sure MockImeSession.create() is used to launch mock IME
327                 .around(sMockImeSessionRule)
328                 //
329                 // mLoggingRule wraps the test but doesn't interfere with it
330                 .around(mLoggingRule)
331                 //
332                 // mSafeCleanerRule will catch errors
333                 .around(mSafeCleanerRule)
334                 //
335                 // mRetryRule should be closest to the main test as possible
336                 .around(mRetryRule)
337                 // mCheckFlagsRule checks for required flags for a test
338                 .around(mCheckFlagsRule)
339                 //
340                 // Augmented Autofill should be disabled by default
341                 .around(new DeviceConfigStateChangerRule(sContext, DeviceConfig.NAMESPACE_AUTOFILL,
342                         AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES,
343                         Integer.toString(getSmartSuggestionMode())))
344                 //
345                 // Fill Dialog should be disabled by default
346                 .around(new DeviceConfigStateChangerRule(sContext, DeviceConfig.NAMESPACE_AUTOFILL,
347                         AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_DIALOG_ENABLED,
348                         Boolean.toString(false)))
349                 //
350                 // Hints list of Fill Dialog should be empty by default
351                 .around(new DeviceConfigStateChangerRule(sContext, DeviceConfig.NAMESPACE_AUTOFILL,
352                         DEVICE_CONFIG_AUTOFILL_DIALOG_HINTS,
353                         ""))
354                 //
355                 // Fill Dialog Improvements should be disabled by default
356                 .around(new DeviceConfigStateChangerRule(sContext, DeviceConfig.NAMESPACE_AUTOFILL,
357                         "improve_fill_dialog",
358                         Boolean.toString(false)))
359 
360                 //
361                 // CredentialManager-Autofill integration enabled by default
362                 .around(new DeviceConfigStateChangerRule(sContext, DeviceConfig.NAMESPACE_AUTOFILL,
363                         AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_CREDENTIAL_MANAGER_ENABLED,
364                         Boolean.toString(true)))
365                 .around(new DeviceConfigStateChangerRule(sContext, DeviceConfig.NAMESPACE_AUTOFILL,
366                         AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_CREDENTIAL_MANAGER_IGNORE_VIEWS,
367                         Boolean.toString(true)))
368 
369                 //
370                 // PCC Detection should be off by default
371                 .around(new DeviceConfigStateChangerRule(sContext, DeviceConfig.NAMESPACE_AUTOFILL,
372                         AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_PCC_CLASSIFICATION_ENABLED,
373                         Boolean.toString(false)))
374 
375                 //
376                 // PCC Detection Hints should be empty by default
377                 .around(new DeviceConfigStateChangerRule(sContext, DeviceConfig.NAMESPACE_AUTOFILL,
378                         AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_PCC_FEATURE_PROVIDER_HINTS,
379                         ""))
380 
381 
382                 //
383                 // AFAA should be off by default
384                 .around(new DeviceConfigStateChangerRule(sContext, DeviceConfig.NAMESPACE_AUTOFILL,
385                             AutofillFeatureFlags.
386                                 DEVICE_CONFIG_TRIGGER_FILL_REQUEST_ON_UNIMPORTANT_VIEW,
387                             Boolean.toString(false)))
388 
389                 .around(new DeviceConfigStateChangerRule(sContext, DeviceConfig.NAMESPACE_AUTOFILL,
390                             "trigger_fill_request_on_filtered_important_views",
391                             Boolean.toString(false)))
392 
393                 .around(new DeviceConfigStateChangerRule(sContext, DeviceConfig.NAMESPACE_AUTOFILL,
394                             "include_all_autofill_type_not_none_views_in_assist_structure",
395                             Boolean.toString(false)))
396 
397                 //
398                 // Relayout fix should be on by default
399                 .around(new DeviceConfigStateChangerRule(sContext, DeviceConfig.NAMESPACE_AUTOFILL,
400                         "enable_relayout", Boolean.toString(true)))
401 
402 
403                 //
404                 // Max input size to provide autofill suggestion should be 3
405                 .around(new DeviceConfigStateChangerRule(sContext, DeviceConfig.NAMESPACE_AUTOFILL,
406                             "max_input_length_for_autofill",
407                             Integer.toString(3)))
408 
409                 //
410                 // Fill fields from current session only should be on by default
411                 .around(new DeviceConfigStateChangerRule(sContext, DeviceConfig.NAMESPACE_AUTOFILL,
412                         "fill_fields_from_current_session_only", Boolean.toString(true)))
413 
414                 //
415                 // Ignore view state reset to empty should be on by default
416                 .around(new DeviceConfigStateChangerRule(sContext, DeviceConfig.NAMESPACE_AUTOFILL,
417                         "ignore_view_state_reset_to_empty", Boolean.toString(true)))
418 
419                 //
420                 // Include invisible view group in assist structure should be on by default
421                 .around(new DeviceConfigStateChangerRule(sContext, DeviceConfig.NAMESPACE_AUTOFILL,
422                         "include_invisible_view_group_in_assist_structure", Boolean.toString(true)))
423 
424                 //
425                 // Finally, let subclasses add their own rules (like ActivityTestRule)
426                 .around(getMainTestRule());
427 
428 
429         protected final Context mContext = sContext;
430         protected final String mPackageName;
431         protected final UiBot mUiBot;
432 
433         protected static final RuleChain sRequiredFeaturesRule = RuleChain
434                 .outerRule(new RequiredFeatureRule(PackageManager.FEATURE_AUTOFILL))
435                 .around(new RequiredFeatureRule(PackageManager.FEATURE_INPUT_METHODS));
436 
437         public BaseTestCase() {
438             mPackageName = mContext.getPackageName();
439             mUiBot = sDefaultUiBot;
440         }
441 
442         private BaseTestCase(@NonNull UiBot uiBot) {
443             mPackageName = mContext.getPackageName();
444             mUiBot = uiBot;
445             mUiBot.reset();
446         }
447 
448         protected int getSmartSuggestionMode() {
449             return AutofillManager.FLAG_SMART_SUGGESTION_OFF;
450         }
451 
452         /**
453          * Gets how many times a test should be retried.
454          *
455          * @return {@code 1} by default, unless overridden by subclasses or by a global settings
456          * named {@code CLASS_NAME + #getNumberRetries} or
457          * {@code CtsAutoFillServiceTestCases#getNumberRetries} (the former having a higher
458          * priority).
459          */
460         protected int getNumberRetries() {
461             final String localProp = getClass().getName() + "#getNumberRetries";
462             final Integer localValue = getNumberRetries(localProp);
463             if (localValue != null) return localValue.intValue();
464 
465             final String globalProp = "CtsAutoFillServiceTestCases#getNumberRetries";
466             final Integer globalValue = getNumberRetries(globalProp);
467             if (globalValue != null) return globalValue.intValue();
468 
469             return 1;
470         }
471 
472         private Integer getNumberRetries(String prop) {
473             final String value = Settings.Global.getString(sContext.getContentResolver(), prop);
474             if (value != null) {
475                 Log.i(TAG, "getNumberRetries(): overriding to " + value + " because of '" + prop
476                         + "' global setting");
477                 try {
478                     return Integer.parseInt(value);
479                 } catch (Exception e) {
480                     Log.w(TAG, "error parsing property '" + prop + "'='" + value + "'", e);
481                 }
482             }
483             return null;
484         }
485 
486         /**
487          * Gets a rule that defines which features must be present for this test to run.
488          *
489          * <p>By default it returns a rule that requires {@link PackageManager#FEATURE_AUTOFILL},
490          * but subclass can override to be more specific.
491          */
492         @NonNull
493         protected TestRule getRequiredFeaturesRule() {
494             return sRequiredFeaturesRule;
495         }
496 
497         /**
498          * Gets the test-specific {@link Rule @Rule}.
499          *
500          * <p>Sub-class <b>MUST</b> override this method instead of annotation their own rules,
501          * so the order is preserved.
502          *
503          */
504         @NonNull
505         protected abstract TestRule getMainTestRule();
506 
507         @BeforeClass
508         public static void disableDefaultAugmentedService() {
509             Log.v(TAG, "@BeforeClass: disableDefaultAugmentedService()");
510             Helper.setDefaultAugmentedAutofillServiceEnabled(false);
511         }
512 
513         @AfterClass
514         public static void enableDefaultAugmentedService() {
515             Log.v(TAG, "@AfterClass: enableDefaultAugmentedService()");
516             Helper.setDefaultAugmentedAutofillServiceEnabled(true);
517         }
518 
519         @Before
520         public void prepareDevice() throws Exception {
521             Log.v(TAG, "@Before: prepareDevice()");
522 
523             // Unlock screen.
524             runShellCommand("input keyevent KEYCODE_WAKEUP");
525 
526             // Dismiss keyguard, in case it's set as "Swipe to unlock".
527             runShellCommand("wm dismiss-keyguard");
528 
529             // Collapse notifications.
530             runShellCommand("cmd statusbar collapse");
531 
532             assumeFalse("Device is half-folded",
533                     Helper.isDeviceInState(mContext, Helper.DeviceStateEnum.HALF_FOLDED));
534 
535             assumeFalse("Device is TV", Helper.isTv(mContext));
536 
537             // Set orientation as portrait, otherwise some tests might fail due to elements not
538             // fitting in, IME orientation, etc...
539             mUiBot.maybeSetScreenOrientation(UiBot.PORTRAIT);
540 
541             // Clear Clipboard
542             // TODO(b/117768051): remove try/catch once fixed
543             try {
544                 ((ClipboardManager) mContext.getSystemService(CLIPBOARD_SERVICE))
545                     .clearPrimaryClip();
546             } catch (Exception e) {
547                 Log.e(TAG, "Ignoring exception clearing clipboard", e);
548             }
549         }
550 
551         @Before
552         public void preTestCleanup() {
553             Log.v(TAG, "@Before: preTestCleanup()");
554 
555             prepareServicePreTest();
556 
557             InstrumentedAutoFillService.resetStaticState();
558             AuthenticationActivity.resetStaticState();
559             AugmentedAuthActivity.resetStaticState();
560             sReplier.reset();
561         }
562 
563         /**
564          * Prepares the service before each test - by default, disables it
565          */
566         protected void prepareServicePreTest() {
567             Log.v(TAG, "prepareServicePreTest(): calling disableService()");
568             disableService();
569         }
570 
571         /**
572          * Enables the {@link InstrumentedAutoFillService} for autofill for the current user.
573          */
574         protected void enableService() {
575             Helper.enableAutofillService(SERVICE_NAME);
576         }
577 
578         /**
579          * Disables the {@link InstrumentedAutoFillService} for autofill for the current user.
580          */
581         protected void disableService() {
582             Helper.disableAutofillService();
583         }
584 
585         /**
586          * Asserts that the {@link InstrumentedAutoFillService} is enabled for the default user.
587          */
588         protected void assertServiceEnabled() {
589             Helper.assertAutofillServiceStatus(SERVICE_NAME, true);
590         }
591 
592         /**
593          * Asserts that the {@link InstrumentedAutoFillService} is disabled for the default user.
594          */
595         protected void assertServiceDisabled() {
596             Helper.assertAutofillServiceStatus(SERVICE_NAME, false);
597         }
598 
599         protected RemoteViews createPresentation(String message) {
600             return Helper.createPresentation(message);
601         }
602 
603         protected RemoteViews createPresentationWithCancel(String message) {
604             final RemoteViews presentation = new RemoteViews(getContext()
605                     .getPackageName(), R.layout.list_item_cancel);
606             presentation.setTextViewText(R.id.text1, message);
607             return presentation;
608         }
609 
610         protected InlinePresentation createInlinePresentation(String message) {
611             return Helper.createInlinePresentation(message);
612         }
613 
614         protected InlinePresentation createInlinePresentation(String message,
615                                                               PendingIntent attribution) {
616             return Helper.createInlinePresentation(message, attribution);
617         }
618 
619         @NonNull
620         protected AutofillManager getAutofillManager() {
621             return mContext.getSystemService(AutofillManager.class);
622         }
623 
624         /**
625          * Used to clean all activities that started by test case and does not control by the
626          * AutofillTestWatcher.
627          */
628         protected void cleanAllActivities() {}
629     }
630 
631     protected static final UiBot sDefaultUiBot = new UiBot();
632 
633     private AutoFillServiceTestCase() {
634         throw new UnsupportedOperationException("Contain static stuff only");
635     }
636 }
637