Indicate optimization policy to SurfaceFlinger from DisplayManager

DisplayManager's never-blank concept is translated in VirtualDisplayAdapter to be a power-optimised display (instead of a performance optimised display) in the downstream components. This concept indicates that these displays typically depend on another display's presence and activeness to be continually rendered and shown. The display they depend on instead optimises for performance when it is on, meaning that all the related displays have good performance.

For cases where power optimisation information is not available (calls to DisplayControl#createVirtualDisplay(String, boolean) and SurfaceComposerClient::createVirtualDisplay), the power optimisation state is defaulted to optimise for power since these are system calls and this preserves the previous behaviour.

Bug: 342681202

Flag: EXEMPT refactor

Test: Flashed build on test device, ran Android Auto Projected
Change-Id: I6a9fdf7c4be080e2f4df6734def8a4fbefde5742
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index df57b27..6ffd99e 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1391,11 +1391,16 @@
 // ---------------------------------------------------------------------------
 
 sp<IBinder> SurfaceComposerClient::createVirtualDisplay(const std::string& displayName,
-                                                        bool isSecure, const std::string& uniqueId,
+                                                        bool isSecure, bool optimizeForPower,
+                                                        const std::string& uniqueId,
                                                         float requestedRefreshRate) {
+    const gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy = optimizeForPower
+            ? gui::ISurfaceComposer::OptimizationPolicy::optimizeForPower
+            : gui::ISurfaceComposer::OptimizationPolicy::optimizeForPerformance;
     sp<IBinder> display = nullptr;
     binder::Status status =
             ComposerServiceAIDL::getComposerService()->createVirtualDisplay(displayName, isSecure,
+                                                                            optimizationPolicy,
                                                                             uniqueId,
                                                                             requestedRefreshRate,
                                                                             &display);
diff --git a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
index da47ee2..9b2f089 100644
--- a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
+++ b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
@@ -67,6 +67,11 @@
         frameRateOverride = 1 << 1,
     }
 
+    enum OptimizationPolicy {
+        optimizeForPower = 0,
+        optimizeForPerformance = 1,
+    }
+
     /**
      * Signal that we're done booting.
      * Requires ACCESS_SURFACE_FLINGER permission
@@ -97,6 +102,10 @@
      *     The name of the virtual display.
      * isSecure
      *     Whether this virtual display is secure.
+     * optimizationPolicy
+     *     Whether to optimize for power or performance. Displays that are optimizing for power may
+     *     be dependent on a different display that optimizes for performance when they are on,
+     *     which will guarantee performance for all of the other displays.
      * uniqueId
      *     The unique ID for the display.
      * requestedRefreshRate
@@ -108,7 +117,7 @@
      * requires ACCESS_SURFACE_FLINGER permission.
      */
     @nullable IBinder createVirtualDisplay(@utf8InCpp String displayName, boolean isSecure,
-            @utf8InCpp String uniqueId, float requestedRefreshRate);
+            OptimizationPolicy optimizationPolicy, @utf8InCpp String uniqueId, float requestedRefreshRate);
 
     /**
      * Destroy a virtual display.
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 60f16ae..18d2a4c 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -396,6 +396,7 @@
 
     static const std::string kEmpty;
     static sp<IBinder> createVirtualDisplay(const std::string& displayName, bool isSecure,
+                                            bool optimizeForPower = true,
                                             const std::string& uniqueId = kEmpty,
                                             float requestedRefreshRate = 0);
 
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 98d1329..25d5b99 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -692,10 +692,11 @@
         return binder::Status::ok();
     }
 
-    binder::Status createVirtualDisplay(const std::string& /*displayName*/, bool /*isSecure*/,
-                                        const std::string& /*uniqueId*/,
-                                        float /*requestedRefreshRate*/,
-                                        sp<IBinder>* /*outDisplay*/) override {
+    binder::Status createVirtualDisplay(
+            const std::string& /*displayName*/, bool /*isSecure*/,
+            gui::ISurfaceComposer::OptimizationPolicy /*optimizationPolicy*/,
+            const std::string& /*uniqueId*/, float /*requestedRefreshRate*/,
+            sp<IBinder>* /*outDisplay*/) override {
         return binder::Status::ok();
     }
 
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index e8b09b0..07770f1 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -51,6 +51,17 @@
 
 namespace hal = hardware::graphics::composer::hal;
 
+namespace gui {
+inline std::string_view to_string(ISurfaceComposer::OptimizationPolicy optimizationPolicy) {
+    switch (optimizationPolicy) {
+        case ISurfaceComposer::OptimizationPolicy::optimizeForPower:
+            return "optimizeForPower";
+        case ISurfaceComposer::OptimizationPolicy::optimizeForPerformance:
+            return "optimizeForPerformance";
+    }
+}
+} // namespace gui
+
 DisplayDeviceCreationArgs::DisplayDeviceCreationArgs(
         const sp<SurfaceFlinger>& flinger, HWComposer& hwComposer, const wp<IBinder>& displayToken,
         std::shared_ptr<compositionengine::Display> compositionDisplay)
@@ -283,6 +294,7 @@
 
     dumper.dump("name"sv, '"' + mDisplayName + '"');
     dumper.dump("powerMode"sv, mPowerMode);
+    dumper.dump("optimizationPolicy"sv, mOptimizationPolicy);
 
     if (mRefreshRateSelector) {
         mRefreshRateSelector->dump(dumper);
@@ -305,6 +317,15 @@
     mCompositionDisplay->setSecure(secure);
 }
 
+gui::ISurfaceComposer::OptimizationPolicy DisplayDevice::getOptimizationPolicy() const {
+    return mOptimizationPolicy;
+}
+
+void DisplayDevice::setOptimizationPolicy(
+        gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy) {
+    mOptimizationPolicy = optimizationPolicy;
+}
+
 const Rect DisplayDevice::getBounds() const {
     return mCompositionDisplay->getState().displaySpace.getBoundsAsRect();
 }
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index b5a543a..be37429 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -93,6 +93,11 @@
     bool isSecure() const;
     void setSecure(bool secure);
 
+    // The optimization policy influences whether this display is optimized for power or
+    // performance.
+    gui::ISurfaceComposer::OptimizationPolicy getOptimizationPolicy() const;
+    void setOptimizationPolicy(gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy);
+
     int getWidth() const;
     int getHeight() const;
     ui::Size getSize() const { return {getWidth(), getHeight()}; }
@@ -236,6 +241,9 @@
     // TODO(b/182939859): Remove special cases for primary display.
     const bool mIsPrimary;
 
+    gui::ISurfaceComposer::OptimizationPolicy mOptimizationPolicy =
+            gui::ISurfaceComposer::OptimizationPolicy::optimizeForPerformance;
+
     uint32_t mFlags = 0;
 
     // Requested refresh rate in fps, supported only for virtual displays.
@@ -283,6 +291,9 @@
     std::string displayName;
     std::string uniqueId;
     bool isSecure = false;
+
+    gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy =
+            gui::ISurfaceComposer::OptimizationPolicy::optimizeForPerformance;
     bool isProtected = false;
     // Refer to DisplayDevice::mRequestedRefreshRate, for virtual display only
     Fps requestedRefreshRate;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 98abd10..806740b 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -576,9 +576,10 @@
     mScheduler->run();
 }
 
