Wrap interactions with ANativeWindow-s in an interface

... so that upcoming end2end tests can set up a mock impl for
emulating ANativeWindow-s in single process tests.

Bug: b/292257025
Test: cvd start --gpu_mode=gfxstream
      cvd start --gpu_mode=gfxstream_guest_angle_host_swiftshader
Change-Id: I3bdab77401e7236b7367f57b3a7e46bec7b08248
diff --git a/guest/OpenglSystemCommon/ANativeWindow.h b/guest/OpenglSystemCommon/ANativeWindow.h
new file mode 100644
index 0000000..a50d9c2
--- /dev/null
+++ b/guest/OpenglSystemCommon/ANativeWindow.h
@@ -0,0 +1,56 @@
+// Copyright 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expresso or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include "Gralloc.h"
+
+namespace gfxstream {
+
+// Abstraction around libnativewindow to support testing.
+class ANativeWindowHelper {
+  public:
+    virtual ~ANativeWindowHelper() {}
+
+    virtual bool isValid(EGLNativeWindowType window) = 0;
+    virtual bool isValid(EGLClientBuffer buffer) = 0;
+
+    virtual void acquire(EGLNativeWindowType window) = 0;
+    virtual void release(EGLNativeWindowType window)= 0;
+
+    virtual void acquire(EGLClientBuffer buffer) = 0;
+    virtual void release(EGLClientBuffer buffer) = 0;
+
+    virtual int getConsumerUsage(EGLNativeWindowType window, int* usage) = 0;
+    virtual void setUsage(EGLNativeWindowType window, int usage) = 0;
+
+    virtual int getWidth(EGLNativeWindowType window) = 0;
+    virtual int getHeight(EGLNativeWindowType window) = 0;
+
+    virtual int getWidth(EGLClientBuffer buffer) = 0;
+    virtual int getHeight(EGLClientBuffer buffer) = 0;
+    virtual int getFormat(EGLClientBuffer buffer, Gralloc* helper) = 0;
+    virtual int getHostHandle(EGLClientBuffer buffer, Gralloc* helper) = 0;
+
+    virtual void setSwapInterval(EGLNativeWindowType window, int interval) = 0;
+
+    virtual int queueBuffer(EGLNativeWindowType window, EGLClientBuffer buffer, int fence) = 0;
+    virtual int dequeueBuffer(EGLNativeWindowType window, EGLClientBuffer* buffer, int* fence) = 0;
+    virtual int cancelBuffer(EGLNativeWindowType window, EGLClientBuffer buffer) = 0;
+};
+
+}  // namespace gfxstream
diff --git a/guest/OpenglSystemCommon/ANativeWindowAndroid.cpp b/guest/OpenglSystemCommon/ANativeWindowAndroid.cpp
new file mode 100644
index 0000000..1edae70
--- /dev/null
+++ b/guest/OpenglSystemCommon/ANativeWindowAndroid.cpp
@@ -0,0 +1,221 @@
+// Copyright 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expresso or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "ANativeWindowAndroid.h"
+
+#if defined(__ANDROID__)
+#include <android/native_window.h>
+#include <system/window.h>
+#endif  // defined(__ANDROID__)
+
+namespace gfxstream {
+
+bool ANativeWindowHelperAndroid::isValid(EGLNativeWindowType window) {
+#if defined(__ANDROID__)
+    auto* anw = reinterpret_cast<ANativeWindow*>(window);
+    return anw->common.magic == ANDROID_NATIVE_WINDOW_MAGIC;
+#else
+    (void)window;
+    return false;
+#endif  // defined(__ANDROID__)
+}
+
+bool ANativeWindowHelperAndroid::isValid(EGLClientBuffer buffer) {
+#if defined(__ANDROID__)
+    auto* anwb = reinterpret_cast<ANativeWindowBuffer*>(buffer);
+    if (anwb->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) {
+        return false;
+    }
+    if (anwb->common.version != sizeof(android_native_buffer_t)) {
+        return false;
+    }
+    if (anwb->handle == nullptr) {
+        return false;
+    }
+    return true;
+#else
+    (void)buffer;
+    return false;
+#endif  // defined(__ANDROID__)
+}
+
+void ANativeWindowHelperAndroid::acquire(EGLNativeWindowType window) {
+#if defined(__ANDROID__)
+    auto* anw = reinterpret_cast<ANativeWindow*>(window);
+    ANativeWindow_acquire(anw);
+#else
+    (void)window;
+#endif  // defined(__ANDROID__)
+}
+
+void ANativeWindowHelperAndroid::release(EGLNativeWindowType window) {
+#if defined(__ANDROID__)
+    auto* anw = reinterpret_cast<ANativeWindow*>(window);
+    ANativeWindow_release(anw);
+#else
+    (void)window;
+#endif  // defined(__ANDROID__)
+}
+
+
+void ANativeWindowHelperAndroid::acquire(EGLClientBuffer buffer) {
+#if defined(__ANDROID__)
+    auto* anwb = reinterpret_cast<ANativeWindowBuffer*>(buffer);
+    anwb->incStrong(anwb);
+#else
+    (void)buffer;
+#endif  // defined(__ANDROID__)
+}
+
+void ANativeWindowHelperAndroid::release(EGLClientBuffer buffer) {
+#if defined(__ANDROID__)
+    auto* anwb = reinterpret_cast<ANativeWindowBuffer*>(buffer);
+    anwb->decStrong(anwb);
+#else
+    (void)buffer;
+#endif  // defined(__ANDROID__)
+}
+
+int ANativeWindowHelperAndroid::getConsumerUsage(EGLNativeWindowType window, int* usage) {
+#if defined(__ANDROID__)
+    auto* anw = reinterpret_cast<ANativeWindow*>(window);
+    return anw->query(anw, NATIVE_WINDOW_CONSUMER_USAGE_BITS, usage);
+#else
+    (void)window;
+    (void)usage;
+    return -1;
+#endif  // defined(__ANDROID__)
+}
+
+void ANativeWindowHelperAndroid::setUsage(EGLNativeWindowType window, int usage) {
+#if defined(__ANDROID__)
+    auto* anw = reinterpret_cast<ANativeWindow*>(window);
+    ANativeWindow_setUsage(anw, usage);
+#else
+    (void)window;
+    (void)usage;
+#endif  // defined(__ANDROID__)
+}
+
+int ANativeWindowHelperAndroid::getWidth(EGLNativeWindowType window) {
+#if defined(__ANDROID__)
+    auto* anw = reinterpret_cast<ANativeWindow*>(window);
+    return ANativeWindow_getWidth(anw);
+#else
+    (void)window;
+    return -1;
+#endif  // defined(__ANDROID__)
+}
+
+int ANativeWindowHelperAndroid::getHeight(EGLNativeWindowType window) {
+#if defined(__ANDROID__)
+    auto* anw = reinterpret_cast<ANativeWindow*>(window);
+    return ANativeWindow_getHeight(anw);
+#else
+    (void)window;
+    return -1;
+#endif  // defined(__ANDROID__)
+}
+
+int ANativeWindowHelperAndroid::getWidth(EGLClientBuffer buffer) {
+#if defined(__ANDROID__)
+    auto* anwb = reinterpret_cast<ANativeWindowBuffer*>(buffer);
+    return anwb->width;
+#else
+    (void)buffer;
+    return -1;
+#endif  // defined(__ANDROID__)
+}
+
+int ANativeWindowHelperAndroid::getHeight(EGLClientBuffer buffer) {
+#if defined(__ANDROID__)
+    auto* anwb = reinterpret_cast<ANativeWindowBuffer*>(buffer);
+    return anwb->height;
+#else
+    (void)buffer;
+    return -1;
+#endif  // defined(__ANDROID__)
+}
+
+int ANativeWindowHelperAndroid::getFormat(EGLClientBuffer buffer, Gralloc* gralloc) {
+#if defined(__ANDROID__)
+    auto* anb = reinterpret_cast<ANativeWindowBuffer*>(buffer);
+    return gralloc->getFormat(anb->handle);
+#else
+    (void)buffer;
+    (void)gralloc;
+    return -1;
+#endif  // defined(__ANDROID__)
+}
+
+void ANativeWindowHelperAndroid::setSwapInterval(EGLNativeWindowType window, int interval) {
+#if defined(__ANDROID__)
+    auto* anw = reinterpret_cast<ANativeWindow*>(window);
+    anw->setSwapInterval(anw, interval);
+#else
+    (void)window;
+    (void)interval;
+#endif  // defined(__ANDROID__)
+}
+
+int ANativeWindowHelperAndroid::queueBuffer(EGLNativeWindowType window, EGLClientBuffer buffer, int fence) {
+#if defined(__ANDROID__)
+    auto* anw = reinterpret_cast<ANativeWindow*>(window);
+    auto* anb = reinterpret_cast<ANativeWindowBuffer*>(buffer);
+    return ANativeWindow_queueBuffer(anw, anb, fence);
+#else
+    (void)window;
+    (void)buffer;
+    (void)fence;
+    return -1;
+#endif  // defined(__ANDROID__)
+}
+
+int ANativeWindowHelperAndroid::dequeueBuffer(EGLNativeWindowType window, EGLClientBuffer* buffer, int* fence) {
+#if defined(__ANDROID__)
+    auto* anw = reinterpret_cast<ANativeWindow*>(window);
+    auto* anb = reinterpret_cast<ANativeWindowBuffer**>(buffer);
+    return ANativeWindow_dequeueBuffer(anw, anb, fence);
+#else
+    (void)window;
+    (void)buffer;
+    (void)fence;
+    return -1;
+#endif  // defined(__ANDROID__)
+}
+
+int ANativeWindowHelperAndroid::cancelBuffer(EGLNativeWindowType window, EGLClientBuffer buffer) {
+#if defined(__ANDROID__)
+    auto* anw = reinterpret_cast<ANativeWindow*>(window);
+    auto* anb = reinterpret_cast<ANativeWindowBuffer*>(buffer);
+    return ANativeWindow_cancelBuffer(anw, anb, -1);
+#else
+    (void)window;
+    (void)buffer;
+    return -1;
+#endif  // defined(__ANDROID__)
+}
+
+int ANativeWindowHelperAndroid::getHostHandle(EGLClientBuffer buffer, Gralloc* gralloc) {
+#if defined(__ANDROID__)
+    auto* anb = reinterpret_cast<ANativeWindowBuffer*>(buffer);
+    return gralloc->getHostHandle(anb->handle);
+#else
+    (void)buffer;
+    (void)gralloc;
+    return -1;
+#endif  // defined(__ANDROID__)
+}
+
+}  // namespace gfxstream
\ No newline at end of file
diff --git a/guest/OpenglSystemCommon/ANativeWindowAndroid.h b/guest/OpenglSystemCommon/ANativeWindowAndroid.h
new file mode 100644
index 0000000..97eba6a
--- /dev/null
+++ b/guest/OpenglSystemCommon/ANativeWindowAndroid.h
@@ -0,0 +1,57 @@
+// Copyright 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expresso or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include "ANativeWindow.h"
+
+namespace gfxstream {
+
+class ANativeWindowHelperAndroid : public ANativeWindowHelper {
+  public:
+    ANativeWindowHelperAndroid() = default;
+
+    bool isValid(EGLNativeWindowType window);
+    bool isValid(EGLClientBuffer buffer);
+
+    void acquire(EGLNativeWindowType window);
+    void release(EGLNativeWindowType window);
+
+    void acquire(EGLClientBuffer buffer);
+    void release(EGLClientBuffer buffer);
+
+    int getConsumerUsage(EGLNativeWindowType window, int* usage);
+    void setUsage(EGLNativeWindowType window, int usage);
+
+    int getWidth(EGLNativeWindowType window);
+    int getHeight(EGLNativeWindowType window);
+
+    int getWidth(EGLClientBuffer buffer);
+    int getHeight(EGLClientBuffer buffer);
+
+    int getFormat(EGLClientBuffer buffer, Gralloc* helper);
+
+    void setSwapInterval(EGLNativeWindowType window, int interval);
+
+    int queueBuffer(EGLNativeWindowType window, EGLClientBuffer buffer, int fence);
+    int dequeueBuffer(EGLNativeWindowType window, EGLClientBuffer* buffer, int* fence);
+    int cancelBuffer(EGLNativeWindowType window, EGLClientBuffer buffer);
+
+    int getHostHandle(EGLClientBuffer buffer, Gralloc* helper);
+};
+
+}  // namespace gfxstream
\ No newline at end of file
diff --git a/guest/OpenglSystemCommon/Android.bp b/guest/OpenglSystemCommon/Android.bp
index 97bccf9..09e454d 100644
--- a/guest/OpenglSystemCommon/Android.bp
+++ b/guest/OpenglSystemCommon/Android.bp
@@ -86,8 +86,12 @@
     target: {
         android: {
             shared_libs: [
+                "libnativewindow",
                 "libsync",
             ],
+            srcs: [
+                "ANativeWindowAndroid.cpp",
+            ],
         },
     },
 }
