Merge "[fuchsia] Migrate fuchsia.hardware.goldfish to //sdk"
diff --git a/Android.bp b/Android.bp
index 2f333a0..00fabf3 100644
--- a/Android.bp
+++ b/Android.bp
@@ -4,7 +4,7 @@
     srcs: [
         "android-emu/android/base/AlignedBuf.cpp",
         "android-emu/android/base/Pool.cpp",
-        "android-emu/android/base/SubAllocator.cpp",
+        "android-emu/android/base/AndroidSubAllocator.cpp",
         "android-emu/android/base/files/MemStream.cpp",
         "android-emu/android/base/files/Stream.cpp",
         "android-emu/android/base/files/StreamSerializing.cpp",
diff --git a/BUILD.gn b/BUILD.gn
index 776d1ec..0f4d394 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -5,8 +5,8 @@
     "android-emu/android/base/Pool.cpp",
     "android-emu/android/base/Pool.h",
     "android-emu/android/base/ring_buffer.c",
-    "android-emu/android/base/SubAllocator.cpp",
-    "android-emu/android/base/SubAllocator.h",
+    "android-emu/android/base/AndroidSubAllocator.cpp",
+    "android-emu/android/base/AndroidSubAllocator.h",
     "android-emu/android/base/files/MemStream.cpp",
     "android-emu/android/base/files/MemStream.h",
     "android-emu/android/base/files/Stream.cpp",
diff --git a/android-emu/Android.mk b/android-emu/Android.mk
index 6de495e..4be199b 100644
--- a/android-emu/Android.mk
+++ b/android-emu/Android.mk
@@ -18,7 +18,7 @@
     android/base/Pool.cpp \
     android/base/ring_buffer.c \
     android/base/StringFormat.cpp \
-    android/base/SubAllocator.cpp \
+    android/base/AndroidSubAllocator.cpp \
     android/base/synchronization/AndroidMessageChannel.cpp \
     android/base/threads/AndroidFunctorThread.cpp \
     android/base/threads/AndroidThreadStore.cpp \
diff --git a/android-emu/CMakeLists.txt b/android-emu/CMakeLists.txt
index e6482d8..5b4b280 100644
--- a/android-emu/CMakeLists.txt
+++ b/android-emu/CMakeLists.txt
@@ -1,8 +1,8 @@
 # This is an autogenerated file! Do not edit!
 # instead run make from .../device/generic/goldfish-opengl
 # which will re-generate this file.
-android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/android-emu/Android.mk" "3654f06acfa661c75b91fe271337a63a77326a69b4247026996c40bff8138bde")
-set(androidemu_src android/base/AlignedBuf.cpp android/base/files/MemStream.cpp android/base/files/Stream.cpp android/base/files/StreamSerializing.cpp android/base/Pool.cpp android/base/ring_buffer.c android/base/StringFormat.cpp android/base/SubAllocator.cpp android/base/synchronization/AndroidMessageChannel.cpp android/base/threads/AndroidFunctorThread.cpp android/base/threads/AndroidThreadStore.cpp android/base/threads/AndroidThread_pthread.cpp android/base/threads/AndroidWorkPool.cpp android/base/Tracing.cpp android/utils/debug.c)
+android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/android-emu/Android.mk" "e7c9acc2277e7c651d6e722f96705a1fd445441b5ab6bb5b6d5b4c46dddfc702")
+set(androidemu_src android/base/AlignedBuf.cpp android/base/files/MemStream.cpp android/base/files/Stream.cpp android/base/files/StreamSerializing.cpp android/base/Pool.cpp android/base/ring_buffer.c android/base/StringFormat.cpp android/base/AndroidSubAllocator.cpp android/base/synchronization/AndroidMessageChannel.cpp android/base/threads/AndroidFunctorThread.cpp android/base/threads/AndroidThreadStore.cpp android/base/threads/AndroidThread_pthread.cpp android/base/threads/AndroidWorkPool.cpp android/base/Tracing.cpp android/utils/debug.c)
 android_add_shared_library(androidemu)
 target_include_directories(androidemu PRIVATE ${GOLDFISH_DEVICE_ROOT}/android-emu ${GOLDFISH_DEVICE_ROOT}/./host/include/libOpenglRender ${GOLDFISH_DEVICE_ROOT}/./system/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/guest)
 target_compile_definitions(androidemu PRIVATE "-DWITH_GLES2" "-DPLATFORM_SDK_VERSION=29" "-DGOLDFISH_HIDL_GRALLOC" "-DEMULATOR_OPENGL_POST_O=1" "-DHOST_BUILD" "-DANDROID" "-DGL_GLEXT_PROTOTYPES" "-DPAGE_SIZE=4096" "-DGOLDFISH_VULKAN" "-DLOG_TAG=\"androidemu\"")
diff --git a/android-emu/android/base/AndroidSubAllocator.cpp b/android-emu/android/base/AndroidSubAllocator.cpp
new file mode 100644
index 0000000..0b17a8a
--- /dev/null
+++ b/android-emu/android/base/AndroidSubAllocator.cpp
@@ -0,0 +1,240 @@
+// Copyright 2018 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 express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#include "android/base/AndroidSubAllocator.h"
+
+#include "android/base/address_space.h"
+#include "android/base/files/Stream.h"
+
+#include <iomanip>
+#include <sstream>
+#include <string>
+
+#include <log/log.h>
+
+namespace android {
+namespace base {
+namespace guest {
+
+class SubAllocator::Impl {
+public:
+    Impl(
+        void* _buffer,
+        uint64_t _totalSize,
+        uint64_t _pageSize) :
+        buffer(_buffer),
+        totalSize(_totalSize),
+        pageSize(_pageSize),
+        startAddr((uintptr_t)buffer),
+        endAddr(startAddr + totalSize) {
+
+        address_space_allocator_init(
+            &addr_alloc,
+            totalSize,
+            32);
+    }
+
+    ~Impl() {
+        address_space_allocator_destroy_nocleanup(&addr_alloc);
+    }
+
+    void clear() {
+        address_space_allocator_destroy_nocleanup(&addr_alloc);
+        address_space_allocator_init(
+            &addr_alloc,
+            totalSize,
+            32);
+    }
+
+    bool save(Stream* stream) {
+        address_space_allocator_iter_func_t allocatorSaver =
+            [](void* context, struct address_space_allocator* allocator) {
+                Stream* stream = reinterpret_cast<Stream*>(context);
+                stream->putBe32(allocator->size);
+                stream->putBe32(allocator->capacity);
+                stream->putBe64(allocator->total_bytes);
+            };
+        address_block_iter_func_t allocatorBlockSaver =
+            [](void* context, struct address_block* block) {
+                Stream* stream = reinterpret_cast<Stream*>(context);
+                stream->putBe64(block->offset);
+                stream->putBe64(block->size_available);
+            };
+        address_space_allocator_run(
+            &addr_alloc,
+            (void*)stream,
+            allocatorSaver,
+            allocatorBlockSaver);
+
+        stream->putBe64(pageSize);
+        stream->putBe64(totalSize);
+        stream->putBe32(allocCount);
+
+        return true;
+    }
+
+    bool load(Stream* stream) {
+        clear();
+        address_space_allocator_iter_func_t allocatorLoader =
+            [](void* context, struct address_space_allocator* allocator) {
+                Stream* stream = reinterpret_cast<Stream*>(context);
+                allocator->size = stream->getBe32();
+                allocator->capacity = stream->getBe32();
+                allocator->total_bytes = stream->getBe64();
+            };
+        address_block_iter_func_t allocatorBlockLoader =
+            [](void* context, struct address_block* block) {
+                Stream* stream = reinterpret_cast<Stream*>(context);
+                block->offset = stream->getBe64();
+                block->size_available = stream->getBe64();
+            };
+        address_space_allocator_run(
+            &addr_alloc,
+            (void*)stream,
+            allocatorLoader,
+            allocatorBlockLoader);
+
+        pageSize = stream->getBe64();
+        totalSize = stream->getBe64();
+        allocCount = stream->getBe32();
+
+        return true;
+    }
+
+    bool postLoad(void* postLoadBuffer) {
+        buffer = postLoadBuffer;
+        startAddr =
+            (uint64_t)(uintptr_t)postLoadBuffer;
+        return true;
+    }
+
+    void rangeCheck(const char* task, void* ptr) {
+        uint64_t addr = (uintptr_t)ptr;
+        if (addr < startAddr ||
+            addr > endAddr) {
+            std::stringstream ss;
+            ss << "SubAllocator " << task << ": ";
+            ss << "Out of range: " << std::hex << addr << " ";
+            ss << "Range: " <<
+                std::hex << startAddr << " " <<
+                std::hex << endAddr;
+            std::string msg = ss.str();
+            ALOGE("Fatal: %s\n", msg.c_str());
+        }
+    }
+
+    uint64_t getOffset(void* checkedPtr) {
+        uint64_t addr = (uintptr_t)checkedPtr;
+        return addr - startAddr;
+    }
+
+    bool free(void* ptr) {
+        if (!ptr) return false;
+
+        rangeCheck("free", ptr);
+        if (EINVAL == address_space_allocator_deallocate(
+            &addr_alloc, getOffset(ptr))) {
+            return false;
+        }
+
+        --allocCount;
+        return true;
+    }
+
+    void freeAll() {
+        address_space_allocator_reset(&addr_alloc);
+        allocCount = 0;
+    }
+
+    void* alloc(size_t wantedSize) {
+        if (wantedSize == 0) return nullptr;
+
+        uint64_t wantedSize64 =
+            (uint64_t)wantedSize;
+
+        size_t toPageSize =
+            pageSize *
+            ((wantedSize + pageSize - 1) / pageSize);
+
+        uint64_t offset =
+            address_space_allocator_allocate(
+                &addr_alloc, toPageSize);
+
+        if (offset == ANDROID_EMU_ADDRESS_SPACE_BAD_OFFSET) {
+            return nullptr;
+        }
+
+        ++allocCount;
+        return (void*)(uintptr_t)(startAddr + offset);
+    }
+
+    bool empty() const {
+        return allocCount == 0;
+    }
+
+    void* buffer;
+    uint64_t totalSize;
+    uint64_t pageSize;
+    uint64_t startAddr;
+    uint64_t endAddr;
+    struct address_space_allocator addr_alloc;
+    uint32_t allocCount = 0;
+};
+
+SubAllocator::SubAllocator(
+    void* buffer,
+    uint64_t totalSize,
+    uint64_t pageSize) :
+    mImpl(
+        new SubAllocator::Impl(buffer, totalSize, pageSize)) { }
+
+SubAllocator::~SubAllocator() {
+    delete mImpl;
+}
+
+// Snapshotting
+bool SubAllocator::save(Stream* stream) {
+    return mImpl->save(stream);
+}
+
+bool SubAllocator::load(Stream* stream) {
+    return mImpl->load(stream);
+}
+
+bool SubAllocator::postLoad(void* postLoadBuffer) {
+    return mImpl->postLoad(postLoadBuffer);
+}
+
+void* SubAllocator::alloc(size_t wantedSize) {
+    return mImpl->alloc(wantedSize);
+}
+
+bool SubAllocator::free(void* ptr) {
+    return mImpl->free(ptr);
+}
+
+void SubAllocator::freeAll() {
+    mImpl->freeAll();
+}
+
+uint64_t SubAllocator::getOffset(void* ptr) {
+    return mImpl->getOffset(ptr);
+}
+
+bool SubAllocator::empty() const {
+    return mImpl->empty();
+}
+
+} // namespace guest
+} // namespace base
+} // namespace android
diff --git a/android-emu/android/base/SubAllocator.h b/android-emu/android/base/AndroidSubAllocator.h
similarity index 86%
rename from android-emu/android/base/SubAllocator.h
rename to android-emu/android/base/AndroidSubAllocator.h
index b2363bd..8442137 100644
--- a/android-emu/android/base/SubAllocator.h
+++ b/android-emu/android/base/AndroidSubAllocator.h
@@ -20,6 +20,16 @@
 namespace android {
 namespace base {
 
+class Stream;
+
+} // namespace base
+} // namespace android
+
+namespace android {
+namespace base {
+namespace guest {
+
+
 // Class to create sub-allocations in an existing buffer. Similar interface to
 // Pool, but underlying mechanism is different as it's difficult to combine
 // same-size heaps in Pool with a preallocated buffer.
@@ -36,12 +46,20 @@
     // SubAllocator, but the prealloced buffer is not freed.
     ~SubAllocator();
 
+    // Snapshotting
+    bool save(Stream* stream);
+    bool load(Stream* stream);
+    bool postLoad(void* postLoadBuffer);
+
     // returns null if the allocation cannot be satisfied.
     void* alloc(size_t wantedSize);
-    void free(void* ptr);
+    // returns true if |ptr| came from alloc(), false otherwise
+    bool free(void* ptr);
     void freeAll();
     uint64_t getOffset(void* ptr);
 
+    bool empty() const;
+
     // Convenience function to allocate an array
     // of objects of type T.
     template <class T>
@@ -80,5 +98,6 @@
     Impl* mImpl = nullptr;
 };
 
+} // namespace guest
 } // namespace base
 } // namespace android
