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/GLESv1/gl.cpp b/guest/GLESv1/gl.cpp
index 9f4a69c..adede19 100644
--- a/guest/GLESv1/gl.cpp
+++ b/guest/GLESv1/gl.cpp
@@ -50,6 +50,11 @@
     if (!grallocHelper) {                                            \
         ALOGE("egl: Failed to get grallocHelper\n");                 \
         return ret;                                                  \
+    }                                                                \
+    auto* anwHelper = hostCon->anwHelper();                          \
+    if (!anwHelper) {                                                \
+        ALOGE("egl: Failed to get anwHelper\n");                     \
+        return ret;                                                  \
     }
 
 //GL extensions
@@ -62,26 +67,22 @@
     EGLImage_t *image = (EGLImage_t*)img;
 
     if (image->target == EGL_NATIVE_BUFFER_ANDROID) {
-        //TODO: check error - we don't have a way to set gl error
-        android_native_buffer_t* native_buffer = image->native_buffer;
+        DEFINE_AND_VALIDATE_HOST_CONNECTION();
 
-        if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) {
-            return;
-        }
-
-        if (native_buffer->common.version != sizeof(android_native_buffer_t)) {
+        EGLClientBuffer buffer = image->buffer;
+        if (!anwHelper->isValid(buffer)) {
+            ALOGE("Invalid native buffer.");
             return;
         }
 
         GET_CONTEXT;
-        DEFINE_AND_VALIDATE_HOST_CONNECTION();
-
         ctx->override2DTextureTarget(target);
-        rcEnc->rcBindTexture(rcEnc,
-                grallocHelper->getHostHandle(native_buffer->handle));
+
+        const int hostHandle = anwHelper->getHostHandle(buffer, grallocHelper);
+        rcEnc->rcBindTexture(rcEnc, hostHandle);
+
         ctx->restore2DTextureTarget();
-    }
-    else if (image->target == EGL_GL_TEXTURE_2D_KHR) {
+    } else if (image->target == EGL_GL_TEXTURE_2D_KHR) {
         GET_CONTEXT;
         ctx->override2DTextureTarget(target);
         GLeglImageOES hostImage = reinterpret_cast<GLeglImageOES>((intptr_t)image->host_egl_image);
@@ -100,19 +101,16 @@
     EGLImage_t *image = (EGLImage_t*)img;
 
     if (image->target == EGL_NATIVE_BUFFER_ANDROID) {
-        android_native_buffer_t* native_buffer = ((EGLImage_t*)image)->native_buffer;
-
-        if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) {
-            return;
-        }
-
-        if (native_buffer->common.version != sizeof(android_native_buffer_t)) {
-            return;
-        }
-
         DEFINE_AND_VALIDATE_HOST_CONNECTION();
-        rcEnc->rcBindRenderbuffer(rcEnc,
-                grallocHelper->getHostHandle(native_buffer->handle));
+
+        EGLClientBuffer buffer = image->buffer;
+        if (!anwHelper->isValid(buffer)) {
+            ALOGE("Invalid native buffer.");
+            return;
+        }
+
+        const int hostHandle = anwHelper->getHostHandle(buffer, grallocHelper);
+        rcEnc->rcBindRenderbuffer(rcEnc, hostHandle);
     } else {
         //TODO
     }
diff --git a/guest/GLESv2/gl2.cpp b/guest/GLESv2/gl2.cpp
index f143aa5..f4b04b1 100644
--- a/guest/GLESv2/gl2.cpp
+++ b/guest/GLESv2/gl2.cpp
@@ -50,6 +50,11 @@
     if (!grallocHelper) {                                            \
         ALOGE("egl: Failed to get grallocHelper\n");                 \
         return ret;                                                  \
+    }                                                                \
+    auto* anwHelper = hostCon->anwHelper();                          \
+    if (!anwHelper) {                                                \
+        ALOGE("egl: Failed to get anwHelper\n");                     \
+        return ret;                                                  \
     }
 
 //GL extensions
@@ -63,29 +68,24 @@
     EGLImage_t *image = (EGLImage_t*)img;
     GLeglImageOES hostImage = reinterpret_cast<GLeglImageOES>((intptr_t)image->host_egl_image);
 
