Merge "Moving native MIDI JNI init to AndroidRuntime.cpp."

This commit is contained in:
Paul Mclean
2018-05-11 20:52:44 +00:00
committed by Android (Google) Code Review
4 changed files with 70 additions and 37 deletions

View File

@@ -165,6 +165,7 @@ cc_library_shared {
"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",

View File

@@ -108,6 +108,7 @@ extern int register_android_media_AudioTrack(JNIEnv *env);
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 @@ static const RegJNIRec gRegJNI[] = {
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),

View File

@@ -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;
}

View File

@@ -87,37 +87,20 @@ enum {
#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 @@ static media_status_t AMIDI_API AMIDI_getDeviceInfo(const AMidiDevice *device,
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 @@ media_status_t AMIDI_API AMidiDevice_fromJava(JNIEnv *env, jobject j_midiDeviceO
{
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 @@ media_status_t AMIDI_API AMidiDevice_fromJava(JNIEnv *env, jobject j_midiDeviceO
// 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 @@ media_status_t AMIDI_API AMidiDevice_release(const AMidiDevice *device)
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);