diff --git a/android-emu/android/base/SubAllocator.cpp b/android-emu/android/base/SubAllocator.cpp
deleted file mode 100644
index 99d7b78..0000000
--- a/android-emu/android/base/SubAllocator.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright 2018 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 express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-#include "android/base/SubAllocator.h"
-
-#include "android/base/address_space.h"
-
-#include <log/log.h>
-
-#include <iomanip>
-#include <sstream>
-#include <string>
-
-namespace android {
-namespace base {
-
-class SubAllocator::Impl {
-public:
-    Impl(
-        void* _buffer,
-        uint64_t _totalSize,
-        uint64_t _pageSize) :
-        buffer(_buffer),
-        totalSize(_totalSize),
-        pageSize(_pageSize),
-        startAddr((uintptr_t)buffer),
-        endAddr(startAddr + totalSize) {
-
-        address_space_allocator_init(
-            &addr_alloc,
-            totalSize,
-            32);
-    }
-
-    ~Impl() {
-        address_space_allocator_destroy(&addr_alloc);
-    }
-
-    void rangeCheck(const char* task, void* ptr) {
-        uint64_t addr = (uintptr_t)ptr;
-        if (addr < startAddr ||
-            addr > endAddr) {
-            std::stringstream ss;
-            ss << "SubAllocator " << task << ": ";
-            ss << "Out of range: " << std::hex << addr << " ";
-            ss << "Range: " <<
-                std::hex << startAddr << " " <<
-                std::hex << endAddr;
-            std::string msg = ss.str();
-            ALOGE("%s", msg.c_str());
-            abort();
-        }
-    }
-
-    uint64_t getOffset(void* checkedPtr) {
-        uint64_t addr = (uintptr_t)checkedPtr;
-        return addr - startAddr;
-    }
-
-    void free(void* ptr) {
-        if (!ptr) return;
-
-        rangeCheck("free", ptr);
-        address_space_allocator_deallocate(
-            &addr_alloc, getOffset(ptr));
-    }
-
-    void freeAll() {
-        address_space_allocator_reset(&addr_alloc);
-    }
-
-    void* alloc(size_t wantedSize) {
-        if (wantedSize == 0) return nullptr;
-
-        size_t toPageSize =
-            pageSize *
-            ((wantedSize + pageSize - 1) / pageSize);
-
-        uint64_t offset =
-            address_space_allocator_allocate(
-                &addr_alloc, toPageSize);
-
-        if (offset == ANDROID_EMU_ADDRESS_SPACE_BAD_OFFSET) {
-            return nullptr;
-        }
-
-        return (void*)(uintptr_t)(startAddr + offset);
-    }
-
-    void* buffer;
-    uint64_t totalSize;
-    uint64_t pageSize;
-    uint64_t startAddr;
-    uint64_t endAddr;
-    struct address_space_allocator addr_alloc;
-};
-
-SubAllocator::SubAllocator(
-    void* buffer,
-    uint64_t totalSize,
-    uint64_t pageSize) :
-    mImpl(
-        new SubAllocator::Impl(buffer, totalSize, pageSize)) { }
-
-SubAllocator::~SubAllocator() {
-    delete mImpl;
-}
-
-void* SubAllocator::alloc(size_t wantedSize) {
-    return mImpl->alloc(wantedSize);
-}
-
-void SubAllocator::free(void* ptr) {
-    mImpl->free(ptr);
-}
-
-void SubAllocator::freeAll() {
-    mImpl->freeAll();
-}
-
-uint64_t SubAllocator::getOffset(void* ptr) {
-    return mImpl->getOffset(ptr);
-}
-
-} // namespace base
-} // namespace android
diff --git a/android-emu/android/base/address_space.h b/android-emu/android/base/address_space.h
index 50c9bbd..e7b43fd 100644
--- a/android-emu/android/base/address_space.h
+++ b/android-emu/android/base/address_space.h
@@ -18,10 +18,15 @@
 #include <errno.h>
 #include <inttypes.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <string.h>
 
 ANDROID_BEGIN_HEADER
 
