Loading media/java/android/media/midi/IMidiDeviceListener.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -17,10 +17,12 @@ package android.media.midi; import android.media.midi.MidiDeviceInfo; import android.media.midi.MidiDeviceStatus; /** @hide */ oneway interface IMidiDeviceListener { void onDeviceAdded(in MidiDeviceInfo device); void onDeviceRemoved(in MidiDeviceInfo device); void onDeviceStatusChanged(in MidiDeviceStatus status); } media/java/android/media/midi/IMidiManager.aidl +8 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.media.midi; import android.media.midi.IMidiDeviceListener; import android.media.midi.IMidiDeviceServer; import android.media.midi.MidiDeviceInfo; import android.media.midi.MidiDeviceStatus; import android.os.Bundle; import android.os.IBinder; Loading @@ -44,4 +45,11 @@ interface IMidiManager // used by MidiDeviceService to access the MidiDeviceInfo that was created based on its // manifest's meta-data MidiDeviceInfo getServiceDeviceInfo(String packageName, String className); // used for client's to retrieve a device's MidiDeviceStatus MidiDeviceStatus getDeviceStatus(in MidiDeviceInfo deviceInfo); // used by MIDI devices to report their status // the token is used by MidiService for death notification void setDeviceStatus(IBinder token, in MidiDeviceStatus status); } media/java/android/media/midi/MidiDeviceServer.java +67 −5 Original line number Diff line number Diff line Loading @@ -16,8 +16,8 @@ package android.media.midi; import android.os.IBinder; import android.os.Binder; import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.RemoteException; Loading Loading @@ -61,7 +61,25 @@ public final class MidiDeviceServer implements Closeable { private final CopyOnWriteArrayList<MidiInputPort> mInputPorts = new CopyOnWriteArrayList<MidiInputPort>(); // for reporting device status private final IBinder mDeviceStatusToken = new Binder(); private final boolean[] mInputPortBusy; private final int[] mOutputPortOpenCount; private final CloseGuard mGuard = CloseGuard.get(); private boolean mIsClosed; private final Callback mCallback; public interface Callback { /** * Called to notify when an our device status has changed * @param server the {@link MidiDeviceServer} that changed * @param status the {@link MidiDeviceStatus} for the device */ public void onDeviceStatusChanged(MidiDeviceServer server, MidiDeviceStatus status); } abstract private class PortClient implements IBinder.DeathRecipient { final IBinder mToken; Loading Loading @@ -96,7 +114,10 @@ public final class MidiDeviceServer implements Closeable { void close() { mToken.unlinkToDeath(this, 0); synchronized (mInputPortOutputPorts) { mInputPortOutputPorts[mOutputPort.getPortNumber()] = null; int portNumber = mOutputPort.getPortNumber(); mInputPortOutputPorts[portNumber] = null; mInputPortBusy[portNumber] = false; updateDeviceStatus(); } IoUtils.closeQuietly(mOutputPort); } Loading @@ -113,7 +134,15 @@ public final class MidiDeviceServer implements Closeable { @Override void close() { mToken.unlinkToDeath(this, 0); mOutputPortDispatchers[mInputPort.getPortNumber()].getSender().disconnect(mInputPort); int portNumber = mInputPort.getPortNumber(); MidiDispatcher dispatcher = mOutputPortDispatchers[portNumber]; synchronized (dispatcher) { dispatcher.getSender().disconnect(mInputPort); int openCount = dispatcher.getReceiverCount(); mOutputPortOpenCount[portNumber] = openCount; updateDeviceStatus(); } mInputPorts.remove(mInputPort); IoUtils.closeQuietly(mInputPort); } Loading Loading @@ -153,6 +182,8 @@ public final class MidiDeviceServer implements Closeable { synchronized (mPortClients) { mPortClients.put(token, client); } mInputPortBusy[portNumber] = true; updateDeviceStatus(); return pair[1]; } catch (IOException e) { Log.e(TAG, "unable to create ParcelFileDescriptors in openInputPort"); Loading @@ -178,7 +209,14 @@ public final class MidiDeviceServer implements Closeable { ParcelFileDescriptor[] pair = ParcelFileDescriptor.createSocketPair( OsConstants.SOCK_SEQPACKET); MidiInputPort inputPort = new MidiInputPort(pair[0], portNumber); mOutputPortDispatchers[portNumber].getSender().connect(inputPort); MidiDispatcher dispatcher = mOutputPortDispatchers[portNumber]; synchronized (dispatcher) { dispatcher.getSender().connect(inputPort); int openCount = dispatcher.getReceiverCount(); mOutputPortOpenCount[portNumber] = openCount; updateDeviceStatus(); } mInputPorts.add(inputPort); OutputPortClient client = new OutputPortClient(token, inputPort); synchronized (mPortClients) { Loading Loading @@ -215,11 +253,12 @@ public final class MidiDeviceServer implements Closeable { }; /* package */ MidiDeviceServer(IMidiManager midiManager, MidiReceiver[] inputPortReceivers, int numOutputPorts) { int numOutputPorts, Callback callback) { mMidiManager = midiManager; mInputPortReceivers = inputPortReceivers; mInputPortCount = inputPortReceivers.length; mOutputPortCount = numOutputPorts; mCallback = callback; mInputPortOutputPorts = new MidiOutputPort[mInputPortCount]; Loading @@ -228,6 +267,9 @@ public final class MidiDeviceServer implements Closeable { mOutputPortDispatchers[i] = new MidiDispatcher(); } mInputPortBusy = new boolean[mInputPortCount]; mOutputPortOpenCount = new int[numOutputPorts]; mGuard.open("close"); } Loading @@ -242,9 +284,28 @@ public final class MidiDeviceServer implements Closeable { mDeviceInfo = deviceInfo; } private void updateDeviceStatus() { // clear calling identity, since we may be in a Binder call from one of our clients long identityToken = Binder.clearCallingIdentity(); MidiDeviceStatus status = new MidiDeviceStatus(mDeviceInfo, mInputPortBusy, mOutputPortOpenCount); if (mCallback != null) { mCallback.onDeviceStatusChanged(this, status); } try { mMidiManager.setDeviceStatus(mDeviceStatusToken, status); } catch (RemoteException e) { Log.e(TAG, "RemoteException in updateDeviceStatus"); } finally { Binder.restoreCallingIdentity(identityToken); } } @Override public void close() throws IOException { synchronized (mGuard) { if (mIsClosed) return; mGuard.close(); for (int i = 0; i < mInputPortCount; i++) { Loading @@ -263,6 +324,7 @@ public final class MidiDeviceServer implements Closeable { } catch (RemoteException e) { Log.e(TAG, "RemoteException in unregisterDeviceServer"); } mIsClosed = true; } } Loading media/java/android/media/midi/MidiDeviceService.java +15 −1 Original line number Diff line number Diff line Loading @@ -57,6 +57,13 @@ abstract public class MidiDeviceService extends Service { private MidiDeviceServer mServer; private MidiDeviceInfo mDeviceInfo; private final MidiDeviceServer.Callback mCallback = new MidiDeviceServer.Callback() { @Override public void onDeviceStatusChanged(MidiDeviceServer server, MidiDeviceStatus status) { MidiDeviceService.this.onDeviceStatusChanged(status); } }; @Override public void onCreate() { mMidiManager = IMidiManager.Stub.asInterface( Loading @@ -75,7 +82,7 @@ abstract public class MidiDeviceService extends Service { inputPortReceivers = new MidiReceiver[0]; } server = new MidiDeviceServer(mMidiManager, inputPortReceivers, deviceInfo.getOutputPortCount()); deviceInfo.getOutputPortCount(), mCallback); server.setDeviceInfo(deviceInfo); } catch (RemoteException e) { Log.e(TAG, "RemoteException in IMidiManager.getServiceDeviceInfo"); Loading Loading @@ -114,6 +121,13 @@ abstract public class MidiDeviceService extends Service { return mDeviceInfo; } /** * Called to notify when an our {@link MidiDeviceStatus} has changed * @param status the number of the port that was opened */ public void onDeviceStatusChanged(MidiDeviceStatus status) { } @Override public IBinder onBind(Intent intent) { if (SERVICE_INTERFACE.equals(intent.getAction()) && mServer != null) { Loading media/java/android/media/midi/MidiDeviceStatus.aidl 0 → 100644 +19 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015, 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. */ package android.media.midi; parcelable MidiDeviceStatus; Loading
media/java/android/media/midi/IMidiDeviceListener.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -17,10 +17,12 @@ package android.media.midi; import android.media.midi.MidiDeviceInfo; import android.media.midi.MidiDeviceStatus; /** @hide */ oneway interface IMidiDeviceListener { void onDeviceAdded(in MidiDeviceInfo device); void onDeviceRemoved(in MidiDeviceInfo device); void onDeviceStatusChanged(in MidiDeviceStatus status); }
media/java/android/media/midi/IMidiManager.aidl +8 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.media.midi; import android.media.midi.IMidiDeviceListener; import android.media.midi.IMidiDeviceServer; import android.media.midi.MidiDeviceInfo; import android.media.midi.MidiDeviceStatus; import android.os.Bundle; import android.os.IBinder; Loading @@ -44,4 +45,11 @@ interface IMidiManager // used by MidiDeviceService to access the MidiDeviceInfo that was created based on its // manifest's meta-data MidiDeviceInfo getServiceDeviceInfo(String packageName, String className); // used for client's to retrieve a device's MidiDeviceStatus MidiDeviceStatus getDeviceStatus(in MidiDeviceInfo deviceInfo); // used by MIDI devices to report their status // the token is used by MidiService for death notification void setDeviceStatus(IBinder token, in MidiDeviceStatus status); }
media/java/android/media/midi/MidiDeviceServer.java +67 −5 Original line number Diff line number Diff line Loading @@ -16,8 +16,8 @@ package android.media.midi; import android.os.IBinder; import android.os.Binder; import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.RemoteException; Loading Loading @@ -61,7 +61,25 @@ public final class MidiDeviceServer implements Closeable { private final CopyOnWriteArrayList<MidiInputPort> mInputPorts = new CopyOnWriteArrayList<MidiInputPort>(); // for reporting device status private final IBinder mDeviceStatusToken = new Binder(); private final boolean[] mInputPortBusy; private final int[] mOutputPortOpenCount; private final CloseGuard mGuard = CloseGuard.get(); private boolean mIsClosed; private final Callback mCallback; public interface Callback { /** * Called to notify when an our device status has changed * @param server the {@link MidiDeviceServer} that changed * @param status the {@link MidiDeviceStatus} for the device */ public void onDeviceStatusChanged(MidiDeviceServer server, MidiDeviceStatus status); } abstract private class PortClient implements IBinder.DeathRecipient { final IBinder mToken; Loading Loading @@ -96,7 +114,10 @@ public final class MidiDeviceServer implements Closeable { void close() { mToken.unlinkToDeath(this, 0); synchronized (mInputPortOutputPorts) { mInputPortOutputPorts[mOutputPort.getPortNumber()] = null; int portNumber = mOutputPort.getPortNumber(); mInputPortOutputPorts[portNumber] = null; mInputPortBusy[portNumber] = false; updateDeviceStatus(); } IoUtils.closeQuietly(mOutputPort); } Loading @@ -113,7 +134,15 @@ public final class MidiDeviceServer implements Closeable { @Override void close() { mToken.unlinkToDeath(this, 0); mOutputPortDispatchers[mInputPort.getPortNumber()].getSender().disconnect(mInputPort); int portNumber = mInputPort.getPortNumber(); MidiDispatcher dispatcher = mOutputPortDispatchers[portNumber]; synchronized (dispatcher) { dispatcher.getSender().disconnect(mInputPort); int openCount = dispatcher.getReceiverCount(); mOutputPortOpenCount[portNumber] = openCount; updateDeviceStatus(); } mInputPorts.remove(mInputPort); IoUtils.closeQuietly(mInputPort); } Loading Loading @@ -153,6 +182,8 @@ public final class MidiDeviceServer implements Closeable { synchronized (mPortClients) { mPortClients.put(token, client); } mInputPortBusy[portNumber] = true; updateDeviceStatus(); return pair[1]; } catch (IOException e) { Log.e(TAG, "unable to create ParcelFileDescriptors in openInputPort"); Loading @@ -178,7 +209,14 @@ public final class MidiDeviceServer implements Closeable { ParcelFileDescriptor[] pair = ParcelFileDescriptor.createSocketPair( OsConstants.SOCK_SEQPACKET); MidiInputPort inputPort = new MidiInputPort(pair[0], portNumber); mOutputPortDispatchers[portNumber].getSender().connect(inputPort); MidiDispatcher dispatcher = mOutputPortDispatchers[portNumber]; synchronized (dispatcher) { dispatcher.getSender().connect(inputPort); int openCount = dispatcher.getReceiverCount(); mOutputPortOpenCount[portNumber] = openCount; updateDeviceStatus(); } mInputPorts.add(inputPort); OutputPortClient client = new OutputPortClient(token, inputPort); synchronized (mPortClients) { Loading Loading @@ -215,11 +253,12 @@ public final class MidiDeviceServer implements Closeable { }; /* package */ MidiDeviceServer(IMidiManager midiManager, MidiReceiver[] inputPortReceivers, int numOutputPorts) { int numOutputPorts, Callback callback) { mMidiManager = midiManager; mInputPortReceivers = inputPortReceivers; mInputPortCount = inputPortReceivers.length; mOutputPortCount = numOutputPorts; mCallback = callback; mInputPortOutputPorts = new MidiOutputPort[mInputPortCount]; Loading @@ -228,6 +267,9 @@ public final class MidiDeviceServer implements Closeable { mOutputPortDispatchers[i] = new MidiDispatcher(); } mInputPortBusy = new boolean[mInputPortCount]; mOutputPortOpenCount = new int[numOutputPorts]; mGuard.open("close"); } Loading @@ -242,9 +284,28 @@ public final class MidiDeviceServer implements Closeable { mDeviceInfo = deviceInfo; } private void updateDeviceStatus() { // clear calling identity, since we may be in a Binder call from one of our clients long identityToken = Binder.clearCallingIdentity(); MidiDeviceStatus status = new MidiDeviceStatus(mDeviceInfo, mInputPortBusy, mOutputPortOpenCount); if (mCallback != null) { mCallback.onDeviceStatusChanged(this, status); } try { mMidiManager.setDeviceStatus(mDeviceStatusToken, status); } catch (RemoteException e) { Log.e(TAG, "RemoteException in updateDeviceStatus"); } finally { Binder.restoreCallingIdentity(identityToken); } } @Override public void close() throws IOException { synchronized (mGuard) { if (mIsClosed) return; mGuard.close(); for (int i = 0; i < mInputPortCount; i++) { Loading @@ -263,6 +324,7 @@ public final class MidiDeviceServer implements Closeable { } catch (RemoteException e) { Log.e(TAG, "RemoteException in unregisterDeviceServer"); } mIsClosed = true; } } Loading
media/java/android/media/midi/MidiDeviceService.java +15 −1 Original line number Diff line number Diff line Loading @@ -57,6 +57,13 @@ abstract public class MidiDeviceService extends Service { private MidiDeviceServer mServer; private MidiDeviceInfo mDeviceInfo; private final MidiDeviceServer.Callback mCallback = new MidiDeviceServer.Callback() { @Override public void onDeviceStatusChanged(MidiDeviceServer server, MidiDeviceStatus status) { MidiDeviceService.this.onDeviceStatusChanged(status); } }; @Override public void onCreate() { mMidiManager = IMidiManager.Stub.asInterface( Loading @@ -75,7 +82,7 @@ abstract public class MidiDeviceService extends Service { inputPortReceivers = new MidiReceiver[0]; } server = new MidiDeviceServer(mMidiManager, inputPortReceivers, deviceInfo.getOutputPortCount()); deviceInfo.getOutputPortCount(), mCallback); server.setDeviceInfo(deviceInfo); } catch (RemoteException e) { Log.e(TAG, "RemoteException in IMidiManager.getServiceDeviceInfo"); Loading Loading @@ -114,6 +121,13 @@ abstract public class MidiDeviceService extends Service { return mDeviceInfo; } /** * Called to notify when an our {@link MidiDeviceStatus} has changed * @param status the number of the port that was opened */ public void onDeviceStatusChanged(MidiDeviceStatus status) { } @Override public IBinder onBind(Intent intent) { if (SERVICE_INTERFACE.equals(intent.getAction()) && mServer != null) { Loading
media/java/android/media/midi/MidiDeviceStatus.aidl 0 → 100644 +19 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015, 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. */ package android.media.midi; parcelable MidiDeviceStatus;