diff --git a/guest/OpenglSystemCommon/EGLImage.h b/guest/OpenglSystemCommon/EGLImage.h
index fe320b2..8ef99c2 100644
--- a/guest/OpenglSystemCommon/EGLImage.h
+++ b/guest/OpenglSystemCommon/EGLImage.h
@@ -35,7 +35,7 @@
 
     union
     {
-        android_native_buffer_t *native_buffer;
+        EGLClientBuffer buffer;
         uint32_t host_egl_image;
     };
 };
diff --git a/guest/OpenglSystemCommon/HostConnection.cpp b/guest/OpenglSystemCommon/HostConnection.cpp
index 41479e6..f0fac92 100644
--- a/guest/OpenglSystemCommon/HostConnection.cpp
+++ b/guest/OpenglSystemCommon/HostConnection.cpp
@@ -17,13 +17,17 @@
 
 #include "GrallocGoldfish.h"
 #include "GrallocMinigbm.h"
-#include "SyncAndroid.h"
 #include "aemu/base/AndroidHealthMonitor.h"
 #include "aemu/base/AndroidHealthMonitorConsumerBasic.h"
 #include "aemu/base/threads/AndroidThread.h"
 #include "cutils/properties.h"
 #include "renderControl_types.h"
 
+#if defined(__ANDROID__)
+#include "ANativeWindowAndroid.h"
+#include "SyncAndroid.h"
+#endif
+
 #ifdef HOST_BUILD
 #include "aemu/base/Tracing.h"
 #endif