+#ifdef ADDRESS_SPACE_NAMESPACE
+namespace ADDRESS_SPACE_NAMESPACE {
+#endif
+
 // This is ported from goldfish_address_space, allowing it to be used for
 // general sub-allocations of any buffer range.
 // It is also a pure header library, so there are no compiler tricks needed
@@ -33,8 +38,13 @@
  */
 struct address_block {
     uint64_t offset;
-    uint64_t size : 63;
-    uint64_t available : 1;
+    union {
+        uint64_t size_available; /* VMSTATE_x does not support bit fields */
+        struct {
+            uint64_t size : 63;
+            uint64_t available : 1;
+        };
+    };
 };
 
 /* A dynamic array of address blocks, with the following invariant:
@@ -53,7 +63,6 @@
 
 /* The assert function to abort if something goes wrong. */
 static void address_space_assert(bool condition) {
-    (void)condition;
 #ifdef ANDROID_EMU_ADDRESS_SPACE_ASSERT_FUNC
     ANDROID_EMU_ADDRESS_SPACE_ASSERT_FUNC(condition);
 #else
@@ -61,7 +70,7 @@
 #endif
 }
 
-void* address_space_malloc0(size_t size) {
+static void* address_space_malloc0(size_t size) {
 #ifdef ANDROID_EMU_ADDRESS_SPACE_MALLOC0_FUNC
     return ANDROID_EMU_ADDRESS_SPACE_MALLOC0_FUNC(size);
 #else
@@ -71,7 +80,7 @@
 #endif
 }
 
-void* address_space_realloc(void* ptr, size_t size) {
+static void* address_space_realloc(void* ptr, size_t size) {
 #ifdef ANDROID_EMU_ADDRESS_SPACE_REALLOC_FUNC
     return ANDROID_EMU_ADDRESS_SPACE_REALLOC_FUNC(ptr, size);
 #else
@@ -80,7 +89,7 @@
 #endif
 }
 
-void address_space_free(void* ptr) {
+static void address_space_free(void* ptr) {
 #ifdef ANDROID_EMU_ADDRESS_SPACE_FREE_FUNC
     return ANDROID_EMU_ADDRESS_SPACE_FREE_FUNC(ptr);
 #else
@@ -302,7 +311,8 @@
 
     allocator->blocks =
         (struct address_block*)
-        address_space_malloc0(sizeof(struct address_block) * initial_capacity);
+        malloc(sizeof(struct address_block) * initial_capacity);
+    memset(allocator->blocks, 0, sizeof(struct address_block) * initial_capacity);
     address_space_assert(allocator->blocks);
 
     struct address_block *block = allocator->blocks;
@@ -328,6 +338,15 @@
     address_space_free(allocator->blocks);
 }
 
+/* Destroy function if we don't care what was previoulsy allocated.
+ * have been merged into one block.
+ */
+static void address_space_allocator_destroy_nocleanup(
+    struct address_space_allocator *allocator)
+{
+    address_space_free(allocator->blocks);
+}
+
 /* Resets the state of the allocator to the initial state without
  * performing any dynamic memory management. */
 static void address_space_allocator_reset(
@@ -343,4 +362,33 @@
     block->available = 1;
 }
 
+typedef void (*address_block_iter_func_t)(void* context, struct address_block*);
+typedef void (*address_space_allocator_iter_func_t)(void* context, struct address_space_allocator*);
+
+static void address_space_allocator_run(
+    struct address_space_allocator *allocator,
+    void* context,
+    address_space_allocator_iter_func_t allocator_func,
+    address_block_iter_func_t block_func)
+{
+    struct address_block *block = 0;
+    int size;
+    int i;
+
+    allocator_func(context, allocator);
+
+    block = allocator->blocks;
+    size = allocator->size;
+
+    address_space_assert(size >= 1);
+
+    for (i = 0; i < size; ++i, ++block) {
+        block_func(context, block);
+    }
+}
+
+#ifdef ADDRESS_SPACE_NAMESPACE
+}
+#endif
+
 ANDROID_END_HEADER
diff --git a/shared/OpenglCodecCommon/goldfish_address_space.h b/shared/OpenglCodecCommon/goldfish_address_space.h
index 9a7af71..de3bbbe 100644
--- a/shared/OpenglCodecCommon/goldfish_address_space.h
+++ b/shared/OpenglCodecCommon/goldfish_address_space.h
@@ -75,6 +75,7 @@
     ~GoldfishAddressSpaceBlock();
 
     bool allocate(GoldfishAddressSpaceBlockProvider *provider, size_t size);
+    bool claimShared(GoldfishAddressSpaceBlockProvider *provider, uint64_t offset, uint64_t size);
     uint64_t physAddr() const;
     uint64_t hostAddr() const;
     uint64_t offset() const { return m_offset; }
@@ -102,6 +103,7 @@
     uint64_t  m_host_addr;
     uint64_t  m_offset;
     uint64_t  m_size;
+    bool      m_is_shared_mapping;
 };
 
 class GoldfishAddressSpaceHostMemoryAllocator {
@@ -119,4 +121,40 @@
     GoldfishAddressSpaceBlockProvider m_provider;
 };
 
+// Convenience functions that run address space driver api without wrapping in
+// a class. Useful for when a client wants to manage the driver handle directly
+// (e.g., mmaping() more than one region associated with a single handle will
+// require different lifetime expectations versus GoldfishAddressSpaceBlock).
+
+// We also expose the ping info struct that is shared between host and guest.
+struct goldfish_address_space_ping {
+    uint64_t offset;
+    uint64_t size;
+    uint64_t metadata;
+    uint32_t version;
+    uint32_t wait_fd;
+    uint32_t wait_flags;
+    uint32_t direction;
+};
+
+address_space_handle_t goldfish_address_space_open();
+void goldfish_address_space_close(address_space_handle_t);
+
+bool goldfish_address_space_allocate(
+    address_space_handle_t, size_t size, uint64_t* phys_addr, uint64_t* offset);
+bool goldfish_address_space_free(
+    address_space_handle_t, uint64_t offset);
+
+bool goldfish_address_space_claim_shared(
+    address_space_handle_t, uint64_t offset, uint64_t size);
+bool goldfish_address_space_unclaim_shared(
+    address_space_handle_t, uint64_t offset);
+
+// pgoff is the offset into the page to return in the result
+void* goldfish_address_space_map(
+    address_space_handle_t, uint64_t offset, uint64_t size, uint64_t pgoff = 0);
+void goldfish_address_space_unmap(void* ptr, uint64_t size);
+
+bool goldfish_address_space_ping(address_space_handle_t, struct goldfish_address_space_ping*);
+
 #endif  // #ifndef ANDROID_INCLUDE_HARDWARE_GOLDFISH_ADDRESS_SPACE_H
diff --git a/shared/OpenglCodecCommon/goldfish_address_space_android.impl b/shared/OpenglCodecCommon/goldfish_address_space_android.impl
index 90fc097..9b0c744 100644
--- a/shared/OpenglCodecCommon/goldfish_address_space_android.impl
+++ b/shared/OpenglCodecCommon/goldfish_address_space_android.impl
@@ -41,14 +41,9 @@
     __u64 phys_addr;
 };
 
-struct goldfish_address_space_ping {
+struct goldfish_address_space_claim_shared {
     __u64 offset;
     __u64 size;
-    __u64 metadata;
-    __u32 version;
-    __u32 wait_fd;
-    __u32 wait_flags;
-    __u32 direction;
 };
 
 #define GOLDFISH_ADDRESS_SPACE_IOCTL_MAGIC		'G'
@@ -56,6 +51,8 @@
 #define GOLDFISH_ADDRESS_SPACE_IOCTL_ALLOCATE_BLOCK	GOLDFISH_ADDRESS_SPACE_IOCTL_OP(10, struct goldfish_address_space_allocate_block)
 #define GOLDFISH_ADDRESS_SPACE_IOCTL_DEALLOCATE_BLOCK	GOLDFISH_ADDRESS_SPACE_IOCTL_OP(11, __u64)
 #define GOLDFISH_ADDRESS_SPACE_IOCTL_PING		GOLDFISH_ADDRESS_SPACE_IOCTL_OP(12, struct goldfish_address_space_ping)
+#define GOLDFISH_ADDRESS_SPACE_IOCTL_CLAIM_SHARED		GOLDFISH_ADDRESS_SPACE_IOCTL_OP(13, struct goldfish_address_space_claim_shared)
+#define GOLDFISH_ADDRESS_SPACE_IOCTL_UNCLAIM_SHARED		GOLDFISH_ADDRESS_SPACE_IOCTL_OP(14, __u64)
 
 const char GOLDFISH_ADDRESS_SPACE_DEVICE_NAME[] = "/dev/goldfish_address_space";
 
@@ -92,6 +89,16 @@
     return ioctl_ping(fd, &request);
 }
 
+long ioctl_claim_shared(int fd, struct goldfish_address_space_claim_shared *request)
+{
+    return ::ioctl(fd, GOLDFISH_ADDRESS_SPACE_IOCTL_CLAIM_SHARED, request);
+}
+
+long ioctl_unclaim_shared(int fd, uint64_t offset)
+{
+    return ::ioctl(fd, GOLDFISH_ADDRESS_SPACE_IOCTL_UNCLAIM_SHARED, &offset);
+}
+
 }  // namespace
 
 GoldfishAddressSpaceBlockProvider::GoldfishAddressSpaceBlockProvider(uint64_t subdevice)
@@ -187,6 +194,7 @@
         m_offset = request.offset;
         m_size = request.size;
         m_handle = provider->m_handle;
+        m_is_shared_mapping = false;
 
         ALOGD("%s: ioctl allocate returned offset 0x%llx size 0x%llx\n", __func__,
                 (unsigned long long)m_offset,
@@ -196,6 +204,35 @@
     }
 }
 
