Loading apct-tests/perftests/autofill/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ android_test { "androidx.test.rules", "androidx.annotation_annotation", "apct-perftests-utils", "compatibility-device-util-axt", "collector-device-lib", ], platform_apis: true, Loading apct-tests/perftests/autofill/src/android/view/autofill/AbstractAutofillPerfTestCase.java +9 −19 Original line number Diff line number Diff line Loading @@ -11,7 +11,7 @@ * 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 * limitations under the License. */ package android.view.autofill; Loading @@ -28,10 +28,10 @@ import android.provider.Settings; import androidx.test.InstrumentationRegistry; import androidx.test.rule.ActivityTestRule; import org.junit.After; import org.junit.Before; import org.junit.ClassRule; import org.junit.Rule; import org.junit.rules.RuleChain; /** * Base class for all autofill tests. Loading @@ -43,12 +43,16 @@ public abstract class AbstractAutofillPerfTestCase { new SettingsStateKeeperRule(InstrumentationRegistry.getTargetContext(), Settings.Secure.AUTOFILL_SERVICE); @Rule public ActivityTestRule<PerfTestActivity> mActivityRule = protected final AutofillTestWatcher mTestWatcher = MyAutofillService.getTestWatcher(); protected ActivityTestRule<PerfTestActivity> mActivityRule = new ActivityTestRule<>(PerfTestActivity.class); protected PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter(); @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter(); public final RuleChain mAllRules = RuleChain .outerRule(mTestWatcher) .around(mPerfStatusReporter) .around(mActivityRule); private final int mLayoutId; Loading @@ -72,20 +76,6 @@ public abstract class AbstractAutofillPerfTestCase { }); } @Before public void enableService() { MyAutofillService.resetStaticState(); MyAutofillService.setEnabled(true); } @After public void disableService() { // Must disable service so calls are ignored in case of errors during the test case; // otherwise, other tests will fail because these calls are made in the UI thread (as both // the service, the tests, and the app run in the same process). MyAutofillService.setEnabled(false); } /** * Initializes the {@link PerfTestActivity} after it was launched. */ Loading apct-tests/perftests/autofill/src/android/view/autofill/AutofillTestWatcher.java 0 → 100644 +133 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 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.view.autofill; import static com.android.compatibility.common.util.ShellUtils.runShellCommand; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.junit.rules.TestWatcher; import org.junit.runner.Description; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; /** * Custom {@link TestWatcher} that does the setup and reset tasks for the tests. */ final class AutofillTestWatcher extends TestWatcher { private static final String TAG = "AutofillTestWatcher"; private static final long GENERIC_TIMEOUT_MS = 10_000; private static ServiceWatcher sServiceWatcher; private String mOriginalLogLevel; @Override protected void starting(Description description) { super.starting(description); enableVerboseLog(); MyAutofillService.resetStaticState(); MyAutofillService.setEnabled(true); setServiceWatcher(); } @Override protected void finished(Description description) { super.finished(description); restoreLogLevel(); disableService(); clearServiceWatcher(); } void waitServiceConnect() throws InterruptedException { if (sServiceWatcher != null) { Log.d(TAG, "waitServiceConnect()"); sServiceWatcher.waitOnConnected(); } } private void enableService() { MyAutofillService.resetStaticState(); MyAutofillService.setEnabled(true); } private void disableService() { // Must disable service so calls are ignored in case of errors during the test case; // otherwise, other tests will fail because these calls are made in the UI thread (as both // the service, the tests, and the app run in the same process). MyAutofillService.setEnabled(false); } private void enableVerboseLog() { mOriginalLogLevel = runShellCommand("cmd autofill get log_level"); Log.d(TAG, "enableVerboseLog(), mOriginalLogLevel=" + mOriginalLogLevel); if (!mOriginalLogLevel.equals("verbose")) { runShellCommand("cmd autofill set log_level verbose"); } } private void restoreLogLevel() { Log.w(TAG, "restoreLogLevel to " + mOriginalLogLevel); if (!mOriginalLogLevel.equals("verbose")) { runShellCommand("cmd autofill set log_level %s", mOriginalLogLevel); } } private static void setServiceWatcher() { if (sServiceWatcher == null) { sServiceWatcher = new ServiceWatcher(); } } private static void clearServiceWatcher() { if (sServiceWatcher != null) { sServiceWatcher = null; } } public static final class ServiceWatcher { private final CountDownLatch mConnected = new CountDownLatch(1); public static void onConnected() { Log.i(TAG, "onConnected: sServiceWatcher=" + sServiceWatcher); sServiceWatcher.mConnected.countDown(); } @NonNull public void waitOnConnected() throws InterruptedException { await(mConnected, "not connected"); } private void await(@NonNull CountDownLatch latch, @NonNull String fmt, @Nullable Object... args) throws InterruptedException { final boolean called = latch.await(GENERIC_TIMEOUT_MS, TimeUnit.MILLISECONDS); if (!called) { throw new IllegalStateException(String.format(fmt, args) + " in " + GENERIC_TIMEOUT_MS + "ms"); } } } } apct-tests/perftests/autofill/src/android/view/autofill/LoginTest.java +17 −17 Original line number Diff line number Diff line Loading @@ -11,7 +11,7 @@ * 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 * limitations under the License. */ package android.view.autofill; Loading Loading @@ -57,14 +57,14 @@ public class LoginTest extends AbstractAutofillPerfTestCase { public void testFocus_noService() throws Throwable { resetService(); mActivityRule.runOnUiThread(() -> { BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); while (state.keepRunning()) { mActivityRule.runOnUiThread(() -> { mUsername.requestFocus(); mPassword.requestFocus(); } }); } } /** * This time the service is called, but it returns a {@code null} response so the UI behaves Loading @@ -82,14 +82,14 @@ public class LoginTest extends AbstractAutofillPerfTestCase { // Then focus on password so loop start with focus away from username mActivityRule.runOnUiThread(() -> mPassword.requestFocus()); mActivityRule.runOnUiThread(() -> { BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); while (state.keepRunning()) { mActivityRule.runOnUiThread(() -> { mUsername.requestFocus(); mPassword.requestFocus(); } }); } } /** * Now the service returns autofill data, for both username and password. Loading Loading @@ -252,19 +252,19 @@ public class LoginTest extends AbstractAutofillPerfTestCase { // outside the loop mActivityRule.runOnUiThread(() -> mUsername.requestFocus()); if (waitForService) { mTestWatcher.waitServiceConnect(); MyAutofillService.getLastFillRequest(); } mActivityRule.runOnUiThread(() -> { BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); while (state.keepRunning()) { mActivityRule.runOnUiThread(() -> { mUsername.setText(""); mUsername.setText("a"); mPassword.setText(""); mPassword.setText("x"); } }); } } // TODO(b/162216576): fix fail test and re-enable it @Ignore Loading apct-tests/perftests/autofill/src/android/view/autofill/MyAutofillService.java +15 −5 Original line number Diff line number Diff line Loading @@ -11,7 +11,7 @@ * 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 * limitations under the License. */ package android.view.autofill; Loading @@ -28,12 +28,9 @@ import android.util.Pair; import android.widget.RemoteViews; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.perftests.autofill.R; import java.util.ArrayList; import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; Loading @@ -44,7 +41,7 @@ import java.util.concurrent.TimeUnit; public class MyAutofillService extends AutofillService { private static final String TAG = "MyAutofillService"; private static final int TIMEOUT_MS = 5000; private static final int TIMEOUT_MS = 5_000; private static final String PACKAGE_NAME = "com.android.perftests.autofill"; static final String COMPONENT_NAME = PACKAGE_NAME + "/android.view.autofill.MyAutofillService"; Loading @@ -55,6 +52,14 @@ public class MyAutofillService extends AutofillService { private static boolean sEnabled; /** * Returns the TestWatcher that was used for the testing. */ @NonNull public static AutofillTestWatcher getTestWatcher() { return new AutofillTestWatcher(); } /** * Resets the static state associated with the service. */ Loading Loading @@ -92,6 +97,11 @@ public class MyAutofillService extends AutofillService { return request; } @Override public void onConnected() { AutofillTestWatcher.ServiceWatcher.onConnected(); } @Override public void onFillRequest(FillRequest request, CancellationSignal cancellationSignal, FillCallback callback) { Loading Loading
apct-tests/perftests/autofill/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ android_test { "androidx.test.rules", "androidx.annotation_annotation", "apct-perftests-utils", "compatibility-device-util-axt", "collector-device-lib", ], platform_apis: true, Loading
apct-tests/perftests/autofill/src/android/view/autofill/AbstractAutofillPerfTestCase.java +9 −19 Original line number Diff line number Diff line Loading @@ -11,7 +11,7 @@ * 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 * limitations under the License. */ package android.view.autofill; Loading @@ -28,10 +28,10 @@ import android.provider.Settings; import androidx.test.InstrumentationRegistry; import androidx.test.rule.ActivityTestRule; import org.junit.After; import org.junit.Before; import org.junit.ClassRule; import org.junit.Rule; import org.junit.rules.RuleChain; /** * Base class for all autofill tests. Loading @@ -43,12 +43,16 @@ public abstract class AbstractAutofillPerfTestCase { new SettingsStateKeeperRule(InstrumentationRegistry.getTargetContext(), Settings.Secure.AUTOFILL_SERVICE); @Rule public ActivityTestRule<PerfTestActivity> mActivityRule = protected final AutofillTestWatcher mTestWatcher = MyAutofillService.getTestWatcher(); protected ActivityTestRule<PerfTestActivity> mActivityRule = new ActivityTestRule<>(PerfTestActivity.class); protected PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter(); @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter(); public final RuleChain mAllRules = RuleChain .outerRule(mTestWatcher) .around(mPerfStatusReporter) .around(mActivityRule); private final int mLayoutId; Loading @@ -72,20 +76,6 @@ public abstract class AbstractAutofillPerfTestCase { }); } @Before public void enableService() { MyAutofillService.resetStaticState(); MyAutofillService.setEnabled(true); } @After public void disableService() { // Must disable service so calls are ignored in case of errors during the test case; // otherwise, other tests will fail because these calls are made in the UI thread (as both // the service, the tests, and the app run in the same process). MyAutofillService.setEnabled(false); } /** * Initializes the {@link PerfTestActivity} after it was launched. */ Loading
apct-tests/perftests/autofill/src/android/view/autofill/AutofillTestWatcher.java 0 → 100644 +133 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 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.view.autofill; import static com.android.compatibility.common.util.ShellUtils.runShellCommand; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.junit.rules.TestWatcher; import org.junit.runner.Description; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; /** * Custom {@link TestWatcher} that does the setup and reset tasks for the tests. */ final class AutofillTestWatcher extends TestWatcher { private static final String TAG = "AutofillTestWatcher"; private static final long GENERIC_TIMEOUT_MS = 10_000; private static ServiceWatcher sServiceWatcher; private String mOriginalLogLevel; @Override protected void starting(Description description) { super.starting(description); enableVerboseLog(); MyAutofillService.resetStaticState(); MyAutofillService.setEnabled(true); setServiceWatcher(); } @Override protected void finished(Description description) { super.finished(description); restoreLogLevel(); disableService(); clearServiceWatcher(); } void waitServiceConnect() throws InterruptedException { if (sServiceWatcher != null) { Log.d(TAG, "waitServiceConnect()"); sServiceWatcher.waitOnConnected(); } } private void enableService() { MyAutofillService.resetStaticState(); MyAutofillService.setEnabled(true); } private void disableService() { // Must disable service so calls are ignored in case of errors during the test case; // otherwise, other tests will fail because these calls are made in the UI thread (as both // the service, the tests, and the app run in the same process). MyAutofillService.setEnabled(false); } private void enableVerboseLog() { mOriginalLogLevel = runShellCommand("cmd autofill get log_level"); Log.d(TAG, "enableVerboseLog(), mOriginalLogLevel=" + mOriginalLogLevel); if (!mOriginalLogLevel.equals("verbose")) { runShellCommand("cmd autofill set log_level verbose"); } } private void restoreLogLevel() { Log.w(TAG, "restoreLogLevel to " + mOriginalLogLevel); if (!mOriginalLogLevel.equals("verbose")) { runShellCommand("cmd autofill set log_level %s", mOriginalLogLevel); } } private static void setServiceWatcher() { if (sServiceWatcher == null) { sServiceWatcher = new ServiceWatcher(); } } private static void clearServiceWatcher() { if (sServiceWatcher != null) { sServiceWatcher = null; } } public static final class ServiceWatcher { private final CountDownLatch mConnected = new CountDownLatch(1); public static void onConnected() { Log.i(TAG, "onConnected: sServiceWatcher=" + sServiceWatcher); sServiceWatcher.mConnected.countDown(); } @NonNull public void waitOnConnected() throws InterruptedException { await(mConnected, "not connected"); } private void await(@NonNull CountDownLatch latch, @NonNull String fmt, @Nullable Object... args) throws InterruptedException { final boolean called = latch.await(GENERIC_TIMEOUT_MS, TimeUnit.MILLISECONDS); if (!called) { throw new IllegalStateException(String.format(fmt, args) + " in " + GENERIC_TIMEOUT_MS + "ms"); } } } }
apct-tests/perftests/autofill/src/android/view/autofill/LoginTest.java +17 −17 Original line number Diff line number Diff line Loading @@ -11,7 +11,7 @@ * 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 * limitations under the License. */ package android.view.autofill; Loading Loading @@ -57,14 +57,14 @@ public class LoginTest extends AbstractAutofillPerfTestCase { public void testFocus_noService() throws Throwable { resetService(); mActivityRule.runOnUiThread(() -> { BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); while (state.keepRunning()) { mActivityRule.runOnUiThread(() -> { mUsername.requestFocus(); mPassword.requestFocus(); } }); } } /** * This time the service is called, but it returns a {@code null} response so the UI behaves Loading @@ -82,14 +82,14 @@ public class LoginTest extends AbstractAutofillPerfTestCase { // Then focus on password so loop start with focus away from username mActivityRule.runOnUiThread(() -> mPassword.requestFocus()); mActivityRule.runOnUiThread(() -> { BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); while (state.keepRunning()) { mActivityRule.runOnUiThread(() -> { mUsername.requestFocus(); mPassword.requestFocus(); } }); } } /** * Now the service returns autofill data, for both username and password. Loading Loading @@ -252,19 +252,19 @@ public class LoginTest extends AbstractAutofillPerfTestCase { // outside the loop mActivityRule.runOnUiThread(() -> mUsername.requestFocus()); if (waitForService) { mTestWatcher.waitServiceConnect(); MyAutofillService.getLastFillRequest(); } mActivityRule.runOnUiThread(() -> { BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); while (state.keepRunning()) { mActivityRule.runOnUiThread(() -> { mUsername.setText(""); mUsername.setText("a"); mPassword.setText(""); mPassword.setText("x"); } }); } } // TODO(b/162216576): fix fail test and re-enable it @Ignore Loading
apct-tests/perftests/autofill/src/android/view/autofill/MyAutofillService.java +15 −5 Original line number Diff line number Diff line Loading @@ -11,7 +11,7 @@ * 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 * limitations under the License. */ package android.view.autofill; Loading @@ -28,12 +28,9 @@ import android.util.Pair; import android.widget.RemoteViews; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.perftests.autofill.R; import java.util.ArrayList; import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; Loading @@ -44,7 +41,7 @@ import java.util.concurrent.TimeUnit; public class MyAutofillService extends AutofillService { private static final String TAG = "MyAutofillService"; private static final int TIMEOUT_MS = 5000; private static final int TIMEOUT_MS = 5_000; private static final String PACKAGE_NAME = "com.android.perftests.autofill"; static final String COMPONENT_NAME = PACKAGE_NAME + "/android.view.autofill.MyAutofillService"; Loading @@ -55,6 +52,14 @@ public class MyAutofillService extends AutofillService { private static boolean sEnabled; /** * Returns the TestWatcher that was used for the testing. */ @NonNull public static AutofillTestWatcher getTestWatcher() { return new AutofillTestWatcher(); } /** * Resets the static state associated with the service. */ Loading Loading @@ -92,6 +97,11 @@ public class MyAutofillService extends AutofillService { return request; } @Override public void onConnected() { AutofillTestWatcher.ServiceWatcher.onConnected(); } @Override public void onFillRequest(FillRequest request, CancellationSignal cancellationSignal, FillCallback callback) { Loading