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.IWindowSession; 30 import android.view.InputChannel; 31 import android.view.InsetsSourceControl; 32 import android.view.InsetsState; 33 import android.view.View; 34 import android.view.WindowInsets; 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 @Rule 52 public final PerfManualStatusReporter mPerfStatusReporter = new PerfManualStatusReporter(); 53 54 @BeforeClass setUpClass()55 public static void setUpClass() { 56 // Get the permission to use most window types. 57 getUiAutomation().adoptShellPermissionIdentity(); 58 } 59 60 @AfterClass tearDownClass()61 public static void tearDownClass() { 62 getUiAutomation().dropShellPermissionIdentity(); 63 } 64 65 /** The last customized iterations will provide the information of method profiling. */ 66 @Override onStart(int iteration)67 public void onStart(int iteration) { 68 startProfiling(WindowAddRemovePerfTest.class.getSimpleName() 69 + "_MethodTracing_" + iteration + ".trace"); 70 } 71 72 @Override onFinished(int iteration)73 public void onFinished(int iteration) { 74 stopProfiling(); 75 } 76 77 @Test 78 @ManualBenchmarkTest(warmupDurationNs = TIME_1_S_IN_NS, targetTestDurationNs = TIME_5_S_IN_NS) testAddRemoveWindow()79 public void testAddRemoveWindow() throws Throwable { 80 final ManualBenchmarkState state = mPerfStatusReporter.getBenchmarkState(); 81 state.setCustomizedIterations(getProfilingIterations(), this); 82 new TestWindow().runBenchmark(state); 83 } 84 85 private static class TestWindow extends BaseIWindow { 86 final WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams(); 87 final int mRequestedVisibleTypes = WindowInsets.Type.defaultVisible(); 88 final InsetsState mOutInsetsState = new InsetsState(); 89 final InsetsSourceControl.Array mOutControls = new InsetsSourceControl.Array(); 90 final Rect mOutAttachedFrame = new Rect(); 91 final float[] mOutSizeCompatScale = { 1f }; 92 TestWindow()93 TestWindow() { 94 mLayoutParams.setTitle(TestWindow.class.getName()); 95 mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; 96 // Simulate as common phone window. 97 mLayoutParams.flags = FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR; 98 } 99 runBenchmark(ManualBenchmarkState state)100 void runBenchmark(ManualBenchmarkState state) throws RemoteException { 101 final IWindowSession session = WindowManagerGlobal.getWindowSession(); 102 long elapsedTimeNs = 0; 103 while (state.keepRunning(elapsedTimeNs)) { 104 // InputChannel cannot be reused. 105 final InputChannel inputChannel = new InputChannel(); 106 107 long startTime = SystemClock.elapsedRealtimeNanos(); 108 session.addToDisplay(this, mLayoutParams, View.VISIBLE, 109 Display.DEFAULT_DISPLAY, mRequestedVisibleTypes, inputChannel, 110 mOutInsetsState, mOutControls, mOutAttachedFrame, mOutSizeCompatScale); 111 final long elapsedTimeNsOfAdd = SystemClock.elapsedRealtimeNanos() - startTime; 112 state.addExtraResult("add", elapsedTimeNsOfAdd); 113 114 startTime = SystemClock.elapsedRealtimeNanos(); 115 session.remove(asBinder()); 116 final long elapsedTimeNsOfRemove = SystemClock.elapsedRealtimeNanos() - startTime; 117 state.addExtraResult("remove", elapsedTimeNsOfRemove); 118 119 elapsedTimeNs = elapsedTimeNsOfAdd + elapsedTimeNsOfRemove; 120 inputChannel.dispose(); 121 } 122 } 123 } 124 } 125