Merge "Moving native MIDI JNI init to AndroidRuntime.cpp."
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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),
|
||||
|
||||
52
core/jni/android_media_midi.cpp
Normal file
52
core/jni/android_media_midi.cpp
Normal 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;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user