SurfaceControl: Add getTransformToDisplayInverse

For seamless rotation, the window manager needs
access to this flag, as it will apply the inverse
display transform itself to all other windows.

Bug: 28823590
Change-Id: Ifeee1078a9cb4cd01c8052570c137c6228b2f13d
diff --git a/include/gui/ISurfaceComposerClient.h b/include/gui/ISurfaceComposerClient.h
index bb79bd0..c27a741 100644
--- a/include/gui/ISurfaceComposerClient.h
+++ b/include/gui/ISurfaceComposerClient.h
@@ -77,6 +77,9 @@
      * Requires ACCESS_SURFACE_FLINGER permission
      */
     virtual status_t getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const = 0;
+
+    virtual status_t getTransformToDisplayInverse(const sp<IBinder>& handle,
+            bool* outTransformToDisplayInverse) const = 0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h
index 3d6051e..95e8b70 100644
--- a/include/gui/SurfaceComposerClient.h
+++ b/include/gui/SurfaceComposerClient.h
@@ -147,6 +147,9 @@
     status_t clearLayerFrameStats(const sp<IBinder>& token) const;
     status_t getLayerFrameStats(const sp<IBinder>& token, FrameStats* outStats) const;
 
+    status_t getTransformToDisplayInverse(const sp<IBinder>& token,
+            bool* outTransformToDisplayInverse) const;
+
     static status_t clearAnimationFrameStats();
     static status_t getAnimationFrameStats(FrameStats* outStats);
 
diff --git a/include/gui/SurfaceControl.h b/include/gui/SurfaceControl.h
index 043eb53..5e731c3 100644
--- a/include/gui/SurfaceControl.h
+++ b/include/gui/SurfaceControl.h
@@ -97,6 +97,8 @@
     status_t clearLayerFrameStats() const;
     status_t getLayerFrameStats(FrameStats* outStats) const;
 
+    status_t getTransformToDisplayInverse(bool* outTransformToDisplayInverse) const;
+
 private:
     // can't be copied
     SurfaceControl& operator = (SurfaceControl& rhs);
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
index 2ecb908..dd5b169 100644
--- a/libs/gui/ISurfaceComposerClient.cpp
+++ b/libs/gui/ISurfaceComposerClient.cpp
@@ -41,7 +41,8 @@
     CREATE_SURFACE = IBinder::FIRST_CALL_TRANSACTION,
     DESTROY_SURFACE,
     CLEAR_LAYER_FRAME_STATS,
-    GET_LAYER_FRAME_STATS
+    GET_LAYER_FRAME_STATS,
+    GET_TRANSFORM_TO_DISPLAY_INVERSE
 };
 
 class BpSurfaceComposerClient : public BpInterface<ISurfaceComposerClient>
@@ -94,6 +95,35 @@
         reply.read(*outStats);
         return reply.readInt32();
     }
+
+    virtual status_t getTransformToDisplayInverse(const sp<IBinder>& handle,
+            bool* outTransformToDisplayInverse) const {
+        Parcel data, reply;
+        status_t result =
+                data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
+        if (result != NO_ERROR) {
+            return result;
+        }
+        result = data.writeStrongBinder(handle);
+        if (result != NO_ERROR) {
+            return result;
+        }
+        result = remote()->transact(GET_TRANSFORM_TO_DISPLAY_INVERSE, data, &reply);
+        if (result != NO_ERROR) {
+            return result;
+        }
+        int transformInverse;
+        result = reply.readInt32(&transformInverse);
+        if (result != NO_ERROR) {
+            return result;
+        }
+        *outTransformToDisplayInverse = transformInverse != 0 ? true : false;
+        status_t result2 = reply.readInt32(&result);
+        if (result2 != NO_ERROR) {
+            return result2;
+        }
+        return result;
+    }
 };
 
 // Out-of-line virtual method definition to trigger vtable emission in this
@@ -145,6 +175,25 @@
             reply->writeInt32(result);
             return NO_ERROR;
         }
