From ba46bf1c98cd165416eca0c9069524165c5bb2a5 Mon Sep 17 00:00:00 2001 From: Robert Wu Date: Fri, 21 Jan 2022 19:22:10 +0000 Subject: [PATCH] Use Executor instead of Transport for callbacks Handlers are now deprecated in favor of executors. This CL makes the changes for the new MIDI APIs This CL also deprecates some legacy functions. Bug: 201003646 Test: atest MidiSoloTest Change-Id: Ia30cc30600d4206ee8d5161023d14d2db3cb7828 --- core/api/current.txt | 8 +-- .../android/media/midi/MidiDeviceInfo.java | 4 +- .../java/android/media/midi/MidiManager.java | 71 +++++++++++++------ 3 files changed, 57 insertions(+), 26 deletions(-) diff --git a/core/api/current.txt b/core/api/current.txt index 14c8bb4a18f5e..76e1deca57789 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -25404,12 +25404,12 @@ package android.media.midi { } public final class MidiManager { - method public android.media.midi.MidiDeviceInfo[] getDevices(); - method @NonNull public java.util.Collection getDevicesForTransport(int); + method @Deprecated public android.media.midi.MidiDeviceInfo[] getDevices(); + method @NonNull public java.util.Set getDevicesForTransport(int); method public void openBluetoothDevice(android.bluetooth.BluetoothDevice, android.media.midi.MidiManager.OnDeviceOpenedListener, android.os.Handler); method public void openDevice(android.media.midi.MidiDeviceInfo, android.media.midi.MidiManager.OnDeviceOpenedListener, android.os.Handler); - method public void registerDeviceCallback(android.media.midi.MidiManager.DeviceCallback, android.os.Handler); - method public void registerDeviceCallbackForTransport(@NonNull android.media.midi.MidiManager.DeviceCallback, @Nullable android.os.Handler, int); + method @Deprecated public void registerDeviceCallback(android.media.midi.MidiManager.DeviceCallback, android.os.Handler); + method public void registerDeviceCallback(int, @NonNull java.util.concurrent.Executor, @NonNull android.media.midi.MidiManager.DeviceCallback); method public void unregisterDeviceCallback(android.media.midi.MidiManager.DeviceCallback); field public static final int TRANSPORT_MIDI_BYTE_STREAM = 1; // 0x1 field public static final int TRANSPORT_UNIVERSAL_MIDI_PACKETS = 2; // 0x2 diff --git a/media/java/android/media/midi/MidiDeviceInfo.java b/media/java/android/media/midi/MidiDeviceInfo.java index b888fb00df9bb..48c50f01c01c4 100644 --- a/media/java/android/media/midi/MidiDeviceInfo.java +++ b/media/java/android/media/midi/MidiDeviceInfo.java @@ -159,7 +159,7 @@ public final class MidiDeviceInfo implements Parcelable { PROTOCOL_UNKNOWN }) @Retention(RetentionPolicy.SOURCE) - public @interface DefaultProtocol {} + public @interface Protocol {} /** * Bundle key for the device's user visible name property. @@ -429,7 +429,7 @@ public final class MidiDeviceInfo implements Parcelable { * * @return the device's default protocol. */ - @DefaultProtocol + @Protocol public int getDefaultProtocol() { return mDefaultProtocol; } diff --git a/media/java/android/media/midi/MidiManager.java b/media/java/android/media/midi/MidiManager.java index a049a8891f48f..8d6320494b82d 100644 --- a/media/java/android/media/midi/MidiManager.java +++ b/media/java/android/media/midi/MidiManager.java @@ -18,7 +18,6 @@ package android.media.midi; import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.Nullable; import android.annotation.RequiresFeature; import android.annotation.SystemService; import android.bluetooth.BluetoothDevice; @@ -29,13 +28,16 @@ import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; +import android.util.ArraySet; import android.util.Log; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.util.ArrayList; -import java.util.Collection; +import java.util.Collections; +import java.util.Objects; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executor; /** * This class is the public application interface to the MIDI service. @@ -108,18 +110,30 @@ public final class MidiManager { private class DeviceListener extends IMidiDeviceListener.Stub { private final DeviceCallback mCallback; private final Handler mHandler; + private final Executor mExecutor; private final int mTransport; DeviceListener(DeviceCallback callback, Handler handler, int transport) { mCallback = callback; mHandler = handler; + mExecutor = null; + mTransport = transport; + } + + DeviceListener(DeviceCallback callback, Executor executor, int transport) { + mCallback = callback; + mHandler = null; + mExecutor = executor; mTransport = transport; } @Override public void onDeviceAdded(MidiDeviceInfo device) { if (shouldInvokeCallback(device)) { - if (mHandler != null) { + if (mExecutor != null) { + mExecutor.execute(() -> + mCallback.onDeviceAdded(device)); + } else if (mHandler != null) { final MidiDeviceInfo deviceF = device; mHandler.post(new Runnable() { @Override public void run() { @@ -135,7 +149,10 @@ public final class MidiManager { @Override public void onDeviceRemoved(MidiDeviceInfo device) { if (shouldInvokeCallback(device)) { - if (mHandler != null) { + if (mExecutor != null) { + mExecutor.execute(() -> + mCallback.onDeviceRemoved(device)); + } else if (mHandler != null) { final MidiDeviceInfo deviceF = device; mHandler.post(new Runnable() { @Override public void run() { @@ -150,7 +167,10 @@ public final class MidiManager { @Override public void onDeviceStatusChanged(MidiDeviceStatus status) { - if (mHandler != null) { + if (mExecutor != null) { + mExecutor.execute(() -> + mCallback.onDeviceStatusChanged(status)); + } else if (mHandler != null) { final MidiDeviceStatus statusF = status; mHandler.post(new Runnable() { @Override public void run() { @@ -234,7 +254,7 @@ public final class MidiManager { /** * Registers a callback to receive notifications when MIDI 1.0 devices are added and removed. * These are devices that do not default to Universal MIDI Packets. To register for a callback - * for those, call {@link #registerDeviceCallbackForTransport} instead. + * for those, call {@link #registerDeviceCallback} instead. * The {@link DeviceCallback#onDeviceStatusChanged} method will be called immediately * for any devices that have open ports. This allows applications to know which input @@ -247,9 +267,19 @@ public final class MidiManager { * @param handler The {@link android.os.Handler Handler} that will be used for delivering the * device notifications. If handler is null, then the thread used for the * callback is unspecified. + * @deprecated Use the {@link #registerDeviceCallback} + * method with Executor and transport instead. */ + @Deprecated public void registerDeviceCallback(DeviceCallback callback, Handler handler) { - registerDeviceCallbackForTransport(callback, handler, TRANSPORT_MIDI_BYTE_STREAM); + DeviceListener deviceListener = new DeviceListener(callback, handler, + TRANSPORT_MIDI_BYTE_STREAM); + try { + mService.registerListener(mToken, deviceListener); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + mDeviceListeners.put(callback, deviceListener); } /** @@ -263,16 +293,16 @@ public final class MidiManager { * Applications should call {@link #getDevicesForTransport} before registering the callback * to get a list of devices already added. * - * @param callback a {@link DeviceCallback} for MIDI device notifications - * @param handler The {@link android.os.Handler Handler} that will be used for delivering the - * device notifications. If handler is null, then the thread used for the - * callback is unspecified. * @param transport The transport to be used. This is either TRANSPORT_MIDI_BYTE_STREAM or * TRANSPORT_UNIVERSAL_MIDI_PACKETS. + * @param executor The {@link Executor} that will be used for delivering the + * device notifications. + * @param callback a {@link DeviceCallback} for MIDI device notifications */ - public void registerDeviceCallbackForTransport(@NonNull DeviceCallback callback, - @Nullable Handler handler, @Transport int transport) { - DeviceListener deviceListener = new DeviceListener(callback, handler, transport); + public void registerDeviceCallback(@Transport int transport, + @NonNull Executor executor, @NonNull DeviceCallback callback) { + Objects.requireNonNull(executor); + DeviceListener deviceListener = new DeviceListener(callback, executor, transport); try { mService.registerListener(mToken, deviceListener); } catch (RemoteException e) { @@ -303,7 +333,9 @@ public final class MidiManager { * {@link #getDevicesForTransport} instead. * * @return an array of MIDI devices + * @deprecated Use {@link #getDevicesForTransport} instead. */ + @Deprecated public MidiDeviceInfo[] getDevices() { try { return mService.getDevices(); @@ -322,14 +354,13 @@ public final class MidiManager { * TRANSPORT_UNIVERSAL_MIDI_PACKETS. * @return a collection of MIDI devices */ - public @NonNull Collection getDevicesForTransport(@Transport int transport) { + public @NonNull Set getDevicesForTransport(@Transport int transport) { try { MidiDeviceInfo[] devices = mService.getDevicesForTransport(transport); - Collection out = new ArrayList(devices.length); - for (int i = 0; i < devices.length; i++) { - out.add(devices[i]); + if (devices == null) { + return Collections.emptySet(); } - return out; + return new ArraySet<>(devices); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); }