diff options
author | Riddle Hsu <riddlehsu@google.com> | 2020-07-22 19:08:10 +0800 |
---|---|---|
committer | Riddle Hsu <riddlehsu@google.com> | 2020-07-22 11:27:56 +0000 |
commit | 36a901b6bd627505e40b9b90ea0ff910043bf932 (patch) | |
tree | 1767875b111abc25e6256ea3af1e8d1ad9b4ff1a | |
parent | de18936dbdefff6da58326be8350be41a05b4624 (diff) |
Add some preconditions for WmPerfTests
- Add a readme file to describe how to lock CPU/GPU frequencies
on local test.
- Ensure gesture navigation is enabled when testing.
- Full compile the test package.
- Remove all activities before testing.
Bug: 161782101
Test: atest WmPerfTests
Change-Id: Iebcfcbc07e3fe7d3b1839b8c2e04041d7338c48e
4 files changed, 204 insertions, 26 deletions
diff --git a/apct-tests/perftests/windowmanager/AndroidTest.xml b/apct-tests/perftests/windowmanager/AndroidTest.xml index 69d187f9419a..0a80cf96fba3 100644 --- a/apct-tests/perftests/windowmanager/AndroidTest.xml +++ b/apct-tests/perftests/windowmanager/AndroidTest.xml @@ -21,9 +21,17 @@ <option name="test-file-name" value="WmPerfTests.apk" /> </target_preparer> + <target_preparer class="com.android.tradefed.targetprep.DeviceSetup"> + <option name="force-skip-system-props" value="true" /> + <option name="run-command" value="input keyevent KEYCODE_WAKEUP" /> + <option name="run-command" value="cmd window dismiss-keyguard" /> + <option name="run-command" value="cmd package compile -m speed com.android.perftests.wm" /> + </target_preparer> + <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.perftests.wm" /> <option name="hidden-api-checks" value="false"/> + <option name="device-listeners" value="android.wm.WmPerfRunListener" /> </test> <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector"> diff --git a/apct-tests/perftests/windowmanager/README.md b/apct-tests/perftests/windowmanager/README.md new file mode 100644 index 000000000000..05fa6279a949 --- /dev/null +++ b/apct-tests/perftests/windowmanager/README.md @@ -0,0 +1,27 @@ +## Window manager performance tests + +### Precondition +To reduce the variance of the test, if `perf-setup.sh` (platform_testing/scripts/perf-setup) +is available, it is better to use the following instructions to lock CPU and GPU frequencies. +``` +m perf-setup.sh +PERF_SETUP_PATH=/data/local/tmp/perf-setup.sh +adb push $OUT/$PERF_SETUP_PATH $PERF_SETUP_PATH +adb shell chmod +x $PERF_SETUP_PATH +adb shell $PERF_SETUP_PATH +``` + +### Example to run +Use `atest` +``` +atest WmPerfTests:RelayoutPerfTest -- \ + --module-arg WmPerfTests:instrumentation-arg:kill-bg:=true +``` +Use `am instrument` +``` +adb shell am instrument -w -r -e class android.wm.RelayoutPerfTest \ + -e listener android.wm.WmPerfRunListener \ + -e kill-bg true \ + com.android.perftests.wm/androidx.test.runner.AndroidJUnitRunner +``` +* `kill-bg` is optional. diff --git a/apct-tests/perftests/windowmanager/src/android/wm/WindowManagerPerfTestBase.java b/apct-tests/perftests/windowmanager/src/android/wm/WindowManagerPerfTestBase.java index 655d2f7f8aa7..dc6245bf2c09 100644 --- a/apct-tests/perftests/windowmanager/src/android/wm/WindowManagerPerfTestBase.java +++ b/apct-tests/perftests/windowmanager/src/android/wm/WindowManagerPerfTestBase.java @@ -23,18 +23,15 @@ import android.app.KeyguardManager; import android.app.UiAutomation; import android.content.Context; import android.content.Intent; -import android.os.BatteryManager; import android.os.ParcelFileDescriptor; import android.os.PowerManager; import android.perftests.utils.PerfTestActivity; -import android.provider.Settings; import androidx.test.rule.ActivityTestRule; import androidx.test.runner.lifecycle.ActivityLifecycleCallback; import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry; import androidx.test.runner.lifecycle.Stage; -import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.runner.Description; import org.junit.runners.model.Statement; @@ -43,7 +40,9 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.util.Objects; import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; public class WindowManagerPerfTestBase { static final UiAutomation sUiAutomation = getInstrumentation().getUiAutomation(); @@ -56,21 +55,11 @@ public class WindowManagerPerfTestBase { * is in /data because while enabling method profling of system server, it cannot write the * trace to external storage. */ - static final File BASE_OUT_PATH = new File("/data/local/CorePerfTests"); - - private static int sOriginalStayOnWhilePluggedIn; + static final File BASE_OUT_PATH = new File("/data/local/WmPerfTests"); @BeforeClass public static void setUpOnce() { final Context context = getInstrumentation().getContext(); - final int stayOnWhilePluggedIn = Settings.Global.getInt(context.getContentResolver(), - Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0); - sOriginalStayOnWhilePluggedIn = -1; - if (stayOnWhilePluggedIn != BatteryManager.BATTERY_PLUGGED_ANY) { - sOriginalStayOnWhilePluggedIn = stayOnWhilePluggedIn; - // Keep the device awake during testing. - setStayOnWhilePluggedIn(BatteryManager.BATTERY_PLUGGED_ANY); - } if (!BASE_OUT_PATH.exists()) { executeShellCommand("mkdir -p " + BASE_OUT_PATH); @@ -84,18 +73,6 @@ public class WindowManagerPerfTestBase { .addCategory(Intent.CATEGORY_HOME).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); } - @AfterClass - public static void tearDownOnce() { - if (sOriginalStayOnWhilePluggedIn != -1) { - setStayOnWhilePluggedIn(sOriginalStayOnWhilePluggedIn); - } - } - - private static void setStayOnWhilePluggedIn(int value) { - executeShellCommand(String.format("settings put global %s %d", - Settings.Global.STAY_ON_WHILE_PLUGGED_IN, value)); - } - /** * Executes shell command with reading the output. It may also used to block until the current * command is completed. @@ -124,6 +101,42 @@ public class WindowManagerPerfTestBase { executeShellCommand("am profile stop system"); } + static void runWithShellPermissionIdentity(Runnable runnable) { + sUiAutomation.adoptShellPermissionIdentity(); + try { + runnable.run(); + } finally { + sUiAutomation.dropShellPermissionIdentity(); + } + } + + static class SettingsSession<T> implements AutoCloseable { + private final Consumer<T> mSetter; + private final T mOriginalValue; + private boolean mChanged; + + SettingsSession(T originalValue, Consumer<T> setter) { + mOriginalValue = originalValue; + mSetter = setter; + } + + void set(T value) { + if (Objects.equals(value, mOriginalValue)) { + mChanged = false; + return; + } + mSetter.accept(value); + mChanged = true; + } + + @Override + public void close() { + if (mChanged) { + mSetter.accept(mOriginalValue); + } + } + } + /** * Provides an activity that keeps screen on and is able to wait for a stable lifecycle stage. */ diff --git a/apct-tests/perftests/windowmanager/src/android/wm/WmPerfRunListener.java b/apct-tests/perftests/windowmanager/src/android/wm/WmPerfRunListener.java new file mode 100644 index 000000000000..6eb85aacb4e8 --- /dev/null +++ b/apct-tests/perftests/windowmanager/src/android/wm/WmPerfRunListener.java @@ -0,0 +1,130 @@ +/* + * 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.wm; + +import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; +import static android.wm.WindowManagerPerfTestBase.executeShellCommand; +import static android.wm.WindowManagerPerfTestBase.runWithShellPermissionIdentity; + +import android.app.ActivityManager; +import android.app.ActivityManager.RunningAppProcessInfo; +import android.app.ActivityTaskManager; +import android.content.Context; +import android.os.BatteryManager; +import android.os.Bundle; +import android.os.SystemClock; +import android.provider.Settings; +import android.view.WindowManagerPolicyConstants; +import android.wm.WindowManagerPerfTestBase.SettingsSession; + +import androidx.test.platform.app.InstrumentationRegistry; + +import com.android.internal.policy.PhoneWindow; + +import org.junit.runner.Description; +import org.junit.runner.Result; +import org.junit.runner.notification.RunListener; + +import java.util.List; + +/** Prepare the preconditions before running performance test. */ +public class WmPerfRunListener extends RunListener { + + private static final String OPTION_KILL_BACKGROUND = "kill-bg"; + private static final long KILL_BACKGROUND_WAIT_MS = 3000; + + private final Context mContext = InstrumentationRegistry.getInstrumentation().getContext(); + private long mWaitPreconditionDoneMs = 500; + + private final SettingsSession<Integer> mStayOnWhilePluggedInSetting = new SettingsSession<>( + Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0), + value -> executeShellCommand(String.format("settings put global %s %d", + Settings.Global.STAY_ON_WHILE_PLUGGED_IN, value))); + + private final SettingsSession<Integer> mNavigationModeSetting = new SettingsSession<>( + mContext.getResources().getInteger( + com.android.internal.R.integer.config_navBarInteractionMode), + value -> { + final String navOverlay; + switch (value) { + case WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON: + navOverlay = WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON_OVERLAY; + break; + case WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON: + navOverlay = WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY; + break; + case WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL: + default: + navOverlay = WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY; + break; + } + executeShellCommand("cmd overlay enable-exclusive " + navOverlay); + }); + + /** It only executes once before all tests. */ + @Override + public void testRunStarted(Description description) { + final Bundle arguments = InstrumentationRegistry.getArguments(); + + // Use gesture navigation for consistency. + mNavigationModeSetting.set(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL); + // Keep the device awake during testing. + mStayOnWhilePluggedInSetting.set(BatteryManager.BATTERY_PLUGGED_ANY); + + runWithShellPermissionIdentity(() -> { + final ActivityTaskManager atm = mContext.getSystemService(ActivityTaskManager.class); + atm.removeAllVisibleRecentTasks(); + atm.removeStacksWithActivityTypes(new int[] { ACTIVITY_TYPE_STANDARD, + ACTIVITY_TYPE_ASSISTANT, ACTIVITY_TYPE_RECENTS, ACTIVITY_TYPE_UNDEFINED }); + }); + PhoneWindow.sendCloseSystemWindows(mContext, "WmPerfTests"); + + if (Boolean.parseBoolean(arguments.getString(OPTION_KILL_BACKGROUND))) { + runWithShellPermissionIdentity(this::killBackgroundProcesses); + mWaitPreconditionDoneMs = KILL_BACKGROUND_WAIT_MS; + } + // Wait a while for the precondition setup to complete. + SystemClock.sleep(mWaitPreconditionDoneMs); + } + + private void killBackgroundProcesses() { + final ActivityManager am = mContext.getSystemService(ActivityManager.class); + final List<RunningAppProcessInfo> processes = am.getRunningAppProcesses(); + if (processes == null) { + return; + } + for (RunningAppProcessInfo processInfo : processes) { + if (processInfo.importanceReasonCode == RunningAppProcessInfo.REASON_UNKNOWN + && processInfo.importance > RunningAppProcessInfo.IMPORTANCE_SERVICE) { + for (String pkg : processInfo.pkgList) { + am.forceStopPackage(pkg); + } + } + } + } + + /** It only executes once after all tests. */ + @Override + public void testRunFinished(Result result) { + mNavigationModeSetting.close(); + mStayOnWhilePluggedInSetting.close(); + } +} |