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

Commit 345eb107 authored by Robert Wu's avatar Robert Wu Committed by Android (Google) Code Review
Browse files

Merge "Accumulate Bluetooth MIDI packets until ready"

parents 93a108fa 90d53f23
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -211,10 +211,10 @@ public final class BluetoothMidiDevice {
        }

        @Override
        public void writePacket(byte[] buffer, int count) {
        public boolean writePacket(byte[] buffer, int count) {
            if (mCharacteristic == null) {
                Log.w(TAG, "not ready to send packet yet");
                return;
                return false;
            }

            // Cache the previous buffer for writePacket so buffers aren't
@@ -223,12 +223,22 @@ public final class BluetoothMidiDevice {
                mCachedBuffer = new byte[count];
            }
            System.arraycopy(buffer, 0, mCachedBuffer, 0, count);
            mCharacteristic.setValue(mCachedBuffer);
            if (!mCharacteristic.setValue(mCachedBuffer)) {
                Log.w(TAG, "could not set characteristic value");
                return false;
            }

            if (DEBUG) {
                logByteArray("Sent ", mCharacteristic.getValue(), 0,
                       mCharacteristic.getValue().length);
            }
            mBluetoothGatt.writeCharacteristic(mCharacteristic);

            if (!mBluetoothGatt.writeCharacteristic(mCharacteristic)) {
                Log.w(TAG, "could not write characteristic to Bluetooth GATT");
                return false;
            }

            return true;
        }
    }

+42 −2
Original line number Diff line number Diff line
@@ -17,11 +17,14 @@
package com.android.bluetoothmidiservice;

import android.media.midi.MidiReceiver;
import android.util.Log;

import com.android.internal.midi.MidiConstants;
import com.android.internal.midi.MidiFramer;

import java.io.IOException;
import java.util.ArrayDeque;
import java.util.Queue;

/**
 * This class accumulates MIDI messages to form a MIDI packet.
@@ -52,6 +55,8 @@ public class BluetoothPacketEncoder extends PacketEncoder {

    private final Object mLock = new Object();

    private Queue<byte[]> mFailedToSendQueue = new ArrayDeque<byte[]>();

    // This receives normalized data from mMidiFramer and accumulates it into a packet buffer
    private final MidiReceiver mFramedDataReceiver = new MidiReceiver() {
        @Override
@@ -59,6 +64,8 @@ public class BluetoothPacketEncoder extends PacketEncoder {
                throws IOException {

            synchronized (mLock) {
                flushFailedToSendQueueLocked();

                int milliTimestamp = (int)(timestamp / MILLISECOND_NANOS) & MILLISECOND_MASK;
                byte status = msg[offset];
                boolean isSysExStart = (status == MidiConstants.STATUS_SYSTEM_EXCLUSIVE);
@@ -227,11 +234,44 @@ public class BluetoothPacketEncoder extends PacketEncoder {
        }

        if (mAccumulatedBytes > 0) {
            mPacketReceiver.writePacket(mAccumulationBuffer, mAccumulatedBytes);
            boolean wasSendSuccessful = mPacketReceiver.writePacket(mAccumulationBuffer,
                    mAccumulatedBytes);

            if (!wasSendSuccessful) {
                byte[] failedBuffer = new byte[mAccumulatedBytes];
                System.arraycopy(mAccumulationBuffer, 0, failedBuffer, 0, mAccumulatedBytes);
                mFailedToSendQueue.add(failedBuffer);
                Log.d(TAG, "Enqueued data into failed queue.");
            }

            mAccumulatedBytes = 0;
            mPacketTimestamp = 0;
            mRunningStatus = 0;
            mWritePending = true;
            mWritePending = wasSendSuccessful;
        }
    }

    private void flushFailedToSendQueueLocked() {
        while (!mFailedToSendQueue.isEmpty()) {
            while (mWritePending) {
                try {
                    mLock.wait();
                } catch (InterruptedException e) {
                    // try again
                    continue;
                }
            }
            byte[] currentBuffer = mFailedToSendQueue.element();

            boolean wasSendSuccessful = mPacketReceiver.writePacket(currentBuffer,
                    currentBuffer.length);
            mWritePending = wasSendSuccessful;
            if (wasSendSuccessful) {
                mFailedToSendQueue.remove();
                Log.d(TAG, "Dequeued data from failed queue.");
            } else {
                return;
            }
        }
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -30,8 +30,9 @@ public abstract class PacketEncoder extends MidiReceiver {
        /** Called to write an accumulated packet.
         * @param buffer the packet buffer to write
         * @param count the number of bytes in the packet buffer to write
         * @return whether the operation was successful
         */
        public void writePacket(byte[] buffer, int count);
        boolean writePacket(byte[] buffer, int count);
    }

    /**
+2 −1
Original line number Diff line number Diff line
@@ -114,7 +114,7 @@ public class BluetoothMidiCodecTest {
        // TODO Should this block?
        // Store the packets and then write them from a periodic task.
        @Override
        public void writePacket(byte[] buffer, int count) {
        public boolean writePacket(byte[] buffer, int count) {
            Log.d(TAG, "writePacket() passed " + MidiFramer.formatMidiData(buffer, 0, count));
            byte[] packet = new byte[count];
            System.arraycopy(buffer, 0, packet, 0, count);
@@ -124,6 +124,7 @@ public class BluetoothMidiCodecTest {
                assertEquals(null, e);
            }
            Log.d(TAG, "writePacket() returns");
            return true;
        }

        void test(final byte[][] midi)
+2 −1
Original line number Diff line number Diff line
@@ -42,11 +42,12 @@ public class BluetoothMidiEncoderTest {
    static class AccumulatingPacketReceiver implements PacketEncoder.PacketReceiver {
        ArrayList<byte[]> mBuffers = new ArrayList<byte[]>();

        public void writePacket(byte[] buffer, int count) {
        public boolean writePacket(byte[] buffer, int count) {
            byte[] actualRow = new byte[count];
            Log.d(TAG, "writePacket() passed " + MidiFramer.formatMidiData(buffer, 0, count));
            System.arraycopy(buffer, 0, actualRow, 0, count);
            mBuffers.add(actualRow);
            return true;
        }

        byte[][] getBuffers() {