Loading apct-tests/perftests/core/src/android/view/autofill/AutofillPerfTest.java +94 −27 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.os.Looper; import android.os.Bundle; import android.os.Bundle; import android.perftests.utils.PerfStatusReporter; import android.perftests.utils.PerfStatusReporter; import android.perftests.utils.SettingsHelper; import android.perftests.utils.SettingsHelper; import android.perftests.utils.SettingsStateKeeperRule; import android.perftests.utils.ShellHelper; import android.perftests.utils.ShellHelper; import android.util.Log; import android.util.Log; import android.view.View; import android.view.View; Loading @@ -42,6 +43,7 @@ import java.util.Arrays; import org.junit.Test; import org.junit.Test; import org.junit.After; import org.junit.After; import org.junit.Before; import org.junit.Before; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Rule; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import org.junit.runners.Parameterized.Parameters; Loading @@ -67,6 +69,10 @@ public class AutofillPerfTest { mLayoutId = layoutId; mLayoutId = layoutId; } } @ClassRule public static final SettingsStateKeeperRule mServiceSettingsKeeper = new SettingsStateKeeperRule( InstrumentationRegistry.getTargetContext(), Settings.Secure.AUTOFILL_SERVICE); @Rule @Rule public ActivityTestRule<StubActivity> mActivityRule = public ActivityTestRule<StubActivity> mActivityRule = new ActivityTestRule<StubActivity>(StubActivity.class); new ActivityTestRule<StubActivity>(StubActivity.class); Loading Loading @@ -97,11 +103,6 @@ public class AutofillPerfTest { MyAutofillService.resetStaticState(); MyAutofillService.resetStaticState(); } } @After public void cleanup() { resetService(); } /** /** * This is the baseline test for focusing the 2 views when autofill is disabled. * This is the baseline test for focusing the 2 views when autofill is disabled. */ */ Loading @@ -109,7 +110,7 @@ public class AutofillPerfTest { public void testFocus_noService() throws Throwable { public void testFocus_noService() throws Throwable { resetService(); resetService(); focusTest(); focusTest(false); } } /** /** Loading @@ -121,13 +122,7 @@ public class AutofillPerfTest { MyAutofillService.newCannedResponse().reply(); MyAutofillService.newCannedResponse().reply(); setService(); setService(); // Must first focus in a field to trigger autofill and wait for service response focusTest(true); // outside the loop mActivityRule.runOnUiThread(() -> mUsername.requestFocus()); MyAutofillService.getLastFillRequest(); // Test properly speaking focusTest(); // Sanity check // Sanity check MyAutofillService.assertNoAsyncErrors(); MyAutofillService.assertNoAsyncErrors(); Loading @@ -144,13 +139,7 @@ public class AutofillPerfTest { .reply(); .reply(); setService(); setService(); // Must first focus in a field to trigger autofill and wait for service response focusTest(true); // outside the loop mActivityRule.runOnUiThread(() -> mUsername.requestFocus()); MyAutofillService.getLastFillRequest(); // Test properly speaking focusTest(); // Sanity check // Sanity check MyAutofillService.assertNoAsyncErrors(); MyAutofillService.assertNoAsyncErrors(); Loading @@ -168,29 +157,107 @@ public class AutofillPerfTest { .reply(); .reply(); setService(); setService(); focusTest(true); // Sanity check MyAutofillService.assertNoAsyncErrors(); } private void focusTest(boolean waitForService) throws Throwable { // Must first focus in a field to trigger autofill and wait for service response // Must first focus in a field to trigger autofill and wait for service response // outside the loop // outside the loop mActivityRule.runOnUiThread(() -> mUsername.requestFocus()); mActivityRule.runOnUiThread(() -> mUsername.requestFocus()); if (waitForService) { MyAutofillService.getLastFillRequest(); MyAutofillService.getLastFillRequest(); } mActivityRule.runOnUiThread(() -> { BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); while (state.keepRunning()) { mUsername.requestFocus(); mPassword.requestFocus(); } }); } focusTest(); /** * This is the baseline test for changing the 2 views when autofill is disabled. */ @Test public void testChange_noService() throws Throwable { resetService(); changeTest(false); } /** * This time the service is called, but it returns a {@code null} response so the UI behaves * as if autofill was disabled. */ @Test public void testChange_serviceDoesNotAutofill() throws Throwable { MyAutofillService.newCannedResponse().reply(); setService(); changeTest(true); // Sanity check // Sanity check MyAutofillService.assertNoAsyncErrors(); MyAutofillService.assertNoAsyncErrors(); } } private void focusTest() throws Throwable { /** * Now the service returns autofill data, for both username and password. */ @Test public void testChange_autofillBothFields() throws Throwable { MyAutofillService.newCannedResponse() .setUsername(mUsername.getAutofillId(), "user") .setPassword(mPassword.getAutofillId(), "pass") .reply(); setService(); changeTest(true); // Sanity check MyAutofillService.assertNoAsyncErrors(); } /** * Now the service returns autofill data, but just for username. */ @Test public void testChange_autofillUsernameOnly() throws Throwable { // Must set ignored ids so focus on password does not trigger new requests MyAutofillService.newCannedResponse() .setUsername(mUsername.getAutofillId(), "user") .setIgnored(mPassword.getAutofillId()) .reply(); setService(); changeTest(true); // Sanity check MyAutofillService.assertNoAsyncErrors(); } private void changeTest(boolean waitForService) throws Throwable { // Must first focus in a field to trigger autofill and wait for service response // outside the loop mActivityRule.runOnUiThread(() -> mUsername.requestFocus()); if (waitForService) { MyAutofillService.getLastFillRequest(); } mActivityRule.runOnUiThread(() -> { mActivityRule.runOnUiThread(() -> { BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); while (state.keepRunning()) { while (state.keepRunning()) { mUsername.requestFocus(); mUsername.setText(""); mPassword.requestFocus(); mUsername.setText("a"); mPassword.setText(""); mPassword.setText("x"); } } }); }); } } // TODO: add tests for changing value of the fields /** /** * Uses the {@code settings} binary to set the autofill service. * Uses the {@code settings} binary to set the autofill service. */ */ Loading apct-tests/perftests/utils/src/android/perftests/utils/SettingsStateKeeperRule.java 0 → 100644 +39 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2018 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.perftests.utils; import android.content.Context; import android.provider.Settings; import androidx.annotation.NonNull; /** * JUnit rule used to restore a {@link Settings} preference after the test is run. * * <p>It stores the current value before the test, and restores it after the test (if necessary). */ public class SettingsStateKeeperRule extends StateKeeperRule<String> { /** * Default constructor. * * @param context context used to retrieve the {@link Settings} provider. * @param key prefence key. */ public SettingsStateKeeperRule(@NonNull Context context, @NonNull String key) { super(new SettingsStateManager(context, SettingsHelper.NAMESPACE_SECURE, key)); } } apct-tests/perftests/utils/src/android/perftests/utils/SettingsStateManager.java 0 → 100644 +63 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2018 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.perftests.utils; import android.content.Context; import android.provider.Settings; import androidx.annotation.NonNull; import androidx.annotation.Nullable; /** * Manages the state of a preference backed by {@link Settings}. */ public class SettingsStateManager implements StateManager<String> { private final Context mContext; private final String mNamespace; private final String mKey; /** * Default constructor. * * @param context context used to retrieve the {@link Settings} provider. * @param namespace settings namespace. * @param key prefence key. */ public SettingsStateManager(@NonNull Context context, @NonNull String namespace, @NonNull String key) { mContext = context; mNamespace = namespace; mKey = key; } @Override public void set(@Nullable String value) { SettingsHelper.syncSet(mContext, mNamespace, mKey, value); } @Override @Nullable public String get() { return SettingsHelper.get(mNamespace, mKey); } @Override public String toString() { return "SettingsStateManager[namespace=" + mNamespace + ", key=" + mKey + "]"; } } apct-tests/perftests/utils/src/android/perftests/utils/StateKeeperRule.java 0 → 100644 +63 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2018 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.perftests.utils; import androidx.annotation.NonNull; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; import java.util.Objects; /** * JUnit rule used to restore a state after the test is run. * * <p>It stores the current state before the test, and restores it after the test (if necessary). */ public class StateKeeperRule<T> implements TestRule { private final StateManager<T> mStateManager; /** * Default constructor. * * @param stateManager abstraction used to manage the state. */ public StateKeeperRule(StateManager<T> stateManager) { mStateManager = stateManager; } @Override public Statement apply(Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { final T previousValue = mStateManager.get(); try { base.evaluate(); } finally { final T currentValue = mStateManager.get(); if (!Objects.equals(previousValue, currentValue)) { mStateManager.set(previousValue); } } } }; } } apct-tests/perftests/utils/src/android/perftests/utils/StateManager.java 0 → 100644 +34 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2018 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.perftests.utils; import androidx.annotation.Nullable; /** * Abstraction for a state that is managed somewhere, like Android Settings. */ public interface StateManager<T> { /** * Sets a new state. */ void set(@Nullable T value); /** * Gets the current state. */ @Nullable T get(); } Loading
apct-tests/perftests/core/src/android/view/autofill/AutofillPerfTest.java +94 −27 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.os.Looper; import android.os.Bundle; import android.os.Bundle; import android.perftests.utils.PerfStatusReporter; import android.perftests.utils.PerfStatusReporter; import android.perftests.utils.SettingsHelper; import android.perftests.utils.SettingsHelper; import android.perftests.utils.SettingsStateKeeperRule; import android.perftests.utils.ShellHelper; import android.perftests.utils.ShellHelper; import android.util.Log; import android.util.Log; import android.view.View; import android.view.View; Loading @@ -42,6 +43,7 @@ import java.util.Arrays; import org.junit.Test; import org.junit.Test; import org.junit.After; import org.junit.After; import org.junit.Before; import org.junit.Before; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Rule; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import org.junit.runners.Parameterized.Parameters; Loading @@ -67,6 +69,10 @@ public class AutofillPerfTest { mLayoutId = layoutId; mLayoutId = layoutId; } } @ClassRule public static final SettingsStateKeeperRule mServiceSettingsKeeper = new SettingsStateKeeperRule( InstrumentationRegistry.getTargetContext(), Settings.Secure.AUTOFILL_SERVICE); @Rule @Rule public ActivityTestRule<StubActivity> mActivityRule = public ActivityTestRule<StubActivity> mActivityRule = new ActivityTestRule<StubActivity>(StubActivity.class); new ActivityTestRule<StubActivity>(StubActivity.class); Loading Loading @@ -97,11 +103,6 @@ public class AutofillPerfTest { MyAutofillService.resetStaticState(); MyAutofillService.resetStaticState(); } } @After public void cleanup() { resetService(); } /** /** * This is the baseline test for focusing the 2 views when autofill is disabled. * This is the baseline test for focusing the 2 views when autofill is disabled. */ */ Loading @@ -109,7 +110,7 @@ public class AutofillPerfTest { public void testFocus_noService() throws Throwable { public void testFocus_noService() throws Throwable { resetService(); resetService(); focusTest(); focusTest(false); } } /** /** Loading @@ -121,13 +122,7 @@ public class AutofillPerfTest { MyAutofillService.newCannedResponse().reply(); MyAutofillService.newCannedResponse().reply(); setService(); setService(); // Must first focus in a field to trigger autofill and wait for service response focusTest(true); // outside the loop mActivityRule.runOnUiThread(() -> mUsername.requestFocus()); MyAutofillService.getLastFillRequest(); // Test properly speaking focusTest(); // Sanity check // Sanity check MyAutofillService.assertNoAsyncErrors(); MyAutofillService.assertNoAsyncErrors(); Loading @@ -144,13 +139,7 @@ public class AutofillPerfTest { .reply(); .reply(); setService(); setService(); // Must first focus in a field to trigger autofill and wait for service response focusTest(true); // outside the loop mActivityRule.runOnUiThread(() -> mUsername.requestFocus()); MyAutofillService.getLastFillRequest(); // Test properly speaking focusTest(); // Sanity check // Sanity check MyAutofillService.assertNoAsyncErrors(); MyAutofillService.assertNoAsyncErrors(); Loading @@ -168,29 +157,107 @@ public class AutofillPerfTest { .reply(); .reply(); setService(); setService(); focusTest(true); // Sanity check MyAutofillService.assertNoAsyncErrors(); } private void focusTest(boolean waitForService) throws Throwable { // Must first focus in a field to trigger autofill and wait for service response // Must first focus in a field to trigger autofill and wait for service response // outside the loop // outside the loop mActivityRule.runOnUiThread(() -> mUsername.requestFocus()); mActivityRule.runOnUiThread(() -> mUsername.requestFocus()); if (waitForService) { MyAutofillService.getLastFillRequest(); MyAutofillService.getLastFillRequest(); } mActivityRule.runOnUiThread(() -> { BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); while (state.keepRunning()) { mUsername.requestFocus(); mPassword.requestFocus(); } }); } focusTest(); /** * This is the baseline test for changing the 2 views when autofill is disabled. */ @Test public void testChange_noService() throws Throwable { resetService(); changeTest(false); } /** * This time the service is called, but it returns a {@code null} response so the UI behaves * as if autofill was disabled. */ @Test public void testChange_serviceDoesNotAutofill() throws Throwable { MyAutofillService.newCannedResponse().reply(); setService(); changeTest(true); // Sanity check // Sanity check MyAutofillService.assertNoAsyncErrors(); MyAutofillService.assertNoAsyncErrors(); } } private void focusTest() throws Throwable { /** * Now the service returns autofill data, for both username and password. */ @Test public void testChange_autofillBothFields() throws Throwable { MyAutofillService.newCannedResponse() .setUsername(mUsername.getAutofillId(), "user") .setPassword(mPassword.getAutofillId(), "pass") .reply(); setService(); changeTest(true); // Sanity check MyAutofillService.assertNoAsyncErrors(); } /** * Now the service returns autofill data, but just for username. */ @Test public void testChange_autofillUsernameOnly() throws Throwable { // Must set ignored ids so focus on password does not trigger new requests MyAutofillService.newCannedResponse() .setUsername(mUsername.getAutofillId(), "user") .setIgnored(mPassword.getAutofillId()) .reply(); setService(); changeTest(true); // Sanity check MyAutofillService.assertNoAsyncErrors(); } private void changeTest(boolean waitForService) throws Throwable { // Must first focus in a field to trigger autofill and wait for service response // outside the loop mActivityRule.runOnUiThread(() -> mUsername.requestFocus()); if (waitForService) { MyAutofillService.getLastFillRequest(); } mActivityRule.runOnUiThread(() -> { mActivityRule.runOnUiThread(() -> { BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); while (state.keepRunning()) { while (state.keepRunning()) { mUsername.requestFocus(); mUsername.setText(""); mPassword.requestFocus(); mUsername.setText("a"); mPassword.setText(""); mPassword.setText("x"); } } }); }); } } // TODO: add tests for changing value of the fields /** /** * Uses the {@code settings} binary to set the autofill service. * Uses the {@code settings} binary to set the autofill service. */ */ Loading
apct-tests/perftests/utils/src/android/perftests/utils/SettingsStateKeeperRule.java 0 → 100644 +39 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2018 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.perftests.utils; import android.content.Context; import android.provider.Settings; import androidx.annotation.NonNull; /** * JUnit rule used to restore a {@link Settings} preference after the test is run. * * <p>It stores the current value before the test, and restores it after the test (if necessary). */ public class SettingsStateKeeperRule extends StateKeeperRule<String> { /** * Default constructor. * * @param context context used to retrieve the {@link Settings} provider. * @param key prefence key. */ public SettingsStateKeeperRule(@NonNull Context context, @NonNull String key) { super(new SettingsStateManager(context, SettingsHelper.NAMESPACE_SECURE, key)); } }
apct-tests/perftests/utils/src/android/perftests/utils/SettingsStateManager.java 0 → 100644 +63 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2018 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.perftests.utils; import android.content.Context; import android.provider.Settings; import androidx.annotation.NonNull; import androidx.annotation.Nullable; /** * Manages the state of a preference backed by {@link Settings}. */ public class SettingsStateManager implements StateManager<String> { private final Context mContext; private final String mNamespace; private final String mKey; /** * Default constructor. * * @param context context used to retrieve the {@link Settings} provider. * @param namespace settings namespace. * @param key prefence key. */ public SettingsStateManager(@NonNull Context context, @NonNull String namespace, @NonNull String key) { mContext = context; mNamespace = namespace; mKey = key; } @Override public void set(@Nullable String value) { SettingsHelper.syncSet(mContext, mNamespace, mKey, value); } @Override @Nullable public String get() { return SettingsHelper.get(mNamespace, mKey); } @Override public String toString() { return "SettingsStateManager[namespace=" + mNamespace + ", key=" + mKey + "]"; } }
apct-tests/perftests/utils/src/android/perftests/utils/StateKeeperRule.java 0 → 100644 +63 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2018 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.perftests.utils; import androidx.annotation.NonNull; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; import java.util.Objects; /** * JUnit rule used to restore a state after the test is run. * * <p>It stores the current state before the test, and restores it after the test (if necessary). */ public class StateKeeperRule<T> implements TestRule { private final StateManager<T> mStateManager; /** * Default constructor. * * @param stateManager abstraction used to manage the state. */ public StateKeeperRule(StateManager<T> stateManager) { mStateManager = stateManager; } @Override public Statement apply(Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { final T previousValue = mStateManager.get(); try { base.evaluate(); } finally { final T currentValue = mStateManager.get(); if (!Objects.equals(previousValue, currentValue)) { mStateManager.set(previousValue); } } } }; } }
apct-tests/perftests/utils/src/android/perftests/utils/StateManager.java 0 → 100644 +34 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2018 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.perftests.utils; import androidx.annotation.Nullable; /** * Abstraction for a state that is managed somewhere, like Android Settings. */ public interface StateManager<T> { /** * Sets a new state. */ void set(@Nullable T value); /** * Gets the current state. */ @Nullable T get(); }