Loading apct-tests/perftests/windowmanager/AndroidTest.xml +8 −0 Original line number Diff line number Diff line Loading @@ -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"> Loading apct-tests/perftests/windowmanager/README.md 0 → 100644 +27 −0 Original line number Diff line number Diff line ## 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. apct-tests/perftests/windowmanager/src/android/wm/WindowManagerPerfTestBase.java +39 −26 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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(); Loading @@ -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); Loading @@ -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. Loading Loading @@ -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. */ Loading apct-tests/perftests/windowmanager/src/android/wm/WmPerfRunListener.java 0 → 100644 +130 −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.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(); } } Loading
apct-tests/perftests/windowmanager/AndroidTest.xml +8 −0 Original line number Diff line number Diff line Loading @@ -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"> Loading
apct-tests/perftests/windowmanager/README.md 0 → 100644 +27 −0 Original line number Diff line number Diff line ## 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.
apct-tests/perftests/windowmanager/src/android/wm/WindowManagerPerfTestBase.java +39 −26 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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(); Loading @@ -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); Loading @@ -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. Loading Loading @@ -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. */ Loading
apct-tests/perftests/windowmanager/src/android/wm/WmPerfRunListener.java 0 → 100644 +130 −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.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(); } }