Implement game mode framerate override

Add logic for setting throttling framerate requested
by Game Dashboard interventions.

- Refactored of FrameRateOverrideMappings in Scheduler
- Have mSupportsFrameRateOverride only guard mFrameRateOverrideByContent
- Remove logic that disables framerate override when it's not a divider

Bug: b/204322816
Test: atest FrameRateOverrideHostTest

Change-Id: I1a2caf378cd87ce4830f6fc48332b5df518330cc
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 0227043..b7594df 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -1346,6 +1346,21 @@
         SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(windowInfosListener));
         return remote()->transact(BnSurfaceComposer::REMOVE_WINDOW_INFOS_LISTENER, data, &reply);
     }
+
+    status_t setOverrideFrameRate(uid_t uid, float frameRate) override {
+        Parcel data, reply;
+        SAFE_PARCEL(data.writeInterfaceToken, ISurfaceComposer::getInterfaceDescriptor());
+        SAFE_PARCEL(data.writeUint32, uid);
+        SAFE_PARCEL(data.writeFloat, frameRate);
+
+        status_t err = remote()->transact(BnSurfaceComposer::SET_OVERRIDE_FRAME_RATE, data, &reply);
+        if (err != NO_ERROR) {
+            ALOGE("setOverrideFrameRate: failed to transact %s (%d)", strerror(-err), err);
+            return err;
+        }
+
+        return NO_ERROR;
+    }
 };
 
 // Out-of-line virtual method definition to trigger vtable emission in this
@@ -2306,6 +2321,17 @@
 
             return removeWindowInfosListener(listener);
         }
+        case SET_OVERRIDE_FRAME_RATE: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+
+            uid_t uid;
+            SAFE_PARCEL(data.readUint32, &uid);
+
+            float frameRate;
+            SAFE_PARCEL(data.readFloat, &frameRate);
+
+            return setOverrideFrameRate(uid, frameRate);
+        }
         default: {
             return BBinder::onTransact(code, data, reply, flags);
         }
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index b4f6cd5..31456cd 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -2094,6 +2094,10 @@
                                                                               displayModeId);
 }
 
+status_t SurfaceComposerClient::setOverrideFrameRate(uid_t uid, float frameRate) {
+    return ComposerService::getComposerService()->setOverrideFrameRate(uid, frameRate);
+}
+
 void SurfaceComposerClient::setAutoLowLatencyMode(const sp<IBinder>& display, bool on) {
     ComposerService::getComposerService()->setAutoLowLatencyMode(display, on);
 }
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index f37580c..fb4fb7e 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -559,6 +559,13 @@
                                   int8_t compatibility, int8_t changeFrameRateStrategy) = 0;
 
     /*
+     * Set the override frame rate for a specified uid by GameManagerService.
+     * Passing the frame rate and uid to SurfaceFlinger to update the override mapping
+     * in the scheduler.
+     */
+    virtual status_t setOverrideFrameRate(uid_t uid, float frameRate) = 0;
+
+    /*
      * Sets the frame timeline vsync info received from choreographer that corresponds to next
      * buffer submitted on that surface.
      */
@@ -678,6 +685,7 @@
         SET_BOOT_DISPLAY_MODE,
         CLEAR_BOOT_DISPLAY_MODE,
         GET_PREFERRED_BOOT_DISPLAY_MODE,
+        SET_OVERRIDE_FRAME_RATE,
         // Always append new enum to the end.
     };
 
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index c192323..4f92878 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -25,6 +25,7 @@
 
 #include <binder/IBinder.h>
 
+#include <utils/Errors.h>
 #include <utils/RefBase.h>
 #include <utils/Singleton.h>
 #include <utils/SortedVector.h>
@@ -175,6 +176,9 @@
     static status_t clearBootDisplayMode(const sp<IBinder>& display);
     // Gets the display mode in which the device boots if there is no user-preferred display mode
     static status_t getPreferredBootDisplayMode(const sp<IBinder>& display, ui::DisplayModeId*);
+    // Sets the frame rate of a particular app (uid). This is currently called
+    // by GameManager.
+    static status_t setOverrideFrameRate(uid_t uid, float frameRate);
 
     // Switches on/off Auto Low Latency Mode on the connected display. This should only be
     // called if the connected display supports Auto Low Latency Mode as reported by
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 999874b..0ebd11c 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -31,9 +31,11 @@
 #include <gui/SyncScreenCaptureListener.h>
 #include <inttypes.h>
 #include <private/gui/ComposerService.h>
+#include <sys/types.h>
 #include <ui/BufferQueueDefs.h>
 #include <ui/DisplayMode.h>
 #include <ui/Rect.h>
+#include <utils/Errors.h>
 #include <utils/String8.h>
 
 #include <limits>
@@ -925,6 +927,8 @@
         return NO_ERROR;
     }
 
+    status_t setOverrideFrameRate(uid_t /*uid*/, float /*frameRate*/) override { return NO_ERROR; }
+
 protected:
     IBinder* onAsBinder() override { return nullptr; }