Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 68671533 authored by Craig Donner's avatar Craig Donner
Browse files

Create graphic buffer using binder interfaces

Using binder interfaces rather than directly allocating the buffer prevents
SELinux warnings.

Bug: 29402015

Change-Id: I26616dcabf46b5419f0841873faaa6a3ee87ff68
parent 46eee7d1
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -31,7 +31,7 @@ LOCAL_SRC_FILES:= \
	EGL/Loader.cpp 	       \
	EGL/Loader.cpp 	       \
#
#


LOCAL_SHARED_LIBRARIES += libcutils libutils liblog libui
LOCAL_SHARED_LIBRARIES += libbinder libcutils libutils liblog libui
LOCAL_MODULE:= libEGL
LOCAL_MODULE:= libEGL
LOCAL_LDFLAGS += -Wl,--exclude-libs=ALL
LOCAL_LDFLAGS += -Wl,--exclude-libs=ALL
LOCAL_SHARED_LIBRARIES += libdl
LOCAL_SHARED_LIBRARIES += libdl
+66 −5
Original line number Original line Diff line number Diff line
@@ -33,6 +33,8 @@
#include <cutils/properties.h>
#include <cutils/properties.h>
#include <cutils/memory.h>
#include <cutils/memory.h>


#include <gui/ISurfaceComposer.h>

#include <ui/GraphicBuffer.h>
#include <ui/GraphicBuffer.h>


#include <utils/KeyedVector.h>
#include <utils/KeyedVector.h>
@@ -40,6 +42,10 @@
#include <utils/String8.h>
#include <utils/String8.h>
#include <utils/Trace.h>
#include <utils/Trace.h>


#include "binder/Binder.h"
#include "binder/Parcel.h"
#include "binder/IServiceManager.h"

#include "../egl_impl.h"
#include "../egl_impl.h"
#include "../hooks.h"
#include "../hooks.h"


@@ -1872,18 +1878,73 @@ EGLClientBuffer eglCreateNativeClientBufferANDROID(const EGLint *attrib_list)
        return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0);
        return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0);
    }
    }


    GraphicBuffer* gBuffer = new GraphicBuffer(width, height, format, usage);
#define CHECK_ERROR_CONDITION(message) \
    const status_t err = gBuffer->initCheck();
    if (err != NO_ERROR) { \
        ALOGE(message); \
        goto error_condition; \
    }

    // The holder is used to destroy the buffer if an error occurs.
    GraphicBuffer* gBuffer = new GraphicBuffer();
    sp<IServiceManager> sm = defaultServiceManager();
    sp<IBinder> surfaceFlinger = sm->getService(String16("SurfaceFlinger"));
    sp<IBinder> allocator;
    Parcel sc_data, sc_reply, data, reply;
    status_t err = NO_ERROR;
    if (sm == NULL) {
        ALOGE("Unable to connect to ServiceManager");
        goto error_condition;
    }

    // Obtain an allocator.
    if (surfaceFlinger == NULL) {
        ALOGE("Unable to connect to SurfaceFlinger");
        goto error_condition;
    }
    sc_data.writeInterfaceToken(String16("android.ui.ISurfaceComposer"));
    err = surfaceFlinger->transact(
            BnSurfaceComposer::CREATE_GRAPHIC_BUFFER_ALLOC, sc_data, &sc_reply);
    CHECK_ERROR_CONDITION("Unable to obtain allocator from SurfaceFlinger");
    allocator = sc_reply.readStrongBinder();

    if (allocator == NULL) {
        ALOGE("Unable to obtain an ISurfaceComposer");
        goto error_condition;
    }
    data.writeInterfaceToken(String16("android.ui.IGraphicBufferAlloc"));
    err = data.writeUint32(width);
    CHECK_ERROR_CONDITION("Unable to write width");
    err = data.writeUint32(height);
    CHECK_ERROR_CONDITION("Unable to write height");
    err = data.writeInt32(static_cast<int32_t>(format));
    CHECK_ERROR_CONDITION("Unable to write format");
    err = data.writeUint32(usage);
    CHECK_ERROR_CONDITION("Unable to write usage");
    err = allocator->transact(IBinder::FIRST_CALL_TRANSACTION, data,
            &reply);
    CHECK_ERROR_CONDITION(
            "Unable to request buffer allocation from surface composer");
    err = reply.readInt32();
    CHECK_ERROR_CONDITION("Unable to obtain buffer from surface composer");
    err = reply.read(*gBuffer);
    CHECK_ERROR_CONDITION("Unable to read buffer from surface composer");

    err = gBuffer->initCheck();
    if (err != NO_ERROR) {
    if (err != NO_ERROR) {
        ALOGE("Unable to create native buffer { w=%d, h=%d, f=%d, u=%#x }: %#x",
        ALOGE("Unable to create native buffer { w=%d, h=%d, f=%d, u=%#x }: %#x",
                width, height, format, usage, err);
                width, height, format, usage, err);
        // Destroy the buffer.
        goto error_condition;
        sp<GraphicBuffer> holder(gBuffer);
        return setError(EGL_BAD_ALLOC, (EGLClientBuffer)0);
    }
    }
    ALOGD("Created new native buffer %p { w=%d, h=%d, f=%d, u=%#x }",
    ALOGD("Created new native buffer %p { w=%d, h=%d, f=%d, u=%#x }",
            gBuffer, width, height, format, usage);
            gBuffer, width, height, format, usage);
    return static_cast<EGLClientBuffer>(gBuffer->getNativeBuffer());
    return static_cast<EGLClientBuffer>(gBuffer->getNativeBuffer());

#undef CHECK_ERROR_CONDITION

error_condition:
    // Delete the buffer.
    sp<GraphicBuffer> holder(gBuffer);
    return setError(EGL_BAD_ALLOC, (EGLClientBuffer)0);
}
}


// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------