diff options
author | Mike Lockwood <lockwood@google.com> | 2015-03-11 19:43:47 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-03-11 19:43:49 +0000 |
commit | 57baee2e12d1102372153cb4a66ff151c5cc855c (patch) | |
tree | b35e7e39a1f720797a473944ff8d819b66d0f5c4 /services | |
parent | 70bea137744658e2e4e64fd7eab5723c2f0dd315 (diff) | |
parent | 5ff9e2a1719f78cddc7a23d6572ab15ab595dafd (diff) | |
download | frameworks_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.java | 105 | ||||
-rw-r--r-- | services/usb/java/com/android/server/usb/UsbMidiDevice.java | 2 |
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; } |