-sp<IBinder> SurfaceFlinger::createVirtualDisplay(const std::string& displayName, bool isSecure,
-                                                 const std::string& uniqueId,
-                                                 float requestedRefreshRate) {
+sp<IBinder> SurfaceFlinger::createVirtualDisplay(
+        const std::string& displayName, bool isSecure,
+        gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy, const std::string& uniqueId,
+        float requestedRefreshRate) {
     // SurfaceComposerAIDL checks for some permissions, but adding an additional check here.
     // This is to ensure that only root, system, and graphics can request to create a secure
     // display. Secure displays can show secure content so we add an additional restriction on it.
@@ -611,6 +612,7 @@
     // Set display as protected when marked as secure to ensure no behavior change
     // TODO (b/314820005): separate as a different arg when creating the display.
     state.isProtected = isSecure;
+    state.optimizationPolicy = optimizationPolicy;
     state.displayName = displayName;
     state.uniqueId = uniqueId;
     state.requestedRefreshRate = Fps::fromValue(requestedRefreshRate);
@@ -3927,6 +3929,7 @@
     display->setProjection(state.orientation, state.layerStackSpaceRect,
                            state.orientedDisplaySpaceRect);
     display->setDisplayName(state.displayName);
+    display->setOptimizationPolicy(state.optimizationPolicy);
     display->setFlags(state.flags);
 
     return display;
@@ -8748,16 +8751,16 @@
     }
 }
 