+bool GoldfishAddressSpaceBlock::claimShared(GoldfishAddressSpaceBlockProvider *provider, uint64_t offset, uint64_t size)
+{
+    ALOGD("%s: Ask to claim region [0x%llx 0x%llx]\n", __func__,
+         (unsigned long long)offset,
+         (unsigned long long)offset + size);
+
+    destroy();
+
+    if (!provider->is_opened()) {
+        return false;
+    }
+
+    struct goldfish_address_space_claim_shared request;
+    request.offset = offset;
+    request.size = size;
+    long res = ioctl_claim_shared(provider->m_handle, &request);
+
+    if (res) {
+        return false;
+    }
+
+    m_offset = offset;
+    m_size = size;
+    m_handle = provider->m_handle;
+    m_is_shared_mapping = true;
+
+    return true;
+}
+
 uint64_t GoldfishAddressSpaceBlock::physAddr() const
 {
     return m_phys_addr;
@@ -246,12 +283,24 @@
     }
 
     if (m_size) {
-        const long res = ioctl_deallocate(m_handle, m_offset);
-        if (res) {
-            ALOGE("ioctl_deallocate failed, res=%ld", res);
-            ::abort();
+        long res = -EINVAL;
+
+        if (m_is_shared_mapping) {
+            res = ioctl_unclaim_shared(m_handle, m_offset);
+            if (res) {
+                ALOGE("ioctl_unclaim_shared failed, res=%ld", res);
+                ::abort();
+            }
+        } else {
+            res = ioctl_deallocate(m_handle, m_offset);
+            if (res) {
+                ALOGE("ioctl_deallocate failed, res=%ld", res);
+                ::abort();
+            }
         }
 
+        m_is_shared_mapping = false;
+
         m_phys_addr = 0;
         m_host_addr = 0;
         m_offset = 0;
@@ -355,3 +404,99 @@
 
     block->replace(NULL);
 }
+
+address_space_handle_t goldfish_address_space_open() {
+    return ::open(GOLDFISH_ADDRESS_SPACE_DEVICE_NAME, O_RDWR);
+}
+
+void goldfish_address_space_close(address_space_handle_t handle) {
+    ::close(handle);
+}
+
+bool goldfish_address_space_allocate(
+    address_space_handle_t handle,
+    size_t size, uint64_t* phys_addr, uint64_t* offset) {
+
+    struct goldfish_address_space_allocate_block request;
+    ::memset(&request, 0, sizeof(request));
+    request.size = size;
+
+    long res = ioctl_allocate(handle, &request);
+
+    if (res) return false;
+
+    *phys_addr = request.phys_addr;
+    *offset = request.offset;
+    return true;
+}
+
+bool goldfish_address_space_free(
+    address_space_handle_t handle, uint64_t offset) {
+
+    long res = ioctl_deallocate(handle, offset);
+
+    if (res) {
+        ALOGE("ioctl_deallocate failed, res=%ld", res);
+        ::abort();
+    }
+
+    return true;
+}
+
+bool goldfish_address_space_claim_shared(
+    address_space_handle_t handle, uint64_t offset, uint64_t size) {
+
+    struct goldfish_address_space_claim_shared request;
+    request.offset = offset;
+    request.size = size;
+    long res = ioctl_claim_shared(handle, &request);
+
+    if (res) return false;
+
+    return true;
+}
+
+bool goldfish_address_space_unclaim_shared(
+        address_space_handle_t handle, uint64_t offset) {
+    long res = ioctl_unclaim_shared(handle, offset);
+    if (res) {
+        ALOGE("ioctl_unclaim_shared failed, res=%ld", res);
+        ::abort();
+    }
+
+    return true;
+}
+
+// pgoff is the offset into the page to return in the result
+void* goldfish_address_space_map(
+    address_space_handle_t handle,
+    uint64_t offset, uint64_t size,
+    uint64_t pgoff) {
+
+    void* res = ::mmap64(0, size, PROT_WRITE, MAP_SHARED, handle, offset);
+
+    if (res == MAP_FAILED) {
+        ALOGE("%s: failed to map. errno: %d\n", __func__, errno);
+        return 0;
+    }
+
+    return (void*)(((char*)res) + (uintptr_t)(pgoff & (PAGE_SIZE - 1)));
+}
+
+void goldfish_address_space_unmap(void* ptr, uint64_t size) {
+    void* pagePtr = (void*)(((uintptr_t)ptr) & ~(PAGE_SIZE - 1));
+    ::munmap(pagePtr, size);
+}
+
+bool goldfish_address_space_ping(
+    address_space_handle_t handle,
+    struct goldfish_address_space_ping* ping) {
+    long res = ioctl_ping(handle, ping);
+
+    if (res) {
+        ALOGE("%s: ping failed: errno: %d\n", __func__, errno);
+        return false;
+    }
+
+    return true;
+}
diff --git a/shared/OpenglCodecCommon/goldfish_address_space_fuchsia.impl b/shared/OpenglCodecCommon/goldfish_address_space_fuchsia.impl
index 7373ac2..e597374 100644
--- a/shared/OpenglCodecCommon/goldfish_address_space_fuchsia.impl
+++ b/shared/OpenglCodecCommon/goldfish_address_space_fuchsia.impl
@@ -120,6 +120,15 @@
     return true;
 }
 
+bool GoldfishAddressSpaceBlock::claimShared(GoldfishAddressSpaceBlockProvider *provider, uint64_t offset, uint64_t size)
+{
+    ALOGD("%s: Ask to claim region [0x%llx 0x%llx]\n", __func__,
+         (unsigned long long)offset,
+         (unsigned long long)offset + size);
+    ALOGE("%s: FATAL: claimShared not supported!\n");
+    abort();
+}
+
 uint64_t GoldfishAddressSpaceBlock::physAddr() const
 {
     return m_phys_addr;
@@ -205,3 +214,60 @@
 void GoldfishAddressSpaceHostMemoryAllocator::hostFree(GoldfishAddressSpaceBlock *block)
 {
 }
+
+// TODO: Implement address_space_handle_t interface
+address_space_handle_t goldfish_address_space_open() {
+    ALOGE("%s: not implemented!\n", __func__);
+    abort();
+}
+
+void goldfish_address_space_close(address_space_handle_t handle) {
+    ALOGE("%s: not implemented!\n", __func__);
+    abort();
+}
+
+bool goldfish_address_space_allocate(
+    address_space_handle_t,
+    size_t, uint64_t*, uint64_t*) {
+    ALOGE("%s: not implemented!\n", __func__);
+    abort();
+}
+
+bool goldfish_address_space_free(
+    address_space_handle_t, uint64_t) {
+    ALOGE("%s: not implemented!\n", __func__);
+    abort();
+}
+
+bool goldfish_address_space_claim_shared(
+    address_space_handle_t, uint64_t, uint64_t) {
+    ALOGE("%s: not implemented!\n", __func__);
+    abort();
+}
+
+bool goldfish_address_space_unclaim_shared(
+    address_space_handle_t, uint64_t) {
+    ALOGE("%s: not implemented!\n", __func__);
+    abort();
+}
+
+// pgoff is the offset into the page to return in the result
+void* goldfish_address_space_map(
+    address_space_handle_t,
+    uint64_t, uint64_t,
+    uint64_t) {
+    ALOGE("%s: not implemented!\n", __func__);
+    abort();
+}
+
+void goldfish_address_space_unmap(void*, uint64_t) {
+    ALOGE("%s: not implemented!\n", __func__);
+    abort();
+}
+
+bool goldfish_address_space_ping(
+    address_space_handle_t handle,
+    struct goldfish_address_space_ping* ping) {
+    ALOGE("%s: not implemented!\n", __func__);
+    abort();
+}
diff --git a/shared/OpenglCodecCommon/goldfish_address_space_host.impl b/shared/OpenglCodecCommon/goldfish_address_space_host.impl
index 7d07d8b..d5567ad 100644
--- a/shared/OpenglCodecCommon/goldfish_address_space_host.impl
+++ b/shared/OpenglCodecCommon/goldfish_address_space_host.impl
@@ -13,15 +13,17 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include <memory>
 #include "android/emulation/hostdevices/HostAddressSpace.h"
 
+#include <memory>
+
 #if PLATFORM_SDK_VERSION < 26
 #include <cutils/log.h>
 #else
 #include <log/log.h>
 #endif
 
+#include <errno.h>
 #include "goldfish_address_space.h"
 
 namespace {
@@ -84,7 +86,8 @@
     , m_phys_addr(0)
     , m_host_addr(0)
     , m_offset(0)
-    , m_size(0) {}
+    , m_size(0)
+    , m_is_shared_mapping(false) {}
 
 GoldfishAddressSpaceBlock::~GoldfishAddressSpaceBlock()
 {
@@ -98,6 +101,7 @@
     m_host_addr = rhs.m_host_addr;
     m_offset = rhs.m_offset;
     m_size = rhs.m_size;
+    m_is_shared_mapping = rhs.m_is_shared_mapping;
     m_handle = rhs.m_handle;
     return *this;
 }
@@ -118,6 +122,36 @@
         HostAddressSpaceDevice::get()->allocBlock(
             provider->m_handle, size, &m_phys_addr);
     m_handle = provider->m_handle;
+    m_is_shared_mapping = false;
+
+    return true;
+}
+
+bool GoldfishAddressSpaceBlock::claimShared(GoldfishAddressSpaceBlockProvider *provider, uint64_t offset, uint64_t size)
+{
+    ALOGD("%s: Ask to claim region [0x%llx 0x%llx]\n", __func__,
+         (unsigned long long)offset,
+         (unsigned long long)offset + size);
+
+    destroy();
+
+    if (!provider->is_opened()) {
+        return false;
+    }
+
+    int claimRes = HostAddressSpaceDevice::get()->claimShared(
+            provider->m_handle, offset, size);
+
+    if (claimRes) {
+        ALOGE("%s: failed to claim shared region. Error: %d\n", __func__, claimRes);
+        return false;
+    }
+
+    m_size = size;
+    m_offset = offset;
+    m_handle = provider->m_handle;
+    m_is_shared_mapping = true;
+    m_phys_addr = HostAddressSpaceDevice::get()->offsetToPhysAddr(m_offset);
 
     return true;
 }
@@ -132,6 +166,8 @@
     return m_host_addr;
 }
 