+    GET_CONTEXT;
+    DEFINE_AND_VALIDATE_HOST_CONNECTION();
+
     if (image->target == EGL_NATIVE_BUFFER_ANDROID) {
-        //TODO: check error - we don't have a way to set gl error
-        android_native_buffer_t* native_buffer = image->native_buffer;
+        EGLClientBuffer buffer = image->buffer;
 
-        if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) {
+        if (!anwHelper->isValid(buffer)) {
+            ALOGE("Invalid native buffer.");
             return;
         }
 
-        if (native_buffer->common.version != sizeof(android_native_buffer_t)) {
-            return;
-        }
-
-        GET_CONTEXT;
-        DEFINE_AND_VALIDATE_HOST_CONNECTION();
-
         ctx->override2DTextureTarget(target);
         ctx->associateEGLImage(target, hostImage, image->width, image->height);
-        rcEnc->rcBindTexture(rcEnc,
-                grallocHelper->getHostHandle(native_buffer->handle));
+
+        const int hostHandle = anwHelper->getHostHandle(buffer, grallocHelper);
+        rcEnc->rcBindTexture(rcEnc, hostHandle);
         ctx->restore2DTextureTarget(target);
-    }
-    else if (image->target == EGL_GL_TEXTURE_2D_KHR) {
-        GET_CONTEXT;
+    } else if (image->target == EGL_GL_TEXTURE_2D_KHR) {
         ctx->override2DTextureTarget(target);
         ctx->associateEGLImage(target, hostImage, image->width, image->height);
         ctx->m_glEGLImageTargetTexture2DOES_enc(self, GL_TEXTURE_2D, hostImage);
@@ -104,21 +104,19 @@
     GLeglImageOES hostImage = reinterpret_cast<GLeglImageOES>((intptr_t)image->host_egl_image);
 
     if (image->target == EGL_NATIVE_BUFFER_ANDROID) {
-        android_native_buffer_t* native_buffer = ((EGLImage_t*)image)->native_buffer;
-
-        if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) {
-            return;
-        }
-
-        if (native_buffer->common.version != sizeof(android_native_buffer_t)) {
-            return;
-        }
-
         DEFINE_AND_VALIDATE_HOST_CONNECTION();
+
+        EGLClientBuffer buffer = image->buffer;
+        if (!anwHelper->isValid(buffer)) {
+            ALOGE("Invalid native buffer.");
+            return;
+        }
+
         GET_CONTEXT;
         ctx->associateEGLImage(target, hostImage, image->width, image->height);
-        rcEnc->rcBindRenderbuffer(rcEnc,
-                grallocHelper->getHostHandle(native_buffer->handle));
+
+        const int hostHandle = anwHelper->getHostHandle(buffer, grallocHelper);
+        rcEnc->rcBindRenderbuffer(rcEnc, hostHandle);
     } else {
         //TODO
     }
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;
diff --git a/guest/egl/egl.cpp b/guest/egl/egl.cpp
index d373682..ad9ef1f 100644
--- a/guest/egl/egl.cpp
+++ b/guest/egl/egl.cpp
@@ -62,7 +62,6 @@
 #endif
 #include <cutils/trace.h>
 
-#include <system/window.h>
 
 using android::base::guest::getCurrentThreadId;
 
@@ -164,6 +163,11 @@
     if (!grallocHelper) {                                            \
         ALOGE("egl: Failed to get grallocHelper\n");                 \
         return ret;                                                  \
+    }                                                                \
+    auto* anwHelper = hostCon->anwHelper();                          \
+    if (!anwHelper) {                                                \
+        ALOGE("egl: Failed to get anwHelper\n");                     \
+        return ret;                                                  \
     }
 
 #define DEFINE_AND_VALIDATE_HOST_CONNECTION_FOR_TLS(ret, tls)         \
@@ -181,6 +185,11 @@
     if (!grallocHelper) {                                             \
         ALOGE("egl: Failed to get grallocHelper\n");                  \
         return ret;                                                   \
+    }                                                                 \
+    auto* anwHelper = hostCon->anwHelper();                           \
+    if (!anwHelper) {                                                 \
+        ALOGE("egl: Failed to get anwHelper\n");                      \
+        return ret;                                                   \
     }
 
 #define VALIDATE_CONTEXT_RETURN(context,ret)  \
@@ -447,7 +456,7 @@
 struct egl_window_surface_t : public egl_surface_t {
     static egl_window_surface_t* create(
             EGLDisplay dpy, EGLConfig config, EGLint surfType,
-            ANativeWindow* window);
+            EGLNativeWindowType window);
 
     virtual ~egl_window_surface_t();
 
@@ -462,53 +471,71 @@
 private:
     egl_window_surface_t(
             EGLDisplay dpy, EGLConfig config, EGLint surfType,
-            ANativeWindow* window);
+            EGLNativeWindowType window);
     EGLBoolean init();
 
