1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.wm; 18 19 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; 20 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; 21 22 import android.graphics.Rect; 23 import android.os.RemoteException; 24 import android.os.SystemClock; 25 import android.perftests.utils.ManualBenchmarkState; 26 import android.perftests.utils.ManualBenchmarkState.ManualBenchmarkTest; 27 import android.perftests.utils.PerfManualStatusReporter; 28 import android.view.Display; 29 import android.view.DisplayCutout; 30 import android.view.IWindowSession; 31 import android.view.InputChannel; 32 import android.view.InsetsSourceControl; 33 import android.view.InsetsState; 34 import android.view.View; 35 import android.view.WindowManager; 36 import android.view.WindowManagerGlobal; 37 38 import androidx.test.filters.LargeTest; 39 40 import com.android.internal.view.BaseIWindow; 41 42 import org.junit.AfterClass; 43 import org.junit.BeforeClass; 44 import org.junit.Rule; 45 import org.junit.Test; 46 47 @LargeTest 48 public class WindowAddRemovePerfTest extends WindowManagerPerfTestBase 49 implements ManualBenchmarkState.CustomizedIterationListener { 50 51 private static final int PROFILED_ITERATIONS = 2; 52 53 @Rule 54 public final PerfManualStatusReporter mPerfStatusReporter = new PerfManualStatusReporter(); 55 56 @BeforeClass setUpClass()57 public static void setUpClass() { 58 // Get the permission to use most window types. 59 sUiAutomation.adoptShellPermissionIdentity(); 60 } 61 62 @AfterClass tearDownClass()63 public static void tearDownClass() { 64 sUiAutomation.dropShellPermissionIdentity(); 65 } 66 67 /** The last {@link #PROFILED_ITERATIONS} will provide the information of method profiling. */ 68 @Override onStart(int iteration)69 public void onStart(int iteration) { 70 startProfiling(WindowAddRemovePerfTest.class.getSimpleName() 71 + "_MethodTracing_" + iteration + ".trace"); 72 } 73 74 @Override onFinished(int iteration)75 public void onFinished(int iteration) { 76 stopProfiling(); 77 } 78 79 @Test 80 @ManualBenchmarkTest(warmupDurationNs = TIME_1_S_IN_NS, targetTestDurationNs = TIME_5_S_IN_NS) testAddRemoveWindow()81 public void testAddRemoveWindow() throws Throwable { 82 final ManualBenchmarkState state = mPerfStatusReporter.getBenchmarkState(); 83 state.setCustomizedIterations(PROFILED_ITERATIONS, this); 84 new TestWindow().runBenchmark(state); 85 } 86 87 private static class TestWindow extends BaseIWindow { 88 final WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams(); 89 final Rect mOutFrame = new Rect(); 90 final Rect mOutContentInsets = new Rect(); 91 final Rect mOutStableInsets = new Rect(); 92 final DisplayCutout.ParcelableWrapper mOutDisplayCutout = 93 new DisplayCutout.ParcelableWrapper(); 94 final InsetsState mOutInsetsState = new InsetsState(); 95 final InsetsSourceControl[] mOutControls = new InsetsSourceControl[0]; 96 TestWindow()97 TestWindow() { 98 mLayoutParams.setTitle(TestWindow.class.getName()); 99 mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; 100 // Simulate as common phone window. 101 mLayoutParams.flags = FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR; 102 } 103 runBenchmark(ManualBenchmarkState state)104 void runBenchmark(ManualBenchmarkState state) throws RemoteException { 105 final IWindowSession session = WindowManagerGlobal.getWindowSession(); 106 long elapsedTimeNs = 0; 107 while (state.keepRunning(elapsedTimeNs)) { 108 // InputChannel cannot be reused. 109 final InputChannel inputChannel = new InputChannel(); 110 111 long startTime = SystemClock.elapsedRealtimeNanos(); 112 session.addToDisplay(this, mSeq, mLayoutParams, View.VISIBLE, 113 Display.DEFAULT_DISPLAY, mOutFrame, mOutContentInsets, mOutStableInsets, 114 mOutDisplayCutout, inputChannel, mOutInsetsState, mOutControls); 115 final long elapsedTimeNsOfAdd = SystemClock.elapsedRealtimeNanos() - startTime; 116 state.addExtraResult("add", elapsedTimeNsOfAdd); 117 118 startTime = SystemClock.elapsedRealtimeNanos(); 119 session.remove(this); 120 final long elapsedTimeNsOfRemove = SystemClock.elapsedRealtimeNanos() - startTime; 121 state.addExtraResult("remove", elapsedTimeNsOfRemove); 122 123 elapsedTimeNs = elapsedTimeNsOfAdd + elapsedTimeNsOfRemove; 124 inputChannel.dispose(); 125 } 126 } 127 } 128 } 129