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

Commit 804ee498 authored by Ron Shaffer's avatar Ron Shaffer Committed by Steve Kondik
Browse files

Bluetooth: Delete Local JNI References

In android_server_BluetoothEventLoop.c and
android_server_BluetoothA2dpService functions, local
references to Java objects while running in the eventloop context
are not explicitly deleted when the functions return. Local
references are implicitly deleted by the JVM when JNI code returns.
However, in this implementation the eventloop code runs as a separate
native thread which is not called from the JVM, therefore any local
references created are not released by the JVM. To prevent memory
from being leaked and reference oveflow in the JVM, these local
references need to be explicitly released.

CRs-fixed: 211008 211226
parent 01a6b2ed
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -223,10 +223,15 @@ DBusHandlerResult a2dp_event_filter(DBusMessage *msg, JNIEnv *env) {
                    parse_property_change(env, msg, (Properties *)&sink_properties,
                                sizeof(sink_properties) / sizeof(Properties));
        const char *c_path = dbus_message_get_path(msg);
        jstring path = env->NewStringUTF(c_path);

        env->CallVoidMethod(nat->me,
                            method_onSinkPropertyChanged,
                            env->NewStringUTF(c_path),
                            path,
                            str_array);

        env->DeleteLocalRef(path);

        result = DBUS_HANDLER_RESULT_HANDLED;
        return result;
    } else {
+91 −34
Original line number Diff line number Diff line
@@ -760,10 +760,14 @@ static DBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg,
                    parse_remote_device_properties(env, &iter);
        }
        if (str_array != NULL) {
            jstring address = env->NewStringUTF(c_address);

            env->CallVoidMethod(nat->me,
                                method_onDeviceFound,
                                env->NewStringUTF(c_address),
                                address,
                                str_array);

            env->DeleteLocalRef(address);
        } else
            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
        goto success;
