Carol Ward
Carol Ward

Reputation: 731

Android Tracing a Java API back to jni

I'm trying to understand the interaction between the java and jni, so I decided to trace one of the java API, public int write (byte[] audioData, int offsetInBytes, int sizeInBytes) (https://android.googlesource.com/platform/frameworks/base/+/android-6.0.1_r1/media/java/android/media/AudioTrack.java#1699).

If someone would point out if my thought process is correct or not.

The method

public int write (byte[] audioData, int offsetInBytes, int sizeInBytes) 

contains

return write(audioData, offsetInBytes, sizeInBytes, WRITE_BLOCKING); 

so it can be traced back to

public int write(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes, @WriteMode int writeMode)

(https://android.googlesource.com/platform/frameworks/base/+/android-6.0.1_r1/media/java/android/media/AudioTrack.java#1739).

Inside that function, it has

int ret = native_write_byte(audioData, offsetInBytes, sizeInBytes, mAudioFormat, writeMode == WRITE_BLOCKING); 

which calls the native method

private native final int native_write_byte(byte[] audioData,i nt offsetInBytes, int sizeInBytes, int format, boolean isBlocking);

After I grep through all of the AOSP, I found that the only place that contains native_write_byte is in static JNINativeMethod gMethods[]

`"native_write_byte",    "([BIIIZ)I", 
 (void*)android_media_AudioTrack_writeArray<jbyteArray>` 
 (`https://android.googlesource.com/platform/frameworks/base/+/android- 
 6.0.1_r1/core/jni/android_media_AudioTrack.cpp#1065`) 
 (`https://android.googlesource.com/platform/frameworks/base/+/android- 
 6.0.1_r1/core/jni/android_media_AudioTrack.cpp#592`)

Now I want to find in which shared objects contains the native function, so I downloaded all of the files in /system/bin and grep through them, and only found one which is libandroid_runtime.so.

After opening the shared object in Ida pro, I found it by searching for the unique string.

So I'm thinking that when developers use the write function, they import libandroid_runtime.so and use write function which contains native_write_byte function which is a native function that calls to static jint android_media_AudioTrack_writeArray.

Is this the right way to trace back to the C++?

Upvotes: 0

Views: 362

Answers (1)

Alex Cohn
Alex Cohn

Reputation: 57163

You did most of the work correctly.

I don't know why you stopped at android-6.0.1_r1, the same CPP file is available in master. This native method is implemented as a template specialization of a C++ function:

template <typename T>
static jint android_media_AudioTrack_writeArray(JNIEnv *env, jobject thiz,
                                            T javaAudioData,
                                            jint offsetInSamples, jint sizeInSamples,
                                            jint javaAudioFormat,
                                            jboolean isWriteBlocking) {

You can study how this function works. Note that here, as typical for Android platform code, the JNI calls are wrapped with nativehelper headers.

to find in which shared objects contains the native function, you can look up the corresponding Android.bp script.

cc_library_shared {
    name: "libandroid_runtime",
...
srcs: [
...
   "android_media_AudioTrack.cpp",

grep through /system/bin is not necessary, and could actually be misleading, especially if the library were built with obfuscation turned on.

So I'm thinking that when developers use the write function, they import libandroid_runtime.so and use write function which contains native_write_byte function which is a native function that calls to static jint android_media_AudioTrack_writeArray.

Basically correct. In Java, we usually invoke System.loadLibrary(name) to import libname dynamic library, and we would say «native_write_byte is implemented with static jint android_media_AudioTrack_writeArray<jbytearray>()» rather than speak about a call from native_write_byte.

Android runtime is a bit different. It is started on system load and reused by all apps. This start invokes, among others, register_android_media_AudioTrack(JNIEnv *), and that registers all native methods listed in the gMethods table which belongs to android_media_AudioTrack.cpp.

Upvotes: 1

Related Questions