summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorMike Lockwood <lockwood@google.com>2015-03-11 19:43:47 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-03-11 19:43:49 +0000
commit57baee2e12d1102372153cb4a66ff151c5cc855c (patch)
treeb35e7e39a1f720797a473944ff8d819b66d0f5c4 /services
parent70bea137744658e2e4e64fd7eab5723c2f0dd315 (diff)
parent5ff9e2a1719f78cddc7a23d6572ab15ab595dafd (diff)
downloadframeworks_base-57baee2e12d1102372153cb4a66ff151c5cc855c.zip
frameworks_base-57baee2e12d1102372153cb4a66ff151c5cc855c.tar.gz
frameworks_base-57baee2e12d1102372153cb4a66ff151c5cc855c.tar.bz2
Merge "MidiManager: Add MIDI device status notifications"
Diffstat (limited to 'services')
-rw-r--r--services/core/java/com/android/server/MidiService.java105
-rw-r--r--services/usb/java/com/android/server/usb/UsbMidiDevice.java2
2 files changed, 93 insertions, 14 deletions
diff --git a/services/core/java/com/android/server/MidiService.java b/services/core/java/com/android/server/MidiService.java
index 7f98b30..d534548 100644
--- a/services/core/java/com/android/server/MidiService.java
+++ b/services/core/java/com/android/server/MidiService.java
@@ -29,6 +29,7 @@ import android.media.midi.IMidiDeviceServer;
import android.media.midi.IMidiManager;
import android.media.midi.MidiDeviceInfo;
import android.media.midi.MidiDeviceService;
+import android.media.midi.MidiDeviceStatus;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
@@ -147,6 +148,19 @@ public class MidiService extends IMidiManager.Stub {
}
}
+ public void deviceStatusChanged(Device device, MidiDeviceStatus status) {
+ // ignore private devices that our client cannot access
+ if (!device.isUidAllowed(mUid)) return;
+
+ try {
+ for (IMidiDeviceListener listener : mListeners) {
+ listener.onDeviceStatusChanged(status);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "remote exception", e);
+ }
+ }
+
public void binderDied() {
removeClient(mToken);
}
@@ -187,6 +201,8 @@ public class MidiService extends IMidiManager.Stub {
private final class Device implements IBinder.DeathRecipient {
private final IMidiDeviceServer mServer;
private final MidiDeviceInfo mDeviceInfo;
+ private MidiDeviceStatus mDeviceStatus;
+ private IBinder mDeviceStatusToken;
// ServiceInfo for the device's MidiDeviceServer implementation (virtual devices only)
private final ServiceInfo mServiceInfo;
// UID of device implementation
@@ -204,6 +220,33 @@ public class MidiService extends IMidiManager.Stub {
return mDeviceInfo;
}
+ public MidiDeviceStatus getDeviceStatus() {
+ return mDeviceStatus;
+ }
+
+ public void setDeviceStatus(IBinder token, MidiDeviceStatus status) {
+ mDeviceStatus = status;
+
+ if (mDeviceStatusToken == null && token != null) {
+ // register a death recipient so we can clear the status when the device dies
+ try {
+ token.linkToDeath(new IBinder.DeathRecipient() {
+ @Override
+ public void binderDied() {
+ // reset to default status and clear the token
+ mDeviceStatus = new MidiDeviceStatus(mDeviceInfo);
+ mDeviceStatusToken = null;
+ notifyDeviceStatusChanged(Device.this, mDeviceStatus);
+ }
+ }, 0);
+ mDeviceStatusToken = token;
+ } catch (RemoteException e) {
+ // reset to default status
+ mDeviceStatus = new MidiDeviceStatus(mDeviceInfo);
+ }
+ }
+ }
+
public IMidiDeviceServer getDeviceServer() {
return mServer;
}
@@ -216,6 +259,10 @@ public class MidiService extends IMidiManager.Stub {
return (mServiceInfo == null ? null : mServiceInfo.packageName);
}
+ public int getUid() {
+ return mUid;
+ }
+
public boolean isUidAllowed(int uid) {
return (!mDeviceInfo.isPrivate() || mUid == uid);
}
@@ -302,13 +349,14 @@ public class MidiService extends IMidiManager.Stub {
@Override
public MidiDeviceInfo registerDeviceServer(IMidiDeviceServer server, int numInputPorts,
int numOutputPorts, Bundle properties, int type) {
- if (type != MidiDeviceInfo.TYPE_VIRTUAL && Binder.getCallingUid() != Process.SYSTEM_UID) {
+ int uid = Binder.getCallingUid();
+ if (type != MidiDeviceInfo.TYPE_VIRTUAL && uid != Process.SYSTEM_UID) {
throw new SecurityException("only system can create non-virtual devices");
}
synchronized (mDevicesByInfo) {
return addDeviceLocked(type, numInputPorts, numOutputPorts, properties,
- server, null, false, -1);
+ server, null, false, uid);
}
}
@@ -337,6 +385,39 @@ public class MidiService extends IMidiManager.Stub {
}
}
+ @Override
+ public MidiDeviceStatus getDeviceStatus(MidiDeviceInfo deviceInfo) {
+ Device device = mDevicesByInfo.get(deviceInfo);
+ if (device == null) {
+ throw new IllegalArgumentException("no such device for " + deviceInfo);
+ }
+ return device.getDeviceStatus();
+ }
+
+ @Override
+ public void setDeviceStatus(IBinder token, MidiDeviceStatus status) {
+ MidiDeviceInfo deviceInfo = status.getDeviceInfo();
+ Device device = mDevicesByInfo.get(deviceInfo);
+ if (device == null) {
+ // Just return quietly here if device no longer exists
+ return;
+ }
+ if (Binder.getCallingUid() != device.getUid()) {
+ throw new SecurityException("setDeviceStatus() caller UID " + Binder.getCallingUid()
+ + " does not match device's UID " + device.getUid());
+ }
+ device.setDeviceStatus(token, status);
+ notifyDeviceStatusChanged(device, status);
+ }
+
+ private void notifyDeviceStatusChanged(Device device, MidiDeviceStatus status) {
+ synchronized (mClients) {
+ for (Client c : mClients.values()) {
+ c.deviceStatusChanged(device, status);
+ }
+ }
+ }
+
// synchronize on mDevicesByInfo
private MidiDeviceInfo addDeviceLocked(int type, int numInputPorts, int numOutputPorts,
Bundle properties, IMidiDeviceServer server, ServiceInfo serviceInfo,
@@ -469,17 +550,15 @@ public class MidiService extends IMidiManager.Stub {
continue;
}
- int uid = -1;
- if (isPrivate) {
- try {
- ApplicationInfo appInfo = mPackageManager.getApplicationInfo(
- serviceInfo.packageName, 0);
- uid = appInfo.uid;
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(TAG, "could not fetch ApplicationInfo for "
- + serviceInfo.packageName);
- continue;
- }
+ int uid;
+ try {
+ ApplicationInfo appInfo = mPackageManager.getApplicationInfo(
+ serviceInfo.packageName, 0);
+ uid = appInfo.uid;
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, "could not fetch ApplicationInfo for "
+ + serviceInfo.packageName);
+ continue;
}
synchronized (mDevicesByInfo) {
diff --git a/services/usb/java/com/android/server/usb/UsbMidiDevice.java b/services/usb/java/com/android/server/usb/UsbMidiDevice.java
index f927965..725f393 100644
--- a/services/usb/java/com/android/server/usb/UsbMidiDevice.java
+++ b/services/usb/java/com/android/server/usb/UsbMidiDevice.java
@@ -121,7 +121,7 @@ public final class UsbMidiDevice implements Closeable {
int outputCount = mOutputStreams.length;
mServer = midiManager.createDeviceServer(mInputPortReceivers, outputCount,
- properties, MidiDeviceInfo.TYPE_USB);
+ properties, MidiDeviceInfo.TYPE_USB, null);
if (mServer == null) {
return false;
}