@@ -775,8 +779,12 @@ static DBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg,
                                  DBUS_TYPE_STRING, &c_address,
                                  DBUS_TYPE_INVALID)) {
            LOGV("... address = %s", c_address);
            env->CallVoidMethod(nat->me, method_onDeviceDisappeared,
                                env->NewStringUTF(c_address));

            jstring address = env->NewStringUTF(c_address);

            env->CallVoidMethod(nat->me, method_onDeviceDisappeared, address);

            env->DeleteLocalRef(address);
        } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
        goto success;
    } else if (dbus_message_is_signal(msg,
@@ -787,9 +795,14 @@ static DBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg,
                                  DBUS_TYPE_OBJECT_PATH, &c_object_path,
                                  DBUS_TYPE_INVALID)) {
            LOGV("... address = %s", c_object_path);

            jstring path = env->NewStringUTF(c_object_path);

            env->CallVoidMethod(nat->me,
                                method_onDeviceCreated,
                                env->NewStringUTF(c_object_path));
                                path);

            env->DeleteLocalRef(path);
        } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
        goto success;
    } else if (dbus_message_is_signal(msg,
@@ -800,9 +813,14 @@ static DBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg,
                                 DBUS_TYPE_OBJECT_PATH, &c_object_path,
                                 DBUS_TYPE_INVALID)) {
           LOGV("... Object Path = %s", c_object_path);

           jstring path = env->NewStringUTF(c_object_path);

           env->CallVoidMethod(nat->me,
                               method_onDeviceRemoved,
                               env->NewStringUTF(c_object_path));
                               path);

           env->DeleteLocalRef(path);
        } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
        goto success;
    } else if (dbus_message_is_signal(msg,
@@ -834,10 +852,14 @@ static DBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg,
        jobjectArray str_array = parse_remote_device_property_change(env, msg);
        if (str_array != NULL) {
            const char *remote_device_path = dbus_message_get_path(msg);
            jstring path = env->NewStringUTF(remote_device_path);

            env->CallVoidMethod(nat->me,
                            method_onDevicePropertyChanged,
                            env->NewStringUTF(remote_device_path),
                            path,
                            str_array);

            env->DeleteLocalRef(path);
        } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
        goto success;
    } else if (dbus_message_is_signal(msg,
@@ -891,22 +913,28 @@ DBusHandlerResult agent_event_filter(DBusConnection *conn,

    } else if (dbus_message_is_method_call(msg,
            "org.bluez.Agent", "Authorize")) {
        char *object_path;
        const char *uuid;
        char *c_object_path;
        const char *c_uuid;
        if (!dbus_message_get_args(msg, NULL,
                                   DBUS_TYPE_OBJECT_PATH, &object_path,
                                   DBUS_TYPE_STRING, &uuid,
                                   DBUS_TYPE_OBJECT_PATH, &c_object_path,
                                   DBUS_TYPE_STRING, &c_uuid,
                                   DBUS_TYPE_INVALID)) {
            LOGE("%s: Invalid arguments for Authorize() method", __FUNCTION__);
            goto failure;
        }

        LOGV("... object_path = %s", object_path);
        LOGV("... uuid = %s", uuid);
        LOGV("... object_path = %s", c_object_path);
        LOGV("... uuid = %s", c_uuid);

        jstring path = env->NewStringUTF(c_object_path);
        jstring uuid = env->NewStringUTF(c_uuid);

        bool auth_granted =
            env->CallBooleanMethod(nat->me, method_onAgentAuthorize,
                env->NewStringUTF(object_path), env->NewStringUTF(uuid));
                path, uuid);

        env->DeleteLocalRef(path);
        env->DeleteLocalRef(uuid);

        // reply
        if (auth_granted) {
@@ -930,40 +958,50 @@ DBusHandlerResult agent_event_filter(DBusConnection *conn,
        goto success;
    } else if (dbus_message_is_method_call(msg,
            "org.bluez.Agent", "RequestPinCode")) {
        char *object_path;
        char *c_object_path;
        if (!dbus_message_get_args(msg, NULL,
                                   DBUS_TYPE_OBJECT_PATH, &object_path,
                                   DBUS_TYPE_OBJECT_PATH, &c_object_path,
                                   DBUS_TYPE_INVALID)) {
            LOGE("%s: Invalid arguments for RequestPinCode() method", __FUNCTION__);
            goto failure;
        }

        dbus_message_ref(msg);  // increment refcount because we pass to java

        jstring path = env->NewStringUTF(c_object_path);

        env->CallVoidMethod(nat->me, method_onRequestPinCode,
                                       env->NewStringUTF(object_path),
                                       path,
                                       int(msg));

        env->DeleteLocalRef(path);
        goto success;
    } else if (dbus_message_is_method_call(msg,
            "org.bluez.Agent", "RequestPasskey")) {
        char *object_path;
        char *c_object_path;
        if (!dbus_message_get_args(msg, NULL,
                                   DBUS_TYPE_OBJECT_PATH, &object_path,
                                   DBUS_TYPE_OBJECT_PATH, &c_object_path,
                                   DBUS_TYPE_INVALID)) {
            LOGE("%s: Invalid arguments for RequestPasskey() method", __FUNCTION__);
            goto failure;
        }

        dbus_message_ref(msg);  // increment refcount because we pass to java

        jstring path = env->NewStringUTF(c_object_path);

        env->CallVoidMethod(nat->me, method_onRequestPasskey,
                                       env->NewStringUTF(object_path),
                                       path,
                                       int(msg));

        env->DeleteLocalRef(path);
        goto success;
    } else if (dbus_message_is_method_call(msg,
            "org.bluez.Agent", "DisplayPasskey")) {
        char *object_path;
        char *c_object_path;
        uint32_t passkey;
        if (!dbus_message_get_args(msg, NULL,
                                   DBUS_TYPE_OBJECT_PATH, &object_path,
                                   DBUS_TYPE_OBJECT_PATH, &c_object_path,
                                   DBUS_TYPE_UINT32, &passkey,
                                   DBUS_TYPE_INVALID)) {
            LOGE("%s: Invalid arguments for RequestPasskey() method", __FUNCTION__);
@@ -971,17 +1009,22 @@ DBusHandlerResult agent_event_filter(DBusConnection *conn,
        }

        dbus_message_ref(msg);  // increment refcount because we pass to java

        jstring path = env->NewStringUTF(c_object_path);

        env->CallVoidMethod(nat->me, method_onDisplayPasskey,
                                       env->NewStringUTF(object_path),
                                       path,
                                       passkey,
                                       int(msg));

        env->DeleteLocalRef(path);
        goto success;
    } else if (dbus_message_is_method_call(msg,
            "org.bluez.Agent", "RequestConfirmation")) {
        char *object_path;
        char *c_object_path;
        uint32_t passkey;
        if (!dbus_message_get_args(msg, NULL,
                                   DBUS_TYPE_OBJECT_PATH, &object_path,
                                   DBUS_TYPE_OBJECT_PATH, &c_object_path,
                                   DBUS_TYPE_UINT32, &passkey,
                                   DBUS_TYPE_INVALID)) {
            LOGE("%s: Invalid arguments for RequestConfirmation() method", __FUNCTION__);
@@ -989,25 +1032,33 @@ DBusHandlerResult agent_event_filter(DBusConnection *conn,
        }

        dbus_message_ref(msg);  // increment refcount because we pass to java
        jstring path = env->NewStringUTF(c_object_path);

        env->CallVoidMethod(nat->me, method_onRequestPasskeyConfirmation,
                                       env->NewStringUTF(object_path),
                                       path,
                                       passkey,
                                       int(msg));

        env->DeleteLocalRef(path);
        goto success;
    } else if (dbus_message_is_method_call(msg,
            "org.bluez.Agent", "RequestPairingConsent")) {
        char *object_path;
        char *c_object_path;
        if (!dbus_message_get_args(msg, NULL,
                                   DBUS_TYPE_OBJECT_PATH, &object_path,
                                   DBUS_TYPE_OBJECT_PATH, &c_object_path,
                                   DBUS_TYPE_INVALID)) {
            LOGE("%s: Invalid arguments for RequestPairingConsent() method", __FUNCTION__);
            goto failure;
        }

        dbus_message_ref(msg);  // increment refcount because we pass to java
        jstring path = env->NewStringUTF(c_object_path);

        env->CallVoidMethod(nat->me, method_onRequestPairingConsent,
                                       env->NewStringUTF(object_path),
                                       path,
                                       int(msg));

        env->DeleteLocalRef(path);
        goto success;
    } else if (dbus_message_is_method_call(msg,
                  "org.bluez.Agent", "Release")) {
@@ -1052,13 +1103,14 @@ void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *n) {
    LOGV(__FUNCTION__);

    native_data_t *nat = (native_data_t *)n;
    const char *address = (const char *)user;
    const char *c_address = (const char *)user;
    DBusError err;
    dbus_error_init(&err);
    JNIEnv *env;
    nat->vm->GetEnv((void**)&env, nat->envVer);

    LOGV("... address = %s", address);
    LOGV("... address = %s", c_address);
    jstring address = env->NewStringUTF(c_address);

    jint result = BOND_RESULT_SUCCESS;
    if (dbus_set_error_from_message(&err, msg)) {
@@ -1106,9 +1158,10 @@ void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *n) {

    env->CallVoidMethod(nat->me,
                        method_onCreatePairedDeviceResult,
                        env->NewStringUTF(address),
                        address,
                        result);
done:
    env->DeleteLocalRef(address);
    dbus_error_free(&err);
    free(user);
}
@@ -1167,7 +1220,7 @@ void onDiscoverServicesResult(DBusMessage *msg, void *user, void *n) {
void onGetDeviceServiceChannelResult(DBusMessage *msg, void *user, void *n) {
    LOGV(__FUNCTION__);

    const char *address = (const char *) user;
    const char *c_address = (const char *) user;
    native_data_t *nat = (native_data_t *) n;

    DBusError err;
@@ -1177,7 +1230,7 @@ void onGetDeviceServiceChannelResult(DBusMessage *msg, void *user, void *n) {

    jint channel = -2;

    LOGV("... address = %s", address);
    LOGV("... address = %s", c_address);

    if (dbus_set_error_from_message(&err, msg) ||
        !dbus_message_get_args(msg, &err,
@@ -1188,10 +1241,14 @@ void onGetDeviceServiceChannelResult(DBusMessage *msg, void *user, void *n) {
    }

done:
    jstring address = env->NewStringUTF(c_address);

    env->CallVoidMethod(nat->me,
                        method_onGetDeviceServiceChannelResult,
                        env->NewStringUTF(address),
                        address,
                        channel);

    env->DeleteLocalRef(address);
    free(user);
}
#endif