+// In the host implementation:
+// mmap: is done by interpreting |host_addr| as the actual host address.
 void *GoldfishAddressSpaceBlock::mmap(uint64_t host_addr)
 {
     if (m_size == 0) {
@@ -162,7 +198,11 @@
     }
 
     if (m_size) {
-        HostAddressSpaceDevice::get()->freeBlock(m_handle, m_offset);
+        if (m_is_shared_mapping) {
+            HostAddressSpaceDevice::get()->unclaimShared(m_handle, m_offset);
+        } else {
+            HostAddressSpaceDevice::get()->freeBlock(m_handle, m_offset);
+        }
         m_phys_addr = 0;
         m_host_addr = 0;
         m_offset = 0;
@@ -248,3 +288,82 @@
     block->replace(NULL);
 }
 
+address_space_handle_t goldfish_address_space_open() {
+    return HostAddressSpaceDevice::get()->open();
+}
+
+void goldfish_address_space_close(address_space_handle_t handle) {
+    HostAddressSpaceDevice::get()->close(handle);
+}
+
+bool goldfish_address_space_allocate(
+    address_space_handle_t handle,
+    size_t size, uint64_t* phys_addr, uint64_t* offset) {
+
+    *offset =
+        HostAddressSpaceDevice::get()->allocBlock(
+            handle, size, phys_addr);
+
+    return true;
+}
+
+bool goldfish_address_space_free(
+    address_space_handle_t handle, uint64_t offset) {
+    HostAddressSpaceDevice::get()->freeBlock(handle, offset);
+    return true;
+}
+
+bool goldfish_address_space_claim_shared(
+    address_space_handle_t handle, uint64_t offset, uint64_t size) {
+
+    int claimRes = HostAddressSpaceDevice::get()->claimShared(
+        handle, offset, size);
+
+    if (claimRes) {
+        ALOGE("%s: failed to claim shared region. Error: %d\n", __func__, claimRes);
+        return false;
+    }
+
+    return true;
+}
+
+bool goldfish_address_space_unclaim_shared(
+        address_space_handle_t handle, uint64_t offset) {
+    HostAddressSpaceDevice::get()->unclaimShared(handle, offset);
+    return true;
+}
+
+// pgoff is the offset into the page to return in the result
+void* goldfish_address_space_map(
+    address_space_handle_t handle,
+    uint64_t offset, uint64_t size,
+    uint64_t pgoff) {
+
+    (void)size;
+
+    void* res = HostAddressSpaceDevice::get()->
+        getHostAddr(
+            HostAddressSpaceDevice::get()->offsetToPhysAddr(offset));
+
+    if (!res) {
+        ALOGE("%s: failed to map. errno: %d\n", __func__, errno);
+        return nullptr;
+    }
+
+    return (void*)(((char*)res) + (uintptr_t)(pgoff & (PAGE_SIZE - 1)));
+}
+
+// same address space
+void goldfish_address_space_unmap(void*, uint64_t) { }
+
+bool goldfish_address_space_ping(
+    address_space_handle_t handle,
+    struct goldfish_address_space_ping* ping) {
+
+    AddressSpaceDevicePingInfo* asHostPingInfo =
+        reinterpret_cast<AddressSpaceDevicePingInfo*>(ping);
+
+    HostAddressSpaceDevice::get()->ping(handle, asHostPingInfo);
+
+    return true;
+}
diff --git a/shared/OpenglCodecCommon/gralloc_cb.h b/shared/OpenglCodecCommon/gralloc_cb.h
index 2d80f26..d58b56e 100644
--- a/shared/OpenglCodecCommon/gralloc_cb.h
+++ b/shared/OpenglCodecCommon/gralloc_cb.h
@@ -17,7 +17,103 @@
 #ifndef __GRALLOC_CB_H__
 #define __GRALLOC_CB_H__
 
-#include "gralloc_cb_old.h"
-typedef cb_handle_old_t cb_handle_t;
+#include <cutils/native_handle.h>
+#include "qemu_pipe.h"
+
+const uint32_t CB_HANDLE_MAGIC_MASK = 0xFFFFFFF0;
+const uint32_t CB_HANDLE_MAGIC_BASE = 0xABFABFA0;
+
+#define CB_HANDLE_NUM_INTS(nfd) \
+    ((sizeof(*this)-sizeof(native_handle_t)-nfd*sizeof(int32_t))/sizeof(int32_t))
+
+struct cb_handle_t : public native_handle_t {
+    cb_handle_t(int32_t p_bufferFd,
+                QEMU_PIPE_HANDLE p_hostHandleRefCountFd,
+                uint32_t p_magic,
+                uint32_t p_hostHandle,
+                int32_t p_usage,
+                int32_t p_width,
+                int32_t p_height,
+                int32_t p_format,
+                int32_t p_glFormat,
+                int32_t p_glType,
+                uint32_t p_bufSize,
+                void* p_bufPtr)
+        : bufferFd(p_bufferFd),
+          hostHandleRefCountFd(p_hostHandleRefCountFd),
+          magic(p_magic),
+          hostHandle(p_hostHandle),
+          usage(p_usage),
+          width(p_width),
+          height(p_height),
+          format(p_format),
+          glFormat(p_glFormat),
+          glType(p_glType),
+          bufferSize(p_bufSize),
+          lockedLeft(0),
+          lockedTop(0),
+          lockedWidth(0),
+          lockedHeight(0) {
+        version = sizeof(native_handle);
+        numFds = ((bufferFd >= 0) ? 1 : 0) + (qemu_pipe_valid(hostHandleRefCountFd) ? 1 : 0);
+        numInts = 0; // has to be overwritten in children classes
+        setBufferPtr(p_bufPtr);
+    }
+
+    void* getBufferPtr() const {
+        const uint64_t addr = (uint64_t(bufferPtrHi) << 32) | bufferPtrLo;
+        return reinterpret_cast<void*>(static_cast<uintptr_t>(addr));
+    }
+
+    void setBufferPtr(void* ptr) {
+        const uint64_t addr = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(ptr));
+        bufferPtrLo = uint32_t(addr);
+        bufferPtrHi = uint32_t(addr >> 32);
+    }
+
+    uint32_t allocatedSize() const {
+        return getBufferPtr() ? bufferSize : 0;
+    }
+
+    bool isValid() const {
+        return (version == sizeof(native_handle))
+               && (magic & CB_HANDLE_MAGIC_MASK) == CB_HANDLE_MAGIC_BASE;
+    }
+
+    static cb_handle_t* from(void* p) {
+        if (!p) { return NULL; }
+        cb_handle_t* cb = static_cast<cb_handle_t*>(p);
+        return cb->isValid() ? cb : NULL;
+    }
+
+    static const cb_handle_t* from(const void* p) {
+        return from(const_cast<void*>(p));
+    }
+
+    static cb_handle_t* from_unconst(const void* p) {
+        return from(const_cast<void*>(p));
+    }
+
+    // fds
+    int32_t bufferFd;       // underlying buffer file handle
+    QEMU_PIPE_HANDLE hostHandleRefCountFd; // guest side refcounter to hostHandle
+
+    // ints
+    uint32_t magic;         // magic number in order to validate a pointer
+    uint32_t hostHandle;    // the host reference to this buffer
+    int32_t  usage;         // usage bits the buffer was created with
+    int32_t  width;         // buffer width
+    int32_t  height;        // buffer height
+    int32_t  format;        // real internal pixel format format
+    int32_t  glFormat;      // OpenGL format enum used for host h/w color buffer
+    int32_t  glType;        // OpenGL type enum used when uploading to host
+    uint32_t bufferSize;    // buffer size and location
+    uint32_t bufferPtrLo;
+    uint32_t bufferPtrHi;
+    int32_t  lockedLeft;    // region of buffer locked for s/w write
+    int32_t  lockedTop;
+    int32_t  lockedWidth;
+    int32_t  lockedHeight;
+};
 
 #endif //__GRALLOC_CB_H__
diff --git a/shared/OpenglCodecCommon/gralloc_cb_common.h b/shared/OpenglCodecCommon/gralloc_cb_common.h
deleted file mode 100644
index 94ada2f..0000000
--- a/shared/OpenglCodecCommon/gralloc_cb_common.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-* Copyright 2011 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 express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-#ifndef __GRALLOC_CB_COMMON_H__
-#define __GRALLOC_CB_COMMON_H__
-
-// Tell the emulator which gralloc formats
-// need special handling.
-enum EmulatorFrameworkFormat {
-    FRAMEWORK_FORMAT_GL_COMPATIBLE = 0,
-    FRAMEWORK_FORMAT_YV12 = 1,
-    FRAMEWORK_FORMAT_YUV_420_888 = 2,              // (Y+)(U+)(V+)
-};
-
-#endif //__GRALLOC_CB_COMMON_H__
diff --git a/shared/OpenglCodecCommon/gralloc_cb_old.h b/shared/OpenglCodecCommon/gralloc_cb_old.h
deleted file mode 100644
index 1c14579..0000000
--- a/shared/OpenglCodecCommon/gralloc_cb_old.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
-* Copyright 2011 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 express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-#ifndef __GRALLOC_CB_OLD_H__
-#define __GRALLOC_CB_OLD_H__
-
-#include <hardware/hardware.h>
-#include <hardware/gralloc.h>
-#include <cutils/native_handle.h>
-
-#include "gralloc_cb_common.h"
-#include "qemu_pipe.h"
-
-#define BUFFER_HANDLE_MAGIC ((int)0xabfabfab)
-#define CB_HANDLE_NUM_INTS(nfds) (int)((sizeof(cb_handle_old_t) - (nfds)*sizeof(int)) / sizeof(int))
-
-//
-// Our buffer handle structure
-//
-struct cb_handle_old_t : public native_handle {
-
-    cb_handle_old_t(int p_fd, int p_ashmemSize, int p_usage,
-                    int p_width, int p_height,
-                    int p_format, int p_glFormat, int p_glType) :
-        fd(p_fd),
-        magic(BUFFER_HANDLE_MAGIC),
-        usage(p_usage),
-        width(p_width),
-        height(p_height),
-        format(p_format),
-        glFormat(p_glFormat),
-        glType(p_glType),
-        ashmemSize(p_ashmemSize),
-        ashmemBase(0),
-        ashmemBasePid(0),
-        mappedPid(0),
-        lockedLeft(0),
-        lockedTop(0),
-        lockedWidth(0),
-        lockedHeight(0),
-        hostHandle(0)
-    {
-        refcount_pipe_fd = QEMU_PIPE_INVALID_HANDLE;
-        version = sizeof(native_handle);
-        numFds = 0;
-        numInts = CB_HANDLE_NUM_INTS(numFds);
-    }
-
-    ~cb_handle_old_t() {
-        magic = 0;
-    }
-
-    static cb_handle_old_t* from_native_handle(native_handle* n) {
-        return static_cast<cb_handle_old_t*>(n);
-    }
-
-    static const cb_handle_old_t* from_native_handle(const native_handle* n) {
-        return static_cast<const cb_handle_old_t*>(n);
-    }
-
-    static cb_handle_old_t* from_raw_pointer(void* ptr) {
-        return from_native_handle(static_cast<native_handle*>(ptr));
-    }
-
-    static const cb_handle_old_t* from_raw_pointer(const void* ptr) {
-        return from_native_handle(static_cast<const native_handle*>(ptr));
-    }
-
-    void setFd(int p_fd) {
-        if (p_fd >= 0) {
-            numFds++;
-        }
-        fd = p_fd;
-        numInts = CB_HANDLE_NUM_INTS(numFds);
-    }
-
-    bool hasRefcountPipe() {
-        return qemu_pipe_valid(refcount_pipe_fd);
-    }
-
-    void setRefcountPipeFd(QEMU_PIPE_HANDLE fd) {
-        if (qemu_pipe_valid(fd)) {
-            numFds++;
-        }
-        refcount_pipe_fd = fd;
-        numInts = CB_HANDLE_NUM_INTS(numFds);
-    }
-
-    static bool validate(const cb_handle_old_t* hnd) {
-        return (hnd &&
-                hnd->version == sizeof(native_handle) &&
-                hnd->magic == BUFFER_HANDLE_MAGIC &&
-                hnd->numInts == CB_HANDLE_NUM_INTS(hnd->numFds));
-    }
-
-    bool canBePosted() {
-        return (0 != (usage & GRALLOC_USAGE_HW_FB));
-    }
-
-    uint32_t allocationSize() const {
-        return ashmemBase ? ashmemSize : 0;
-    }
-
-    // file-descriptors
-    int fd;  // ashmem fd (-1 of ashmem region did not allocated, i.e. no SW access needed)
-    QEMU_PIPE_HANDLE refcount_pipe_fd; // goldfish pipe service for gralloc refcounting fd.
-
-    // ints
-    int magic;              // magic number in order to validate a pointer to be a cb_handle_old_t
-    int usage;              // usage bits the buffer was created with
-    int width;              // buffer width
-    int height;             // buffer height
-    int format;             // real internal pixel format format
-    int glFormat;           // OpenGL format enum used for host h/w color buffer
-    int glType;             // OpenGL type enum used when uploading to host
-    int ashmemSize;         // ashmem region size for the buffer (0 unless is HW_FB buffer or
-                            //                                    s/w access is needed)
-    union {
-        intptr_t ashmemBase;    // CPU address of the mapped ashmem region
-        uint64_t padding;       // enforce same size on 32-bit/64-bit
-    } __attribute__((aligned(8)));
-
-    int ashmemBasePid;      // process id which mapped the ashmem region
-    int mappedPid;          // process id which succeeded gralloc_register call
-    int lockedLeft;         // region of buffer locked for s/w write
-    int lockedTop;
-    int lockedWidth;
-    int lockedHeight;
-    uint32_t hostHandle;
-};
-
-
-#endif //__GRALLOC_CB_OLD_H__
diff --git a/system/OpenglSystemCommon/HostConnection.cpp b/system/OpenglSystemCommon/HostConnection.cpp
index 28b3bfc..2cd1d38 100644
--- a/system/OpenglSystemCommon/HostConnection.cpp
+++ b/system/OpenglSystemCommon/HostConnection.cpp
@@ -112,12 +112,12 @@
 public:
     uint32_t getHostHandle(native_handle_t const* handle)
     {
-        return cb_handle_t::from_native_handle(handle)->hostHandle;
+        return cb_handle_t::from(handle)->hostHandle;
     }
 
     int getFormat(native_handle_t const* handle)
     {
-        return cb_handle_t::from_native_handle(handle)->format;
+        return cb_handle_t::from(handle)->format;
     }
 };
 
