blob: 2f4de155f31e860644e2dc3d76b4b0d9c3adbfa5 [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.autofillservice.cts;
import android.autofillservice.cts.CannedFillResponse.CannedDataset;
import android.content.Intent;
import android.os.SystemClock;
import android.platform.test.annotations.AppModeFull;
import android.service.autofill.FillResponse;
import android.util.Log;
import org.junit.Test;
/**
* Tests for the {@link android.service.autofill.FillResponse.Builder#disableAutofill(long)} API.
*/
public class DisableAutofillTest extends AutoFillServiceTestCase {
private static final String TAG = "DisableAutofillTest";
private SimpleSaveActivity startSimpleSaveActivity() throws Exception {
final Intent intent = new Intent(mContext, SimpleSaveActivity.class)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
mUiBot.assertShownByRelativeId(SimpleSaveActivity.ID_LABEL);
return SimpleSaveActivity.getInstance();
}
private PreSimpleSaveActivity startPreSimpleSaveActivity() throws Exception {
final Intent intent = new Intent(mContext, PreSimpleSaveActivity.class)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
mUiBot.assertShownByRelativeId(PreSimpleSaveActivity.ID_PRE_LABEL);
return PreSimpleSaveActivity.getInstance();
}
/**
* Defines what to do after the activity being tested is launched.
*/
enum PostLaunchAction {
/**
* Used when the service disables autofill in the fill response for this activty. As such:
*
* <ol>
* <li>There should be a fill request on {@code sReplier}.
* <li>The first UI focus should generate a
* {@link android.view.autofill.AutofillManager.AutofillCallback#EVENT_INPUT_UNAVAILABLE}
* event.
* <li>Subsequent UI focus should not trigger events.
* </ol>
*/
ASSERT_DISABLING,
/**
* Used when the service already disabled autofill prior to launching activty. As such:
*
* <ol>
* <li>There should be no fill request on {@code sReplier}.
* <li>There should be no callback calls when UI is focused
* </ol>
*/
ASSERT_DISABLED,
/**
* Used when autofill is enabled, so it tries to autofill the activity.
*/
ASSERT_ENABLED_AND_AUTOFILL
}
private void launchSimpleSaveActivity(PostLaunchAction action) throws Exception {
Log.v(TAG, "launchPreSimpleSaveActivity(): " + action);
sReplier.assertNoUnhandledFillRequests();
if (action == PostLaunchAction.ASSERT_ENABLED_AND_AUTOFILL) {
sReplier.addResponse(new CannedFillResponse.Builder()
.addDataset(new CannedDataset.Builder()
.setField(SimpleSaveActivity.ID_INPUT, "id")
.setField(SimpleSaveActivity.ID_PASSWORD, "pass")
.setPresentation(createPresentation("YO"))
.build())
.build());
}
final SimpleSaveActivity activity = startSimpleSaveActivity();
final MyAutofillCallback callback = activity.registerCallback();
try {
// Trigger autofill
activity.syncRunOnUiThread(() -> activity.mInput.requestFocus());
if (action == PostLaunchAction.ASSERT_DISABLING) {
callback.assertUiUnavailableEvent(activity.mInput);
sReplier.getNextFillRequest();
// Make sure other fields are not triggered.
activity.syncRunOnUiThread(() -> activity.mPassword.requestFocus());
callback.assertNotCalled();
} else if (action == PostLaunchAction.ASSERT_DISABLED) {
// Make sure forced requests are ignored as well.
activity.getAutofillManager().requestAutofill(activity.mInput);
callback.assertNotCalled();
} else if (action == PostLaunchAction.ASSERT_ENABLED_AND_AUTOFILL) {
callback.assertUiShownEvent(activity.mInput);
sReplier.getNextFillRequest();
final SimpleSaveActivity.FillExpectation autofillExpectation =
activity.expectAutoFill("id", "pass");
mUiBot.selectDataset("YO");
autofillExpectation.assertAutoFilled();
}
// Asserts isEnabled() status.
assertAutofillEnabled(activity, action == PostLaunchAction.ASSERT_ENABLED_AND_AUTOFILL);
} finally {
activity.finish();
}
}
private void launchPreSimpleSaveActivity(PostLaunchAction action) throws Exception {
Log.v(TAG, "launchPreSimpleSaveActivity(): " + action);
sReplier.assertNoUnhandledFillRequests();
if (action == PostLaunchAction.ASSERT_ENABLED_AND_AUTOFILL) {
sReplier.addResponse(new CannedFillResponse.Builder()
.addDataset(new CannedDataset.Builder()
.setField(PreSimpleSaveActivity.ID_PRE_INPUT, "yo")
.setPresentation(createPresentation("YO"))
.build())
.build());
}
final PreSimpleSaveActivity activity = startPreSimpleSaveActivity();
final MyAutofillCallback callback = activity.registerCallback();
try {
// Trigger autofill
activity.syncRunOnUiThread(() -> activity.mPreInput.requestFocus());
if (action == PostLaunchAction.ASSERT_DISABLING) {
callback.assertUiUnavailableEvent(activity.mPreInput);
sReplier.getNextFillRequest();
} else if (action == PostLaunchAction.ASSERT_DISABLED) {
activity.getAutofillManager().requestAutofill(activity.mPreInput);
callback.assertNotCalled();
} else if (action == PostLaunchAction.ASSERT_ENABLED_AND_AUTOFILL) {
callback.assertUiShownEvent(activity.mPreInput);
sReplier.getNextFillRequest();
final PreSimpleSaveActivity.FillExpectation autofillExpectation =
activity.expectAutoFill("yo");
mUiBot.selectDataset("YO");
autofillExpectation.assertAutoFilled();
}
// Asserts isEnabled() status.
assertAutofillEnabled(activity, action == PostLaunchAction.ASSERT_ENABLED_AND_AUTOFILL);
} finally {
activity.finish();
}
}
@Test
public void testDisableApp() throws Exception {
// Set service.
enableService();
// Set expectations.
sReplier.addResponse(
new CannedFillResponse.Builder().disableAutofill(Long.MAX_VALUE).build());
// Trigger autofill for the first time.
launchSimpleSaveActivity(PostLaunchAction.ASSERT_DISABLING);
// Launch activity again.
launchSimpleSaveActivity(PostLaunchAction.ASSERT_DISABLED);
// Now try it using a different activity - should be disabled too.
launchPreSimpleSaveActivity(PostLaunchAction.ASSERT_DISABLED);
}
@Test
@AppModeFull // testDisableApp() is enough to test ephemeral apps support
public void testDisableAppThenWaitToReenableIt() throws Exception {
// Set service.
enableService();
// Need to wait the equivalent of launching 2 activities, plus some extra legging room
final long duration = 2 * Timeouts.ACTIVITY_RESURRECTION.ms() + 500;
// Set expectations.
sReplier.addResponse(new CannedFillResponse.Builder().disableAutofill(duration).build());
// Trigger autofill for the first time.
launchSimpleSaveActivity(PostLaunchAction.ASSERT_DISABLING);
// Launch activity again.
launchSimpleSaveActivity(PostLaunchAction.ASSERT_DISABLED);
// Wait for the timeout, then try again, autofilling it this time.
SystemClock.sleep(duration + 1);
launchSimpleSaveActivity(PostLaunchAction.ASSERT_ENABLED_AND_AUTOFILL);
// Also try it on another activity.
launchPreSimpleSaveActivity(PostLaunchAction.ASSERT_ENABLED_AND_AUTOFILL);
}
@Test
@AppModeFull // testDisableApp() is enough to test ephemeral apps support
public void testDisableAppThenResetServiceToReenableIt() throws Exception {
enableService();
sReplier.addResponse(new CannedFillResponse.Builder()
.disableAutofill(Long.MAX_VALUE).build());
// Trigger autofill for the first time.
launchSimpleSaveActivity(PostLaunchAction.ASSERT_DISABLING);
// Launch activity again.
launchSimpleSaveActivity(PostLaunchAction.ASSERT_DISABLED);
// Then "reset" service to re-enable autofill.
disableService();
enableService();
// Try again on activity that disabled it.
launchSimpleSaveActivity(PostLaunchAction.ASSERT_ENABLED_AND_AUTOFILL);
// Try again on other activity.
launchPreSimpleSaveActivity(PostLaunchAction.ASSERT_ENABLED_AND_AUTOFILL);
}
@Test
public void testDisableActivity() throws Exception {
// Set service.
enableService();
// Set expectations.
sReplier.addResponse(new CannedFillResponse.Builder()
.disableAutofill(Long.MAX_VALUE)
.setFillResponseFlags(FillResponse.FLAG_DISABLE_ACTIVITY_ONLY)
.build());
// Trigger autofill for the first time.
launchSimpleSaveActivity(PostLaunchAction.ASSERT_DISABLING);
// Launch activity again.
launchSimpleSaveActivity(PostLaunchAction.ASSERT_DISABLED);
// Now try it using a different activity - should work.
launchPreSimpleSaveActivity(PostLaunchAction.ASSERT_ENABLED_AND_AUTOFILL);
}
@Test
@AppModeFull // testDisableActivity() is enough to test ephemeral apps support
public void testDisableActivityThenWaitToReenableIt() throws Exception {
// Set service.
enableService();
// Need to wait the equivalent of launching 2 activities, plus some extra legging room
final long duration = 2 * Timeouts.ACTIVITY_RESURRECTION.ms() + 500;
// Set expectations.
sReplier.addResponse(new CannedFillResponse.Builder()
.disableAutofill(duration)
.setFillResponseFlags(FillResponse.FLAG_DISABLE_ACTIVITY_ONLY)
.build());
// Trigger autofill for the first time.
launchSimpleSaveActivity(PostLaunchAction.ASSERT_DISABLING);
// Launch activity again.
launchSimpleSaveActivity(PostLaunchAction.ASSERT_DISABLED);
// Make sure other app is working.
launchPreSimpleSaveActivity(PostLaunchAction.ASSERT_ENABLED_AND_AUTOFILL);
// Wait for the timeout, then try again, autofilling it this time.
SystemClock.sleep(duration + 1);
launchSimpleSaveActivity(PostLaunchAction.ASSERT_ENABLED_AND_AUTOFILL);
}
@Test
@AppModeFull // testDisableActivity() is enough to test ephemeral apps support
public void testDisableActivityThenResetServiceToReenableIt() throws Exception {
enableService();
sReplier.addResponse(new CannedFillResponse.Builder()
.disableAutofill(Long.MAX_VALUE)
.setFillResponseFlags(FillResponse.FLAG_DISABLE_ACTIVITY_ONLY)
.build());
// Trigger autofill for the first time.
launchSimpleSaveActivity(PostLaunchAction.ASSERT_DISABLING);
// Launch activity again.
launchSimpleSaveActivity(PostLaunchAction.ASSERT_DISABLED);
// Make sure other app is working.
launchPreSimpleSaveActivity(PostLaunchAction.ASSERT_ENABLED_AND_AUTOFILL);
// Then "reset" service to re-enable autofill.
disableService();
enableService();
// Try again on activity that disabled it.
launchSimpleSaveActivity(PostLaunchAction.ASSERT_ENABLED_AND_AUTOFILL);
}
private void assertAutofillEnabled(AbstractAutoFillActivity activity, boolean expected)
throws Exception {
Timeouts.ACTIVITY_RESURRECTION.run(
"assertAutofillEnabled(" + activity.getComponentName().flattenToShortString() + ")",
() -> {
return activity.getAutofillManager().isEnabled() == expected
? Boolean.TRUE : null;
});
}
}