Switching Native MIDI API to an "opaque pointers" model.
Test: manual
Change-Id: Ic181008427e6e81106d867cc3a70deef8c591841
diff --git a/media/java/android/media/midi/MidiDevice.java b/media/java/android/media/midi/MidiDevice.java
index 4b43260..f7dd0b3 100644
--- a/media/java/android/media/midi/MidiDevice.java
+++ b/media/java/android/media/midi/MidiDevice.java
@@ -30,6 +30,8 @@
import java.io.FileDescriptor;
import java.io.IOException;
+import java.util.HashSet;
+
/**
* This class is used for sending and receiving data to and from a MIDI device
* Instances of this class are created by {@link MidiManager#openDevice}.
@@ -47,7 +49,18 @@
private final IBinder mClientToken;
private final IBinder mDeviceToken;
private boolean mIsDeviceClosed;
- private boolean mIsMirroredToNative;
+
+ // Native API Helpers
+ /**
+ * Keep a static list of MidiDevice objects that are mirrorToNative()'d so they
+ * don't get inadvertantly garbage collected.
+ */
+ private static HashSet<MidiDevice> mMirroredDevices = new HashSet<MidiDevice>();
+
+ /**
+ * If this device is mirrorToNatived(), this is the native device handler.
+ */
+ private long mNativeHandle;
private final CloseGuard mGuard = CloseGuard.get();
@@ -218,34 +231,39 @@
* Makes Midi Device available to the Native API
* @hide
*/
- public void mirrorToNative() throws IOException {
- if (mIsDeviceClosed || mIsMirroredToNative) {
- return;
+ public long mirrorToNative() throws IOException {
+ if (mIsDeviceClosed || mNativeHandle != 0) {
+ return 0;
}
- int result = mirrorToNative(mDeviceServer.asBinder(), mDeviceInfo.getId());
- if (result != 0) {
- throw new IOException("Failed mirroring to native: " + result);
+ mNativeHandle = native_mirrorToNative(mDeviceServer.asBinder(), mDeviceInfo.getId());
+ if (mNativeHandle == 0) {
+ throw new IOException("Failed mirroring to native");
}
- mIsMirroredToNative = true;
+ synchronized (mMirroredDevices) {
+ mMirroredDevices.add(this);
+ }
+ return mNativeHandle;
}
/**
* Makes Midi Device no longer available to the Native API
* @hide
*/
- public void removeFromNative() throws IOException {
- if (!mIsMirroredToNative) {
+ public void removeFromNative() {
+ if (mNativeHandle == 0) {
return;
}
- int result = removeFromNative(mDeviceInfo.getId());
- if (result != 0) {
- throw new IOException("Failed removing from native: " + result);
+ synchronized (mGuard) {
+ native_removeFromNative(mNativeHandle);
+ mNativeHandle = 0;
}
- mIsMirroredToNative = false;
+ synchronized (mMirroredDevices) {
+ mMirroredDevices.remove(this);
+ }
}
@Override
@@ -279,6 +297,6 @@
return ("MidiDevice: " + mDeviceInfo.toString());
}
- private native int mirrorToNative(IBinder deviceServerBinder, int uid);
- private native int removeFromNative(int uid);
+ private native long native_mirrorToNative(IBinder deviceServerBinder, int id);
+ private native void native_removeFromNative(long deviceHandle);
}
diff --git a/media/jni/midi/android_media_midi_MidiDevice.cpp b/media/jni/midi/android_media_midi_MidiDevice.cpp
index 1e54bac..3743e4a 100644
--- a/media/jni/midi/android_media_midi_MidiDevice.cpp
+++ b/media/jni/midi/android_media_midi_MidiDevice.cpp
@@ -18,32 +18,33 @@
#define LOG_TAG "Midi-JNI"
#include <android_util_Binder.h>
-#include <midi/MidiDeviceRegistry.h>
+#include <midi/midi_internal.h>
#include <nativehelper/jni.h>
#include <utils/Log.h>
using namespace android;
using namespace android::media::midi;
-extern "C" jint Java_android_media_midi_MidiDevice_mirrorToNative(
- JNIEnv *env, jobject thiz, jobject midiDeviceServer, jint id)
+extern "C" jlong Java_android_media_midi_MidiDevice_native_1mirrorToNative(
+ JNIEnv *env, jobject, jobject midiDeviceServer, jint id)
{
- (void)thiz;
+ // ALOGI("native_mirrorToNative(%p)...", midiDeviceServer);
sp<IBinder> serverBinder = ibinderForJavaObject(env, midiDeviceServer);
if (serverBinder.get() == NULL) {
ALOGE("Could not obtain IBinder from passed jobject");
return -EINVAL;
}
- // return MidiDeviceManager::getInstance().addDevice(serverBinder, uid);
- return MidiDeviceRegistry::getInstance().addDevice(
- new BpMidiDeviceServer(serverBinder), id);
+
+ AMIDI_Device* devicePtr = new AMIDI_Device;
+ devicePtr->server = new BpMidiDeviceServer(serverBinder);
+ devicePtr->deviceId = id;
+
+ return (jlong)devicePtr;
}
-extern "C" jint Java_android_media_midi_MidiDevice_removeFromNative(
- JNIEnv *env, jobject thiz, jint uid)
+extern "C" void Java_android_media_midi_MidiDevice_native_removeFromNative(
+ JNIEnv *, jobject , jlong nativeToken)
{
- (void)env;
- (void)thiz;
- // return MidiDeviceManager::getInstance().removeDevice(uid);
- return MidiDeviceRegistry::getInstance().removeDevice(uid);
+ AMIDI_Device* devicePtr = (AMIDI_Device*)nativeToken;
+ delete devicePtr;
}
diff --git a/media/native/midi/Android.mk b/media/native/midi/Android.mk
index b91c430..dbc5eed 100644
--- a/media/native/midi/Android.mk
+++ b/media/native/midi/Android.mk
@@ -4,9 +4,7 @@
LOCAL_SRC_FILES := \
../../java/android/media/midi/IMidiDeviceServer.aidl \
- midi.cpp \
- MidiDeviceRegistry.cpp \
- MidiPortRegistry.cpp
+ midi.cpp
LOCAL_AIDL_INCLUDES := \
$(FRAMEWORKS_BASE_JAVA_SRC_DIRS) \
diff --git a/media/native/midi/MidiDeviceRegistry.cpp b/media/native/midi/MidiDeviceRegistry.cpp
deleted file mode 100644
index 8854a08..0000000
--- a/media/native/midi/MidiDeviceRegistry.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#include "MidiDeviceRegistry.h"
-
-namespace android {
-
-ANDROID_SINGLETON_STATIC_INSTANCE(media::midi::MidiDeviceRegistry);
-
-namespace media {
-namespace midi {
-
-MidiDeviceRegistry::MidiDeviceRegistry() : mNextDeviceToken(1) {
-}
-
-status_t MidiDeviceRegistry::addDevice(sp<BpMidiDeviceServer> server, int32_t deviceId) {
- if (server.get() == nullptr) {
- return -EINVAL;
- }
-
- std::lock_guard<std::mutex> guard(mMapsLock);
- mServers[deviceId] = server;
- return OK;
-}
-
-status_t MidiDeviceRegistry::removeDevice(int32_t deviceId) {
- std::lock_guard<std::mutex> guard(mMapsLock);
- mServers.erase(deviceId);
- const auto& iter = mUidToToken.find(deviceId);
- if (iter != mUidToToken.end()) {
- mTokenToUid.erase(iter->second);
- mUidToToken.erase(iter);
- }
- return OK;
-}
-
-//NOTE: This creates an entry if not found, or returns an existing one.
-status_t MidiDeviceRegistry::obtainDeviceToken(int32_t deviceId, AMIDI_Device *deviceTokenPtr) {
- std::lock_guard<std::mutex> guard(mMapsLock);
- const auto& serversIter = mServers.find(deviceId);
- if (serversIter == mServers.end()) {
- // Not found.
- return -EINVAL;
- }
-
- const auto& iter = mUidToToken.find(deviceId);
- if (iter != mUidToToken.end()) {
- *deviceTokenPtr = iter->second;
- } else {
- *deviceTokenPtr = mNextDeviceToken++;
- mTokenToUid[*deviceTokenPtr] = deviceId;
- mUidToToken[deviceId] = *deviceTokenPtr;
- }
- return OK;
-}
-
-status_t MidiDeviceRegistry::releaseDevice(AMIDI_Device deviceToken) {
- std::lock_guard<std::mutex> guard(mMapsLock);
- const auto& iter = mTokenToUid.find(deviceToken);
- if (iter == mTokenToUid.end()) {
- // Not found
- return -EINVAL;
- }
-
- mServers.erase(iter->second);
- mUidToToken.erase(iter->second);
- mTokenToUid.erase(iter);
- return OK;
-}
-
-status_t MidiDeviceRegistry::getDeviceByToken(
- AMIDI_Device deviceToken, sp<BpMidiDeviceServer> *devicePtr) {
- std::lock_guard<std::mutex> guard(mMapsLock);
- int32_t id = -1;
- {
- const auto& iter = mTokenToUid.find(deviceToken);
- if (iter == mTokenToUid.end()) {
- return -EINVAL;
- }
- id = iter->second;
- }
- const auto& iter = mServers.find(id);
- if (iter == mServers.end()) {
- return -EINVAL;
- }
-
- *devicePtr = iter->second;
- return OK;
-}
-
-} // namespace midi
-} // namespace media
-} // namespace android
diff --git a/media/native/midi/MidiDeviceRegistry.h b/media/native/midi/MidiDeviceRegistry.h
deleted file mode 100644
index 93be733..0000000
--- a/media/native/midi/MidiDeviceRegistry.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#ifndef ANDROID_MEDIA_MIDI_DEVICE_REGISTRY_H_
-#define ANDROID_MEDIA_MIDI_DEVICE_REGISTRY_H_
-
-#include <map>
-#include <mutex>
-
-#include <binder/IBinder.h>
-#include <utils/Errors.h>
-#include <utils/Singleton.h>
-
-#include "android/media/midi/BpMidiDeviceServer.h"
-#include "midi.h"
-
-namespace android {
-namespace media {
-namespace midi {
-
-/*
- * Maintains a thread-safe, (singleton) list of MIDI devices with associated Binder interfaces,
- * which are exposed to the Native API via (Java) MidiDevice.mirrorToNative() &
- * MidiDevice.removeFromNative().
- * (Called via MidiDeviceManager::addDevice() MidiManager::removeDevice()).
- */
-class MidiDeviceRegistry : public Singleton<MidiDeviceRegistry> {
- public:
- /* Add a MIDI Device to the registry.
- *
- * server The Binder interface to the MIDI device server.
- * deviceUId The unique ID of the device obtained from
- * the Java API via MidiDeviceInfo.getId().
- */
- status_t addDevice(sp<BpMidiDeviceServer> server, int32_t deviceId);
-
- /* Remove the device (and associated server) from the Device registry.
- *
- * deviceUid The ID of the device which was used in the call to addDevice().
- */
- status_t removeDevice(int32_t deviceId);
-
- /* Gets a device token associated with the device ID. This is used by the
- * native API to identify/access the device.
- * Multiple calls without releasing the token will return the same value.
- *
- * deviceUid The ID of the device.
- * deviceTokenPtr Receives the device (native) token associated with the device ID.
- * returns: OK on success, error code otherwise.
- */
- status_t obtainDeviceToken(int32_t deviceId, AMIDI_Device *deviceTokenPtr);
-
- /*
- * Releases the native API device token associated with a MIDI device.
- *
- * deviceToken The device (native) token associated with the device ID.
- */
- status_t releaseDevice(AMIDI_Device deviceToken);
-
- /*
- * Gets the Device server binder interface associated with the device token.
- *
- * deviceToken The device (native) token associated with the device ID.
- */
- status_t getDeviceByToken(AMIDI_Device deviceToken, sp<BpMidiDeviceServer> *devicePtr);
-
- private:
- friend class Singleton<MidiDeviceRegistry>;
- MidiDeviceRegistry();
-
- // Access Mutex
- std::mutex mMapsLock;
-
- // maps device IDs to servers
- std::map<int32_t, sp<BpMidiDeviceServer>> mServers;
-
- // maps device tokens to device ID
- std::map<AMIDI_Device, int32_t> mTokenToUid;
-
- // maps device IDs to device tokens
- std::map<int32_t, AMIDI_Device> mUidToToken;
-
- // Value of next device token to dole out.
- AMIDI_Device mNextDeviceToken;
-};
-
-} // namespace midi
-} // namespace media
-} // namespace android
-
-#endif // ANDROID_MEDIA_MIDI_DEVICE_REGISTRY_H_
diff --git a/media/native/midi/MidiPortRegistry.cpp b/media/native/midi/MidiPortRegistry.cpp
deleted file mode 100644
index fa70af8..0000000
--- a/media/native/midi/MidiPortRegistry.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#include "MidiPortRegistry.h"
-
-namespace android {
-
-ANDROID_SINGLETON_STATIC_INSTANCE(media::midi::MidiPortRegistry);
-
-namespace media {
-namespace midi {
-
-//TODO Note that these 2 are identical
-struct MidiPortRegistry::OutputPort {
- AMIDI_Device device;
- sp<IBinder> binderToken;
- base::unique_fd ufd;
-};
-
-struct MidiPortRegistry::InputPort {
- AMIDI_Device device;
- sp<IBinder> binderToken;
- base::unique_fd ufd;
-};
-
-MidiPortRegistry::MidiPortRegistry() : mNextOutputPortToken(0), mNextInputPortToken(0) {
-}
-
-status_t MidiPortRegistry::addOutputPort(
- AMIDI_Device device,
- sp<IBinder> portToken,
- base::unique_fd &&ufd,
- AMIDI_OutputPort *portPtr) {
- *portPtr = mNextOutputPortToken++;
-
- OutputPortEntry* portEntry = new OutputPortEntry;
- portEntry->port = new OutputPort;
- portEntry->state = MIDI_OUTPUT_PORT_STATE_OPEN_IDLE;
- portEntry->port = new OutputPort;
- portEntry->port->device = device;
- portEntry->port->binderToken = portToken;
- portEntry->port->ufd = std::move(ufd);
-
- mOutputPortMap[*portPtr] = portEntry;
-
- return OK;
-}
-
-status_t MidiPortRegistry::removeOutputPort(
- AMIDI_OutputPort port,
- AMIDI_Device *devicePtr,
- sp<IBinder> *portTokenPtr) {
- OutputPortMap::iterator itr = mOutputPortMap.find(port);
- if (itr == mOutputPortMap.end()) {
- return -EINVAL;
- }
-
- OutputPortEntry *entry = mOutputPortMap[port];
- int portState = MIDI_OUTPUT_PORT_STATE_OPEN_IDLE;
- while (!entry->state.compare_exchange_weak(portState, MIDI_OUTPUT_PORT_STATE_CLOSED)) {
- if (portState == MIDI_OUTPUT_PORT_STATE_CLOSED) {
- return -EINVAL; // Already closed
- }
- }
- *devicePtr = entry->port->device;
- *portTokenPtr = entry->port->binderToken;
- delete entry->port;
- entry->port = nullptr;
-
- mOutputPortMap.erase(itr);
-
- return OK;
-}
-
-status_t MidiPortRegistry::getOutputPortFdAndLock(
- AMIDI_OutputPort port, base::unique_fd **ufdPtr) {
- if (mOutputPortMap.find(port) == mOutputPortMap.end()) {
- return -EINVAL;
- }
-
- OutputPortEntry *entry = mOutputPortMap[port];
- int portState = MIDI_OUTPUT_PORT_STATE_OPEN_IDLE;
- if (!entry->state.compare_exchange_strong(portState, MIDI_OUTPUT_PORT_STATE_OPEN_ACTIVE)) {
- // The port has been closed.
- return -EPIPE;
- }
- *ufdPtr = &entry->port->ufd;
-
- return OK;
-}
-
-status_t MidiPortRegistry::unlockOutputPort(AMIDI_OutputPort port) {
- if (mOutputPortMap.find(port) == mOutputPortMap.end()) {
- return -EINVAL;
- }
-
- OutputPortEntry *entry = mOutputPortMap[port];
- entry->state.store(MIDI_OUTPUT_PORT_STATE_OPEN_IDLE);
- return OK;
-}
-
-status_t MidiPortRegistry::addInputPort(
- AMIDI_Device device,
- sp<IBinder> portToken,
- base::unique_fd &&ufd,
- AMIDI_InputPort *portPtr) {
- *portPtr = mNextInputPortToken++;
-
- InputPortEntry *entry = new InputPortEntry;
-
- entry->state = MIDI_INPUT_PORT_STATE_OPEN_IDLE;
- entry->port = new InputPort;
- entry->port->device = device;
- entry->port->binderToken = portToken;
- entry->port->ufd = std::move(ufd);
-
- mInputPortMap[*portPtr] = entry;
-
- return OK;
-}
-
-status_t MidiPortRegistry::removeInputPort(
- AMIDI_InputPort port,
- AMIDI_Device *devicePtr,
- sp<IBinder> *portTokenPtr) {
- InputPortMap::iterator itr = mInputPortMap.find(port);
- if (itr == mInputPortMap.end()) {
- return -EINVAL;
- }
-
- InputPortEntry *entry = mInputPortMap[port];
- int portState = MIDI_INPUT_PORT_STATE_OPEN_IDLE;
- while (!entry->state.compare_exchange_weak(portState, MIDI_INPUT_PORT_STATE_CLOSED)) {
- if (portState == MIDI_INPUT_PORT_STATE_CLOSED) return -EINVAL; // Already closed
- }
-
- *devicePtr = entry->port->device;
- *portTokenPtr = entry->port->binderToken;
- delete entry->port;
- entry->port = nullptr;
-
- mInputPortMap.erase(itr);
-
- return OK;
-}
-
-status_t MidiPortRegistry::getInputPortFd(AMIDI_InputPort port, base::unique_fd **ufdPtr) {
- if (mInputPortMap.find(port) == mInputPortMap.end()) {
- return -EINVAL;
- }
-
- InputPortEntry *entry = mInputPortMap[port];
-
- *ufdPtr = &entry->port->ufd;
-
- return OK;
-}
-
-status_t MidiPortRegistry::getInputPortFdAndLock(AMIDI_InputPort port, base::unique_fd **ufdPtr) {
- if (mInputPortMap.find(port) == mInputPortMap.end()) {
- return -EINVAL;
- }
-
- InputPortEntry *entry = mInputPortMap[port];
-
- int portState = MIDI_INPUT_PORT_STATE_OPEN_IDLE;
- if (!entry->state.compare_exchange_strong(portState, MIDI_INPUT_PORT_STATE_OPEN_ACTIVE)) {
- // The port has been closed.
- return -EPIPE;
- }
- *ufdPtr = &entry->port->ufd;
- return OK;
-}
-
-status_t MidiPortRegistry::MidiPortRegistry::unlockInputPort(AMIDI_InputPort port) {
- if (mInputPortMap.find(port) == mInputPortMap.end()) {
- return -EINVAL;
- }
-
- InputPortEntry *entry = mInputPortMap[port];
- entry->state.store(MIDI_INPUT_PORT_STATE_OPEN_IDLE);
- return OK;
-}
-
-} // namespace midi
-} // namespace media
-} // namespace android
diff --git a/media/native/midi/MidiPortRegistry.h b/media/native/midi/MidiPortRegistry.h
deleted file mode 100644
index f1ffb78..0000000
--- a/media/native/midi/MidiPortRegistry.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#ifndef ANDROID_MEDIA_MIDI_PORT_REGISTRY_H_
-#define ANDROID_MEDIA_MIDI_PORT_REGISTRY_H_
-
-#include <atomic>
-#include <map>
-
-#include <android-base/unique_fd.h>
-#include <binder/IBinder.h>
-#include <utils/Errors.h>
-#include <utils/Singleton.h>
-
-#include "midi.h"
-
-namespace android {
-namespace media {
-namespace midi {
-
-/*
- * Maintains lists of all active input and output MIDI ports and controls access to them. Provides
- * exclusive access to specific MIDI ports.
- */
-class MidiPortRegistry : public Singleton<MidiPortRegistry> {
- public:
- /*
- * Creates an output port entry and associates it with the specified MIDI device.
- * Called by AMIDI_openOutputPort();
- *
- * device The native API device ID.
- * portToken The port token (returned from the device server).
- * udf File descriptor for the data port associated with the MIDI output port.
- * portPtr Receives the native API port ID of the port being opened.
- */
- status_t addOutputPort(
- AMIDI_Device device,
- sp<IBinder> portToken,
- base::unique_fd &&ufd,
- AMIDI_OutputPort *portPtr);
-
- /*
- * Removes for the output port list a previously added output port.
- * Called by AMIDI_closeOutputPort();
- *
- * port The native API port ID of the port being closed.
- * devicePtr Receives the native API device ID associated with the port.
- * portTokenPtr Receives the binder token associated with the port.
- */
- status_t removeOutputPort(
- AMIDI_OutputPort port,
- AMIDI_Device *devicePtr,
- sp<IBinder> *portTokenPtr);
-
- /*
- * Creates an input port entry and associates it with the specified MIDI device.
- * Called by AMIDI_openInputPort();
- *
- * device The native API device ID.
- * portToken The port token (returned from the device server).
- * udf File descriptor for the data port associated with the MIDI input port.
- * portPtr Receives the native API port ID of the port being opened.
- */
- status_t addInputPort(
- AMIDI_Device device,
- sp<IBinder> portToken,
- base::unique_fd &&ufd,
- AMIDI_InputPort *portPtr);
-
- /*
- * Removes for the input port list a previously added input port.
- * Called by AMIDI_closeINputPort();
- *
- * port The native API port ID of the port being closed.
- * devicePtr Receives the native API device ID associated with the port.
- * portTokenPtr Receives the binder token associated with the port.
- */
- status_t removeInputPort(
- AMIDI_InputPort port,
- AMIDI_Device *devicePtr,
- sp<IBinder> *portTokenPtr);
-
- /*
- * Retrieves an exclusive-access file descriptor for an output port.
- * Called from AMIDI_receive().
- *
- * port The native API id of the output port.
- * ufdPtr Receives the exclusive-access file descriptor for the output port.
- */
- status_t getOutputPortFdAndLock(AMIDI_OutputPort port, base::unique_fd **ufdPtr);
-
- /*
- * Releases exclusive-access to the port and invalidates the previously received file
- * descriptor.
- * Called from AMIDI_receive().
- *
- * port The native API id of the output port.
- */
- status_t unlockOutputPort(AMIDI_OutputPort port);
-
- /*
- * Retrieves an exclusive-access file descriptor for an input port.
- * (Not being used as (perhaps) AMIDI_sendWithTimestamp() doesn't need exclusive access
- * to the port).
- *
- * port The native API id of the input port.
- * ufdPtr Receives the exclusive-access file descriptor for the input port.
- */
- status_t getInputPortFdAndLock(AMIDI_InputPort port, base::unique_fd **ufdPtr);
-
- /*
- * Releases exclusive-access to the port and invalidates the previously received file
- * descriptor.
- * (Not used. See above).
- *
- * port The native API id of the input port.
- */
- status_t unlockInputPort(AMIDI_InputPort port);
-
- /*
- * Retrieves an unlocked (multi-access) file descriptor for an input port.
- * Used by AMIDI_sendWith(), AMIDI_sendWithTimestamp & AMIDI_flush.
- *
- * port The native API id of the input port.
- * ufdPtr Receives the multi-access file descriptor for the input port.
- */
- status_t getInputPortFd(AMIDI_InputPort port, base::unique_fd **ufdPtr);
-
- private:
- friend class Singleton<MidiPortRegistry>;
- MidiPortRegistry();
-
- /*
- * Output (data receiving) ports.
- */
- struct OutputPort;
- enum {
- MIDI_OUTPUT_PORT_STATE_CLOSED = 0,
- MIDI_OUTPUT_PORT_STATE_OPEN_IDLE,
- MIDI_OUTPUT_PORT_STATE_OPEN_ACTIVE
- };
-
- struct OutputPortEntry {
- std::atomic_int state;
- OutputPort *port;
- };
-
- typedef std::map<AMIDI_OutputPort, OutputPortEntry*> OutputPortMap;
- // Access is synchronized per record via 'state' field.
- std::atomic<AMIDI_OutputPort> mNextOutputPortToken;
- OutputPortMap mOutputPortMap;
-
- /*
- * Input (data sending) ports.
- */
- struct InputPort;
- enum {
- MIDI_INPUT_PORT_STATE_CLOSED = 0,
- MIDI_INPUT_PORT_STATE_OPEN_IDLE,
- MIDI_INPUT_PORT_STATE_OPEN_ACTIVE
- };
-
- struct InputPortEntry {
- std::atomic_int state;
- InputPort *port;
- };
-
- typedef std::map<AMIDI_OutputPort, InputPortEntry*> InputPortMap;
- // Access is synchronized per record via 'state' field.
- std::atomic<AMIDI_InputPort> mNextInputPortToken;
- InputPortMap mInputPortMap;
-
-};
-
-} // namespace midi
-} // namespace media
-} // namespace android
-
-#endif // ANDROID_MEDIA_MIDI_PORT_REGISTRY_H_
diff --git a/media/native/midi/midi.cpp b/media/native/midi/midi.cpp
index 1bf0bd0..17b92da3 100644
--- a/media/native/midi/midi.cpp
+++ b/media/native/midi/midi.cpp
@@ -25,10 +25,9 @@
#include "android/media/midi/BpMidiDeviceServer.h"
#include "media/MidiDeviceInfo.h"
-#include "MidiDeviceRegistry.h"
-#include "MidiPortRegistry.h"
#include "midi.h"
+#include "midi_internal.h"
using android::IBinder;
using android::BBinder;
@@ -37,13 +36,28 @@
using android::status_t;
using android::base::unique_fd;
using android::binder::Status;
-using android::media::midi::BpMidiDeviceServer;
using android::media::midi::MidiDeviceInfo;
-using android::media::midi::MidiDeviceRegistry;
-using android::media::midi::MidiPortRegistry;
+
+struct AMIDI_Port {
+ std::atomic_int state;
+ AMIDI_Device *device;
+ sp<IBinder> binderToken;
+ unique_fd ufd;
+};
#define SIZE_MIDIRECEIVEBUFFER AMIDI_BUFFER_SIZE
+enum {
+ MIDI_PORT_STATE_CLOSED = 0,
+ MIDI_PORT_STATE_OPEN_IDLE,
+ MIDI_PORT_STATE_OPEN_ACTIVE
+};
+
+enum {
+ PORTTYPE_OUTPUT = 0,
+ PORTTYPE_INPUT = 1
+};
+
/* TRANSFER PACKET FORMAT (as defined in MidiPortImpl.java)
*
* Transfer packet format is as follows (see MidiOutputPort.mThread.run() to see decomposition):
@@ -63,20 +77,12 @@
* So 'read()' always returns a whole message.
*/
-status_t AMIDI_getDeviceById(int32_t id, AMIDI_Device *devicePtr) {
- return MidiDeviceRegistry::getInstance().obtainDeviceToken(id, devicePtr);
-}
-
-status_t AMIDI_getDeviceInfo(AMIDI_Device device, AMIDI_DeviceInfo *deviceInfoPtr) {
- sp<BpMidiDeviceServer> deviceServer;
- status_t result = MidiDeviceRegistry::getInstance().getDeviceByToken(device, &deviceServer);
- if (result != OK) {
- ALOGE("AMIDI_getDeviceInfo bad device token %d: %d", device, result);
- return result;
- }
-
+/*
+ * Device Functions
+ */
+status_t AMIDI_getDeviceInfo(AMIDI_Device *device, AMIDI_DeviceInfo *deviceInfoPtr) {
MidiDeviceInfo deviceInfo;
- Status txResult = deviceServer->getDeviceInfo(&deviceInfo);
+ Status txResult = device->server->getDeviceInfo(&deviceInfo);
if (!txResult.isOk()) {
ALOGE("AMIDI_getDeviceInfo transaction error: %d", txResult.transactionError());
return txResult.transactionError();
@@ -87,49 +93,74 @@
deviceInfoPtr->isPrivate = deviceInfo.isPrivate();
deviceInfoPtr->inputPortCount = deviceInfo.getInputPortNames().size();
deviceInfoPtr->outputPortCount = deviceInfo.getOutputPortNames().size();
+
+ return OK;
+}
+
+/*
+ * Port Helpers
+ */
+static status_t AMIDI_openPort(AMIDI_Device *device, int portNumber, int type,
+ AMIDI_Port **portPtr) {
+ sp<BBinder> portToken(new BBinder());
+ unique_fd ufd;
+ Status txResult = type == PORTTYPE_OUTPUT
+ ? device->server->openOutputPort(portToken, portNumber, &ufd)
+ : device->server->openInputPort(portToken, portNumber, &ufd);
+ if (!txResult.isOk()) {
+ ALOGE("AMIDI_openPort transaction error: %d", txResult.transactionError());
+ return txResult.transactionError();
+ }
+
+ AMIDI_Port* port = new AMIDI_Port;
+ port->state = MIDI_PORT_STATE_OPEN_IDLE;
+ port->device = device;
+ port->binderToken = portToken;
+ port->ufd = std::move(ufd);
+
+ *portPtr = port;
+
+ return OK;
+}
+
+static status_t AMIDI_closePort(AMIDI_Port *port) {
+ int portState = MIDI_PORT_STATE_OPEN_IDLE;
+ while (!port->state.compare_exchange_weak(portState, MIDI_PORT_STATE_CLOSED)) {
+ if (portState == MIDI_PORT_STATE_CLOSED) {
+ return -EINVAL; // Already closed
+ }
+ }
+
+ Status txResult = port->device->server->closePort(port->binderToken);
+ if (!txResult.isOk()) {
+ return txResult.transactionError();
+ }
+
+ delete port;
+
return OK;
}
/*
* Output (receiving) API
*/
-status_t AMIDI_openOutputPort(AMIDI_Device device, int portNumber, AMIDI_OutputPort *outputPortPtr) {
- sp<BpMidiDeviceServer> deviceServer;
- status_t result = MidiDeviceRegistry::getInstance().getDeviceByToken(device, &deviceServer);
- if (result != OK) {
- ALOGE("AMIDI_openOutputPort bad device token %d: %d", device, result);
- return result;
- }
-
- sp<BBinder> portToken(new BBinder());
- unique_fd ufd;
- Status txResult = deviceServer->openOutputPort(portToken, portNumber, &ufd);
- if (!txResult.isOk()) {
- ALOGE("AMIDI_openOutputPort transaction error: %d", txResult.transactionError());
- return txResult.transactionError();
- }
-
- result = MidiPortRegistry::getInstance().addOutputPort(
- device, portToken, std::move(ufd), outputPortPtr);
- if (result != OK) {
- ALOGE("AMIDI_openOutputPort port registration error: %d", result);
- // Close port
- return result;
- }
- return OK;
+status_t AMIDI_openOutputPort(AMIDI_Device *device, int portNumber,
+ AMIDI_OutputPort **outputPortPtr) {
+ return AMIDI_openPort(device, portNumber, PORTTYPE_OUTPUT, (AMIDI_Port**)outputPortPtr);
}
-ssize_t AMIDI_receive(AMIDI_OutputPort outputPort, AMIDI_Message *messages, ssize_t maxMessages) {
- unique_fd *ufd;
- // TODO: May return a nicer self-unlocking object
- status_t result = MidiPortRegistry::getInstance().getOutputPortFdAndLock(outputPort, &ufd);
- if (result != OK) {
- return result;
+ssize_t AMIDI_receive(AMIDI_OutputPort *outputPort, AMIDI_Message *messages, ssize_t maxMessages) {
+ AMIDI_Port *port = (AMIDI_Port*)outputPort;
+ int portState = MIDI_PORT_STATE_OPEN_IDLE;
+ if (!port->state.compare_exchange_strong(portState, MIDI_PORT_STATE_OPEN_ACTIVE)) {
+ // The port has been closed.
+ return -EPIPE;
}
+ status_t result = OK;
ssize_t messagesRead = 0;
while (messagesRead < maxMessages) {
- struct pollfd checkFds[1] = { { *ufd, POLLIN, 0 } };
+ struct pollfd checkFds[1] = { { port->ufd, POLLIN, 0 } };
int pollResult = poll(checkFds, 1, 0);
if (pollResult < 1) {
result = android::INVALID_OPERATION;
@@ -139,7 +170,7 @@
AMIDI_Message *message = &messages[messagesRead];
uint8_t readBuffer[AMIDI_PACKET_SIZE];
memset(readBuffer, 0, sizeof(readBuffer));
- ssize_t readCount = read(*ufd, readBuffer, sizeof(readBuffer));
+ ssize_t readCount = read(port->ufd, readBuffer, sizeof(readBuffer));
if (readCount == EINTR) {
continue;
}
@@ -157,100 +188,38 @@
if (dataSize) {
memcpy(message->buffer, readBuffer + 1, dataSize);
}
- message->timestamp = *(uint64_t*) (readBuffer + readCount - sizeof(uint64_t));
+ message->timestamp = *(uint64_t*)(readBuffer + readCount - sizeof(uint64_t));
}
message->len = dataSize;
++messagesRead;
}
- MidiPortRegistry::getInstance().unlockOutputPort(outputPort);
+ port->state.store(MIDI_PORT_STATE_OPEN_IDLE);
+
return result == OK ? messagesRead : result;
}
-status_t AMIDI_closeOutputPort(AMIDI_OutputPort outputPort) {
- AMIDI_Device device;
- sp<IBinder> portToken;
- status_t result =
- MidiPortRegistry::getInstance().removeOutputPort(outputPort, &device, &portToken);
- if (result != OK) {
- return result;
- }
-
- sp<BpMidiDeviceServer> deviceServer;
- result = MidiDeviceRegistry::getInstance().getDeviceByToken(device, &deviceServer);
- if (result != OK) {
- return result;
- }
-
- Status txResult = deviceServer->closePort(portToken);
- if (!txResult.isOk()) {
- return txResult.transactionError();
- }
- return OK;
+status_t AMIDI_closeOutputPort(AMIDI_OutputPort *outputPort) {
+ return AMIDI_closePort((AMIDI_Port*)outputPort);
}
/*
* Input (sending) API
*/
-status_t AMIDI_openInputPort(AMIDI_Device device, int portNumber, AMIDI_InputPort *inputPortPtr) {
- sp<BpMidiDeviceServer> deviceServer;
- status_t result = MidiDeviceRegistry::getInstance().getDeviceByToken(device, &deviceServer);
- if (result != OK) {
- ALOGE("AMIDI_openInputPort bad device token %d: %d", device, result);
- return result;
- }
-
- sp<BBinder> portToken(new BBinder());
- unique_fd ufd; // this is the file descriptor of the "receive" port s
- Status txResult = deviceServer->openInputPort(portToken, portNumber, &ufd);
- if (!txResult.isOk()) {
- ALOGE("AMIDI_openInputPort transaction error: %d", txResult.transactionError());
- return txResult.transactionError();
- }
-
- result = MidiPortRegistry::getInstance().addInputPort(
- device, portToken, std::move(ufd), inputPortPtr);
- if (result != OK) {
- ALOGE("AMIDI_openInputPort port registration error: %d", result);
- // Close port
- return result;
- }
-
- return OK;
+status_t AMIDI_openInputPort(AMIDI_Device *device, int portNumber, AMIDI_InputPort **inputPortPtr) {
+ return AMIDI_openPort(device, portNumber, PORTTYPE_INPUT, (AMIDI_Port**)inputPortPtr);
}
-status_t AMIDI_closeInputPort(AMIDI_InputPort inputPort) {
- AMIDI_Device device;
- sp<IBinder> portToken;
- status_t result = MidiPortRegistry::getInstance().removeInputPort(
- inputPort, &device, &portToken);
- if (result != OK) {
- ALOGE("AMIDI_closeInputPort remove port error: %d", result);
- return result;
- }
-
- sp<BpMidiDeviceServer> deviceServer;
- result = MidiDeviceRegistry::getInstance().getDeviceByToken(device, &deviceServer);
- if (result != OK) {
- ALOGE("AMIDI_closeInputPort can't find device error: %d", result);
- return result;
- }
-
- Status txResult = deviceServer->closePort(portToken);
- if (!txResult.isOk()) {
- result = txResult.transactionError();
- ALOGE("AMIDI_closeInputPort transaction error: %d", result);
- return result;
- }
-
- return OK;
+status_t AMIDI_closeInputPort(AMIDI_InputPort *inputPort) {
+ return AMIDI_closePort((AMIDI_Port*)inputPort);
}
-ssize_t AMIDI_getMaxMessageSizeInBytes(AMIDI_InputPort /*inputPort*/) {
+ssize_t AMIDI_getMaxMessageSizeInBytes(AMIDI_InputPort */*inputPort*/) {
return SIZE_MIDIRECEIVEBUFFER;
}
-static ssize_t AMIDI_makeSendBuffer(uint8_t *buffer, uint8_t *data, ssize_t numBytes, uint64_t timestamp) {
+static ssize_t AMIDI_makeSendBuffer(
+ uint8_t *buffer, uint8_t *data, ssize_t numBytes,uint64_t timestamp) {
buffer[0] = AMIDI_OPCODE_DATA;
memcpy(buffer + 1, data, numBytes);
memcpy(buffer + 1 + numBytes, ×tamp, sizeof(timestamp));
@@ -264,11 +233,11 @@
// }
//}
-ssize_t AMIDI_send(AMIDI_InputPort inputPort, uint8_t *buffer, ssize_t numBytes) {
+ssize_t AMIDI_send(AMIDI_InputPort *inputPort, uint8_t *buffer, ssize_t numBytes) {
return AMIDI_sendWithTimestamp(inputPort, buffer, numBytes, 0);
}
-ssize_t AMIDI_sendWithTimestamp(AMIDI_InputPort inputPort, uint8_t *data,
+ssize_t AMIDI_sendWithTimestamp(AMIDI_InputPort *inputPort, uint8_t *data,
ssize_t numBytes, int64_t timestamp) {
if (numBytes > SIZE_MIDIRECEIVEBUFFER) {
@@ -277,15 +246,9 @@
// AMIDI_logBuffer(data, numBytes);
- unique_fd *ufd = NULL;
- status_t result = MidiPortRegistry::getInstance().getInputPortFd(inputPort, &ufd);
- if (result != OK) {
- return result;
- }
-
uint8_t writeBuffer[SIZE_MIDIRECEIVEBUFFER + AMIDI_PACKET_OVERHEAD];
ssize_t numTransferBytes = AMIDI_makeSendBuffer(writeBuffer, data, numBytes, timestamp);
- ssize_t numWritten = write(*ufd, writeBuffer, numTransferBytes);
+ ssize_t numWritten = write(((AMIDI_Port*)inputPort)->ufd, writeBuffer, numTransferBytes);
if (numWritten < numTransferBytes) {
ALOGE("AMIDI_sendWithTimestamp Couldn't write MIDI data buffer. requested:%zu, written%zu",
@@ -295,16 +258,10 @@
return numWritten - AMIDI_PACKET_OVERHEAD;
}
-status_t AMIDI_flush(AMIDI_InputPort inputPort) {
- unique_fd *ufd = NULL;
- status_t result = MidiPortRegistry::getInstance().getInputPortFd(inputPort, &ufd);
- if (result != OK) {
- return result;
- }
-
+status_t AMIDI_flush(AMIDI_InputPort *inputPort) {
uint8_t opCode = AMIDI_OPCODE_FLUSH;
ssize_t numTransferBytes = 1;
- ssize_t numWritten = write(*ufd, &opCode, numTransferBytes);
+ ssize_t numWritten = write(((AMIDI_Port*)inputPort)->ufd, &opCode, numTransferBytes);
if (numWritten < numTransferBytes) {
ALOGE("AMIDI_flush Couldn't write MIDI flush. requested:%zu, written%zu",
diff --git a/media/native/midi/midi.h b/media/native/midi/midi.h
index 717bc66..9332b44 100644
--- a/media/native/midi/midi.h
+++ b/media/native/midi/midi.h
@@ -29,22 +29,11 @@
extern "C" {
#endif
-//typedef struct _AMIDI_Device;
-//typedef struct _AMIDI_InputPort;
-//typedef struct _AMIDI_OutputPort;
-//typedef _AMIDI_Device* AMIDI_Device;
-//typedef _AMIDI_InputPort* AMIDI_InputPort;
-//typedef _AMIDI_OutputPort* AMIDI_OutputPort;
+struct AMIDI_Device;
+struct AMIDI_InputPort;
+struct AMIDI_OutputPort;
-typedef int32_t AMIDI_Device;
-typedef int32_t AMIDI_InputPort;
-typedef int32_t AMIDI_OutputPort;
-
-//TODO - Do we want to wrap this stuff in namespace android { namespace media { namespace midi {?
-
-enum {
- AMIDI_INVALID_HANDLE = -1
-};
+#define AMIDI_INVALID_HANDLE NULL
enum {
AMIDI_OPCODE_DATA = 1,
@@ -56,10 +45,10 @@
};
typedef struct {
- uint32_t opcode;
- uint8_t buffer[AMIDI_BUFFER_SIZE];
- size_t len;
- int64_t timestamp;
+ uint32_t opcode;
+ uint8_t buffer[AMIDI_BUFFER_SIZE];
+ size_t len;
+ int64_t timestamp;
} AMIDI_Message;
enum {
@@ -80,16 +69,6 @@
* Device API
*/
/*
- * Retrieves the native API device token for the specified Java API device ID.
- *
- * uid The Java API id of the device.
- * devicePtr Receives the associated native API token for the device.
- *
- * Returns OK or a (negative) error code.
- */
-status_t AMIDI_getDeviceById(int32_t id, AMIDI_Device *devicePtr);
-
-/*
* Retrieves information for the native MIDI device.
*
* device The Native API token for the device.
@@ -97,7 +76,7 @@
*
* Returns OK or a (negative) error code.
*/
-status_t AMIDI_getDeviceInfo(AMIDI_Device device, AMIDI_DeviceInfo *deviceInfoPtr);
+status_t AMIDI_getDeviceInfo(AMIDI_Device *device, AMIDI_DeviceInfo *deviceInfoPtr);
/*
* API for receiving data from the Output port of a device.
@@ -111,7 +90,8 @@
*
* Returns OK, or a (negative) error code.
*/
-status_t AMIDI_openOutputPort(AMIDI_Device device, int portNumber, AMIDI_OutputPort *outputPortPtr);
+status_t AMIDI_openOutputPort(AMIDI_Device *device, int portNumber,
+ AMIDI_OutputPort **outputPortPtr);
/*
* Receives any pending MIDI messages (up to the specified maximum number of messages).
@@ -122,7 +102,7 @@
*
* Returns the number of messages received, or a (negative) error code.
*/
-ssize_t AMIDI_receive(AMIDI_OutputPort outputPort, AMIDI_Message *messages, ssize_t maxMessages);
+ssize_t AMIDI_receive(AMIDI_OutputPort *outputPort, AMIDI_Message *messages, ssize_t maxMessages);
/*
* Closes the output port.
@@ -131,7 +111,7 @@
*
* Returns OK, or a (negative) error code.
*/
-status_t AMIDI_closeOutputPort(AMIDI_OutputPort outputPort);
+status_t AMIDI_closeOutputPort(AMIDI_OutputPort *outputPort);
/*
* API for sending data to the Input port of a device.
@@ -145,12 +125,12 @@
*
* Returns OK, or a (negative) error code.
*/
-status_t AMIDI_openInputPort(AMIDI_Device device, int portNumber, AMIDI_InputPort *inputPortPtr);
+status_t AMIDI_openInputPort(AMIDI_Device *device, int portNumber, AMIDI_InputPort **inputPortPtr);
/*
* Returns the maximum number of bytes that can be received in a single MIDI message.
*/
-ssize_t AMIDI_getMaxMessageSizeInBytes(AMIDI_InputPort inputPort);
+ssize_t AMIDI_getMaxMessageSizeInBytes(AMIDI_InputPort *inputPort);
/*
* Sends data to the specified input port.
@@ -161,7 +141,7 @@
*
* Returns The number of bytes sent or a (negative) error code.
*/
-ssize_t AMIDI_send(AMIDI_InputPort inputPort, uint8_t *buffer, ssize_t numBytes);
+ssize_t AMIDI_send(AMIDI_InputPort *inputPort, uint8_t *buffer, ssize_t numBytes);
/*
* Sends data to the specified input port with a timestamp.
@@ -173,7 +153,7 @@
*
* Returns The number of bytes sent or a (negative) error code.
*/
-ssize_t AMIDI_sendWithTimestamp(AMIDI_InputPort inputPort, uint8_t *buffer,
+ssize_t AMIDI_sendWithTimestamp(AMIDI_InputPort *inputPort, uint8_t *buffer,
ssize_t numBytes, int64_t timestamp);
/*
@@ -183,7 +163,7 @@
*
* Returns OK, or a (negative) error code.
*/
-status_t AMIDI_flush(AMIDI_InputPort inputPort);
+status_t AMIDI_flush(AMIDI_InputPort *inputPort);
/*
* Closes the input port.
@@ -193,7 +173,7 @@
*
* Returns OK, or a (negative) error code.
*/
-status_t AMIDI_closeInputPort(AMIDI_InputPort inputPort);
+status_t AMIDI_closeInputPort(AMIDI_InputPort *inputPort);
#ifdef __cplusplus
}
diff --git a/media/native/midi/midi_internal.h b/media/native/midi/midi_internal.h
new file mode 100644
index 0000000..fd4770e
--- /dev/null
+++ b/media/native/midi/midi_internal.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef ANDROID_MEDIA_MIDI_INTERNAL_H_
+#define ANDROID_MEDIA_MIDI_INTERNAL_H_
+
+#include "android/media/midi/BpMidiDeviceServer.h"
+
+struct AMIDI_Device {
+ android::sp<android::media::midi::BpMidiDeviceServer> server;
+ int32_t deviceId;
+};
+
+#endif // ANDROID_MEDIA_MIDI_INTERNAL_H_
diff --git a/media/tests/NativeMidiDemo/jni/nativemidi-jni.cpp b/media/tests/NativeMidiDemo/jni/nativemidi-jni.cpp
index 8aa874a..0110b75 100644
--- a/media/tests/NativeMidiDemo/jni/nativemidi-jni.cpp
+++ b/media/tests/NativeMidiDemo/jni/nativemidi-jni.cpp
@@ -66,8 +66,8 @@
static std::atomic_ullong sharedCounter;
-static AMIDI_Device midiDevice = AMIDI_INVALID_HANDLE;
-static std::atomic<AMIDI_OutputPort> midiOutputPort(AMIDI_INVALID_HANDLE);
+static AMIDI_Device* midiDevice = AMIDI_INVALID_HANDLE;
+static std::atomic<AMIDI_OutputPort*> midiOutputPort(AMIDI_INVALID_HANDLE);
static int setPlaySamples(int newPlaySamples)
{
@@ -86,7 +86,7 @@
{
sharedCounter++;
- AMIDI_OutputPort outputPort = midiOutputPort.load();
+ AMIDI_OutputPort* outputPort = midiOutputPort.load();
if (outputPort != AMIDI_INVALID_HANDLE) {
char midiDumpBuffer[1024];
ssize_t midiReceived = AMIDI_receive(
@@ -235,20 +235,21 @@
}
void Java_com_example_android_nativemididemo_NativeMidi_startReadingMidi(
- JNIEnv*, jobject, jint deviceId, jint portNumber) {
+ JNIEnv*, jobject, jlong deviceHandle, jint portNumber) {
char buffer[1024];
- int result = AMIDI_getDeviceById(deviceId, &midiDevice);
- if (result == 0) {
- snprintf(buffer, sizeof(buffer), "Obtained device token for uid %d: token %d", deviceId, midiDevice);
- } else {
- snprintf(buffer, sizeof(buffer), "Could not obtain device token for uid %d: %d", deviceId, result);
- }
+ midiDevice = (AMIDI_Device*)deviceHandle;
+// int result = AMIDI_getDeviceById(deviceId, &midiDevice);
+// if (result == 0) {
+// snprintf(buffer, sizeof(buffer), "Obtained device token for uid %d: token %d", deviceId, midiDevice);
+// } else {
+// snprintf(buffer, sizeof(buffer), "Could not obtain device token for uid %d: %d", deviceId, result);
+// }
nativemididemo::writeMessage(buffer);
- if (result) return;
+// if (result) return;
AMIDI_DeviceInfo deviceInfo;
- result = AMIDI_getDeviceInfo(midiDevice, &deviceInfo);
+ int result = AMIDI_getDeviceInfo(midiDevice, &deviceInfo);
if (result == 0) {
snprintf(buffer, sizeof(buffer), "Device info: uid %d, type %d, priv %d, ports %d I / %d O",
deviceInfo.uid, deviceInfo.type, deviceInfo.isPrivate,
@@ -259,27 +260,27 @@
nativemididemo::writeMessage(buffer);
if (result) return;
- AMIDI_OutputPort outputPort;
+ AMIDI_OutputPort* outputPort;
result = AMIDI_openOutputPort(midiDevice, portNumber, &outputPort);
if (result == 0) {
- snprintf(buffer, sizeof(buffer), "Opened port %d: token %d", portNumber, outputPort);
+ snprintf(buffer, sizeof(buffer), "Opened port %d: token %p", portNumber, outputPort);
midiOutputPort.store(outputPort);
} else {
- snprintf(buffer, sizeof(buffer), "Could not open port %d: %d", deviceId, result);
+ snprintf(buffer, sizeof(buffer), "Could not open port %p: %d", midiDevice, result);
}
nativemididemo::writeMessage(buffer);
}
void Java_com_example_android_nativemididemo_NativeMidi_stopReadingMidi(
JNIEnv*, jobject) {
- AMIDI_OutputPort outputPort = midiOutputPort.exchange(AMIDI_INVALID_HANDLE);
+ AMIDI_OutputPort* outputPort = midiOutputPort.exchange(AMIDI_INVALID_HANDLE);
if (outputPort == AMIDI_INVALID_HANDLE) return;
int result = AMIDI_closeOutputPort(outputPort);
char buffer[1024];
if (result == 0) {
- snprintf(buffer, sizeof(buffer), "Closed port by token %d", outputPort);
+ snprintf(buffer, sizeof(buffer), "Closed port by token %p", outputPort);
} else {
- snprintf(buffer, sizeof(buffer), "Could not close port by token %d: %d", outputPort, result);
+ snprintf(buffer, sizeof(buffer), "Could not close port by token %p: %d", outputPort, result);
}
nativemididemo::writeMessage(buffer);
}