diff --git a/system/gralloc/gralloc_common.h b/system/gralloc/gralloc_common.h
index 574e659..6dba9cd 100644
--- a/system/gralloc/gralloc_common.h
+++ b/system/gralloc/gralloc_common.h
@@ -17,6 +17,14 @@
 #ifndef __GRALLOC_COMMON_H__
 #define __GRALLOC_COMMON_H__
 
+// Tell the emulator which gralloc formats
+// need special handling.
+enum EmulatorFrameworkFormat {
+    FRAMEWORK_FORMAT_GL_COMPATIBLE = 0,
+    FRAMEWORK_FORMAT_YV12 = 1,
+    FRAMEWORK_FORMAT_YUV_420_888 = 2,              // (Y+)(U+)(V+)
+};
+
 #ifndef GL_RGBA16F
 #define GL_RGBA16F                        0x881A
 #endif // GL_RGBA16F
diff --git a/system/gralloc/gralloc_old.cpp b/system/gralloc/gralloc_old.cpp
index eecf698..99d6033 100644
--- a/system/gralloc/gralloc_old.cpp
+++ b/system/gralloc/gralloc_old.cpp
@@ -21,11 +21,12 @@
 #include <errno.h>
 #include <dlfcn.h>
 #include <sys/mman.h>
+#include <hardware/gralloc.h>
 
 #if PLATFORM_SDK_VERSION < 28
-#include "gralloc_cb_old.h"
+#include "gralloc_cb.h"
 #else
-#include "../../shared/OpenglCodecCommon/gralloc_cb_old.h"
+#include "../../shared/OpenglCodecCommon/gralloc_cb.h"
 #endif
 
 #include "gralloc_common.h"
@@ -81,8 +82,69 @@
 static const bool isHidlGralloc = false;
 #endif
 
-int32_t* getOpenCountPtr(cb_handle_old_t* cb) {
-    return ((int32_t*)cb->ashmemBase) + 1;
+const uint32_t CB_HANDLE_MAGIC_OLD = CB_HANDLE_MAGIC_BASE | 0x1;
+
+struct cb_handle_old_t : public cb_handle_t {
+    cb_handle_old_t(int p_fd, int p_ashmemSize, int p_usage,
+                    int p_width, int p_height,
+                    int p_format, int p_glFormat, int p_glType)
+            : cb_handle_t(p_fd,
+                          QEMU_PIPE_INVALID_HANDLE,
+                          CB_HANDLE_MAGIC_OLD,
+                          0,
+                          p_usage,
+                          p_width,
+                          p_height,
+                          p_format,
+                          p_glFormat,
+                          p_glType,
+                          p_ashmemSize,
+                          nullptr),
+              ashmemBasePid(0),
+              mappedPid(0) {
+        numInts = CB_HANDLE_NUM_INTS(numFds);
+    }
+
+    bool hasRefcountPipe() const {
+        return qemu_pipe_valid(hostHandleRefCountFd);
+    }
+
+    void setRefcountPipeFd(QEMU_PIPE_HANDLE fd) {
+        if (qemu_pipe_valid(fd)) {
+            numFds++;
+        }
+        hostHandleRefCountFd = fd;
+        numInts = CB_HANDLE_NUM_INTS(numFds);
+    }
+
+    bool canBePosted() const {
+        return (0 != (usage & GRALLOC_USAGE_HW_FB));
+    }
+
+    bool isValid() const {
+        return (version == sizeof(native_handle)) && (magic == CB_HANDLE_MAGIC_OLD);
+    }
+
+    static cb_handle_old_t* from(void* p) {
+        if (!p) { return nullptr; }
+        cb_handle_old_t* cb = static_cast<cb_handle_old_t*>(p);
+        return cb->isValid() ? cb : nullptr;
+    }
+
+    static const cb_handle_old_t* from(const void* p) {
+        return from(const_cast<void*>(p));
+    }
+
+    static cb_handle_old_t* from_unconst(const void* p) {
+        return from(const_cast<void*>(p));
+    }
+
+    int32_t ashmemBasePid;      // process id which mapped the ashmem region
+    int32_t mappedPid;          // process id which succeeded gralloc_register call
+};
+
+int32_t* getOpenCountPtr(const cb_handle_old_t* cb) {
+    return ((int32_t*)cb->getBufferPtr()) + 1;
 }
 
 uint32_t getAshmemColorOffset(cb_handle_old_t* cb) {
@@ -331,7 +393,7 @@
     dump_regions(rcEnc);
 #endif
 
-    get_mem_region((void*)cb->ashmemBase);
+    get_mem_region(cb->getBufferPtr());
 
 #if DEBUG
     dump_regions(rcEnc);
@@ -345,13 +407,13 @@
     dump_regions(rcEnc);
 #endif
 
-    const bool should_unmap = put_mem_region(rcEnc, (void*)cb->ashmemBase);
+    const bool should_unmap = put_mem_region(rcEnc, cb->getBufferPtr());
 
 #if DEBUG
     dump_regions(rcEnc);
 #endif
 
-    put_gralloc_region(rcEnc, cb->ashmemSize);
+    put_gralloc_region(rcEnc, cb->bufferSize);
 
     return should_unmap;
 }
@@ -365,21 +427,21 @@
 
 static int map_buffer(cb_handle_old_t *cb, void **vaddr)
 {
-    if (cb->fd < 0 || cb->ashmemSize <= 0) {
+    if (cb->bufferFd < 0) {
         return -EINVAL;
     }
 
-    void *addr = mmap(0, cb->ashmemSize, PROT_READ | PROT_WRITE,
-                      MAP_SHARED, cb->fd, 0);
+    void *addr = mmap(0, cb->bufferSize, PROT_READ | PROT_WRITE,
+                      MAP_SHARED, cb->bufferFd, 0);
     if (addr == MAP_FAILED) {
         ALOGE("%s: failed to map ashmem region!", __FUNCTION__);
         return -errno;
     }
 
-    cb->ashmemBase = intptr_t(addr);
+    cb->setBufferPtr(addr);
     cb->ashmemBasePid = getpid();
     D("%s: %p mapped ashmem base %p size %d\n", __FUNCTION__,
-      cb, cb->ashmemBase, cb->ashmemSize);
+      cb, addr, cb->bufferSize);
 
     *vaddr = addr;
     return 0;
@@ -788,7 +850,6 @@
             delete cb;
             return err;
         }
-        cb->setFd(fd);
     }
 
     const bool hasDMA = has_DMA_support(rcEnc);
