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

Commit de3341c3 authored by Patrick Williams's avatar Patrick Williams
Browse files

Refactor InputWindowHandle JNI code

* Remove unnecessary NativeInputWindowHandle wrapper class
* Combine getting and updating WindowInfoHandle into a single function
* Remove unnecessary copying of gui::WindowInfoHandle in android_view_InputWindowHandle_fromWindowInfo and Transaction::setInputWindowInfo

Bug: 294381558
Flag: EXEMPT refactor
Test: presubmits
Change-Id: Iaacbc1e5a39446483ea0d4aa38f5de1c33534160
parent 13d32366
Loading
Loading
Loading
Loading
+64 −101
Original line number Diff line number Diff line
@@ -83,68 +83,53 @@ static struct {
    jmethodID ctor;
} gRegionClassInfo;

static Mutex gHandleMutex;


// --- NativeInputWindowHandle ---

NativeInputWindowHandle::NativeInputWindowHandle(jweak objWeak) :
        mObjWeak(objWeak) {
}

NativeInputWindowHandle::~NativeInputWindowHandle() {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    env->DeleteWeakGlobalRef(mObjWeak);
// --- Global functions ---

    // Clear the weak reference to the layer handle and flush any binder ref count operations so we
    // do not hold on to any binder references.
    // TODO(b/139697085) remove this after it can be flushed automatically
    mInfo.touchableRegionCropHandle.clear();
    IPCThreadState::self()->flushCommands();
sp<gui::WindowInfoHandle> android_view_InputWindowHandle_getHandle(JNIEnv* env, jobject obj) {
    sp<gui::WindowInfoHandle> handle = [&]() {
        jlong cachedHandle = env->GetLongField(obj, gInputWindowHandleClassInfo.ptr);
        if (cachedHandle) {
            return sp<gui::WindowInfoHandle>::fromExisting(
                    reinterpret_cast<gui::WindowInfoHandle*>(cachedHandle));
        }

jobject NativeInputWindowHandle::getInputWindowHandleObjLocalRef(JNIEnv* env) {
    return env->NewLocalRef(mObjWeak);
}
        auto newHandle = sp<gui::WindowInfoHandle>::make();
        newHandle->incStrong((void*)android_view_InputWindowHandle_getHandle);
        env->SetLongField(obj, gInputWindowHandleClassInfo.ptr,
                          reinterpret_cast<jlong>(newHandle.get()));
        return newHandle;
    }();

bool NativeInputWindowHandle::updateInfo() {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    jobject obj = env->NewLocalRef(mObjWeak);
    if (!obj) {
        releaseChannel();
        return false;
    }
    gui::WindowInfo* windowInfo = handle->editInfo();

    mInfo.touchableRegion.clear();
    windowInfo->touchableRegion.clear();

    jobject tokenObj = env->GetObjectField(obj, gInputWindowHandleClassInfo.token);
    if (tokenObj) {
        mInfo.token = ibinderForJavaObject(env, tokenObj);
        windowInfo->token = ibinderForJavaObject(env, tokenObj);
        env->DeleteLocalRef(tokenObj);
    } else {
        mInfo.token.clear();
        windowInfo->token.clear();
    }

    mInfo.name = getStringField(env, obj, gInputWindowHandleClassInfo.name, "<null>");
    windowInfo->name = getStringField(env, obj, gInputWindowHandleClassInfo.name, "<null>");

    mInfo.dispatchingTimeout = std::chrono::milliseconds(
    windowInfo->dispatchingTimeout = std::chrono::milliseconds(
            env->GetLongField(obj, gInputWindowHandleClassInfo.dispatchingTimeoutMillis));

    ScopedLocalRef<jobject> frameObj(env,
                                     env->GetObjectField(obj, gInputWindowHandleClassInfo.frame));
    mInfo.frame = JNICommon::rectFromObj(env, frameObj.get());
    windowInfo->frame = JNICommon::rectFromObj(env, frameObj.get());

    mInfo.surfaceInset = env->GetIntField(obj,
            gInputWindowHandleClassInfo.surfaceInset);
    mInfo.globalScaleFactor = env->GetFloatField(obj,
            gInputWindowHandleClassInfo.scaleFactor);
    windowInfo->surfaceInset = env->GetIntField(obj, gInputWindowHandleClassInfo.surfaceInset);
    windowInfo->globalScaleFactor =
            env->GetFloatField(obj, gInputWindowHandleClassInfo.scaleFactor);

    jobject regionObj = env->GetObjectField(obj,
            gInputWindowHandleClassInfo.touchableRegion);
    jobject regionObj = env->GetObjectField(obj, gInputWindowHandleClassInfo.touchableRegion);
    if (regionObj) {
        for (graphics::RegionIterator it(env, regionObj); !it.isDone(); it.next()) {
            ARect rect = it.getRect();
            mInfo.addTouchableRegion(Rect(rect.left, rect.top, rect.right, rect.bottom));
            windowInfo->addTouchableRegion(Rect(rect.left, rect.top, rect.right, rect.bottom));
        }
        env->DeleteLocalRef(regionObj);
    }
@@ -153,49 +138,55 @@ bool NativeInputWindowHandle::updateInfo() {
            env->GetIntField(obj, gInputWindowHandleClassInfo.layoutParamsFlags));
    const auto type = static_cast<WindowInfo::Type>(
            env->GetIntField(obj, gInputWindowHandleClassInfo.layoutParamsType));
    mInfo.layoutParamsFlags = flags;
    mInfo.layoutParamsType = type;
    windowInfo->layoutParamsFlags = flags;
    windowInfo->layoutParamsType = type;

    mInfo.inputConfig = static_cast<gui::WindowInfo::InputConfig>(
    windowInfo->inputConfig = static_cast<gui::WindowInfo::InputConfig>(
            env->GetIntField(obj, gInputWindowHandleClassInfo.inputConfig));

    mInfo.touchOcclusionMode = static_cast<TouchOcclusionMode>(
    windowInfo->touchOcclusionMode = static_cast<TouchOcclusionMode>(
            env->GetIntField(obj, gInputWindowHandleClassInfo.touchOcclusionMode));
    mInfo.ownerPid = gui::Pid{env->GetIntField(obj, gInputWindowHandleClassInfo.ownerPid)};
    mInfo.ownerUid = gui::Uid{
    windowInfo->ownerPid = gui::Pid{env->GetIntField(obj, gInputWindowHandleClassInfo.ownerPid)};
    windowInfo->ownerUid = gui::Uid{
            static_cast<uid_t>(env->GetIntField(obj, gInputWindowHandleClassInfo.ownerUid))};
    mInfo.packageName = getStringField(env, obj, gInputWindowHandleClassInfo.packageName, "<null>");
    mInfo.displayId =
    windowInfo->packageName =
            getStringField(env, obj, gInputWindowHandleClassInfo.packageName, "<null>");
    windowInfo->displayId =
            ui::LogicalDisplayId{env->GetIntField(obj, gInputWindowHandleClassInfo.displayId)};

    jobject inputApplicationHandleObj = env->GetObjectField(obj,
            gInputWindowHandleClassInfo.inputApplicationHandle);
    jobject inputApplicationHandleObj =
            env->GetObjectField(obj, gInputWindowHandleClassInfo.inputApplicationHandle);
    if (inputApplicationHandleObj) {
        std::shared_ptr<InputApplicationHandle> inputApplicationHandle =
                android_view_InputApplicationHandle_getHandle(env, inputApplicationHandleObj);
        if (inputApplicationHandle != nullptr) {
            inputApplicationHandle->updateInfo();
            mInfo.applicationInfo = *(inputApplicationHandle->getInfo());
            windowInfo->applicationInfo = *(inputApplicationHandle->getInfo());
        }
        env->DeleteLocalRef(inputApplicationHandleObj);
    }

    mInfo.replaceTouchableRegionWithCrop = env->GetBooleanField(obj,
            gInputWindowHandleClassInfo.replaceTouchableRegionWithCrop);
    windowInfo->replaceTouchableRegionWithCrop =
            env->GetBooleanField(obj, gInputWindowHandleClassInfo.replaceTouchableRegionWithCrop);

    jobject weakSurfaceCtrl = env->GetObjectField(obj,
    jobject weakSurfaceCtrl =
            env->GetObjectField(obj,
                                gInputWindowHandleClassInfo.touchableRegionSurfaceControl.ctrl);
    bool touchableRegionCropHandleSet = false;
    if (weakSurfaceCtrl) {
        // Promote java weak reference.
        jobject strongSurfaceCtrl = env->CallObjectMethod(weakSurfaceCtrl,
                gInputWindowHandleClassInfo.touchableRegionSurfaceControl.get);
        jobject strongSurfaceCtrl =
                env->CallObjectMethod(weakSurfaceCtrl,
                                      gInputWindowHandleClassInfo.touchableRegionSurfaceControl
                                              .get);
        if (strongSurfaceCtrl) {
            jlong mNativeObject = env->GetLongField(strongSurfaceCtrl,
                    gInputWindowHandleClassInfo.touchableRegionSurfaceControl.mNativeObject);
            jlong mNativeObject =
                    env->GetLongField(strongSurfaceCtrl,
                                      gInputWindowHandleClassInfo.touchableRegionSurfaceControl
                                              .mNativeObject);
            if (mNativeObject) {
                auto ctrl = reinterpret_cast<SurfaceControl *>(mNativeObject);
                mInfo.touchableRegionCropHandle = ctrl->getHandle();
                windowInfo->touchableRegionCropHandle = ctrl->getHandle();
                touchableRegionCropHandleSet = true;
            }
            env->DeleteLocalRef(strongSurfaceCtrl);
@@ -203,15 +194,15 @@ bool NativeInputWindowHandle::updateInfo() {
        env->DeleteLocalRef(weakSurfaceCtrl);
    }
    if (!touchableRegionCropHandleSet) {
        mInfo.touchableRegionCropHandle.clear();
        windowInfo->touchableRegionCropHandle.clear();
    }

    jobject windowTokenObj = env->GetObjectField(obj, gInputWindowHandleClassInfo.windowToken);
    if (windowTokenObj) {
        mInfo.windowToken = ibinderForJavaObject(env, windowTokenObj);
        windowInfo->windowToken = ibinderForJavaObject(env, windowTokenObj);
        env->DeleteLocalRef(windowTokenObj);
    } else {
        mInfo.windowToken.clear();
        windowInfo->windowToken.clear();
    }

    ScopedLocalRef<jobject>
@@ -220,41 +211,16 @@ bool NativeInputWindowHandle::updateInfo() {
                                                       gInputWindowHandleClassInfo
                                                               .focusTransferTarget));
    if (focusTransferTargetObj.get()) {
        mInfo.focusTransferTarget = ibinderForJavaObject(env, focusTransferTargetObj.get());
        windowInfo->focusTransferTarget = ibinderForJavaObject(env, focusTransferTargetObj.get());
    } else {
        mInfo.focusTransferTarget.clear();
    }

    env->DeleteLocalRef(obj);
    return true;
}


// --- Global functions ---

sp<NativeInputWindowHandle> android_view_InputWindowHandle_getHandle(
        JNIEnv* env, jobject inputWindowHandleObj) {
    if (!inputWindowHandleObj) {
        return NULL;
        windowInfo->focusTransferTarget.clear();
    }

    AutoMutex _l(gHandleMutex);

    jlong ptr = env->GetLongField(inputWindowHandleObj, gInputWindowHandleClassInfo.ptr);
    NativeInputWindowHandle* handle;
    if (ptr) {
        handle = reinterpret_cast<NativeInputWindowHandle*>(ptr);
    } else {
        jweak objWeak = env->NewWeakGlobalRef(inputWindowHandleObj);
        handle = new NativeInputWindowHandle(objWeak);
        handle->incStrong((void*)android_view_InputWindowHandle_getHandle);
        env->SetLongField(inputWindowHandleObj, gInputWindowHandleClassInfo.ptr,
                reinterpret_cast<jlong>(handle));
    }
    return handle;
}

jobject android_view_InputWindowHandle_fromWindowInfo(JNIEnv* env, gui::WindowInfo windowInfo) {
jobject android_view_InputWindowHandle_fromWindowInfo(JNIEnv* env,
                                                      const gui::WindowInfo& windowInfo) {
    ScopedLocalRef<jobject>
            applicationHandle(env,
                              android_view_InputApplicationHandle_fromInputApplicationInfo(
@@ -337,17 +303,14 @@ jobject android_view_InputWindowHandle_fromWindowInfo(JNIEnv* env, gui::WindowIn
// --- JNI ---

static void android_view_InputWindowHandle_nativeDispose(JNIEnv* env, jobject obj) {
    AutoMutex _l(gHandleMutex);

    jlong ptr = env->GetLongField(obj, gInputWindowHandleClassInfo.ptr);
    if (ptr) {
    if (!ptr) {
        return;
    }
    env->SetLongField(obj, gInputWindowHandleClassInfo.ptr, 0);

        NativeInputWindowHandle* handle = reinterpret_cast<NativeInputWindowHandle*>(ptr);
    auto handle = reinterpret_cast<gui::WindowInfoHandle*>(ptr);
    handle->decStrong((void*)android_view_InputWindowHandle_getHandle);
}
}


static const JNINativeMethod gInputWindowHandleMethods[] = {
    /* name, signature, funcPtr */
+4 −17
Original line number Diff line number Diff line
@@ -24,24 +24,11 @@

namespace android {

class NativeInputWindowHandle : public gui::WindowInfoHandle {
public:
    NativeInputWindowHandle(jweak objWeak);
    virtual ~NativeInputWindowHandle();
sp<gui::WindowInfoHandle> android_view_InputWindowHandle_getHandle(JNIEnv* env,
                                                                   jobject inputWindowHandleObj);

    jobject getInputWindowHandleObjLocalRef(JNIEnv* env);

    virtual bool updateInfo();

private:
    jweak mObjWeak;
};

extern sp<NativeInputWindowHandle> android_view_InputWindowHandle_getHandle(
        JNIEnv* env, jobject inputWindowHandleObj);

extern jobject android_view_InputWindowHandle_fromWindowInfo(JNIEnv* env,
                                                             gui::WindowInfo windowInfo);
jobject android_view_InputWindowHandle_fromWindowInfo(JNIEnv* env,
                                                      const gui::WindowInfo& windowInfo);

} // namespace android

+7 −5
Original line number Diff line number Diff line
@@ -979,14 +979,16 @@ static void nativeSetAlpha(JNIEnv* env, jclass clazz, jlong transactionObj,

static void nativeSetInputWindowInfo(JNIEnv* env, jclass clazz, jlong transactionObj,
        jlong nativeObject, jobject inputWindow) {
    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
    if (!inputWindow) {
        jniThrowNullPointerException(env, "InputWindowHandle is null");
        return;
    }

    sp<NativeInputWindowHandle> handle = android_view_InputWindowHandle_getHandle(
            env, inputWindow);
    handle->updateInfo();
    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);

    sp<gui::WindowInfoHandle> info = android_view_InputWindowHandle_getHandle(env, inputWindow);
    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
    transaction->setInputWindowInfo(ctrl, *handle->getInfo());
    transaction->setInputWindowInfo(ctrl, std::move(info));
}

static void nativeAddWindowInfosReportedListener(JNIEnv* env, jclass clazz, jlong transactionObj,