Implement seamless rotation mode.

Add a rotation mode which does not require freezing
the screen. For situations like Camera where only small
elements move on screen, this allows for seamless changes
of display orientation. This is achieved by transforming the
windows with their current buffer in the same transaction that
we rotate the display. We set things up so the windows are
frozen this way until they submit buffers in the new orientation.
There is a special case in the Camera window itself, and it's use
of NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY. In this case the buffer
contents are rotated by SurfaceFlinger and will never resize, for these
windows we just need to update the scaling matrix.

Bug: 28823590
Change-Id: I52dc6a86fcb3c08f736f0977ba3975a24fb8136c
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 7da849a..286e097 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -58,6 +58,7 @@
 
     private static native long nativeGetNextFrameNumber(long nativeObject);
     private static native int nativeSetScalingMode(long nativeObject, int scalingMode);
+    private static native void nativeSetBuffersTransform(long nativeObject, long transform);
 
     public static final Parcelable.Creator<Surface> CREATOR =
             new Parcelable.Creator<Surface>() {
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 415e70c..f1abca8 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -51,7 +51,7 @@
 
     private static native void nativeSetLayer(long nativeObject, int zorder);
     private static native void nativeSetPosition(long nativeObject, float x, float y);
-    private static native void nativeSetPositionAppliesWithResize(long nativeObject);
+    private static native void nativeSetGeometryAppliesWithResize(long nativeObject);
     private static native void nativeSetSize(long nativeObject, int w, int h);
     private static native void nativeSetTransparentRegionHint(long nativeObject, Region region);
     private static native void nativeSetAlpha(long nativeObject, float alpha);
@@ -89,6 +89,8 @@
     private static native void nativeSetOverrideScalingMode(long nativeObject,
             int scalingMode);
     private static native IBinder nativeGetHandle(long nativeObject);
+    private static native boolean nativeGetTransformToDisplayInverse(long nativeObject);
+
     private static native Display.HdrCapabilities nativeGetHdrCapabilities(IBinder displayToken);
 
 
@@ -393,6 +395,10 @@
         return nativeGetHandle(mNativeObject);
     }
 
+    public boolean getTransformToDisplayInverse() {
+        return nativeGetTransformToDisplayInverse(mNativeObject);
+    }
+
     /** flag the transaction as an animation */
     public static void setAnimationTransaction() {
         nativeSetAnimationTransaction();
@@ -409,13 +415,15 @@
     }
 
     /**
-     * If the size changes in this transaction, position updates specified
+     * If the buffer size changes in this transaction, position and crop updates specified
      * in this transaction will not complete until a buffer of the new size
-     * arrives.
+     * arrives. As transform matrix and size are already frozen in this fashion,
+     * this enables totally freezing the surface until the resize has completed
+     * (at which point the geometry influencing aspects of this transaction will then occur)
      */
-    public void setPositionAppliesWithResize() {
+    public void setGeometryAppliesWithResize() {
         checkNotReleased();
-        nativeSetPositionAppliesWithResize(mNativeObject);
+        nativeSetGeometryAppliesWithResize(mNativeObject);
     }
 
     public void setSize(int w, int h) {
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index e6f5b83..a8afaf2 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -1410,4 +1410,6 @@
      * Called when the configuration has changed, and it's safe to load new values from resources.
      */
     public void onConfigurationChanged();
+
+    public boolean shouldRotateSeamlessly(int oldRotation, int newRotation);
 }
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index ff75677..fa1313b 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -248,10 +248,10 @@
     }
 }
 
-static void nativeSetPositionAppliesWithResize(JNIEnv* env, jclass clazz,
+static void nativeSetGeometryAppliesWithResize(JNIEnv* env, jclass clazz,
         jlong nativeObject) {
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    status_t err = ctrl->setPositionAppliesWithResize();
+    status_t err = ctrl->setGeometryAppliesWithResize();
     if (err < 0 && err != NO_INIT) {
         doThrowIAE(env);
     }
@@ -626,6 +626,16 @@
     return javaObjectForIBinder(env, ctrl->getHandle());
 }
 
+static jboolean nativeGetTransformToDisplayInverse(JNIEnv* env, jclass clazz, jlong nativeObject) {
+    bool out = false;
+    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+    status_t status = ctrl->getTransformToDisplayInverse(&out);
+    if (status != NO_ERROR) {
+        return false;
+    }
+    return out;
+}
+
 static jobject nativeGetHdrCapabilities(JNIEnv* env, jclass clazz, jobject tokenObject) {
     sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
     if (token == NULL) return NULL;
@@ -667,8 +677,8 @@
             (void*)nativeSetLayer },
     {"nativeSetPosition", "(JFF)V",
             (void*)nativeSetPosition },
-    {"nativeSetPositionAppliesWithResize", "(J)V",
-            (void*)nativeSetPositionAppliesWithResize },
+    {"nativeSetGeometryAppliesWithResize", "(J)V",
+            (void*)nativeSetGeometryAppliesWithResize },
     {"nativeSetSize", "(JII)V",
             (void*)nativeSetSize },
     {"nativeSetTransparentRegionHint", "(JLandroid/graphics/Region;)V",
@@ -722,7 +732,9 @@
     {"nativeSetOverrideScalingMode", "(JI)V",
             (void*)nativeSetOverrideScalingMode },
     {"nativeGetHandle", "(J)Landroid/os/IBinder;",
-            (void*)nativeGetHandle }
+            (void*)nativeGetHandle },
+    {"nativeGetTransformToDisplayInverse", "(J)Z",
+            (void*)nativeGetTransformToDisplayInverse },
 };
 
 int register_android_view_SurfaceControl(JNIEnv* env)