summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorMike Lockwood <lockwood@google.com>2015-06-08 19:37:00 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-06-08 19:37:36 +0000
commit383ce580b1c9e706d1b06a23d81986f3b4ed83fb (patch)
tree9a672b4825f4f470d03526a3697ad6781ec77c0c /media
parente4bd7c98323b39a47682216bebf442de206a95dd (diff)
parente0a6ca64fac5bd4f10139321604031816e90adb4 (diff)
downloadframeworks_base-383ce580b1c9e706d1b06a23d81986f3b4ed83fb.zip
frameworks_base-383ce580b1c9e706d1b06a23d81986f3b4ed83fb.tar.gz
frameworks_base-383ce580b1c9e706d1b06a23d81986f3b4ed83fb.tar.bz2
Merge "MidiManager: proxy all requests to open devices through MidiService" into mnc-dev
Diffstat (limited to 'media')
-rw-r--r--media/java/android/media/midi/IMidiDeviceOpenCallback.aidl25
-rw-r--r--media/java/android/media/midi/IMidiDeviceServer.aidl1
-rw-r--r--media/java/android/media/midi/IMidiManager.aidl15
-rw-r--r--media/java/android/media/midi/MidiDevice.java27
-rw-r--r--media/java/android/media/midi/MidiDeviceServer.java16
-rw-r--r--media/java/android/media/midi/MidiDeviceService.java11
-rw-r--r--media/java/android/media/midi/MidiManager.java118
-rw-r--r--media/java/android/media/midi/package.html6
-rw-r--r--media/packages/BluetoothMidiService/AndroidManifest.xml3
-rw-r--r--media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothMidiDevice.java26
10 files changed, 140 insertions, 108 deletions
diff --git a/media/java/android/media/midi/IMidiDeviceOpenCallback.aidl b/media/java/android/media/midi/IMidiDeviceOpenCallback.aidl
new file mode 100644
index 0000000..6e3dbbf
--- /dev/null
+++ b/media/java/android/media/midi/IMidiDeviceOpenCallback.aidl
@@ -0,0 +1,25 @@
+/*
+ * 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;
+
+import android.media.midi.IMidiDeviceServer;
+
+/** @hide */
+oneway interface IMidiDeviceOpenCallback
+{
+ void onDeviceOpened(in IMidiDeviceServer server, IBinder token);
+}
diff --git a/media/java/android/media/midi/IMidiDeviceServer.aidl b/media/java/android/media/midi/IMidiDeviceServer.aidl
index 96d12fd..e30796d 100644
--- a/media/java/android/media/midi/IMidiDeviceServer.aidl
+++ b/media/java/android/media/midi/IMidiDeviceServer.aidl
@@ -25,6 +25,7 @@ interface IMidiDeviceServer
ParcelFileDescriptor openInputPort(IBinder token, int portNumber);
ParcelFileDescriptor openOutputPort(IBinder token, int portNumber);
void closePort(IBinder token);
+ void closeDevice();
// connects the input port pfd to the specified output port
void connectPorts(IBinder token, in ParcelFileDescriptor pfd, int outputPortNumber);
diff --git a/media/java/android/media/midi/IMidiManager.aidl b/media/java/android/media/midi/IMidiManager.aidl
index fcd4aff..d3c8e0a 100644
--- a/media/java/android/media/midi/IMidiManager.aidl
+++ b/media/java/android/media/midi/IMidiManager.aidl
@@ -16,7 +16,10 @@
package android.media.midi;
+import android.bluetooth.BluetoothDevice;
import android.media.midi.IMidiDeviceListener;
+import android.media.midi.IMidiDeviceOpenCallback;
+import android.media.midi.IMidiDeviceServer;
import android.media.midi.IMidiDeviceServer;
import android.media.midi.MidiDeviceInfo;
import android.media.midi.MidiDeviceStatus;
@@ -29,11 +32,13 @@ interface IMidiManager
MidiDeviceInfo[] getDevices();
// for device creation & removal notifications
- void registerListener(IBinder token, in IMidiDeviceListener listener);
- void unregisterListener(IBinder token, in IMidiDeviceListener listener);
+ void registerListener(IBinder clientToken, in IMidiDeviceListener listener);
+ void unregisterListener(IBinder clientToken, in IMidiDeviceListener listener);
- // for opening built-in MIDI devices
- IMidiDeviceServer openDevice(IBinder token, in MidiDeviceInfo device);
+ void openDevice(IBinder clientToken, in MidiDeviceInfo device, in IMidiDeviceOpenCallback callback);
+ void openBluetoothDevice(IBinder clientToken, in BluetoothDevice bluetoothDevice,
+ in IMidiDeviceOpenCallback callback);
+ void closeDevice(IBinder clientToken, IBinder deviceToken);
// for registering built-in MIDI devices
MidiDeviceInfo registerDeviceServer(in IMidiDeviceServer server, int numInputPorts,
@@ -52,5 +57,5 @@ interface IMidiManager
// used by MIDI devices to report their status
// the token is used by MidiService for death notification
- void setDeviceStatus(IBinder token, in MidiDeviceStatus status);
+ void setDeviceStatus(in IMidiDeviceServer server, in MidiDeviceStatus status);
}
diff --git a/media/java/android/media/midi/MidiDevice.java b/media/java/android/media/midi/MidiDevice.java
index 6526adc..7998a92 100644
--- a/media/java/android/media/midi/MidiDevice.java
+++ b/media/java/android/media/midi/MidiDevice.java
@@ -16,8 +16,6 @@
package android.media.midi;
-import android.content.Context;
-import android.content.ServiceConnection;
import android.os.Binder;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
@@ -40,9 +38,9 @@ public final class MidiDevice implements Closeable {
private final MidiDeviceInfo mDeviceInfo;
private final IMidiDeviceServer mDeviceServer;
- private Context mContext;
- private ServiceConnection mServiceConnection;
-
+ private final IMidiManager mMidiManager;
+ private final IBinder mClientToken;
+ private final IBinder mDeviceToken;
private final CloseGuard mGuard = CloseGuard.get();
@@ -71,16 +69,13 @@ public final class MidiDevice implements Closeable {
}
}
- /* package */ MidiDevice(MidiDeviceInfo deviceInfo, IMidiDeviceServer server) {
- this(deviceInfo, server, null, null);
- }
-
/* package */ MidiDevice(MidiDeviceInfo deviceInfo, IMidiDeviceServer server,
- Context context, ServiceConnection serviceConnection) {
+ IMidiManager midiManager, IBinder clientToken, IBinder deviceToken) {
mDeviceInfo = deviceInfo;
mDeviceServer = server;
- mContext = context;
- mServiceConnection = serviceConnection;
+ mMidiManager = midiManager;
+ mClientToken = clientToken;
+ mDeviceToken = deviceToken;
mGuard.open("close");
}
@@ -170,10 +165,10 @@ public final class MidiDevice implements Closeable {
public void close() throws IOException {
synchronized (mGuard) {
mGuard.close();
- if (mContext != null && mServiceConnection != null) {
- mContext.unbindService(mServiceConnection);
- mContext = null;
- mServiceConnection = null;
+ try {
+ mMidiManager.closeDevice(mClientToken, mDeviceToken);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in closeDevice");
}
}
}
diff --git a/media/java/android/media/midi/MidiDeviceServer.java b/media/java/android/media/midi/MidiDeviceServer.java
index a316a44..1b56e1c 100644
--- a/media/java/android/media/midi/MidiDeviceServer.java
+++ b/media/java/android/media/midi/MidiDeviceServer.java
@@ -65,7 +65,6 @@ public final class MidiDeviceServer implements Closeable {
// for reporting device status
- private final IBinder mDeviceStatusToken = new Binder();
private final boolean[] mInputPortOpen;
private final int[] mOutputPortOpenCount;
@@ -81,6 +80,11 @@ public final class MidiDeviceServer implements Closeable {
* @param status the {@link MidiDeviceStatus} for the device
*/
public void onDeviceStatusChanged(MidiDeviceServer server, MidiDeviceStatus status);
+
+ /**
+ * Called to notify when the device is closed
+ */
+ public void onClose();
}
abstract private class PortClient implements IBinder.DeathRecipient {
@@ -242,6 +246,14 @@ public final class MidiDeviceServer implements Closeable {
}
@Override
+ public void closeDevice() {
+ if (mCallback != null) {
+ mCallback.onClose();
+ }
+ IoUtils.closeQuietly(MidiDeviceServer.this);
+ }
+
+ @Override
public void connectPorts(IBinder token, ParcelFileDescriptor pfd,
int outputPortNumber) {
MidiInputPort inputPort = new MidiInputPort(pfd, outputPortNumber);
@@ -305,7 +317,7 @@ public final class MidiDeviceServer implements Closeable {
mCallback.onDeviceStatusChanged(this, status);
}
try {
- mMidiManager.setDeviceStatus(mDeviceStatusToken, status);
+ mMidiManager.setDeviceStatus(mServer, status);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException in updateDeviceStatus");
} finally {
diff --git a/media/java/android/media/midi/MidiDeviceService.java b/media/java/android/media/midi/MidiDeviceService.java
index ce12a4f..d897ad2 100644
--- a/media/java/android/media/midi/MidiDeviceService.java
+++ b/media/java/android/media/midi/MidiDeviceService.java
@@ -59,6 +59,11 @@ abstract public class MidiDeviceService extends Service {
public void onDeviceStatusChanged(MidiDeviceServer server, MidiDeviceStatus status) {
MidiDeviceService.this.onDeviceStatusChanged(status);
}
+
+ @Override
+ public void onClose() {
+ MidiDeviceService.this.onClose();
+ }
};
@Override
@@ -125,6 +130,12 @@ abstract public class MidiDeviceService extends Service {
public void onDeviceStatusChanged(MidiDeviceStatus status) {
}
+ /**
+ * Called to notify when our device has been closed by all its clients
+ */
+ public void onClose() {
+ }
+
@Override
public IBinder onBind(Intent intent) {
if (SERVICE_INTERFACE.equals(intent.getAction()) && mServer != null) {
diff --git a/media/java/android/media/midi/MidiManager.java b/media/java/android/media/midi/MidiManager.java
index d19cf36..0beb9a4 100644
--- a/media/java/android/media/midi/MidiManager.java
+++ b/media/java/android/media/midi/MidiManager.java
@@ -17,11 +17,6 @@
package android.media.midi;
import android.bluetooth.BluetoothDevice;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.content.pm.ServiceInfo;
import android.os.Binder;
import android.os.IBinder;
import android.os.Bundle;
@@ -52,16 +47,17 @@ public final class MidiManager {
/**
* BluetoothMidiService package name
+ * @hide
*/
- private static final String BLUETOOTH_MIDI_SERVICE_PACKAGE = "com.android.bluetoothmidiservice";
+ public static final String BLUETOOTH_MIDI_SERVICE_PACKAGE = "com.android.bluetoothmidiservice";
/**
* BluetoothMidiService class name
+ * @hide
*/
- private static final String BLUETOOTH_MIDI_SERVICE_CLASS =
+ public static final String BLUETOOTH_MIDI_SERVICE_CLASS =
"com.android.bluetoothmidiservice.BluetoothMidiService";
- private final Context mContext;
private final IMidiManager mService;
private final IBinder mToken = new Binder();
@@ -166,8 +162,7 @@ public final class MidiManager {
/**
* @hide
*/
- public MidiManager(Context context, IMidiManager service) {
- mContext = context;
+ public MidiManager(IMidiManager service) {
mService = service;
}
@@ -237,7 +232,7 @@ public final class MidiManager {
* Opens a MIDI device for reading and writing.
*
* @param deviceInfo a {@link android.media.midi.MidiDeviceInfo} to open
- * @param listener a {@link MidiManager.OnDeviceOpenedListener} to be called
+ * @param listener a {@link MidiManager.OnDeviceOpenedListener} to be called
* to receive the result
* @param handler the {@link android.os.Handler Handler} that will be used for delivering
* the result. If handler is null, then the thread used for the
@@ -245,52 +240,28 @@ public final class MidiManager {
*/
public void openDevice(MidiDeviceInfo deviceInfo, OnDeviceOpenedListener listener,
Handler handler) {
- MidiDevice device = null;
- try {
- IMidiDeviceServer server = mService.openDevice(mToken, deviceInfo);
- if (server == null) {
- ServiceInfo serviceInfo = (ServiceInfo)deviceInfo.getProperties().getParcelable(
- MidiDeviceInfo.PROPERTY_SERVICE_INFO);
- if (serviceInfo == null) {
- Log.e(TAG, "no ServiceInfo for " + deviceInfo);
- } else {
- Intent intent = new Intent(MidiDeviceService.SERVICE_INTERFACE);
- intent.setComponent(new ComponentName(serviceInfo.packageName,
- serviceInfo.name));
- final MidiDeviceInfo deviceInfoF = deviceInfo;
- final OnDeviceOpenedListener listenerF = listener;
- final Handler handlerF = handler;
- if (mContext.bindService(intent,
- new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName name, IBinder binder) {
- IMidiDeviceServer server =
- IMidiDeviceServer.Stub.asInterface(binder);
- MidiDevice device = new MidiDevice(deviceInfoF, server, mContext,
- this);
- sendOpenDeviceResponse(device, listenerF, handlerF);
- }
+ final MidiDeviceInfo deviceInfoF = deviceInfo;
+ final OnDeviceOpenedListener listenerF = listener;
+ final Handler handlerF = handler;
- @Override
- public void onServiceDisconnected(ComponentName name) {
- // FIXME - anything to do here?
- }
- },
- Context.BIND_AUTO_CREATE))
- {
- // return immediately to avoid calling sendOpenDeviceResponse below
- return;
- } else {
- Log.e(TAG, "Unable to bind service: " + intent);
- }
+ IMidiDeviceOpenCallback callback = new IMidiDeviceOpenCallback.Stub() {
+ @Override
+ public void onDeviceOpened(IMidiDeviceServer server, IBinder deviceToken) {
+ MidiDevice device;
+ if (server != null) {
+ device = new MidiDevice(deviceInfoF, server, mService, mToken, deviceToken);
+ } else {
+ device = null;
}
- } else {
- device = new MidiDevice(deviceInfo, server);
+ sendOpenDeviceResponse(device, listenerF, handlerF);
}
+ };
+
+ try {
+ mService.openDevice(mToken, deviceInfo, callback);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException in openDevice");
}
- sendOpenDeviceResponse(device, listener, handler);
}
/**
@@ -303,38 +274,33 @@ public final class MidiManager {
* the result. If handler is null, then the thread used for the
* listener is unspecified.
*/
- public void openBluetoothDevice(final BluetoothDevice bluetoothDevice,
- final OnDeviceOpenedListener listener, final Handler handler) {
- Intent intent = new Intent(BLUETOOTH_MIDI_SERVICE_INTENT);
- intent.setComponent(new ComponentName(BLUETOOTH_MIDI_SERVICE_PACKAGE,
- BLUETOOTH_MIDI_SERVICE_CLASS));
- intent.putExtra("device", bluetoothDevice);
- if (!mContext.bindService(intent,
- new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName name, IBinder binder) {
- IMidiDeviceServer server =
- IMidiDeviceServer.Stub.asInterface(binder);
+ public void openBluetoothDevice(BluetoothDevice bluetoothDevice,
+ OnDeviceOpenedListener listener, Handler handler) {
+ final OnDeviceOpenedListener listenerF = listener;
+ final Handler handlerF = handler;
+
+ IMidiDeviceOpenCallback callback = new IMidiDeviceOpenCallback.Stub() {
+ @Override
+ public void onDeviceOpened(IMidiDeviceServer server, IBinder deviceToken) {
+ MidiDevice device = null;
+ if (server != null) {
try {
// fetch MidiDeviceInfo from the server
MidiDeviceInfo deviceInfo = server.getDeviceInfo();
- MidiDevice device = new MidiDevice(deviceInfo, server, mContext, this);
- sendOpenDeviceResponse(device, listener, handler);
+ device = new MidiDevice(deviceInfo, server, mService, mToken, deviceToken);
+ sendOpenDeviceResponse(device, listenerF, handlerF);
} catch (RemoteException e) {
- Log.e(TAG, "remote exception in onServiceConnected");
- sendOpenDeviceResponse(null, listener, handler);
+ Log.e(TAG, "remote exception in getDeviceInfo()");
}
}
+ sendOpenDeviceResponse(device, listenerF, handlerF);
+ }
+ };
- @Override
- public void onServiceDisconnected(ComponentName name) {
- // FIXME - anything to do here?
- }
- },
- Context.BIND_AUTO_CREATE))
- {
- Log.e(TAG, "Unable to bind service: " + intent);
- sendOpenDeviceResponse(null, listener, handler);
+ try {
+ mService.openBluetoothDevice(mToken, bluetoothDevice, callback);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in openDevice");
}
}
diff --git a/media/java/android/media/midi/package.html b/media/java/android/media/midi/package.html
index bd589a9..8b2bd16 100644
--- a/media/java/android/media/midi/package.html
+++ b/media/java/android/media/midi/package.html
@@ -241,7 +241,8 @@ messages.</p>
<p>An app can provide a MIDI Service that can be used by other apps. For example,
-an app can provide a custom synthesizer that other apps can send messages to. </p>
+an app can provide a custom synthesizer that other apps can send messages to.
+The service must be guarded with permission &quot;android.permission.BIND_MIDI_DEVICE_SERVICE&quot;.</p>
<h2 id=manifest_files>Manifest Files</h2>
@@ -250,7 +251,8 @@ an app can provide a custom synthesizer that other apps can send messages to. </
AndroidManifest.xml file.</p>
<pre class=prettyprint>
-&lt;service android:name="<strong>MySynthDeviceService</strong>">
+&lt;service android:name="<strong>MySynthDeviceService</strong>"
+ android:permission="android.permission.BIND_MIDI_DEVICE_SERVICE">
&lt;intent-filter>
&lt;action android:name="android.media.midi.MidiDeviceService" />
&lt;/intent-filter>
diff --git a/media/packages/BluetoothMidiService/AndroidManifest.xml b/media/packages/BluetoothMidiService/AndroidManifest.xml
index 15aa581..b0b389a 100644
--- a/media/packages/BluetoothMidiService/AndroidManifest.xml
+++ b/media/packages/BluetoothMidiService/AndroidManifest.xml
@@ -8,7 +8,8 @@
<application
android:label="@string/app_name">
- <service android:name="BluetoothMidiService">
+ <service android:name="BluetoothMidiService"
+ android:permission="android.permission.BIND_MIDI_DEVICE_SERVICE">
<intent-filter>
<action android:name="android.media.midi.BluetoothMidiService" />
</intent-filter>
diff --git a/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothMidiDevice.java b/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothMidiDevice.java
index 60c6570..e6d59e4 100644
--- a/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothMidiDevice.java
+++ b/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothMidiDevice.java
@@ -24,10 +24,11 @@ import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
-import android.media.midi.MidiReceiver;
-import android.media.midi.MidiManager;
-import android.media.midi.MidiDeviceServer;
import android.media.midi.MidiDeviceInfo;
+import android.media.midi.MidiDeviceServer;
+import android.media.midi.MidiDeviceStatus;
+import android.media.midi.MidiManager;
+import android.media.midi.MidiReceiver;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
@@ -81,6 +82,18 @@ public final class BluetoothMidiDevice {
private final BluetoothPacketDecoder mPacketDecoder
= new BluetoothPacketDecoder(MAX_PACKET_SIZE);
+ private final MidiDeviceServer.Callback mDeviceServerCallback
+ = new MidiDeviceServer.Callback() {
+ @Override
+ public void onDeviceStatusChanged(MidiDeviceServer server, MidiDeviceStatus status) {
+ }
+
+ @Override
+ public void onClose() {
+ close();
+ }
+ };
+
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status,
@@ -213,7 +226,7 @@ public final class BluetoothMidiDevice {
inputPortReceivers[0] = mEventScheduler.getReceiver();
mDeviceServer = mMidiManager.createDeviceServer(inputPortReceivers, 1,
- null, null, properties, MidiDeviceInfo.TYPE_BLUETOOTH, null);
+ null, null, properties, MidiDeviceInfo.TYPE_BLUETOOTH, mDeviceServerCallback);
mOutputReceiver = mDeviceServer.getOutputPortReceivers()[0];
@@ -248,11 +261,12 @@ public final class BluetoothMidiDevice {
private void close() {
synchronized (mBluetoothDevice) {
- mEventScheduler.close();
+ mEventScheduler.close();
+ mService.deviceClosed(mBluetoothDevice);
+
if (mDeviceServer != null) {
IoUtils.closeQuietly(mDeviceServer);
mDeviceServer = null;
- mService.deviceClosed(mBluetoothDevice);
}
if (mBluetoothGatt != null) {
mBluetoothGatt.close();