@@ -865,20 +926,20 @@
 {
     DEFINE_AND_VALIDATE_HOST_CONNECTION;
 
-    cb_handle_old_t *cb = (cb_handle_old_t *)handle;
-    if (!cb_handle_old_t::validate((cb_handle_old_t*)cb)) {
-        ERR("gralloc_free: invalid handle");
+    const cb_handle_old_t *cb = cb_handle_old_t::from(handle);
+    if (!cb) {
+        ERR("gralloc_free: invalid handle %p", handle);
         return -EINVAL;
     }
 
     D("%s: for buf %p ptr %p size %d\n",
-      __FUNCTION__, handle, cb->ashmemBase, cb->ashmemSize);
+      __FUNCTION__, handle, cb->getBufferPtr(), cb->bufferSize);
 
     if (cb->hostHandle && !cb->hasRefcountPipe()) {
         int32_t openCount = 1;
         int32_t* openCountPtr = &openCount;
 
-        if (isHidlGralloc && cb->ashmemBase) {
+        if (isHidlGralloc && cb->getBufferPtr()) {
             openCountPtr = getOpenCountPtr(cb);
         }
 
@@ -896,17 +957,17 @@
     //
     // detach and unmap ashmem area if present
     //
-    if (cb->fd > 0) {
-        if (cb->ashmemSize > 0 && cb->ashmemBase) {
-            D("%s: unmapped %p", __FUNCTION__, cb->ashmemBase);
-            munmap((void *)cb->ashmemBase, cb->ashmemSize);
-            put_gralloc_region(rcEnc, cb->ashmemSize);
+    if (cb->bufferFd > 0) {
+        if (cb->bufferSize > 0 && cb->getBufferPtr()) {
+            D("%s: unmapped %p", __FUNCTION__, cb->getBufferPtr());
+            munmap(cb->getBufferPtr(), cb->bufferSize);
+            put_gralloc_region(rcEnc, cb->bufferSize);
         }
-        close(cb->fd);
+        close(cb->bufferFd);
     }
 
-    if(qemu_pipe_valid(cb->refcount_pipe_fd)) {
-        qemu_pipe_close(cb->refcount_pipe_fd);
+    if(qemu_pipe_valid(cb->hostHandleRefCountFd)) {
+        qemu_pipe_close(cb->hostHandleRefCountFd);
     }
     D("%s: done", __FUNCTION__);
     // remove it from the allocated list
@@ -949,9 +1010,14 @@
 static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
 {
     fb_device_t *fbdev = (fb_device_t *)dev;
-    cb_handle_old_t *cb = (cb_handle_old_t *)buffer;
-
-    if (!fbdev || !cb_handle_old_t::validate(cb) || !cb->canBePosted()) {
+    if (!fbdev) {
+        return -EINVAL;
+    }
+    const cb_handle_old_t *cb = cb_handle_old_t::from(buffer);
+    if (!cb) {
+        return -EINVAL;
+    }
+    if (!cb->canBePosted()) {
         return -EINVAL;
     }
 
@@ -959,7 +1025,7 @@
     DEFINE_AND_VALIDATE_HOST_CONNECTION;
 
     // increment the post count of the buffer
-    intptr_t *postCountPtr = (intptr_t *)cb->ashmemBase;
+    int32_t *postCountPtr = (int32_t *)cb->getBufferPtr();
     if (!postCountPtr) {
         // This should not happen
         return -EINVAL;
@@ -1047,9 +1113,12 @@
     }
 
     private_module_t *gr = (private_module_t *)module;
-    cb_handle_old_t *cb = (cb_handle_old_t *)handle;
+    if (!gr) {
+        return -EINVAL;
+    }
 
-    if (!gr || !cb_handle_old_t::validate(cb)) {
+    cb_handle_old_t *cb = cb_handle_old_t::from_unconst(handle);
+    if (!cb) {
         ERR("gralloc_register_buffer(%p): invalid buffer", cb);
         return -EINVAL;
     }
@@ -1068,7 +1137,7 @@
     // if the color buffer has ashmem region and it is not mapped in this
     // process map it now.
     //
-    if (cb->ashmemSize > 0 && cb->mappedPid != getpid()) {
+    if (cb->bufferSize > 0 && cb->mappedPid != getpid()) {
         void *vaddr;
         int err = map_buffer(cb, &vaddr);
         if (err) {
@@ -1083,7 +1152,7 @@
         }
     }
 
-    if (cb->ashmemSize > 0) {
+    if (cb->bufferSize > 0) {
         get_ashmem_region(rcEnc, cb);
     }
 
@@ -1100,9 +1169,12 @@
     }
 
     private_module_t *gr = (private_module_t *)module;
-    cb_handle_old_t *cb = (cb_handle_old_t *)handle;
+    if (!gr) {
+        return -EINVAL;
+    }
 
-    if (!gr || !cb_handle_old_t::validate(cb)) {
+    cb_handle_old_t *cb = cb_handle_old_t::from_unconst(handle);
+    if (!cb) {
         ERR("gralloc_unregister_buffer(%p): invalid buffer", cb);
         return -EINVAL;
     }
@@ -1116,7 +1188,7 @@
         if (isHidlGralloc) {
             // Queue up another rcCloseColorBuffer if applicable.
             // invariant: have ashmem.
-            if (cb->ashmemSize > 0 && cb->mappedPid == getpid()) {
+            if (cb->bufferSize > 0 && cb->mappedPid == getpid()) {
                 int32_t* openCountPtr = getOpenCountPtr(cb);
                 if (*openCountPtr == -1) {
                     D("%s: revenge of the rcCloseColorBuffer!", __func__);
@@ -1132,16 +1204,16 @@
     // unmap ashmem region if it was previously mapped in this process
     // (through register_buffer)
     //
-    if (cb->ashmemSize > 0 && cb->mappedPid == getpid()) {
+    if (cb->bufferSize > 0 && cb->mappedPid == getpid()) {
         const bool should_unmap = put_ashmem_region(rcEnc, cb);
         if (!should_unmap) goto done;
 
-        int err = munmap((void *)cb->ashmemBase, cb->ashmemSize);
+        int err = munmap(cb->getBufferPtr(), cb->bufferSize);
         if (err) {
             ERR("gralloc_unregister_buffer(%p): unmap failed", cb);
             return -EINVAL;
         }
-        cb->ashmemBase = 0;
+        cb->bufferSize = 0;
         cb->mappedPid = 0;
         D("%s: Unregister buffer previous mapped to pid %d", __FUNCTION__, getpid());
     }
@@ -1161,9 +1233,12 @@
     }
 
     private_module_t *gr = (private_module_t *)module;
-    cb_handle_old_t *cb = (cb_handle_old_t *)handle;
+    if (!gr) {
+        return -EINVAL;
+    }
 
-    if (!gr || !cb_handle_old_t::validate(cb)) {
+    cb_handle_old_t *cb = cb_handle_old_t::from_unconst(handle);
+    if (!cb) {
         ALOGE("gralloc_lock bad handle\n");
         return -EINVAL;
     }
@@ -1223,11 +1298,11 @@
     if (cb->canBePosted() || sw_read || sw_write ||
             hw_cam_write || hw_cam_read ||
             hw_vid_enc_read) {
-        if (cb->ashmemBasePid != getpid() || !cb->ashmemBase) {
+        if (cb->ashmemBasePid != getpid() || !cb->getBufferPtr()) {
             return -EACCES;
         }
 
-        cpu_addr = (void *)(cb->ashmemBase + getAshmemColorOffset(cb));
+        cpu_addr = (void *)((char*)cb->getBufferPtr() + getAshmemColorOffset(cb));
     }
 
     if (cb->hostHandle) {
@@ -1291,7 +1366,7 @@
         }
 
         if (has_DMA_support(rcEnc)) {
-            gralloc_dmaregion_register_ashmem(rcEnc, cb->ashmemSize);
+            gralloc_dmaregion_register_ashmem(rcEnc, cb->bufferSize);
         }
         hostCon->unlock();
     }
@@ -1327,10 +1402,13 @@
     }
 
     private_module_t *gr = (private_module_t *)module;
-    cb_handle_old_t *cb = (cb_handle_old_t *)handle;
+    if (!gr) {
+        return -EINVAL;
+    }
 
-    if (!gr || !cb_handle_old_t::validate(cb)) {
-        ALOGD("%s: invalid gr or cb handle. -EINVAL", __FUNCTION__);
+    cb_handle_old_t *cb = cb_handle_old_t::from_unconst(handle);
+    if (!cb) {
+        ALOGD("%s: invalid cb handle. -EINVAL", __FUNCTION__);
         return -EINVAL;
     }
 
@@ -1344,14 +1422,13 @@
         DEFINE_AND_VALIDATE_HOST_CONNECTION;
         hostCon->lock();
 
-        void *cpu_addr = (void *)(cb->ashmemBase + getAshmemColorOffset(cb));
+        char *cpu_addr = (char*)cb->getBufferPtr() + getAshmemColorOffset(cb);
 
-        char* rgb_addr = (char *)cpu_addr;
         if (cb->lockedWidth < cb->width || cb->lockedHeight < cb->height) {
-            updateHostColorBuffer(cb, true, rgb_addr);
+            updateHostColorBuffer(cb, true, cpu_addr);
         }
         else {
-            updateHostColorBuffer(cb, false, rgb_addr);
+            updateHostColorBuffer(cb, false, cpu_addr);
         }
 
         hostCon->unlock();
@@ -1380,8 +1457,12 @@
     }
 
     private_module_t *gr = (private_module_t *)module;
-    cb_handle_old_t *cb = (cb_handle_old_t *)handle;
-    if (!gr || !cb_handle_old_t::validate(cb)) {
+    if (!gr) {
+        return -EINVAL;
+    }
+
+    cb_handle_old_t *cb = cb_handle_old_t::from_unconst(handle);
+    if (!cb) {
         ALOGE("%s: bad colorbuffer handle. -EINVAL", __FUNCTION__);
         return -EINVAL;
     }
diff --git a/system/hwc2/EmuHWC2.cpp b/system/hwc2/EmuHWC2.cpp
index 0f5c631..edf6397 100644
--- a/system/hwc2/EmuHWC2.cpp
+++ b/system/hwc2/EmuHWC2.cpp
@@ -392,8 +392,7 @@
     if (mHandle != nullptr) {
         mGralloc->unregisterBuffer(mGralloc, mHandle);
         mAllocDev->free(mAllocDev, mHandle);
-        ALOGI("free targetCb %u",
-            cb_handle_t::from_raw_pointer(mHandle)->hostHandle);
+        ALOGI("free targetCb %u", cb_handle_t::from(mHandle)->hostHandle);
     }
 }
 
@@ -408,9 +407,9 @@
                                &mHandle, &stride);
         assert(ret == 0 && "Fail to allocate target ColorBuffer");
         mGralloc->registerBuffer(mGralloc, mHandle);
-        ALOGI("targetCb %u", cb_handle_t::from_raw_pointer(mHandle)->hostHandle);
+        ALOGI("targetCb %u", cb_handle_t::from(mHandle)->hostHandle);
     }
-    return cb_handle_t::from_raw_pointer(mHandle)->hostHandle;
+    return cb_handle_t::from(mHandle)->hostHandle;
 }
 
 // Display functions
@@ -814,7 +813,7 @@
                           __FUNCTION__, (uint32_t)layer->getId());
                 }
                 const cb_handle_t *cb =
-                    cb_handle_t::from_raw_pointer(layer->getLayerBuffer().getBuffer());
+                    cb_handle_t::from(layer->getLayerBuffer().getBuffer());
                 if (cb != nullptr) {
                     l->cbHandle = cb->hostHandle;
                 }
@@ -924,7 +923,7 @@
         int32_t acquireFence, int32_t /*dataspace*/, hwc_region_t /*damage*/) {
     ALOGVV("%s", __FUNCTION__);
 
-    const cb_handle_t *cb = cb_handle_t::from_raw_pointer(target);
+    const cb_handle_t *cb = cb_handle_t::from(target);
     ALOGV("%s: display(%u) buffer handle %p cb %d, acquireFence %d", __FUNCTION__,
           (uint32_t)mId, target, cb->hostHandle, acquireFence);
     std::unique_lock<std::mutex> lock(mStateMutex);
diff --git a/system/vulkan_enc/AndroidHardwareBuffer.cpp b/system/vulkan_enc/AndroidHardwareBuffer.cpp
index e2f2ad1..0a71d6d 100644
--- a/system/vulkan_enc/AndroidHardwareBuffer.cpp
+++ b/system/vulkan_enc/AndroidHardwareBuffer.cpp
@@ -111,9 +111,12 @@
 
     const native_handle_t *handle =
        AHardwareBuffer_getNativeHandle(buffer);
-    const cb_handle_t* cb_handle = cb_handle_t::from_native_handle(handle);
-    uint32_t colorBufferHandle = cb_handle->hostHandle;
+    const cb_handle_t* cb_handle = cb_handle_t::from(handle);
+    if (!cb_handle) {
+        return VK_ERROR_INVALID_EXTERNAL_HANDLE;
+    }
 
+    uint32_t colorBufferHandle = cb_handle->hostHandle;
     if (!colorBufferHandle) {
         return VK_ERROR_INVALID_EXTERNAL_HANDLE;
     }
@@ -128,7 +131,7 @@
     }
 
     pProperties->memoryTypeBits = memoryTypeBits;
-    pProperties->allocationSize = cb_handle->allocationSize();
+    pProperties->allocationSize = cb_handle->allocatedSize();
 
     return VK_SUCCESS;
 }
@@ -164,9 +167,12 @@
 
     const native_handle_t *handle =
        AHardwareBuffer_getNativeHandle(info->buffer);
-    const cb_handle_t* cb_handle = cb_handle_t::from_native_handle(handle);
-    uint32_t colorBufferHandle = cb_handle->hostHandle;
+    const cb_handle_t* cb_handle = cb_handle_t::from(handle);
+    if (!cb_handle) {
+        return VK_ERROR_INVALID_EXTERNAL_HANDLE;
+    }
 
+    uint32_t colorBufferHandle = cb_handle->hostHandle;
     if (!colorBufferHandle) {
         return VK_ERROR_INVALID_EXTERNAL_HANDLE;
     }
diff --git a/system/vulkan_enc/HostVisibleMemoryVirtualization.cpp b/system/vulkan_enc/HostVisibleMemoryVirtualization.cpp
index 2780d2a..b6bd91a 100644
--- a/system/vulkan_enc/HostVisibleMemoryVirtualization.cpp
+++ b/system/vulkan_enc/HostVisibleMemoryVirtualization.cpp
@@ -14,7 +14,7 @@
 // limitations under the License.
 #include "HostVisibleMemoryVirtualization.h"
 
-#include "android/base/SubAllocator.h"
+#include "android/base/AndroidSubAllocator.h"
 
 #include "Resources.h"
 #include "VkEncoder.h"
@@ -23,7 +23,7 @@
 
 #include <set>
 
-using android::base::SubAllocator;
+using android::base::guest::SubAllocator;
 
 namespace goldfish_vk {
 
@@ -296,7 +296,7 @@
     memset(toFree, 0x0, sizeof(SubAlloc));
 }
 
-bool canSubAlloc(android::base::SubAllocator* subAlloc, VkDeviceSize size) {
+bool canSubAlloc(android::base::guest::SubAllocator* subAlloc, VkDeviceSize size) {
     auto ptr = subAlloc->alloc(size);
     if (!ptr) return false;
     subAlloc->free(ptr);
diff --git a/system/vulkan_enc/HostVisibleMemoryVirtualization.h b/system/vulkan_enc/HostVisibleMemoryVirtualization.h
index ad25353..84e39bb 100644
--- a/system/vulkan_enc/HostVisibleMemoryVirtualization.h
+++ b/system/vulkan_enc/HostVisibleMemoryVirtualization.h
@@ -20,9 +20,11 @@
 
 namespace android {
 namespace base {
+namespace guest {
 
 class SubAllocator;
 
+} // namespace guest
 } // namespace base
 } // namespace android
 
@@ -81,7 +83,7 @@
     VkDeviceSize allocSize = 0;
     VkDeviceSize mappedSize = 0;
     uint8_t* mappedPtr = nullptr;
-    android::base::SubAllocator* subAlloc = nullptr;
+    android::base::guest::SubAllocator* subAlloc = nullptr;
 };
 
 VkResult finishHostMemAllocInit(
@@ -106,7 +108,7 @@
 
     VkDeviceMemory baseMemory = VK_NULL_HANDLE;
     VkDeviceSize baseOffset = 0;
-    android::base::SubAllocator* subAlloc = nullptr;
+    android::base::guest::SubAllocator* subAlloc = nullptr;
     VkDeviceMemory subMemory = VK_NULL_HANDLE;
 };
 
@@ -117,5 +119,5 @@
 
 void subFreeHostMemory(SubAlloc* toFree);
 
-bool canSubAlloc(android::base::SubAllocator* subAlloc, VkDeviceSize size);
+bool canSubAlloc(android::base::guest::SubAllocator* subAlloc, VkDeviceSize size);
 } // namespace goldfish_vk
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index 5dcc579..6109534 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -890,10 +890,15 @@
 
         std::vector<const char*> allowedExtensionNames = {
             "VK_KHR_maintenance1",
+            "VK_KHR_maintenance2",
+            "VK_KHR_maintenance3",
             "VK_KHR_get_memory_requirements2",
             "VK_KHR_dedicated_allocation",
             "VK_KHR_bind_memory2",
             "VK_KHR_sampler_ycbcr_conversion",
+            "VK_KHR_shader_float16_int8",
+            "VK_AMD_gpu_shader_half_float",
+            "VK_NV_shader_subgroup_partitioned",
 #ifdef VK_USE_PLATFORM_ANDROID_KHR
             "VK_KHR_external_semaphore",
             "VK_KHR_external_semaphore_fd",
@@ -902,8 +907,6 @@
             "VK_KHR_external_fence",
             "VK_KHR_external_fence_fd",
 #endif
-            // "VK_KHR_maintenance2",
-            // "VK_KHR_maintenance3",
             // TODO:
             // VK_KHR_external_memory_capabilities
         };
@@ -1836,7 +1839,7 @@
             ALOGD("%s: Import AHardwareBulffer", __func__);
             const native_handle_t *handle =
                 AHardwareBuffer_getNativeHandle(ahw);
-            const cb_handle_t* cb_handle = cb_handle_t::from_native_handle(handle);
+            const cb_handle_t* cb_handle = cb_handle_t::from(handle);
             importCbInfo.colorBuffer = cb_handle->hostHandle;
             vk_append_struct(&structChainIter, &importCbInfo);
         }
@@ -3463,9 +3466,7 @@
             return;
         }
 
-        const cb_handle_t* cb_handle =
-            cb_handle_t::from_raw_pointer(nativeInfo->handle);
-
+        const cb_handle_t* cb_handle = cb_handle_t::from(nativeInfo->handle);
         if (!cb_handle) return;
 
         VkNativeBufferANDROID* nativeInfoOut =
diff --git a/system/vulkan_enc/vk_format_info.h b/system/vulkan_enc/vk_format_info.h
index 8c0b7dc..dd9c99b 100644
--- a/system/vulkan_enc/vk_format_info.h
+++ b/system/vulkan_enc/vk_format_info.h
@@ -27,6 +27,9 @@
 #define VK_FORMAT_INFO_H
 
 #include <stdbool.h>
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+#include <system/graphics.h>
+#endif
 #include <vulkan/vulkan.h>
 #include <vndk/hardware_buffer.h>