ANativeWindow: add query for the concrete type.

This change adds a query to the ANativeWindow interface for getting the
concrete type of the ANativeWindow.

Bug: 4086509
Change-Id: I64aa86d72fbca3b52a98e1fc35608737781a3178
diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h
index 0ac34d0..0fc1ddf 100644
--- a/include/ui/egl/android_natives.h
+++ b/include/ui/egl/android_natives.h
@@ -110,6 +110,14 @@
      * conjunction with this query.
      */
     NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
+
+    /* Get the concrete type of a ANativeWindow.  See below for the list of
+     * possible return values.
+     *
+     * This query should not be used outside the Android framework and will
+     * likely be removed in the near future.
+     */
+    NATIVE_WINDOW_CONCRETE_TYPE,
 };
 
 /* valid operations for the (*perform)() hook */
@@ -142,6 +150,13 @@
     NATIVE_WINDOW_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_270,
 };
 
+/* values returned by the NATIVE_WINDOW_CONCRETE_TYPE query */
+enum {
+    NATIVE_WINDOW_FRAMEBUFFER,                  // FramebufferNativeWindow
+    NATIVE_WINDOW_SURFACE,                      // Surface
+    NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT,       // SurfaceTextureClient
+};
+
 struct ANativeWindow 
 {
 #ifdef __cplusplus
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index a40fac9..111141f 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -160,6 +160,9 @@
         // SurfaceTextureClient currently never queues frames to SurfaceFlinger.
         *value = 0;
         return NO_ERROR;
+    case NATIVE_WINDOW_CONCRETE_TYPE:
+        *value = NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT;
+        return NO_ERROR;
     }
     return BAD_VALUE;
 }
diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp
index 0f140ff..359b71c 100644
--- a/libs/gui/tests/SurfaceTextureClient_test.cpp
+++ b/libs/gui/tests/SurfaceTextureClient_test.cpp
@@ -44,4 +44,12 @@
     EXPECT_EQ(0, result);
 }
 
+TEST_F(SurfaceTextureClientTest, ConcreteTypeIsSurfaceTextureClient) {
+    sp<ANativeWindow> anw(mSTC);
+    int result = -123;
+    int err = anw->query(anw.get(), NATIVE_WINDOW_CONCRETE_TYPE, &result);
+    EXPECT_EQ(NO_ERROR, err);
+    EXPECT_EQ(NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT, result);
+}
+
 }
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index afabbf4..21d509a 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -712,11 +712,15 @@
     case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
         *value = MIN_UNDEQUEUED_BUFFERS;
         return NO_ERROR;
-    case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
+    case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: {
         sp<ISurfaceComposer> sf(ComposerService::getComposerService());
         *value = sf->authenticateSurface(mSurface) ? 1 : 0;
         return NO_ERROR;
     }
+    case NATIVE_WINDOW_CONCRETE_TYPE:
+        *value = NATIVE_WINDOW_SURFACE;
+        return NO_ERROR;
+    }
     return BAD_VALUE;
 }
 
diff --git a/libs/surfaceflinger_client/tests/Surface_test.cpp b/libs/surfaceflinger_client/tests/Surface_test.cpp
index 74ebf4e..fd07479 100644
--- a/libs/surfaceflinger_client/tests/Surface_test.cpp
+++ b/libs/surfaceflinger_client/tests/Surface_test.cpp
@@ -130,4 +130,12 @@
     ASSERT_TRUE(heap != NULL);
 }
 
+TEST_F(SurfaceTest, ConcreteTypeIsSurface) {
+    sp<ANativeWindow> anw(mSurface);
+    int result = -123;
+    int err = anw->query(anw.get(), NATIVE_WINDOW_CONCRETE_TYPE, &result);
+    EXPECT_EQ(NO_ERROR, err);
+    EXPECT_EQ(NATIVE_WINDOW_SURFACE, result);
+}
+
 }
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index 0702d49..dc223f9 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -286,6 +286,9 @@
         case NATIVE_WINDOW_FORMAT:
             *value = fb->format;
             return NO_ERROR;
+        case NATIVE_WINDOW_CONCRETE_TYPE:
+            *value = NATIVE_WINDOW_FRAMEBUFFER;
+            return NO_ERROR;
     }
     *value = 0;
     return BAD_VALUE;