Add frame rate flexibility token

Add support for temporarily relaxing frame rate restrictions in surface
flinger. This is used by CTS tests to get a consistent device state
while running frame rate tests.

Bug: 148033900

Test: - On a Pixel 4, I turned the brightness down and covered the
ambient light sensor, causing the display manager to set a frame rate
restriction. I ran the frame rate CTS test without these CLs applied,
and confirmed the test failed because surface flinger couldn't switch
frame rates, as expected. Then I ran the tests with the CLs applied, and
confirmed the tests pass.

- I confirmed that, without adopting shell permission identity, the CTS
test is denied the request to acquire a frame rate flexibility token. So
normal apps won't be able to access this.

Change-Id: I6685edc4bc07c7888b79a9dd72a90f56b74e7604
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 8d79cf8..bd4d62c 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -1145,6 +1145,42 @@
             ALOGE("setFrameRate: failed to transact: %s (%d)", strerror(-err), err);
             return err;
         }
+
+        return reply.readInt32();
+    }
+
+    virtual status_t acquireFrameRateFlexibilityToken(sp<IBinder>* outToken) {
+        if (!outToken) return BAD_VALUE;
+
+        Parcel data, reply;
+        status_t err = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        if (err != NO_ERROR) {
+            ALOGE("acquireFrameRateFlexibilityToken: failed writing interface token: %s (%d)",
+                  strerror(-err), -err);
+            return err;
+        }
+
+        err = remote()->transact(BnSurfaceComposer::ACQUIRE_FRAME_RATE_FLEXIBILITY_TOKEN, data,
+                                 &reply);
+        if (err != NO_ERROR) {
+            ALOGE("acquireFrameRateFlexibilityToken: failed to transact: %s (%d)", strerror(-err),
+                  err);
+            return err;
+        }
+
+        err = reply.readInt32();
+        if (err != NO_ERROR) {
+            ALOGE("acquireFrameRateFlexibilityToken: call failed: %s (%d)", strerror(-err), err);
+            return err;
+        }
+
+        err = reply.readStrongBinder(outToken);
+        if (err != NO_ERROR) {
+            ALOGE("acquireFrameRateFlexibilityToken: failed reading binder token: %s (%d)",
+                  strerror(-err), err);
+            return err;
+        }
+
         return NO_ERROR;
     }
 };
@@ -1945,6 +1981,16 @@
             reply->writeInt32(result);
             return NO_ERROR;
         }
+        case ACQUIRE_FRAME_RATE_FLEXIBILITY_TOKEN: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+            sp<IBinder> token;
+            status_t result = acquireFrameRateFlexibilityToken(&token);
+            reply->writeInt32(result);
+            if (result == NO_ERROR) {
+                reply->writeStrongBinder(token);
+            }
+            return NO_ERROR;
+        }
         default: {
             return BBinder::onTransact(code, data, reply, flags);
         }