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

Commit faa1b0ab authored by John Reck's avatar John Reck
Browse files

Have HWUI validate the WebViewFunctors at registration

Also tweak how webview's plat_support creates the functor
sruct to be thread-safe, avoids any potential race conditions
even though WebView itself is stated to be thread-hostile in
general. It's too easy to have this just be defined-safe instead.

Bug: 186814981
Test: build & boot, no crashes in real-webview apps
Change-Id: I06f02a279e248fee375ce133c5ce9a2250665ad9
parent c49b886d
Loading
Loading
Loading
Loading
+22 −0
Original line number Original line Diff line number Diff line
@@ -221,8 +221,30 @@ WebViewFunctorManager& WebViewFunctorManager::instance() {
    return sInstance;
    return sInstance;
}
}


static void validateCallbacks(const WebViewFunctorCallbacks& callbacks) {
    // TODO: Should we do a stack peek to see if this is really webview?
    LOG_ALWAYS_FATAL_IF(callbacks.onSync == nullptr, "onSync is null");
    LOG_ALWAYS_FATAL_IF(callbacks.onContextDestroyed == nullptr, "onContextDestroyed is null");
    LOG_ALWAYS_FATAL_IF(callbacks.onDestroyed == nullptr, "onDestroyed is null");
    LOG_ALWAYS_FATAL_IF(callbacks.removeOverlays == nullptr, "removeOverlays is null");
    switch (auto mode = WebViewFunctor_queryPlatformRenderMode()) {
        case RenderMode::OpenGL_ES:
            LOG_ALWAYS_FATAL_IF(callbacks.gles.draw == nullptr, "gles.draw is null");
            break;
        case RenderMode::Vulkan:
            LOG_ALWAYS_FATAL_IF(callbacks.vk.initialize == nullptr, "vk.initialize is null");
            LOG_ALWAYS_FATAL_IF(callbacks.vk.draw == nullptr, "vk.draw is null");
            LOG_ALWAYS_FATAL_IF(callbacks.vk.postDraw == nullptr, "vk.postDraw is null");
            break;
        default:
            LOG_ALWAYS_FATAL("unknown platform mode? %d", (int)mode);
            break;
    }
}

int WebViewFunctorManager::createFunctor(void* data, const WebViewFunctorCallbacks& callbacks,
int WebViewFunctorManager::createFunctor(void* data, const WebViewFunctorCallbacks& callbacks,
                                         RenderMode functorMode) {
                                         RenderMode functorMode) {
    validateCallbacks(callbacks);
    auto object = std::make_unique<WebViewFunctor>(data, callbacks, functorMode);
    auto object = std::make_unique<WebViewFunctor>(data, callbacks, functorMode);
    int id = object->id();
    int id = object->id();
    auto handle = object->createHandle();
    auto handle = object->createHandle();
+7 −0
Original line number Original line Diff line number Diff line
@@ -287,6 +287,7 @@ public:
        int sync = 0;
        int sync = 0;
        int contextDestroyed = 0;
        int contextDestroyed = 0;
        int destroyed = 0;
        int destroyed = 0;
        int removeOverlays = 0;
        int glesDraw = 0;
        int glesDraw = 0;
    };
    };


@@ -311,6 +312,12 @@ public:
                            expectOnRenderThread("onDestroyed");
                            expectOnRenderThread("onDestroyed");
                            sMockFunctorCounts[functor].destroyed++;
                            sMockFunctorCounts[functor].destroyed++;
                        },
                        },
                .removeOverlays =
                        [](int functor, void* data,
                           void (*mergeTransaction)(ASurfaceTransaction*)) {
                            expectOnRenderThread("removeOverlays");
                            sMockFunctorCounts[functor].removeOverlays++;
                        },
        };
        };
        switch (mode) {
        switch (mode) {
            case RenderMode::OpenGL_ES:
            case RenderMode::OpenGL_ES:
+3 −1
Original line number Original line Diff line number Diff line
@@ -62,8 +62,10 @@ int main(int argc, char* argv[]) {
        gSigChain.insert(pair<int, struct sigaction>(sig, old_sa));
        gSigChain.insert(pair<int, struct sigaction>(sig, old_sa));
    }
    }


    // Replace the default GLES driver
    // Avoid talking to SF
    Properties::isolatedProcess = true;
    Properties::isolatedProcess = true;
    // Default to GLES (Vulkan-aware tests will override this)
    Properties::overrideRenderPipelineType(RenderPipelineType::SkiaGL);


    // Run the tests
    // Run the tests
    testing::InitGoogleTest(&argc, argv);
    testing::InitGoogleTest(&argc, argv);
+35 −36
Original line number Original line Diff line number Diff line
@@ -192,26 +192,25 @@ void postDrawVk(int functor, void* data) {


int CreateFunctor_v3(void* data, int version,
int CreateFunctor_v3(void* data, int version,
                     AwDrawFnFunctorCallbacks* functor_callbacks) {
                     AwDrawFnFunctorCallbacks* functor_callbacks) {
  static bool callbacks_initialized = false;
    static uirenderer::WebViewFunctorCallbacks webview_functor_callbacks = [] {
  static uirenderer::WebViewFunctorCallbacks webview_functor_callbacks = {
        uirenderer::WebViewFunctorCallbacks ret = {
                .onSync = &onSync,
                .onSync = &onSync,
                .onContextDestroyed = &onContextDestroyed,
                .onContextDestroyed = &onContextDestroyed,
                .onDestroyed = &onDestroyed,
                .onDestroyed = &onDestroyed,
                .removeOverlays = &removeOverlays,
                .removeOverlays = &removeOverlays,
        };
        };
  if (!callbacks_initialized) {
        switch (uirenderer::WebViewFunctor_queryPlatformRenderMode()) {
        switch (uirenderer::WebViewFunctor_queryPlatformRenderMode()) {
            case uirenderer::RenderMode::OpenGL_ES:
            case uirenderer::RenderMode::OpenGL_ES:
        webview_functor_callbacks.gles.draw = &draw_gl;
                ret.gles.draw = &draw_gl;
                break;
                break;
            case uirenderer::RenderMode::Vulkan:
            case uirenderer::RenderMode::Vulkan:
        webview_functor_callbacks.vk.initialize = &initializeVk;
                ret.vk.initialize = &initializeVk;
        webview_functor_callbacks.vk.draw = &drawVk;
                ret.vk.draw = &drawVk;
        webview_functor_callbacks.vk.postDraw = &postDrawVk;
                ret.vk.postDraw = &postDrawVk;
                break;
                break;
        }
        }
    callbacks_initialized = true;
        return ret;
  }
    }();
    SupportData* support = new SupportData{
    SupportData* support = new SupportData{
            .data = data,
            .data = data,
    };
    };