Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7ce094c authored by Mike Lockwood's avatar Mike Lockwood
Browse files

MIDI Manager: remove USB peripheral MIDI device when USB is disconnected

Otherwise, the MIDI device would appear available always, rather than
only when USB is connected.

Also fixed file descriptor leak in UsbMidiDevice

Change-Id: I0d38e81c488de4748eef36ca359635fa59e0e636
parent 221d2cbf
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -94,9 +94,20 @@ android_server_UsbMidiDevice_open(JNIEnv *env, jobject /* thiz */, jint card, ji
    return fds;
}

static void
android_server_UsbMidiDevice_close(JNIEnv *env, jobject /* thiz */, jobjectArray fds)
{
    int count = env->GetArrayLength(fds);
    for (int i = 0; i < count; i++) {
        jobject fd = env->GetObjectArrayElement(fds, i);
        close(jniGetFDFromFileDescriptor(env, fd));
    }
}

static JNINativeMethod method_table[] = {
    { "nativeGetSubdeviceCount", "(II)I", (void*)android_server_UsbMidiDevice_get_subdevice_count },
    { "nativeOpen", "(III)[Ljava/io/FileDescriptor;", (void*)android_server_UsbMidiDevice_open },
    { "nativeClose", "([Ljava/io/FileDescriptor;)V", (void*)android_server_UsbMidiDevice_close },
};

int register_android_server_UsbMidiDevice(JNIEnv *env)
+2 −2
Original line number Diff line number Diff line
@@ -459,7 +459,7 @@ public final class UsbAlsaManager {
    }

   /* package */ void setPeripheralMidiState(boolean enabled, int card, int device) {
        if (enabled) {
        if (enabled && mPeripheralMidiDevice == null) {
            Bundle properties = new Bundle();
            Resources r = mContext.getResources();
            properties.putString(MidiDeviceInfo.PROPERTY_MANUFACTURER, r.getString(
@@ -469,7 +469,7 @@ public final class UsbAlsaManager {
            properties.putInt(MidiDeviceInfo.PROPERTY_ALSA_CARD, card);
            properties.putInt(MidiDeviceInfo.PROPERTY_ALSA_DEVICE, device);
            mPeripheralMidiDevice = UsbMidiDevice.create(mContext, properties, card, device);
        } else if (mPeripheralMidiDevice != null) {
        } else if (!enabled && mPeripheralMidiDevice != null) {
            IoUtils.closeQuietly(mPeripheralMidiDevice);
            mPeripheralMidiDevice = null;
        }
+6 −6
Original line number Diff line number Diff line
@@ -126,6 +126,8 @@ public class UsbDeviceManager {
    private boolean mAdbEnabled;
    private boolean mAudioSourceEnabled;
    private boolean mMidiEnabled;
    private int mMidiCard;
    private int mMidiDevice;
    private Map<String, List<Pair<String, String>>> mOemModeMap;
    private String[] mAccessoryStrings;
    private UsbDebuggingManager mDebuggingManager;
@@ -623,26 +625,24 @@ public class UsbDeviceManager {
        private void updateMidiFunction() {
            boolean enabled = containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_MIDI);
            if (enabled != mMidiEnabled) {
                int card = -1;
                int device = -1;

                if (enabled) {
                    Scanner scanner = null;
                    try {
                        scanner = new Scanner(new File(MIDI_ALSA_PATH));
                        card = scanner.nextInt();
                        device = scanner.nextInt();
                        mMidiCard = scanner.nextInt();
                        mMidiDevice = scanner.nextInt();
                    } catch (FileNotFoundException e) {
                        Slog.e(TAG, "could not open MIDI PCM file", e);
                        enabled = false;
                    } finally {
                        if (scanner != null) {
                            scanner.close();
                        }
                    }
                }
                mUsbAlsaManager.setPeripheralMidiState(enabled, card, device);
                mMidiEnabled = enabled;
            }
            mUsbAlsaManager.setPeripheralMidiState(mMidiEnabled && mConfigured, mMidiCard, mMidiDevice);
        }

        @Override
+11 −6
Original line number Diff line number Diff line
@@ -47,6 +47,8 @@ public final class UsbMidiDevice implements Closeable {

    private static final int BUFFER_SIZE = 512;

    private final FileDescriptor[] mFileDescriptors;

    // for polling multiple FileDescriptors for MIDI events
    private final StructPollfd[] mPollFDs;
    // streams for reading from ALSA driver
@@ -69,7 +71,7 @@ public final class UsbMidiDevice implements Closeable {
            return null;
        }

        UsbMidiDevice midiDevice = new UsbMidiDevice(fileDescriptors, fileDescriptors);
        UsbMidiDevice midiDevice = new UsbMidiDevice(fileDescriptors);
        if (!midiDevice.register(context, properties)) {
            IoUtils.closeQuietly(midiDevice);
            Log.e(TAG, "createDeviceServer failed");
@@ -78,14 +80,15 @@ public final class UsbMidiDevice implements Closeable {
        return midiDevice;
    }

    private UsbMidiDevice(FileDescriptor[] inputFiles, FileDescriptor[] outputFiles) {
        int inputCount = inputFiles.length;
        int outputCount = outputFiles.length;
    private UsbMidiDevice(FileDescriptor[] fileDescriptors) {
        mFileDescriptors = fileDescriptors;
        int inputCount = fileDescriptors.length;
        int outputCount = fileDescriptors.length;

        mPollFDs = new StructPollfd[inputCount];
        mInputStreams = new FileInputStream[inputCount];
        for (int i = 0; i < inputCount; i++) {
            FileDescriptor fd = inputFiles[i];
            FileDescriptor fd = fileDescriptors[i];
            StructPollfd pollfd = new StructPollfd();
            pollfd.fd = fd;
            pollfd.events = (short)OsConstants.POLLIN;
@@ -95,7 +98,7 @@ public final class UsbMidiDevice implements Closeable {

        mOutputStreams = new FileOutputStream[outputCount];
        for (int i = 0; i < outputCount; i++) {
            mOutputStreams[i] = new FileOutputStream(outputFiles[i]);
            mOutputStreams[i] = new FileOutputStream(fileDescriptors[i]);
        }

        mInputPortReceivers = new MidiReceiver[inputCount];
@@ -176,8 +179,10 @@ public final class UsbMidiDevice implements Closeable {
        for (int i = 0; i < mOutputStreams.length; i++) {
            mOutputStreams[i].close();
        }
        nativeClose(mFileDescriptors);
    }

    private static native int nativeGetSubdeviceCount(int card, int device);
    private static native FileDescriptor[] nativeOpen(int card, int device, int subdeviceCount);
    private static native void nativeClose(FileDescriptor[] fileDescriptors);
}