-    ANativeWindow*              nativeWindow;
-    android_native_buffer_t*    buffer;
+    EGLNativeWindowType nativeWindow;
+    EGLClientBuffer     buffer;
     bool collectingTimestamps;
 };
 
 egl_window_surface_t::egl_window_surface_t (
         EGLDisplay dpy, EGLConfig config, EGLint surfType,
-        ANativeWindow* window)
+        EGLNativeWindowType window)
 :   egl_surface_t(dpy, config, surfType),
     nativeWindow(window),
     buffer(NULL),
     collectingTimestamps(false)
 {
-    // keep a reference on the window
-    nativeWindow->common.incRef(&nativeWindow->common);
 }
 
-
 EGLBoolean egl_window_surface_t::init()
 {
-#ifndef HOST_BUILD
+    DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
+
+    // keep a reference on the window
+    anwHelper->acquire(nativeWindow);
+
     int consumerUsage = 0;
-    if (nativeWindow->query(nativeWindow, NATIVE_WINDOW_CONSUMER_USAGE_BITS, &consumerUsage) != 0) {
+    if (anwHelper->getConsumerUsage(nativeWindow, &consumerUsage) != 0) {
         setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE);
     } else {
         int producerUsage = GRALLOC_USAGE_HW_RENDER;
-        native_window_set_usage(nativeWindow, consumerUsage | producerUsage);
+        anwHelper->setUsage(nativeWindow, consumerUsage | producerUsage);
     }
-#endif
 
-    if (nativeWindow->dequeueBuffer_DEPRECATED(nativeWindow, &buffer) != 0) {
+    int acquireFenceFd = -1;
+    if (anwHelper->dequeueBuffer(nativeWindow, &buffer, &acquireFenceFd) != 0) {
         setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE);
     }
-    setWidth(buffer->width);
-    setHeight(buffer->height);
+    if (acquireFenceFd >= 0) {
+        auto* syncHelper = hostCon->syncHelper();
 
-    int nativeWidth, nativeHeight;
-          nativeWindow->query(nativeWindow, NATIVE_WINDOW_WIDTH, &nativeWidth);
-          nativeWindow->query(nativeWindow, NATIVE_WINDOW_HEIGHT, &nativeHeight);
+        int waitRet = syncHelper->wait(acquireFenceFd, /* wait forever */-1);
+        if (waitRet < 0) {
+            ALOGE("Failed to wait for window surface's dequeued buffer.");
+            anwHelper->cancelBuffer(nativeWindow, buffer);
+        }
+
+        syncHelper->close(acquireFenceFd);
+
+        if (waitRet < 0) {
+            setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE);
+        }
+    }
+
+    int bufferWidth = anwHelper->getWidth(buffer);
+    int bufferHeight = anwHelper->getHeight(buffer);
+
+    setWidth(bufferWidth);
+    setHeight(bufferHeight);
+
+    int nativeWidth = anwHelper->getWidth(nativeWindow);
+    int nativeHeight = anwHelper->getHeight(nativeWindow);
 
     setNativeWidth(nativeWidth);
     setNativeHeight(nativeHeight);
 
-    DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
     rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uintptr_t)s_display.getIndexOfConfig(config),
             getWidth(), getHeight());
 
@@ -516,15 +543,16 @@
         ALOGE("rcCreateWindowSurface returned 0");
         return EGL_FALSE;
     }
-    rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface,
-            grallocHelper->getHostHandle(buffer->handle));
+
+    const int hostHandle = anwHelper->getHostHandle(buffer, grallocHelper);
+    rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, hostHandle);
 
     return EGL_TRUE;
 }
 
 egl_window_surface_t* egl_window_surface_t::create(
         EGLDisplay dpy, EGLConfig config, EGLint surfType,
-        ANativeWindow* window)
+        EGLNativeWindowType window)
 {
     egl_window_surface_t* wnd = new egl_window_surface_t(
             dpy, config, surfType, window);
@@ -541,15 +569,17 @@
         rcEnc->rcDestroyWindowSurface(rcEnc, rcSurface);
     }
 
+    auto* anwHelper = hostCon->anwHelper();
     if (buffer) {
-        nativeWindow->cancelBuffer_DEPRECATED(nativeWindow, buffer);
+        anwHelper->cancelBuffer(nativeWindow, buffer);
     }
-    nativeWindow->common.decRef(&nativeWindow->common);
+    anwHelper->release(nativeWindow);
 }
 
 void egl_window_surface_t::setSwapInterval(int interval)
 {
-    nativeWindow->setSwapInterval(nativeWindow, interval);
+    DEFINE_HOST_CONNECTION;
+    hostCon->anwHelper()->setSwapInterval(nativeWindow, interval);
 }
 
 // createNativeSync() creates an OpenGL sync object on the host
