summaryrefslogtreecommitdiff
path: root/apct-tests/perftests
diff options
context:
space:
mode:
authorTreeHugger Robot <treehugger-gerrit@google.com>2021-06-29 20:05:44 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2021-06-29 20:05:44 +0000
commitb65f67968dd3023a8231f6c31014fa7a176d87bd (patch)
treea254d1f78c096ab87b1ed8ffc9fdb424b276b606 /apct-tests/perftests
parentc529cc68a47a834af063796ed0b46563c7124a5e (diff)
parent3f6ae29b01b0489ee1ee87eaa7b6b8633c3829fa (diff)
Merge "Improve IME perf test show/hide stability" into sc-dev
Diffstat (limited to 'apct-tests/perftests')
-rw-r--r--apct-tests/perftests/inputmethod/src/android/inputmethod/ImePerfTest.java50
-rw-r--r--apct-tests/perftests/utils/src/android/perftests/utils/TestUtils.java44
2 files changed, 83 insertions, 11 deletions
diff --git a/apct-tests/perftests/inputmethod/src/android/inputmethod/ImePerfTest.java b/apct-tests/perftests/inputmethod/src/android/inputmethod/ImePerfTest.java
index 689fb3645daf..21c4491fc371 100644
--- a/apct-tests/perftests/inputmethod/src/android/inputmethod/ImePerfTest.java
+++ b/apct-tests/perftests/inputmethod/src/android/inputmethod/ImePerfTest.java
@@ -18,6 +18,7 @@ package android.inputmethod;
import static android.perftests.utils.ManualBenchmarkState.StatsReport;
import static android.perftests.utils.PerfTestActivity.ID_EDITOR;
+import static android.perftests.utils.TestUtils.getOnMainSync;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.WindowInsetsAnimation.Callback.DISPATCH_MODE_STOP;
@@ -25,6 +26,7 @@ import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentat
import static org.junit.Assert.assertTrue;
+import android.annotation.UiThread;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
@@ -64,6 +66,7 @@ import java.io.InputStreamReader;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
@@ -72,6 +75,7 @@ import java.util.concurrent.atomic.AtomicReference;
public class ImePerfTest extends ImePerfTestBase
implements ManualBenchmarkState.CustomizedIterationListener {
private static final String TAG = ImePerfTest.class.getSimpleName();
+ private static final long ANIMATION_NOT_STARTED = -1;
@Rule
public final PerfManualStatusReporter mPerfStatusReporter = new PerfManualStatusReporter();
@@ -304,12 +308,18 @@ public class ImePerfTest extends ImePerfTestBase
latchEnd.set(new CountDownLatch(2));
// For measuring hide, lets show IME first.
if (!show) {
- activity.runOnUiThread(() -> {
- controller.show(WindowInsets.Type.ime());
+ AtomicBoolean showCalled = new AtomicBoolean();
+ getInstrumentation().runOnMainSync(() -> {
+ if (!isImeVisible(activity)) {
+ controller.show(WindowInsets.Type.ime());
+ showCalled.set(true);
+ }
});
- PollingCheck.check("IME show animation should finish ", TIMEOUT_1_S_IN_MS,
- () -> latchStart.get().getCount() == 1
- && latchEnd.get().getCount() == 1);
+ if (showCalled.get()) {
+ PollingCheck.check("IME show animation should finish ", TIMEOUT_1_S_IN_MS,
+ () -> latchStart.get().getCount() == 1
+ && latchEnd.get().getCount() == 1);
+ }
}
if (!mIsTraceStarted && !state.isWarmingUp()) {
startAsyncAtrace();
@@ -317,23 +327,35 @@ public class ImePerfTest extends ImePerfTestBase
}
AtomicLong startTime = new AtomicLong();
- activity.runOnUiThread(() -> {
+ AtomicBoolean unexpectedVisibility = new AtomicBoolean();
+ getInstrumentation().runOnMainSync(() -> {
+ boolean isVisible = isImeVisible(activity);
startTime.set(SystemClock.elapsedRealtimeNanos());
- if (show) {
+
+ if (show && !isVisible) {
controller.show(WindowInsets.Type.ime());
- } else {
+ } else if (!show && isVisible) {
controller.hide(WindowInsets.Type.ime());
+ } else {
+ // ignore this iteration as unexpected IME visibility was encountered.
+ unexpectedVisibility.set(true);
}
});
- measuredTimeNs = waitForAnimationStart(latchStart, startTime);
+ if (!unexpectedVisibility.get()) {
+ long timeElapsed = waitForAnimationStart(latchStart, startTime);
+ if (timeElapsed != ANIMATION_NOT_STARTED) {
+ measuredTimeNs = timeElapsed;
+ }
+ }
// hide IME before next iteration.
if (show) {
activity.runOnUiThread(() -> controller.hide(WindowInsets.Type.ime()));
try {
latchEnd.get().await(TIMEOUT_1_S_IN_MS * 5, TimeUnit.MILLISECONDS);
- if (latchEnd.get().getCount() != 0) {
+ if (latchEnd.get().getCount() != 0
+ && getOnMainSync(() -> isImeVisible(activity))) {
Assert.fail("IME hide animation should finish.");
}
} catch (InterruptedException e) {
@@ -350,12 +372,18 @@ public class ImePerfTest extends ImePerfTestBase
addResultToState(state);
}
+ @UiThread
+ private boolean isImeVisible(@NonNull final Activity activity) {
+ return activity.getWindow().getDecorView().getRootWindowInsets().isVisible(
+ WindowInsets.Type.ime());
+ }
+
private long waitForAnimationStart(
AtomicReference<CountDownLatch> latchStart, AtomicLong startTime) {
try {
latchStart.get().await(TIMEOUT_1_S_IN_MS * 5, TimeUnit.MILLISECONDS);
if (latchStart.get().getCount() != 0) {
- Assert.fail("IME animation should start " + latchStart.get().getCount());
+ return ANIMATION_NOT_STARTED;
}
} catch (InterruptedException e) { }
diff --git a/apct-tests/perftests/utils/src/android/perftests/utils/TestUtils.java b/apct-tests/perftests/utils/src/android/perftests/utils/TestUtils.java
new file mode 100644
index 000000000000..d8d3ee329638
--- /dev/null
+++ b/apct-tests/perftests/utils/src/android/perftests/utils/TestUtils.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2021 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.app.Instrumentation;
+
+import androidx.annotation.NonNull;
+import androidx.test.InstrumentationRegistry;
+
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Supplier;
+
+public final class TestUtils {
+
+ /**
+ * Retrieves a value that needs to be obtained on the main thread.
+ *
+ * <p>A simple utility method that helps to return an object from the UI thread.</p>
+ *
+ * @param supplier callback to be called on the UI thread to return a value
+ * @param <T> Type of the value to be returned
+ * @return Value returned from {@code supplier}
+ */
+ public static <T> T getOnMainSync(@NonNull Supplier<T> supplier) {
+ final AtomicReference<T> result = new AtomicReference<>();
+ final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ instrumentation.runOnMainSync(() -> result.set(supplier.get()));
+ return result.get();
+ }
+}