Denoise hermetric surfaceflinger perf tests

Remove overheard by disabling features during the test including:
- perfetto tracing
- region sampling by hiding navbar
- transaction tracing

Reduce variations between each frame by
- forcing max frame rate (avoids any frame misses)
- consuming transform hint (avoids gpu comp)
- starting simpleperf after test setup to move test activity
launch outside of measurement window

Test: atest android.surfaceflinger.SurfaceFlingerPerfTest
Bug: 298240242
Change-Id: Ida7422c37b9afa323147949c9776c042ca97cd08
diff --git a/apct-tests/perftests/surfaceflinger/Android.bp b/apct-tests/perftests/surfaceflinger/Android.bp
index 0c28bce..21d0d44 100644
--- a/apct-tests/perftests/surfaceflinger/Android.bp
+++ b/apct-tests/perftests/surfaceflinger/Android.bp
@@ -32,6 +32,7 @@
         "apct-perftests-utils",
         "collector-device-lib",
         "platform-test-annotations",
+        "cts-wm-util",
     ],
     test_suites: ["device-tests"],
     data: [":perfetto_artifacts"],
diff --git a/apct-tests/perftests/surfaceflinger/AndroidManifest.xml b/apct-tests/perftests/surfaceflinger/AndroidManifest.xml
index 26f2586..aa55b01 100644
--- a/apct-tests/perftests/surfaceflinger/AndroidManifest.xml
+++ b/apct-tests/perftests/surfaceflinger/AndroidManifest.xml
@@ -16,9 +16,11 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.perftests.surfaceflinger">
 
-    <!-- permission needed to write perfetto trace and read/write simpleperf report -->
+    <!-- permission needed to read/write simpleperf report -->
     <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <!-- permission needed to disable tracing -->
+    <uses-permission android:name="android.permission.HARDWARE_TEST" />
 
     <application android:label="SurfaceFlingerPerfTests">
         <uses-library android:name="android.test.runner" />
diff --git a/apct-tests/perftests/surfaceflinger/AndroidTest.xml b/apct-tests/perftests/surfaceflinger/AndroidTest.xml
index 58cf58b..6dcd86e 100644
--- a/apct-tests/perftests/surfaceflinger/AndroidTest.xml
+++ b/apct-tests/perftests/surfaceflinger/AndroidTest.xml
@@ -44,17 +44,12 @@
         <option name="hidden-api-checks" value="false"/>
 
         <!-- Listener related args for collecting the traces and waiting for the device to stabilize. -->
-        <option name="device-listeners" value="android.device.collectors.ProcLoadListener,android.device.collectors.PerfettoListener,android.device.collectors.SimpleperfListener" />
-
-        <!-- Guarantee that user defined RunListeners will be running before any of the default listeners defined in this runner. -->
-        <option name="instrumentation-arg" key="newRunListenerMode" value="true" />
+        <option name="device-listeners" value="android.device.collectors.ProcLoadListener,android.device.collectors.SimpleperfListener" />
 
         <option name="instrumentation-arg" key="profiling-iterations" value="525" />
-        <!-- PerfettoListener related arguments -->
-        <option name="instrumentation-arg" key="perfetto_config_text_proto" value="true" />
-        <option name="instrumentation-arg" key="perfetto_config_file" value="trace_config.textproto" />
 
         <!-- SimpleperfListener related arguments -->
+        <option name="instrumentation-arg" key="record" value="false"/>
         <option name="instrumentation-arg" key="report" value="true" />
         <option name="instrumentation-arg" key="arguments" value="-g" />
         <option name="instrumentation-arg" key="events_to_record" value="instructions,cpu-cycles,raw-l3d-cache-refill,sched:sched_waking" />
@@ -70,13 +65,11 @@
         <option name="instrumentation-arg" key="proc-loadavg-threshold" value="3" />
         <option name="instrumentation-arg" key="proc-loadavg-timeout" value="120000" />
         <option name="instrumentation-arg" key="proc-loadavg-interval" value="10000" />
-
     </test>
 
     <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
         <option name="directory-keys" value="/data/local/tmp/SurfaceFlingerPerfTests" />
         <!-- Needed for pulling the collected trace config on to the host -->
-        <option name="pull-pattern-keys" value="perfetto_file_path" />
         <option name="pull-pattern-keys" value="simpleperf_file_path" />
     </metrics_collector>
 