@@ -788,14 +818,14 @@
         sFrameTracingState.frameNumber, &presentFenceFd);
 
     DPRINT("queueBuffer with fence %d", presentFenceFd);
-    nativeWindow->queueBuffer(nativeWindow, buffer, presentFenceFd);
+    anwHelper->queueBuffer(nativeWindow, buffer, presentFenceFd);
 
     appTimeMetric.onQueueBufferReturn();
 
     DPRINT("calling dequeueBuffer...");
 
     int acquireFenceFd = -1;
-    if (nativeWindow->dequeueBuffer(nativeWindow, &buffer, &acquireFenceFd)) {
+    if (anwHelper->dequeueBuffer(nativeWindow, &buffer, &acquireFenceFd)) {
         buffer = NULL;
         setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
     }
@@ -807,11 +837,11 @@
         syncHelper->close(acquireFenceFd);
     }
 
-    rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface,
-            grallocHelper->getHostHandle(buffer->handle));
+    const int hostHandle = anwHelper->getHostHandle(buffer, grallocHelper);
+    rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, hostHandle);
 
-    setWidth(buffer->width);
-    setHeight(buffer->height);
+    setWidth(anwHelper->getWidth(buffer));
+    setHeight(anwHelper->getHeight(buffer));
 
     sFrameTracingState.onSwapBuffersSuccesful(rcEnc);
     appTimeMetric.onSwapBuffersReturn();
@@ -1279,12 +1309,12 @@
         setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
     }
 
-    if (reinterpret_cast<ANativeWindow*>(win)->common.magic != ANDROID_NATIVE_WINDOW_MAGIC) {
+    DEFINE_HOST_CONNECTION;
+    if (!hostCon->anwHelper()->isValid(win)) {
         setErrorReturn(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
     }
 
-    egl_surface_t* surface = egl_window_surface_t::create(
-            &s_display, config, EGL_WINDOW_BIT, reinterpret_cast<ANativeWindow*>(win));
+    egl_surface_t* surface = egl_window_surface_t::create(&s_display, config, EGL_WINDOW_BIT, win);
     if (!surface) {
         setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE);
     }
@@ -2205,19 +2235,12 @@
             setErrorReturn(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
         }
 
-        android_native_buffer_t* native_buffer = (android_native_buffer_t*)buffer;
-
-        if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
-            setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
-
-        if (native_buffer->common.version != sizeof(android_native_buffer_t))
-            setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
-
-        if (native_buffer->handle == NULL)
-            setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
-
         DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
-        int format = grallocHelper->getFormat(native_buffer->handle);
+        if (!anwHelper->isValid(buffer)) {
+            setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+        }
+
+        int format = anwHelper->getFormat(buffer, grallocHelper);
         switch (format) {
             case HAL_PIXEL_FORMAT_R8:
             case HAL_PIXEL_FORMAT_RGBA_8888:
@@ -2245,14 +2268,14 @@
                 setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
         }
 
-        native_buffer->common.incRef(&native_buffer->common);
+        anwHelper->acquire(buffer);
 
         EGLImage_t *image = new EGLImage_t();
         image->dpy = dpy;
         image->target = target;
-        image->native_buffer = native_buffer;
-        image->width = native_buffer->width;
-        image->height = native_buffer->width;
+        image->buffer = buffer;
+        image->width = anwHelper->getWidth(buffer);
+        image->height = anwHelper->getHeight(buffer);
 
         return (EGLImageKHR)image;
     }
@@ -2287,24 +2310,22 @@
         RETURN_ERROR(EGL_FALSE, EGL_BAD_PARAMETER);
     }
 
+    DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
+
     if (image->target == EGL_NATIVE_BUFFER_ANDROID) {
-        android_native_buffer_t* native_buffer = image->native_buffer;
-
-        if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
+        EGLClientBuffer buffer = image->buffer;
+        if (!anwHelper->isValid(buffer)) {
             setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
+        }
 
-        if (native_buffer->common.version != sizeof(android_native_buffer_t))
-            setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
-
-        native_buffer->common.decRef(&native_buffer->common);
+        anwHelper->release(buffer);
         delete image;
 
         return EGL_TRUE;
-    }
-    else if (image->target == EGL_GL_TEXTURE_2D_KHR) {
+    } else if (image->target == EGL_GL_TEXTURE_2D_KHR) {
         uint32_t host_egl_image = image->host_egl_image;
         delete image;
-        DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
+
         return rcEnc->rcDestroyClientImage(rcEnc, host_egl_image);
     }