/* * Copyright (C) 2019 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.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; import android.graphics.Rect; import android.os.RemoteException; import android.os.SystemClock; import android.perftests.utils.ManualBenchmarkState; import android.perftests.utils.ManualBenchmarkState.ManualBenchmarkTest; import android.perftests.utils.PerfManualStatusReporter; import android.view.Display; import android.view.DisplayCutout; import android.view.IWindowSession; import android.view.InputChannel; import android.view.InsetsSourceControl; import android.view.InsetsState; import android.view.View; import android.view.WindowManager; import android.view.WindowManagerGlobal; import androidx.test.filters.LargeTest; import com.android.internal.view.BaseIWindow; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; @LargeTest public class WindowAddRemovePerfTest extends WindowManagerPerfTestBase implements ManualBenchmarkState.CustomizedIterationListener { private static final int PROFILED_ITERATIONS = 2; @Rule public final PerfManualStatusReporter mPerfStatusReporter = new PerfManualStatusReporter(); @BeforeClass public static void setUpClass() { // Get the permission to use most window types. sUiAutomation.adoptShellPermissionIdentity(); } @AfterClass public static void tearDownClass() { sUiAutomation.dropShellPermissionIdentity(); } /** The last {@link #PROFILED_ITERATIONS} will provide the information of method profiling. */ @Override public void onStart(int iteration) { startProfiling(WindowAddRemovePerfTest.class.getSimpleName() + "_MethodTracing_" + iteration + ".trace"); } @Override public void onFinished(int iteration) { stopProfiling(); } @Test @ManualBenchmarkTest(warmupDurationNs = TIME_1_S_IN_NS, targetTestDurationNs = TIME_5_S_IN_NS) public void testAddRemoveWindow() throws Throwable { final ManualBenchmarkState state = mPerfStatusReporter.getBenchmarkState(); state.setCustomizedIterations(PROFILED_ITERATIONS, this); new TestWindow().runBenchmark(state); } private static class TestWindow extends BaseIWindow { final WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams(); final Rect mOutFrame = new Rect(); final Rect mOutContentInsets = new Rect(); final Rect mOutStableInsets = new Rect(); final DisplayCutout.ParcelableWrapper mOutDisplayCutout = new DisplayCutout.ParcelableWrapper(); final InsetsState mOutInsetsState = new InsetsState(); final InsetsSourceControl[] mOutControls = new InsetsSourceControl[0]; TestWindow() { mLayoutParams.setTitle(TestWindow.class.getName()); mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; // Simulate as common phone window. mLayoutParams.flags = FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR; } void runBenchmark(ManualBenchmarkState state) throws RemoteException { final IWindowSession session = WindowManagerGlobal.getWindowSession(); long elapsedTimeNs = 0; while (state.keepRunning(elapsedTimeNs)) { // InputChannel cannot be reused. final InputChannel inputChannel = new InputChannel(); long startTime = SystemClock.elapsedRealtimeNanos(); session.addToDisplay(this, mSeq, mLayoutParams, View.VISIBLE, Display.DEFAULT_DISPLAY, mOutFrame, mOutContentInsets, mOutStableInsets, mOutDisplayCutout, inputChannel, mOutInsetsState, mOutControls); final long elapsedTimeNsOfAdd = SystemClock.elapsedRealtimeNanos() - startTime; state.addExtraResult("add", elapsedTimeNsOfAdd); startTime = SystemClock.elapsedRealtimeNanos(); session.remove(this); final long elapsedTimeNsOfRemove = SystemClock.elapsedRealtimeNanos() - startTime; state.addExtraResult("remove", elapsedTimeNsOfRemove); elapsedTimeNs = elapsedTimeNsOfAdd + elapsedTimeNsOfRemove; inputChannel.dispose(); } } } }