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