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

Commit 7c615582 authored by Steven Moreland's avatar Steven Moreland
Browse files

libbinder_ndk: AParcel_fromJavaParcel

This allows creating a view into a Java Parcel. Note, that this doesn't
allow conversions of both directions. This is mostly out of convenience:
Parcel.obtain(long) only allows us to create a view. Also, there isn't
currently a usecase for this other API.

Bug: 145227478
Test: atest CtsNdkBinderTestCases
Change-Id: Iec043741ec778036e167aaf9a2fb275d4309e8f6
parent 6f435621
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */
#define LOG_TAG "ANDROID_RUNTIME_LAZY"
#include "android_runtime/AndroidRuntime.h"
#include "android_os_Parcel.h"
#include "android_util_Binder.h"

#include <dlfcn.h>
@@ -28,12 +29,18 @@ namespace {
std::once_flag loadFlag;

typedef JNIEnv* (*getJNIEnv_t)();

// android_util_Binder.h
typedef sp<IBinder> (*ibinderForJavaObject_t)(JNIEnv* env, jobject obj);
typedef jobject (*javaObjectForIBinder_t)(JNIEnv* env, const sp<IBinder>& val);

// android_os_Parcel.h
typedef Parcel* (*parcelForJavaObject_t)(JNIEnv* env, jobject obj);

getJNIEnv_t _getJNIEnv;
ibinderForJavaObject_t _ibinderForJavaObject;
javaObjectForIBinder_t _javaObjectForIBinder;
parcelForJavaObject_t _parcelForJavaObject;

void load() {
    std::call_once(loadFlag, []() {
@@ -64,6 +71,13 @@ void load() {
            ALOGW("Could not find javaObjectForIBinder.");
            // no return
        }

        _parcelForJavaObject = reinterpret_cast<parcelForJavaObject_t>(
            dlsym(handle, "_ZN7android19parcelForJavaObjectEP7_JNIEnvP8_jobject"));
        if (_parcelForJavaObject == nullptr) {
            ALOGW("Could not find parcelForJavaObject.");
            // no return
        }
    });
}

@@ -95,4 +109,12 @@ jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val) {
    return _javaObjectForIBinder(env, val);
}

Parcel* parcelForJavaObject(JNIEnv* env, jobject obj) {
    load();
    if (_parcelForJavaObject == nullptr) {
        return nullptr;
    }
    return _parcelForJavaObject(env, obj);
}

} // namespace android
+30 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <binder/Parcel.h>
#include "jni.h"

namespace android {

// The name of this file is same with the file in frameworks/base/core/jni/
// This is intentional to make the client use these exported functions
// in the same way with the original.

Parcel* parcelForJavaObject(JNIEnv* env, jobject obj);

} // namespace android
+1 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ cc_library_shared {
        "ibinder.cpp",
        "ibinder_jni.cpp",
        "parcel.cpp",
        "parcel_jni.cpp",
        "process.cpp",
        "stability.cpp",
        "status.cpp",
+56 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup NdkBinder
 * @{
 */

/**
 * @file binder_parcel_jni.h
 * @brief Conversions between AParcel and android.os.Parcel
 */

#pragma once

#include <android/binder_parcel.h>

#include <jni.h>

__BEGIN_DECLS
#if __ANDROID_API__ >= 30

/**
 * Converts an android.os.Parcel object into an AParcel* object.
 *
 * If the parcel is null, null is returned.
 *
 * Available since API level 30.
 *
 * \param env Java environment. Must not be null.
 * \param parcel android.os.Parcel java object.
 *
 * \return an AParcel object representing the Java parcel object. If either parameter is null, this
 * will return null. This must be deleted with AParcel_delete. This does not take ownership of the
 * jobject and is only good for as long as the jobject is alive.
 */
__attribute__((warn_unused_result)) AParcel* AParcel_fromJavaParcel(JNIEnv* env, jobject parcel)
        __INTRODUCED_IN(30);

#endif  //__ANDROID_API__ >= 30
__END_DECLS

/** @} */
+1 −0
Original line number Diff line number Diff line
@@ -105,6 +105,7 @@ LIBBINDER_NDK30 { # introduced=30
    AIBinder_setExtension;
    AStatus_getDescription;
    AStatus_deleteDescription;
    AParcel_fromJavaParcel;

    AIBinder_markSystemStability; # apex
    AIBinder_markVendorStability; # llndk
Loading