Loading libs/gui/view/Surface.cpp +47 −5 Original line number Diff line number Diff line Loading @@ -16,17 +16,59 @@ #define LOG_TAG "Surface" #include <gui/view/Surface.h> #include <android/binder_libbinder.h> #include <android/binder_parcel.h> #include <android/native_window.h> #include <binder/Parcel.h> #include <utils/Log.h> #include <gui/IGraphicBufferProducer.h> #include <gui/Surface.h> #include <gui/view/Surface.h> #include <system/window.h> #include <utils/Log.h> namespace android { namespace view { // Since this is a parcelable utility and we want to keep the wire format stable, only build this // when building the system libgui to detect any issues loading the wrong libgui from // libnativewindow #if (!defined(__ANDROID_APEX__) && !defined(__ANDROID_VNDK__)) extern "C" status_t android_view_Surface_writeToParcel(ANativeWindow* _Nonnull window, Parcel* _Nonnull parcel) { int value; int err = (*window->query)(window, NATIVE_WINDOW_CONCRETE_TYPE, &value); if (err != OK || value != NATIVE_WINDOW_SURFACE) { ALOGE("Error: ANativeWindow is not backed by Surface"); return STATUS_BAD_VALUE; } // Use a android::view::Surface to parcelize the window android::view::Surface shimSurface; shimSurface.graphicBufferProducer = android::Surface::getIGraphicBufferProducer(window); shimSurface.surfaceControlHandle = android::Surface::getSurfaceControlHandle(window); return shimSurface.writeToParcel(parcel); } extern "C" status_t android_view_Surface_readFromParcel( const Parcel* _Nonnull parcel, ANativeWindow* _Nullable* _Nonnull outWindow) { // Use a android::view::Surface to unparcel the window android::view::Surface shimSurface; status_t ret = shimSurface.readFromParcel(parcel); if (ret != OK) { ALOGE("%s: Error: Failed to create android::view::Surface from AParcel", __FUNCTION__); return STATUS_BAD_VALUE; } auto surface = sp<android::Surface>::make(shimSurface.graphicBufferProducer, false, shimSurface.surfaceControlHandle); ANativeWindow* anw = surface.get(); ANativeWindow_acquire(anw); *outWindow = anw; return STATUS_OK; } #endif status_t Surface::writeToParcel(Parcel* parcel) const { return writeToParcel(parcel, false); } Loading libs/nativewindow/ANativeWindow.cpp +49 −35 Original line number Diff line number Diff line Loading @@ -24,14 +24,49 @@ #include <private/android/AHardwareBufferHelpers.h> #include <android/binder_libbinder.h> #include <dlfcn.h> #include <log/log.h> #include <ui/GraphicBuffer.h> #include <gui/Surface.h> #include <gui/view/Surface.h> #include <android/binder_libbinder.h> using namespace android; #if defined(__ANDROID_APEX__) || defined(__ANDROID_VNDK__) #error libnativewindow can only be built for system #endif using android_view_Surface_writeToParcel = status_t (*)(ANativeWindow* _Nonnull window, Parcel* _Nonnull parcel); using android_view_Surface_readFromParcel = status_t (*)(const Parcel* _Nonnull parcel, ANativeWindow* _Nullable* _Nonnull outWindow); struct SurfaceParcelables { android_view_Surface_writeToParcel write = nullptr; android_view_Surface_readFromParcel read = nullptr; }; const SurfaceParcelables* getSurfaceParcelFunctions() { static SurfaceParcelables funcs = []() -> SurfaceParcelables { SurfaceParcelables ret; void* dl = dlopen("libgui.so", RTLD_NOW); LOG_ALWAYS_FATAL_IF(!dl, "Failed to find libgui.so"); ret.write = (android_view_Surface_writeToParcel)dlsym(dl, "android_view_Surface_writeToParcel"); LOG_ALWAYS_FATAL_IF(!ret.write, "libgui.so missing android_view_Surface_writeToParcel; " "loaded wrong libgui?"); ret.read = (android_view_Surface_readFromParcel)dlsym(dl, "android_view_Surface_readFromParcel"); LOG_ALWAYS_FATAL_IF(!ret.read, "libgui.so missing android_view_Surface_readFromParcel; " "loaded wrong libgui?"); return ret; }(); return &funcs; } static int32_t query(ANativeWindow* window, int what) { int value; int res = window->query(window, what, &value); Loading Loading @@ -64,13 +99,6 @@ static bool isDataSpaceValid(ANativeWindow* window, int32_t dataSpace) { return false; } } static sp<IGraphicBufferProducer> IGraphicBufferProducer_from_ANativeWindow(ANativeWindow* window) { return Surface::getIGraphicBufferProducer(window); } static sp<IBinder> SurfaceControlHandle_from_ANativeWindow(ANativeWindow* window) { return Surface::getSurfaceControlHandle(window); } /************************************************************************************************** * NDK Loading Loading @@ -348,38 +376,24 @@ int ANativeWindow_setAutoPrerotation(ANativeWindow* window, bool autoPrerotation binder_status_t ANativeWindow_readFromParcel( const AParcel* _Nonnull parcel, ANativeWindow* _Nullable* _Nonnull outWindow) { const Parcel* nativeParcel = AParcel_viewPlatformParcel(parcel); // Use a android::view::Surface to unparcel the window std::shared_ptr<android::view::Surface> shimSurface = std::shared_ptr<android::view::Surface>(); status_t ret = shimSurface->readFromParcel(nativeParcel); if (ret != OK) { ALOGE("%s: Error: Failed to create android::view::Surface from AParcel", __FUNCTION__); return STATUS_BAD_VALUE; auto funcs = getSurfaceParcelFunctions(); if (funcs->read == nullptr) { ALOGE("Failed to load Surface_readFromParcel implementation"); return STATUS_FAILED_TRANSACTION; } sp<Surface> surface = sp<Surface>::make( shimSurface->graphicBufferProducer, false, shimSurface->surfaceControlHandle); ANativeWindow* anw = surface.get(); ANativeWindow_acquire(anw); *outWindow = anw; return STATUS_OK; const Parcel* nativeParcel = AParcel_viewPlatformParcel(parcel); return funcs->read(nativeParcel, outWindow); } binder_status_t ANativeWindow_writeToParcel( ANativeWindow* _Nonnull window, AParcel* _Nonnull parcel) { int value; int err = (*window->query)(window, NATIVE_WINDOW_CONCRETE_TYPE, &value); if (err != OK || value != NATIVE_WINDOW_SURFACE) { ALOGE("Error: ANativeWindow is not backed by Surface"); return STATUS_BAD_VALUE; auto funcs = getSurfaceParcelFunctions(); if (funcs->write == nullptr) { ALOGE("Failed to load Surface_writeToParcel implementation"); return STATUS_FAILED_TRANSACTION; } // Use a android::view::Surface to parcelize the window std::shared_ptr<android::view::Surface> shimSurface = std::shared_ptr<android::view::Surface>(); shimSurface->graphicBufferProducer = IGraphicBufferProducer_from_ANativeWindow(window); shimSurface->surfaceControlHandle = SurfaceControlHandle_from_ANativeWindow(window); Parcel* nativeParcel = AParcel_viewPlatformParcel(parcel); return shimSurface->writeToParcel(nativeParcel); return funcs->write(window, nativeParcel); } /************************************************************************************************** Loading Loading
libs/gui/view/Surface.cpp +47 −5 Original line number Diff line number Diff line Loading @@ -16,17 +16,59 @@ #define LOG_TAG "Surface" #include <gui/view/Surface.h> #include <android/binder_libbinder.h> #include <android/binder_parcel.h> #include <android/native_window.h> #include <binder/Parcel.h> #include <utils/Log.h> #include <gui/IGraphicBufferProducer.h> #include <gui/Surface.h> #include <gui/view/Surface.h> #include <system/window.h> #include <utils/Log.h> namespace android { namespace view { // Since this is a parcelable utility and we want to keep the wire format stable, only build this // when building the system libgui to detect any issues loading the wrong libgui from // libnativewindow #if (!defined(__ANDROID_APEX__) && !defined(__ANDROID_VNDK__)) extern "C" status_t android_view_Surface_writeToParcel(ANativeWindow* _Nonnull window, Parcel* _Nonnull parcel) { int value; int err = (*window->query)(window, NATIVE_WINDOW_CONCRETE_TYPE, &value); if (err != OK || value != NATIVE_WINDOW_SURFACE) { ALOGE("Error: ANativeWindow is not backed by Surface"); return STATUS_BAD_VALUE; } // Use a android::view::Surface to parcelize the window android::view::Surface shimSurface; shimSurface.graphicBufferProducer = android::Surface::getIGraphicBufferProducer(window); shimSurface.surfaceControlHandle = android::Surface::getSurfaceControlHandle(window); return shimSurface.writeToParcel(parcel); } extern "C" status_t android_view_Surface_readFromParcel( const Parcel* _Nonnull parcel, ANativeWindow* _Nullable* _Nonnull outWindow) { // Use a android::view::Surface to unparcel the window android::view::Surface shimSurface; status_t ret = shimSurface.readFromParcel(parcel); if (ret != OK) { ALOGE("%s: Error: Failed to create android::view::Surface from AParcel", __FUNCTION__); return STATUS_BAD_VALUE; } auto surface = sp<android::Surface>::make(shimSurface.graphicBufferProducer, false, shimSurface.surfaceControlHandle); ANativeWindow* anw = surface.get(); ANativeWindow_acquire(anw); *outWindow = anw; return STATUS_OK; } #endif status_t Surface::writeToParcel(Parcel* parcel) const { return writeToParcel(parcel, false); } Loading
libs/nativewindow/ANativeWindow.cpp +49 −35 Original line number Diff line number Diff line Loading @@ -24,14 +24,49 @@ #include <private/android/AHardwareBufferHelpers.h> #include <android/binder_libbinder.h> #include <dlfcn.h> #include <log/log.h> #include <ui/GraphicBuffer.h> #include <gui/Surface.h> #include <gui/view/Surface.h> #include <android/binder_libbinder.h> using namespace android; #if defined(__ANDROID_APEX__) || defined(__ANDROID_VNDK__) #error libnativewindow can only be built for system #endif using android_view_Surface_writeToParcel = status_t (*)(ANativeWindow* _Nonnull window, Parcel* _Nonnull parcel); using android_view_Surface_readFromParcel = status_t (*)(const Parcel* _Nonnull parcel, ANativeWindow* _Nullable* _Nonnull outWindow); struct SurfaceParcelables { android_view_Surface_writeToParcel write = nullptr; android_view_Surface_readFromParcel read = nullptr; }; const SurfaceParcelables* getSurfaceParcelFunctions() { static SurfaceParcelables funcs = []() -> SurfaceParcelables { SurfaceParcelables ret; void* dl = dlopen("libgui.so", RTLD_NOW); LOG_ALWAYS_FATAL_IF(!dl, "Failed to find libgui.so"); ret.write = (android_view_Surface_writeToParcel)dlsym(dl, "android_view_Surface_writeToParcel"); LOG_ALWAYS_FATAL_IF(!ret.write, "libgui.so missing android_view_Surface_writeToParcel; " "loaded wrong libgui?"); ret.read = (android_view_Surface_readFromParcel)dlsym(dl, "android_view_Surface_readFromParcel"); LOG_ALWAYS_FATAL_IF(!ret.read, "libgui.so missing android_view_Surface_readFromParcel; " "loaded wrong libgui?"); return ret; }(); return &funcs; } static int32_t query(ANativeWindow* window, int what) { int value; int res = window->query(window, what, &value); Loading Loading @@ -64,13 +99,6 @@ static bool isDataSpaceValid(ANativeWindow* window, int32_t dataSpace) { return false; } } static sp<IGraphicBufferProducer> IGraphicBufferProducer_from_ANativeWindow(ANativeWindow* window) { return Surface::getIGraphicBufferProducer(window); } static sp<IBinder> SurfaceControlHandle_from_ANativeWindow(ANativeWindow* window) { return Surface::getSurfaceControlHandle(window); } /************************************************************************************************** * NDK Loading Loading @@ -348,38 +376,24 @@ int ANativeWindow_setAutoPrerotation(ANativeWindow* window, bool autoPrerotation binder_status_t ANativeWindow_readFromParcel( const AParcel* _Nonnull parcel, ANativeWindow* _Nullable* _Nonnull outWindow) { const Parcel* nativeParcel = AParcel_viewPlatformParcel(parcel); // Use a android::view::Surface to unparcel the window std::shared_ptr<android::view::Surface> shimSurface = std::shared_ptr<android::view::Surface>(); status_t ret = shimSurface->readFromParcel(nativeParcel); if (ret != OK) { ALOGE("%s: Error: Failed to create android::view::Surface from AParcel", __FUNCTION__); return STATUS_BAD_VALUE; auto funcs = getSurfaceParcelFunctions(); if (funcs->read == nullptr) { ALOGE("Failed to load Surface_readFromParcel implementation"); return STATUS_FAILED_TRANSACTION; } sp<Surface> surface = sp<Surface>::make( shimSurface->graphicBufferProducer, false, shimSurface->surfaceControlHandle); ANativeWindow* anw = surface.get(); ANativeWindow_acquire(anw); *outWindow = anw; return STATUS_OK; const Parcel* nativeParcel = AParcel_viewPlatformParcel(parcel); return funcs->read(nativeParcel, outWindow); } binder_status_t ANativeWindow_writeToParcel( ANativeWindow* _Nonnull window, AParcel* _Nonnull parcel) { int value; int err = (*window->query)(window, NATIVE_WINDOW_CONCRETE_TYPE, &value); if (err != OK || value != NATIVE_WINDOW_SURFACE) { ALOGE("Error: ANativeWindow is not backed by Surface"); return STATUS_BAD_VALUE; auto funcs = getSurfaceParcelFunctions(); if (funcs->write == nullptr) { ALOGE("Failed to load Surface_writeToParcel implementation"); return STATUS_FAILED_TRANSACTION; } // Use a android::view::Surface to parcelize the window std::shared_ptr<android::view::Surface> shimSurface = std::shared_ptr<android::view::Surface>(); shimSurface->graphicBufferProducer = IGraphicBufferProducer_from_ANativeWindow(window); shimSurface->surfaceControlHandle = SurfaceControlHandle_from_ANativeWindow(window); Parcel* nativeParcel = AParcel_viewPlatformParcel(parcel); return shimSurface->writeToParcel(nativeParcel); return funcs->write(window, nativeParcel); } /************************************************************************************************** Loading