Moving native MIDI JNI init to AndroidRuntime.cpp.
Remove (non-working) lazy init in midi.cpp
Bug: 79464070
Test: Verify function with NativeMidiTestbed app.
Change-Id: I30182d19d205b4ab952d622824f1a63ab1fef72e
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 302189f..d4903d8 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -165,6 +165,7 @@
"android_media_JetPlayer.cpp",
"android_media_MediaMetricsJNI.cpp",
"android_media_MicrophoneInfo.cpp",
+ "android_media_midi.cpp",
"android_media_RemoteDisplay.cpp",
"android_media_ToneGenerator.cpp",
"android_hardware_Camera.cpp",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 01ca054..11f3558 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -108,6 +108,7 @@
extern int register_android_media_MicrophoneInfo(JNIEnv *env);
extern int register_android_media_JetPlayer(JNIEnv *env);
extern int register_android_media_ToneGenerator(JNIEnv *env);
+extern int register_android_media_midi(JNIEnv *env);
namespace android {
@@ -1441,6 +1442,7 @@
REG_JNI(register_android_media_MicrophoneInfo),
REG_JNI(register_android_media_RemoteDisplay),
REG_JNI(register_android_media_ToneGenerator),
+ REG_JNI(register_android_media_midi),
REG_JNI(register_android_opengl_classes),
REG_JNI(register_android_server_NetworkManagementSocketTagger),
diff --git a/core/jni/android_media_midi.cpp b/core/jni/android_media_midi.cpp
new file mode 100644
index 0000000..b8af3ead
--- /dev/null
+++ b/core/jni/android_media_midi.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#define LOG_TAG "NativeMIDI_JNI"
+
+#include <core_jni_helpers.h>
+
+namespace android { namespace midi {
+// MidiDevice Fields
+static jobject gMidiDeviceClassGlobalRef = nullptr; // A GlobalRef for MidiDevice Class
+jfieldID gFidMidiNativeHandle = nullptr; // MidiDevice.mNativeHandle
+jfieldID gFidMidiDeviceServerBinder = nullptr; // MidiDevice.mDeviceServerBinder
+jfieldID gFidMidiDeviceInfo = nullptr; // MidiDevice.mDeviceInfo
+
+// MidiDeviceInfo Fields
+static jobject gMidiDeviceInfoClassGlobalRef = nullptr; // A GlobalRef for MidiDeviceInfoClass
+jfieldID mFidMidiDeviceId = nullptr; // MidiDeviceInfo.mId
+}}
+
+using namespace android::midi;
+
+int register_android_media_midi(JNIEnv *env) {
+ jclass deviceClass = android::FindClassOrDie(env, "android/media/midi/MidiDevice");
+ gMidiDeviceClassGlobalRef = env->NewGlobalRef(deviceClass);
+
+ // MidiDevice Field IDs
+ gFidMidiNativeHandle = android::GetFieldIDOrDie(env, deviceClass, "mNativeHandle", "J");
+ gFidMidiDeviceServerBinder = android::GetFieldIDOrDie(env, deviceClass,
+ "mDeviceServerBinder", "Landroid/os/IBinder;");
+ gFidMidiDeviceInfo = android::GetFieldIDOrDie(env, deviceClass,
+ "mDeviceInfo", "Landroid/media/midi/MidiDeviceInfo;");
+
+ // MidiDeviceInfo Field IDs
+ jclass deviceInfoClass = android::FindClassOrDie(env, "android/media/midi/MidiDeviceInfo");
+ gMidiDeviceInfoClassGlobalRef = env->NewGlobalRef(deviceInfoClass);
+ mFidMidiDeviceId = android::GetFieldIDOrDie(env, deviceInfoClass, "mId", "I");
+
+ return 0;
+}
diff --git a/media/native/midi/midi.cpp b/media/native/midi/midi.cpp
index a9b498f..78ca0ab 100644
--- a/media/native/midi/midi.cpp
+++ b/media/native/midi/midi.cpp
@@ -87,37 +87,20 @@
#define AMIDI_PACKET_OVERHEAD 9
#define AMIDI_BUFFER_SIZE (AMIDI_PACKET_SIZE - AMIDI_PACKET_OVERHEAD)
+// JNI IDs (see android_media_midi.cpp)
+namespace android { namespace midi {
// MidiDevice Fields
-static jobject deviceClassGlobalRef = nullptr; // A GlobalRef for MidiDevice Class
-static jfieldID fidDeviceClosed = nullptr; // MidiDevice.mIsDeviceClosed
-static jfieldID fidNativeHandle = nullptr; // MidiDevice.mNativeHandle
-static jfieldID fidDeviceServerBinder = nullptr; // MidiDevice.mDeviceServerBinder
-static jfieldID fidDeviceInfo = nullptr; // MidiDevice.mDeviceInfo
+extern jfieldID gFidMidiNativeHandle; // MidiDevice.mNativeHandle
+extern jfieldID gFidMidiDeviceServerBinder; // MidiDevice.mDeviceServerBinder
+extern jfieldID gFidMidiDeviceInfo; // MidiDevice.mDeviceInfo
// MidiDeviceInfo Fields
-static jobject deviceInfoClassGlobalRef = nullptr; // A GlobalRef for MidiDeviceInfoClass
-static jfieldID fidDeviceId = nullptr; // MidiDeviceInfo.mId
+extern jfieldID mFidMidiDeviceId; // MidiDeviceInfo.mId
+}}
+using namespace android::midi;
static std::mutex openMutex; // Ensure that the device can be connected just once to 1 thread
-static void AMIDI_initJNI(JNIEnv *env) {
- jclass deviceClass = android::FindClassOrDie(env, "android/media/midi/MidiDevice");
- deviceClassGlobalRef = env->NewGlobalRef(deviceClass);
-
- // MidiDevice Field IDs
- fidDeviceClosed = android::GetFieldIDOrDie(env, deviceClass, "mIsDeviceClosed", "Z");
- fidNativeHandle = android::GetFieldIDOrDie(env, deviceClass, "mNativeHandle", "J");
- fidDeviceServerBinder = android::GetFieldIDOrDie(env, deviceClass,
- "mDeviceServerBinder", "Landroid/os/IBinder;");
- fidDeviceInfo = android::GetFieldIDOrDie(env, deviceClass,
- "mDeviceInfo", "Landroid/media/midi/MidiDeviceInfo;");
-
- // MidiDeviceInfo Field IDs
- jclass deviceInfoClass = android::FindClassOrDie(env, "android/media/midi/MidiDeviceInfo");
- deviceInfoClassGlobalRef = env->NewGlobalRef(deviceInfoClass);
- fidDeviceId = android::GetFieldIDOrDie(env, deviceInfoClass, "mId", "I");
-}
-
//// Handy debugging function.
//static void AMIDI_logBuffer(const uint8_t *data, size_t numBytes) {
// for (size_t index = 0; index < numBytes; index++) {
@@ -162,10 +145,6 @@
media_status_t AMIDI_API AMidiDevice_fromJava(JNIEnv *env, jobject j_midiDeviceObj,
AMidiDevice** devicePtrPtr)
{
- // Ensures JNI initialization is performed just once.
- static std::once_flag initCallFlag;
- std::call_once(initCallFlag, AMIDI_initJNI, env);
-
if (j_midiDeviceObj == nullptr) {
ALOGE("AMidiDevice_fromJava() invalid MidiDevice object.");
return AMEDIA_ERROR_INVALID_OBJECT;
@@ -174,13 +153,13 @@
{
std::lock_guard<std::mutex> guard(openMutex);
- long handle = env->GetLongField(j_midiDeviceObj, fidNativeHandle);
+ long handle = env->GetLongField(j_midiDeviceObj, gFidMidiNativeHandle);
if (handle != 0) {
// Already opened by someone.
return AMEDIA_ERROR_INVALID_OBJECT;
}
- jobject serverBinderObj = env->GetObjectField(j_midiDeviceObj, fidDeviceServerBinder);
+ jobject serverBinderObj = env->GetObjectField(j_midiDeviceObj, gFidMidiDeviceServerBinder);
sp<IBinder> serverBinder = android::ibinderForJavaObject(env, serverBinderObj);
if (serverBinder.get() == nullptr) {
ALOGE("AMidiDevice_fromJava couldn't connect to native MIDI server.");
@@ -190,11 +169,11 @@
// don't check allocation failures, just abort..
AMidiDevice* devicePtr = new AMidiDevice;
devicePtr->server = new BpMidiDeviceServer(serverBinder);
- jobject midiDeviceInfoObj = env->GetObjectField(j_midiDeviceObj, fidDeviceInfo);
- devicePtr->deviceId = env->GetIntField(midiDeviceInfoObj, fidDeviceId);
+ jobject midiDeviceInfoObj = env->GetObjectField(j_midiDeviceObj, gFidMidiDeviceInfo);
+ devicePtr->deviceId = env->GetIntField(midiDeviceInfoObj, mFidMidiDeviceId);
// Synchronize with the associated Java MidiDevice.
- env->SetLongField(j_midiDeviceObj, fidNativeHandle, (long)devicePtr);
+ env->SetLongField(j_midiDeviceObj, gFidMidiNativeHandle, (long)devicePtr);
env->GetJavaVM(&devicePtr->javaVM);
devicePtr->midiDeviceObj = env->NewGlobalRef(j_midiDeviceObj);
@@ -220,17 +199,16 @@
LOG_ALWAYS_FATAL_IF(err != JNI_OK, "AMidiDevice_release Error accessing JNIEnv err:%d", err);
// Synchronize with the associated Java MidiDevice.
- // env->CallVoidMethod(j_midiDeviceObj, midClearNativeHandle);
{
std::lock_guard<std::mutex> guard(openMutex);
- long handle = env->GetLongField(device->midiDeviceObj, fidNativeHandle);
+ long handle = env->GetLongField(device->midiDeviceObj, gFidMidiNativeHandle);
if (handle == 0) {
// Not opened as native.
ALOGE("AMidiDevice_release() device not opened in native client.");
return AMEDIA_ERROR_INVALID_OBJECT;
}
- env->SetLongField(device->midiDeviceObj, fidNativeHandle, 0L);
+ env->SetLongField(device->midiDeviceObj, gFidMidiNativeHandle, 0L);
}
env->DeleteGlobalRef(device->midiDeviceObj);