@@ -367,6 +371,7 @@
     }
 
 #if defined(__ANDROID__)
+    con->m_anwHelper = new gfxstream::ANativeWindowHelperAndroid();
     con->m_syncHelper = new gfxstream::SyncHelperAndroid();
 #else
     // Host builds are expected to set a sync helper for testing.
diff --git a/guest/OpenglSystemCommon/HostConnection.h b/guest/OpenglSystemCommon/HostConnection.h
index 6823981..0388912 100644
--- a/guest/OpenglSystemCommon/HostConnection.h
+++ b/guest/OpenglSystemCommon/HostConnection.h
@@ -16,6 +16,7 @@
 #ifndef __COMMON_HOST_CONNECTION_H
 #define __COMMON_HOST_CONNECTION_H
 
+#include "ANativeWindow.h"
 #include "ChecksumCalculator.h"
 #include "EmulatorFeatureInfo.h"
 #include "Gralloc.h"
@@ -29,8 +30,6 @@
 #include "goldfish_dma.h"
 #endif
 
-#include <cutils/native_handle.h>
-
 #ifdef GFXSTREAM
 #include <mutex>
 #else
@@ -180,6 +179,9 @@
     gfxstream::SyncHelper* syncHelper() { return m_syncHelper; }
     void setSyncHelperForTesting(gfxstream::SyncHelper* sync) { m_syncHelper = sync;}
 
+    gfxstream::ANativeWindowHelper* anwHelper() { return m_anwHelper; }
+    void setANativeWindowHelperForTesting(gfxstream::ANativeWindowHelper* anw) { m_anwHelper = anw; }
+
     void flush() {
         if (m_stream) {
             m_stream->flush();
@@ -256,6 +258,7 @@
     std::unique_ptr<ExtendedRCEncoderContext> m_rcEnc;
 
     ChecksumCalculator m_checksumHelper;
+    gfxstream::ANativeWindowHelper* m_anwHelper = nullptr;
     gfxstream::Gralloc* m_grallocHelper = nullptr;
     gfxstream::SyncHelper* m_syncHelper = nullptr;
     ProcessPipe* m_processPipe = nullptr;