Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 66f04764 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Improve autofill perf test."

parents 443ce4f9 506fd71e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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,
+9 −19
Original line number Diff line number Diff line
@@ -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;
@@ -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.
@@ -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;

@@ -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.
     */
+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");
            }
        }
    }
}
+17 −17
Original line number Diff line number Diff line
@@ -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;
@@ -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
@@ -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.
@@ -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
+15 −5
Original line number Diff line number Diff line
@@ -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;

@@ -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;
@@ -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";
@@ -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.
     */
@@ -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) {