-binder::Status SurfaceComposerAIDL::createVirtualDisplay(const std::string& displayName,
-                                                         bool isSecure, const std::string& uniqueId,
-                                                         float requestedRefreshRate,
-                                                         sp<IBinder>* outDisplay) {
+binder::Status SurfaceComposerAIDL::createVirtualDisplay(
+        const std::string& displayName, bool isSecure,
+        gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy, const std::string& uniqueId,
+        float requestedRefreshRate, sp<IBinder>* outDisplay) {
     status_t status = checkAccessPermission();
     if (status != OK) {
         return binderStatusFromStatusT(status);
     }
-    *outDisplay =
-            mFlinger->createVirtualDisplay(displayName, isSecure, uniqueId, requestedRefreshRate);
+    *outDisplay = mFlinger->createVirtualDisplay(displayName, isSecure, optimizationPolicy,
+                                                 uniqueId, requestedRefreshRate);
     return binder::Status::ok();
 }
 
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 3f454ba..57bc1f3 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -531,6 +531,7 @@
 
     // ISurfaceComposer implementation:
     sp<IBinder> createVirtualDisplay(const std::string& displayName, bool isSecure,
+                                     gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy,
                                      const std::string& uniqueId,
                                      float requestedRefreshRate = 0.0f);
     status_t destroyVirtualDisplay(const sp<IBinder>& displayToken);
@@ -1564,9 +1565,11 @@
             const sp<IBinder>& layerHandle,
             sp<gui::IDisplayEventConnection>* outConnection) override;
     binder::Status createConnection(sp<gui::ISurfaceComposerClient>* outClient) override;
-    binder::Status createVirtualDisplay(const std::string& displayName, bool isSecure,
-                                        const std::string& uniqueId, float requestedRefreshRate,
-                                        sp<IBinder>* outDisplay) override;
+    binder::Status createVirtualDisplay(
+            const std::string& displayName, bool isSecure,
+            gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy,
+            const std::string& uniqueId, float requestedRefreshRate,
+            sp<IBinder>* outDisplay) override;
     binder::Status destroyVirtualDisplay(const sp<IBinder>& displayToken) override;
     binder::Status getPhysicalDisplayIds(std::vector<int64_t>* outDisplayIds) override;
     binder::Status getPhysicalDisplayToken(int64_t displayId, sp<IBinder>* outDisplay) override;
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp
index aadff76..aa5b786 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp
@@ -141,7 +141,11 @@
     // --------------------------------------------------------------------
     // Invocation
 
-    sp<IBinder> displayToken = mFlinger.createVirtualDisplay(kDisplayName, false, kUniqueId);
+    sp<IBinder> displayToken =
+            mFlinger.createVirtualDisplay(kDisplayName, false,
+                                          gui::ISurfaceComposer::OptimizationPolicy::
+                                                  optimizeForPower,
+                                          kUniqueId);
 
     // --------------------------------------------------------------------
     // Postconditions
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 41f2b6e..18e2d7b 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -399,12 +399,16 @@
                               float requestedRefreshRate = 0.0f) {
         static const std::string kTestId =
                 "virtual:libsurfaceflinger_unittest:TestableSurfaceFlinger";
-        return mFlinger->createVirtualDisplay(displayName, isSecure, kTestId, requestedRefreshRate);
+        return mFlinger
+                ->createVirtualDisplay(displayName, isSecure,
+                                       gui::ISurfaceComposer::OptimizationPolicy::optimizeForPower,
+                                       kTestId, requestedRefreshRate);
     }
 
     auto createVirtualDisplay(const std::string& displayName, bool isSecure,
+                              gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy,
                               const std::string& uniqueId, float requestedRefreshRate = 0.0f) {
-        return mFlinger->createVirtualDisplay(displayName, isSecure, uniqueId,
+        return mFlinger->createVirtualDisplay(displayName, isSecure, optimizationPolicy, uniqueId,
                                               requestedRefreshRate);
     }