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

Commit afca2d91 authored by John Reck's avatar John Reck Committed by Automerger Merge Worker
Browse files

Merge "Add hook for intercepting query" into rvc-dev am: b4cc5f4a

Change-Id: I18efb361e0acdb58d6bd4d5a54be136684ef7a1d
parents 34e0f9bf b4cc5f4a
Loading
Loading
Loading
Loading
+27 −1
Original line number Diff line number Diff line
@@ -57,7 +57,8 @@ bool isInterceptorRegistrationOp(int op) {
    return op == NATIVE_WINDOW_SET_CANCEL_INTERCEPTOR ||
            op == NATIVE_WINDOW_SET_DEQUEUE_INTERCEPTOR ||
            op == NATIVE_WINDOW_SET_PERFORM_INTERCEPTOR ||
            op == NATIVE_WINDOW_SET_QUEUE_INTERCEPTOR;
            op == NATIVE_WINDOW_SET_QUEUE_INTERCEPTOR ||
            op == NATIVE_WINDOW_SET_QUERY_INTERCEPTOR;
}

} // namespace
@@ -500,6 +501,19 @@ int Surface::performInternal(ANativeWindow* window, int operation, va_list args)
}

int Surface::hook_query(const ANativeWindow* window, int what, int* value) {
    const Surface* c = getSelf(window);
    {
        std::shared_lock<std::shared_mutex> lock(c->mInterceptorMutex);
        if (c->mQueryInterceptor != nullptr) {
            auto interceptor = c->mQueryInterceptor;
            auto data = c->mQueryInterceptorData;
            return interceptor(window, Surface::queryInternal, data, what, value);
        }
    }
    return c->query(what, value);
}

int Surface::queryInternal(const ANativeWindow* window, int what, int* value) {
    const Surface* c = getSelf(window);
    return c->query(what, value);
}
@@ -1177,6 +1191,9 @@ int Surface::perform(int operation, va_list args)
    case NATIVE_WINDOW_SET_QUEUE_INTERCEPTOR:
        res = dispatchAddQueueInterceptor(args);
        break;
    case NATIVE_WINDOW_SET_QUERY_INTERCEPTOR:
        res = dispatchAddQueryInterceptor(args);
        break;
    case NATIVE_WINDOW_ALLOCATE_BUFFERS:
        allocateBuffers();
        res = NO_ERROR;
@@ -1457,6 +1474,15 @@ int Surface::dispatchAddQueueInterceptor(va_list args) {
    return NO_ERROR;
}

int Surface::dispatchAddQueryInterceptor(va_list args) {
    ANativeWindow_queryInterceptor interceptor = va_arg(args, ANativeWindow_queryInterceptor);
    void* data = va_arg(args, void*);
    std::lock_guard<std::shared_mutex> lock(mInterceptorMutex);
    mQueryInterceptor = interceptor;
    mQueryInterceptorData = data;
    return NO_ERROR;
}

int Surface::dispatchGetLastQueuedBuffer(va_list args) {
    AHardwareBuffer** buffer = va_arg(args, AHardwareBuffer**);
    int* fence = va_arg(args, int*);
+5 −1
Original line number Diff line number Diff line
@@ -209,6 +209,7 @@ private:
                                     int* fenceFd);
    static int performInternal(ANativeWindow* window, int operation, va_list args);
    static int queueBufferInternal(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd);
    static int queryInternal(const ANativeWindow* window, int what, int* value);

    static int hook_cancelBuffer_DEPRECATED(ANativeWindow* window,
            ANativeWindowBuffer* buffer);
@@ -261,6 +262,7 @@ private:
    int dispatchAddDequeueInterceptor(va_list args);
    int dispatchAddPerformInterceptor(va_list args);
    int dispatchAddQueueInterceptor(va_list args);
    int dispatchAddQueryInterceptor(va_list args);
    int dispatchGetLastQueuedBuffer(va_list args);
    bool transformToDisplayInverse();

@@ -468,7 +470,7 @@ protected:
    mutable Mutex mMutex;

    // mInterceptorMutex is the mutex guarding interceptors.
    std::shared_mutex mInterceptorMutex;
    mutable std::shared_mutex mInterceptorMutex;

    ANativeWindow_cancelBufferInterceptor mCancelInterceptor = nullptr;
    void* mCancelInterceptorData = nullptr;
@@ -478,6 +480,8 @@ protected:
    void* mPerformInterceptorData = nullptr;
    ANativeWindow_queueBufferInterceptor mQueueInterceptor = nullptr;
    void* mQueueInterceptorData = nullptr;
    ANativeWindow_queryInterceptor mQueryInterceptor = nullptr;
    void* mQueryInterceptorData = nullptr;

    // must be used from the lock/unlock thread
    sp<GraphicBuffer>           mLockedBuffer;
+35 −0
Original line number Diff line number Diff line
@@ -254,6 +254,7 @@ enum {
    NATIVE_WINDOW_SET_QUEUE_INTERCEPTOR           = 44,    /* private */
    NATIVE_WINDOW_ALLOCATE_BUFFERS                = 45,    /* private */
    NATIVE_WINDOW_GET_LAST_QUEUED_BUFFER          = 46,    /* private */
    NATIVE_WINDOW_SET_QUERY_INTERCEPTOR           = 47,    /* private */
    // clang-format on
};

@@ -1062,4 +1063,38 @@ static inline int64_t ANativeWindow_getNextFrameId(ANativeWindow* window) {
    return value;
}

/**
 * Prototype of the function that an ANativeWindow implementation would call
 * when ANativeWindow_query is called.
 */
typedef int (*ANativeWindow_queryFn)(const ANativeWindow* window, int what, int* value);

/**
 * Prototype of the function that intercepts an invocation of
 * ANativeWindow_queryFn, along with a data pointer that's passed by the
 * caller who set the interceptor, as well as arguments that would be
 * passed to ANativeWindow_queryFn if it were to be called.
 */
typedef int (*ANativeWindow_queryInterceptor)(const ANativeWindow* window,
                                                ANativeWindow_queryFn perform, void* data,
                                                int what, int* value);

/**
 * Registers an interceptor for ANativeWindow_query. Instead of calling
 * the underlying query function, instead the provided interceptor is
 * called, which may optionally call the underlying query function. An
 * optional data pointer is also provided to side-channel additional arguments.
 *
 * Note that usage of this should only be used for specialized use-cases by
 * either the system partition or to Mainline modules. This should never be
 * exposed to NDK or LL-NDK.
 *
 * Returns NO_ERROR on success, -errno if registration failed.
 */
static inline int ANativeWindow_setQueryInterceptor(ANativeWindow* window,
                                            ANativeWindow_queryInterceptor interceptor,
                                            void* data) {
    return window->perform(window, NATIVE_WINDOW_SET_QUERY_INTERCEPTOR, interceptor, data);
}

__END_DECLS