+        case GET_TRANSFORM_TO_DISPLAY_INVERSE: {
+            CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
+            sp<IBinder> handle;
+            status_t result = data.readStrongBinder(&handle);
+            if (result != NO_ERROR) {
+                return result;
+            }
+            bool transformInverse = false;
+            result = getTransformToDisplayInverse(handle, &transformInverse);
+            if (result != NO_ERROR) {
+                return result;
+            }
+            result = reply->writeInt32(transformInverse ? 1 : 0);
+            if (result != NO_ERROR) {
+                return result;
+            }
+            result = reply->writeInt32(NO_ERROR);
+            return result;
+        }
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 1620eb2..26b2209 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -612,6 +612,14 @@
     return mClient->getLayerFrameStats(token, outStats);
 }
 
+status_t SurfaceComposerClient::getTransformToDisplayInverse(const sp<IBinder>& token,
+        bool* outTransformToDisplayInverse) const {
+    if (mStatus != NO_ERROR) {
+        return mStatus;
+    }
+    return mClient->getTransformToDisplayInverse(token, outTransformToDisplayInverse);
+}
+
 inline Composer& SurfaceComposerClient::getComposer() {
     return mComposer;
 }
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index 223e1f4..33c1d90 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -190,6 +190,13 @@
     return client->getLayerFrameStats(mHandle, outStats);
 }
 
+status_t SurfaceControl::getTransformToDisplayInverse(bool* outTransformToDisplayInverse) const {
+    status_t err = validate();
+    if (err < 0) return err;
+    const sp<SurfaceComposerClient>& client(mClient);
+    return client->getTransformToDisplayInverse(mHandle, outTransformToDisplayInverse);
+}
+
 status_t SurfaceControl::validate() const
 {
     if (mHandle==0 || mClient==0) {
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index 2a025b8..415bdca 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -173,5 +173,15 @@
     return NO_ERROR;
 }
 
+status_t Client::getTransformToDisplayInverse(const sp<IBinder>& handle,
+        bool* outTransformToDisplayInverse) const {
+    sp<Layer> layer = getLayerUser(handle);
+    if (layer == NULL) {
+        return NAME_NOT_FOUND;
+    }
+    *outTransformToDisplayInverse = layer->getTransformToDisplayInverse();
+    return NO_ERROR;
+}
+
 // ---------------------------------------------------------------------------
 }; // namespace android
diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h
index b6d7381..12db505 100644
--- a/services/surfaceflinger/Client.h
+++ b/services/surfaceflinger/Client.h
@@ -63,6 +63,8 @@
     virtual status_t clearLayerFrameStats(const sp<IBinder>& handle) const;
 
     virtual status_t getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const;
+    virtual status_t getTransformToDisplayInverse(
+            const sp<IBinder>& handle, bool* outTransformToDisplayInverse) const;
 
     virtual status_t onTransact(
         uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 3f70144..f67e66e 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -2207,6 +2207,10 @@
     return history;
 }
 
+bool Layer::getTransformToDisplayInverse() const {
+    return mSurfaceFlingerConsumer->getTransformToDisplayInverse();
+}
+
 // ---------------------------------------------------------------------------
 
 Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 3ea38f0..a51c804 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -418,6 +418,8 @@
         return mFlinger->getFrameTimestamps(*this, frameNumber, outTimestamps);
     }
 
+    bool getTransformToDisplayInverse() const;
+
 protected:
     // constant
     sp<SurfaceFlinger> mFlinger;
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
index ba0a527..e0e4c61 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
@@ -129,6 +129,7 @@
 }
 
 bool SurfaceFlingerConsumer::getTransformToDisplayInverse() const {
+    Mutex::Autolock lock(mMutex);
     return mTransformToDisplayInverse;
 }
 
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h
index 3762659..4271039 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.h
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.h
@@ -66,8 +66,9 @@
     // See GLConsumer::bindTextureImageLocked().
     status_t bindTextureImage();
 
-    // must be called from SF main thread
     bool getTransformToDisplayInverse() const;
+
+    // must be called from SF main thread
     const Region& getSurfaceDamage() const;
 
     // Sets the contents changed listener. This should be used instead of