diff --git a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/BufferFlinger.java b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/BufferFlinger.java
index 8a447bb..8d6dd12 100644
--- a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/BufferFlinger.java
+++ b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/BufferFlinger.java
@@ -16,6 +16,10 @@
 
 package android.surfaceflinger;
 
+import static android.view.SurfaceControl.BUFFER_TRANSFORM_IDENTITY;
+import static android.view.SurfaceControl.BUFFER_TRANSFORM_ROTATE_270;
+import static android.view.SurfaceControl.BUFFER_TRANSFORM_ROTATE_90;
+
 import android.annotation.ColorInt;
 import android.graphics.Canvas;
 import android.graphics.GraphicBuffer;
@@ -33,9 +37,11 @@
  * @hide
  */
 public class BufferFlinger {
+    private final int mTransformHint;
     ArrayBlockingQueue<GraphicBuffer> mBufferQ;
 
-    public BufferFlinger(int numOfBuffers, @ColorInt int color) {
+    public BufferFlinger(int numOfBuffers, @ColorInt int color, int bufferTransformHint) {
+        mTransformHint = bufferTransformHint;
         mBufferQ = new ArrayBlockingQueue<>(numOfBuffers);
 
         while (numOfBuffers > 0) {
@@ -56,12 +62,18 @@
     public void addBuffer(SurfaceControl.Transaction t, SurfaceControl surfaceControl) {
         try {
             final GraphicBuffer buffer = mBufferQ.take();
-            t.setBuffer(surfaceControl,
+            int transform = BUFFER_TRANSFORM_IDENTITY;
+            if (mTransformHint == BUFFER_TRANSFORM_ROTATE_90) {
+                transform = BUFFER_TRANSFORM_ROTATE_270;
+            } else if (mTransformHint == BUFFER_TRANSFORM_ROTATE_270) {
+                transform = BUFFER_TRANSFORM_ROTATE_90;
+            }
+            t.setBufferTransform(surfaceControl, transform);
+            t.setBuffer(
+                    surfaceControl,
                     HardwareBuffer.createFromGraphicBuffer(buffer),
                     null,
-                    (SyncFence fence) -> {
-                        releaseCallback(fence, buffer);
-                    });
+                    (SyncFence fence) -> releaseCallback(fence, buffer));
         } catch (InterruptedException ignore) {
         }
     }
diff --git a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java
index dca818e..fd9d991 100644
--- a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java
+++ b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java
@@ -16,6 +16,9 @@
 
 package android.surfaceflinger;
 
+import static android.server.wm.CtsWindowInfoUtils.waitForWindowOnTop;
+
+import android.app.Instrumentation;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -25,12 +28,13 @@
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 
-
 import androidx.test.ext.junit.rules.ActivityScenarioRule;
 import androidx.test.filters.LargeTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.helpers.SimpleperfHelper;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -39,6 +43,8 @@
 import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 
+import java.io.IOException;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Random;
 
@@ -63,12 +69,33 @@
     public final RuleChain mAllRules = RuleChain
             .outerRule(mActivityRule);
 
+    private int mTransformHint;
+    private SimpleperfHelper mSimpleperfHelper = new SimpleperfHelper();
+
+    /** Start simpleperf sampling. */
+    public void startSimpleperf(String subcommand, String arguments) {
+        if (!mSimpleperfHelper.startCollecting(subcommand, arguments)) {
+            Log.e(TAG, "Simpleperf did not start successfully.");
+        }
+    }
+
+    /** Stop simpleperf sampling and dump the collected file into the given path. */
+    private void stopSimpleperf(Path path) {
+        if (!mSimpleperfHelper.stopCollecting(path.toString())) {
+            Log.e(TAG, "Failed to collect the simpleperf output.");
+        }
+    }
+
     @BeforeClass
     public static void suiteSetup() {
         final Bundle arguments = InstrumentationRegistry.getArguments();
         sProfilingIterations = Integer.parseInt(
                 arguments.getString(ARGUMENT_PROFILING_ITERATIONS, DEFAULT_PROFILING_ITERATIONS));
         Log.d(TAG, "suiteSetup: mProfilingIterations = " + sProfilingIterations);
+        // disable transaction tracing
+        InstrumentationRegistry.getInstrumentation()
+                .getUiAutomation()
+                .executeShellCommand("service call SurfaceFlinger 1041 i32 -1");
     }
 
     @Before
@@ -77,17 +104,45 @@
         SurfaceControl.Transaction t = new SurfaceControl.Transaction();
         for (int i = 0; i < MAX_BUFFERS; i++) {
             SurfaceControl sc = createSurfaceControl();
-            BufferFlinger bufferTracker = createBufferTracker(Color.argb(getRandomColorComponent(),
-                    getRandomColorComponent(), getRandomColorComponent(),
-                    getRandomColorComponent()));
+            BufferFlinger bufferTracker =
+                    createBufferTracker(
+                            Color.argb(
+                                    getRandomColorComponent(),
+                                    getRandomColorComponent(),
+                                    getRandomColorComponent(),
+                                    getRandomColorComponent()),
+                            mActivity.getBufferTransformHint());
             bufferTracker.addBuffer(t, sc);
             t.setPosition(sc, i * 10, i * 10);
         }
         t.apply(true);
+        mBufferTrackers.get(0).addBuffer(mTransaction, mSurfaceControls.get(0));
+        mTransaction.show(mSurfaceControls.get(0)).apply(true);
+        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+
+        instrumentation.waitForIdleSync();
+        // Wait for device animation that shows above the activity to leave.
+        try {
+            waitForWindowOnTop(mActivity.getWindow());
+        } catch (InterruptedException e) {
+            Log.e(TAG, "Failed to wait for window", e);
+        }
+        String args =
+                "-o /data/local/tmp/perf.data -g -e"
+                    + " instructions,cpu-cycles,raw-l3d-cache-refill,sched:sched_waking -p "
+                        + mSimpleperfHelper.getPID("surfaceflinger")
+                        + ","
+                        + mSimpleperfHelper.getPID("android.perftests.surfaceflinger");
+        startSimpleperf("record", args);
     }
 
     @After
     public void teardown() {
+        try {
+            mSimpleperfHelper.stopSimpleperf();
+        } catch (IOException e) {
+            Log.e(TAG, "Failed to stop simpleperf", e);
+        }
         mSurfaceControls.forEach(SurfaceControl::release);
         mBufferTrackers.forEach(BufferFlinger::freeBuffers);
     }
@@ -97,8 +152,9 @@
     }
 
     private final ArrayList<BufferFlinger> mBufferTrackers = new ArrayList<>();
-    private BufferFlinger createBufferTracker(int color) {
-        BufferFlinger bufferTracker = new BufferFlinger(BUFFER_COUNT, color);
+
+    private BufferFlinger createBufferTracker(int color, int bufferTransformHint) {
+        BufferFlinger bufferTracker = new BufferFlinger(BUFFER_COUNT, color, bufferTransformHint);
         mBufferTrackers.add(bufferTracker);
         return bufferTracker;
     }
diff --git a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerTestActivity.java b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerTestActivity.java
index bb95659..5f1f44d 100644
--- a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerTestActivity.java
+++ b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerTestActivity.java
@@ -16,12 +16,15 @@
 
 package android.surfaceflinger;
 
+import static android.view.Surface.FRAME_RATE_COMPATIBILITY_DEFAULT;
+
 import android.app.Activity;
 import android.content.Context;
 import android.os.Bundle;
 import android.view.SurfaceControl;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
+import android.view.View;
 import android.view.Window;
 import android.view.WindowManager;
 
@@ -42,6 +45,11 @@
         requestWindowFeature(Window.FEATURE_NO_TITLE);
         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                 WindowManager.LayoutParams.FLAG_FULLSCREEN);
+        View decorView = getWindow().getDecorView();
+        // Hide both the navigation bar and the status bar.
+        int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN;
+        decorView.setSystemUiVisibility(uiOptions);
+
         getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
         mTestSurfaceView = new TestSurfaceView(this);
         setContentView(mTestSurfaceView);
@@ -51,6 +59,10 @@
         return mTestSurfaceView.getChildSurfaceControlHelper();
     }
 
+    public int getBufferTransformHint() {
+        return mTestSurfaceView.getRootSurfaceControl().getBufferTransformHint();
+    }
+
     public class TestSurfaceView extends SurfaceView {
         public TestSurfaceView(Context context) {
             super(context);
@@ -79,6 +91,9 @@
             // check to see if surface is valid
             if (holder.getSurface().isValid()) {
                 mSurfaceControl = getSurfaceControl();
+                new SurfaceControl.Transaction()
+                        .setFrameRate(mSurfaceControl, 1000, FRAME_RATE_COMPATIBILITY_DEFAULT)
+                        .apply(true);
             }
             return new SurfaceControl.Builder()
                     .setName("ChildSurfaceControl")