Merge "MIDI: Add virtual devices per user" into udc-qpr-dev
This commit is contained in:
@@ -16,7 +16,9 @@
|
||||
|
||||
package com.android.server.midi;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothUuid;
|
||||
import android.content.BroadcastReceiver;
|
||||
@@ -48,6 +50,7 @@ import android.os.ParcelUuid;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.EventLog;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -81,6 +84,11 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
// 2. synchronized (mDeviceConnections)
|
||||
//TODO Introduce a single lock object to lock the whole state and avoid the requirement above.
|
||||
|
||||
// All users should be able to connect to USB and Bluetooth MIDI devices.
|
||||
// All users can create can install an app that provides, a Virtual MIDI Device Service.
|
||||
// Users can not open virtual MIDI devices created by other users.
|
||||
// getDevices() surfaces devices that can be opened by that user.
|
||||
// openDevice() rejects devices that are cannot be opened by that user.
|
||||
public class MidiService extends IMidiManager.Stub {
|
||||
|
||||
public static class Lifecycle extends SystemService {
|
||||
@@ -97,10 +105,21 @@ public class MidiService extends IMidiManager.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
@RequiresPermission(allOf = {Manifest.permission.INTERACT_ACROSS_USERS},
|
||||
anyOf = {Manifest.permission.QUERY_USERS,
|
||||
Manifest.permission.CREATE_USERS,
|
||||
Manifest.permission.MANAGE_USERS})
|
||||
public void onUserStarting(@NonNull TargetUser user) {
|
||||
mMidiService.onStartOrUnlockUser(user, false /* matchDirectBootUnaware */);
|
||||
}
|
||||
|
||||
@Override
|
||||
@RequiresPermission(allOf = {Manifest.permission.INTERACT_ACROSS_USERS},
|
||||
anyOf = {Manifest.permission.QUERY_USERS,
|
||||
Manifest.permission.CREATE_USERS,
|
||||
Manifest.permission.MANAGE_USERS})
|
||||
public void onUserUnlocking(@NonNull TargetUser user) {
|
||||
if (user.getUserIdentifier() == UserHandle.USER_SYSTEM) {
|
||||
mMidiService.onUnlockUser();
|
||||
}
|
||||
mMidiService.onStartOrUnlockUser(user, true /* matchDirectBootUnaware */);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,6 +153,7 @@ public class MidiService extends IMidiManager.Stub {
|
||||
private int mNextDeviceId = 1;
|
||||
|
||||
private final PackageManager mPackageManager;
|
||||
private final UserManager mUserManager;
|
||||
|
||||
private static final String MIDI_LEGACY_STRING = "MIDI 1.0";
|
||||
private static final String MIDI_UNIVERSAL_STRING = "MIDI 2.0";
|
||||
@@ -159,21 +179,24 @@ public class MidiService extends IMidiManager.Stub {
|
||||
private final HashSet<ParcelUuid> mNonMidiUUIDs = new HashSet<ParcelUuid>();
|
||||
|
||||
// PackageMonitor for listening to package changes
|
||||
// uid is the uid of the package so use getChangingUserId() to fetch the userId.
|
||||
private final PackageMonitor mPackageMonitor = new PackageMonitor() {
|
||||
@Override
|
||||
@RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS)
|
||||
public void onPackageAdded(String packageName, int uid) {
|
||||
addPackageDeviceServers(packageName);
|
||||
addPackageDeviceServers(packageName, getChangingUserId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS)
|
||||
public void onPackageModified(String packageName) {
|
||||
removePackageDeviceServers(packageName);
|
||||
addPackageDeviceServers(packageName);
|
||||
removePackageDeviceServers(packageName, getChangingUserId());
|
||||
addPackageDeviceServers(packageName, getChangingUserId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPackageRemoved(String packageName, int uid) {
|
||||
removePackageDeviceServers(packageName);
|
||||
removePackageDeviceServers(packageName, getChangingUserId());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -202,6 +225,10 @@ public class MidiService extends IMidiManager.Stub {
|
||||
return mUid;
|
||||
}
|
||||
|
||||
private int getUserId() {
|
||||
return UserHandle.getUserId(mUid);
|
||||
}
|
||||
|
||||
public void addListener(IMidiDeviceListener listener) {
|
||||
if (mListeners.size() >= MAX_LISTENERS_PER_CLIENT) {
|
||||
throw new SecurityException(
|
||||
@@ -219,8 +246,12 @@ public class MidiService extends IMidiManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
public void addDeviceConnection(Device device, IMidiDeviceOpenCallback callback) {
|
||||
Log.d(TAG, "addDeviceConnection() device:" + device);
|
||||
@RequiresPermission(anyOf = {Manifest.permission.INTERACT_ACROSS_USERS_FULL,
|
||||
Manifest.permission.INTERACT_ACROSS_USERS,
|
||||
Manifest.permission.INTERACT_ACROSS_PROFILES})
|
||||
public void addDeviceConnection(Device device, IMidiDeviceOpenCallback callback,
|
||||
int userId) {
|
||||
Log.d(TAG, "addDeviceConnection() device:" + device + " userId:" + userId);
|
||||
if (mDeviceConnections.size() >= MAX_CONNECTIONS_PER_CLIENT) {
|
||||
Log.i(TAG, "too many MIDI connections for UID = " + mUid);
|
||||
throw new SecurityException(
|
||||
@@ -228,7 +259,7 @@ public class MidiService extends IMidiManager.Stub {
|
||||
}
|
||||
DeviceConnection connection = new DeviceConnection(device, this, callback);
|
||||
mDeviceConnections.put(connection.getToken(), connection);
|
||||
device.addDeviceConnection(connection);
|
||||
device.addDeviceConnection(connection, userId);
|
||||
}
|
||||
|
||||
// called from MidiService.closeDevice()
|
||||
@@ -251,8 +282,8 @@ public class MidiService extends IMidiManager.Stub {
|
||||
}
|
||||
|
||||
public void deviceAdded(Device device) {
|
||||
// ignore private devices that our client cannot access
|
||||
if (!device.isUidAllowed(mUid)) return;
|
||||
// ignore devices that our client cannot access
|
||||
if (!device.isUidAllowed(mUid) || !device.isUserIdAllowed(getUserId())) return;
|
||||
|
||||
MidiDeviceInfo deviceInfo = device.getDeviceInfo();
|
||||
try {
|
||||
@@ -265,8 +296,8 @@ public class MidiService extends IMidiManager.Stub {
|
||||
}
|
||||
|
||||
public void deviceRemoved(Device device) {
|
||||
// ignore private devices that our client cannot access
|
||||
if (!device.isUidAllowed(mUid)) return;
|
||||
// ignore devices that our client cannot access
|
||||
if (!device.isUidAllowed(mUid) || !device.isUserIdAllowed(getUserId())) return;
|
||||
|
||||
MidiDeviceInfo deviceInfo = device.getDeviceInfo();
|
||||
try {
|
||||
@@ -279,8 +310,8 @@ 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;
|
||||
// ignore devices that our client cannot access
|
||||
if (!device.isUidAllowed(mUid) || !device.isUserIdAllowed(getUserId())) return;
|
||||
|
||||
try {
|
||||
for (IMidiDeviceListener listener : mListeners.values()) {
|
||||
@@ -354,6 +385,8 @@ public class MidiService extends IMidiManager.Stub {
|
||||
private final ServiceInfo mServiceInfo;
|
||||
// UID of device implementation
|
||||
private final int mUid;
|
||||
// User Id of the app. Only used for virtual devices
|
||||
private final int mUserId;
|
||||
|
||||
// ServiceConnection for implementing Service (virtual devices only)
|
||||
// mServiceConnection is non-null when connected or attempting to connect to the service
|
||||
@@ -375,19 +408,24 @@ public class MidiService extends IMidiManager.Stub {
|
||||
private AtomicInteger mTotalOutputBytes = new AtomicInteger();
|
||||
|
||||
public Device(IMidiDeviceServer server, MidiDeviceInfo deviceInfo,
|
||||
ServiceInfo serviceInfo, int uid) {
|
||||
ServiceInfo serviceInfo, int uid, int userId) {
|
||||
mDeviceInfo = deviceInfo;
|
||||
mServiceInfo = serviceInfo;
|
||||
mUid = uid;
|
||||
mUserId = userId;
|
||||
mBluetoothDevice = (BluetoothDevice)deviceInfo.getProperties().getParcelable(
|
||||
MidiDeviceInfo.PROPERTY_BLUETOOTH_DEVICE, android.bluetooth.BluetoothDevice.class);;
|
||||
setDeviceServer(server);
|
||||
}
|
||||
|
||||
@RequiresPermission(anyOf = {Manifest.permission.QUERY_USERS,
|
||||
Manifest.permission.CREATE_USERS,
|
||||
Manifest.permission.MANAGE_USERS})
|
||||
public Device(BluetoothDevice bluetoothDevice) {
|
||||
mBluetoothDevice = bluetoothDevice;
|
||||
mServiceInfo = null;
|
||||
mUid = mBluetoothServiceUid;
|
||||
mUserId = mUserManager.getMainUser().getIdentifier();
|
||||
}
|
||||
|
||||
private void setDeviceServer(IMidiDeviceServer server) {
|
||||
@@ -468,11 +506,22 @@ public class MidiService extends IMidiManager.Stub {
|
||||
return mUid;
|
||||
}
|
||||
|
||||
public int getUserId() {
|
||||
return mUserId;
|
||||
}
|
||||
|
||||
public boolean isUidAllowed(int uid) {
|
||||
return (!mDeviceInfo.isPrivate() || mUid == uid);
|
||||
}
|
||||
|
||||
public void addDeviceConnection(DeviceConnection connection) {
|
||||
public boolean isUserIdAllowed(int userId) {
|
||||
return (mDeviceInfo.getType() != MidiDeviceInfo.TYPE_VIRTUAL || mUserId == userId);
|
||||
}
|
||||
|
||||
@RequiresPermission(anyOf = {Manifest.permission.INTERACT_ACROSS_USERS_FULL,
|
||||
Manifest.permission.INTERACT_ACROSS_USERS,
|
||||
Manifest.permission.INTERACT_ACROSS_PROFILES})
|
||||
public void addDeviceConnection(DeviceConnection connection, int userId) {
|
||||
Log.d(TAG, "addDeviceConnection() [A] connection:" + connection);
|
||||
synchronized (mDeviceConnections) {
|
||||
mDeviceConnectionsAdded.incrementAndGet();
|
||||
@@ -537,8 +586,8 @@ public class MidiService extends IMidiManager.Stub {
|
||||
new ComponentName(mServiceInfo.packageName, mServiceInfo.name));
|
||||
}
|
||||
|
||||
if (!mContext.bindService(intent, mServiceConnection,
|
||||
Context.BIND_AUTO_CREATE)) {
|
||||
if (!mContext.bindServiceAsUser(intent, mServiceConnection,
|
||||
Context.BIND_AUTO_CREATE, UserHandle.of(mUserId))) {
|
||||
Log.e(TAG, "Unable to bind service: " + intent);
|
||||
setDeviceServer(null);
|
||||
mServiceConnection = null;
|
||||
@@ -886,6 +935,8 @@ public class MidiService extends IMidiManager.Stub {
|
||||
public MidiService(Context context) {
|
||||
mContext = context;
|
||||
mPackageManager = context.getPackageManager();
|
||||
mUserManager = mContext.getSystemService(UserManager.class);
|
||||
mPackageMonitor.register(mContext, null, UserHandle.ALL, true);
|
||||
|
||||
// TEMPORARY - Disable BTL-MIDI
|
||||
//FIXME - b/25689266
|
||||
@@ -913,32 +964,41 @@ public class MidiService extends IMidiManager.Stub {
|
||||
// mNonMidiUUIDs.add(BluetoothUuid.BATTERY);
|
||||
}
|
||||
|
||||
private void onUnlockUser() {
|
||||
mPackageMonitor.register(mContext, null, true);
|
||||
|
||||
@RequiresPermission(allOf = {Manifest.permission.INTERACT_ACROSS_USERS},
|
||||
anyOf = {Manifest.permission.QUERY_USERS,
|
||||
Manifest.permission.CREATE_USERS,
|
||||
Manifest.permission.MANAGE_USERS})
|
||||
private void onStartOrUnlockUser(TargetUser user, boolean matchDirectBootUnaware) {
|
||||
Log.d(TAG, "onStartOrUnlockUser " + user.getUserIdentifier() + " matchDirectBootUnaware: "
|
||||
+ matchDirectBootUnaware);
|
||||
Intent intent = new Intent(MidiDeviceService.SERVICE_INTERFACE);
|
||||
List<ResolveInfo> resolveInfos = mPackageManager.queryIntentServices(intent,
|
||||
PackageManager.GET_META_DATA);
|
||||
int resolveFlags = PackageManager.GET_META_DATA;
|
||||
if (matchDirectBootUnaware) {
|
||||
resolveFlags |= PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
|
||||
}
|
||||
List<ResolveInfo> resolveInfos = mPackageManager.queryIntentServicesAsUser(intent,
|
||||
resolveFlags, user.getUserIdentifier());
|
||||
if (resolveInfos != null) {
|
||||
int count = resolveInfos.size();
|
||||
for (int i = 0; i < count; i++) {
|
||||
ServiceInfo serviceInfo = resolveInfos.get(i).serviceInfo;
|
||||
if (serviceInfo != null) {
|
||||
addPackageDeviceServer(serviceInfo);
|
||||
addPackageDeviceServer(serviceInfo, user.getUserIdentifier());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PackageInfo info;
|
||||
try {
|
||||
info = mPackageManager.getPackageInfo(MidiManager.BLUETOOTH_MIDI_SERVICE_PACKAGE, 0);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
info = null;
|
||||
}
|
||||
if (info != null && info.applicationInfo != null) {
|
||||
mBluetoothServiceUid = info.applicationInfo.uid;
|
||||
} else {
|
||||
mBluetoothServiceUid = -1;
|
||||
if (user.getUserIdentifier() == mUserManager.getMainUser().getIdentifier()) {
|
||||
PackageInfo info;
|
||||
try {
|
||||
info = mPackageManager.getPackageInfoAsUser(
|
||||
MidiManager.BLUETOOTH_MIDI_SERVICE_PACKAGE, 0, user.getUserIdentifier());
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
info = null;
|
||||
}
|
||||
if (info != null && info.applicationInfo != null) {
|
||||
mBluetoothServiceUid = info.applicationInfo.uid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -960,10 +1020,11 @@ public class MidiService extends IMidiManager.Stub {
|
||||
|
||||
// Inform listener of the status of all known devices.
|
||||
private void updateStickyDeviceStatus(int uid, IMidiDeviceListener listener) {
|
||||
int userId = UserHandle.getUserId(uid);
|
||||
synchronized (mDevicesByInfo) {
|
||||
for (Device device : mDevicesByInfo.values()) {
|
||||
// ignore private devices that our client cannot access
|
||||
if (device.isUidAllowed(uid)) {
|
||||
// ignore devices that our client cannot access
|
||||
if (device.isUidAllowed(uid) && device.isUserIdAllowed(userId)) {
|
||||
try {
|
||||
MidiDeviceStatus status = device.getDeviceStatus();
|
||||
if (status != null) {
|
||||
@@ -989,10 +1050,11 @@ public class MidiService extends IMidiManager.Stub {
|
||||
public MidiDeviceInfo[] getDevicesForTransport(int transport) {
|
||||
ArrayList<MidiDeviceInfo> deviceInfos = new ArrayList<MidiDeviceInfo>();
|
||||
int uid = Binder.getCallingUid();
|
||||
int userId = getCallingUserId();
|
||||
|
||||
synchronized (mDevicesByInfo) {
|
||||
for (Device device : mDevicesByInfo.values()) {
|
||||
if (device.isUidAllowed(uid)) {
|
||||
if (device.isUidAllowed(uid) && device.isUserIdAllowed(userId)) {
|
||||
// UMP devices have protocols that are not PROTOCOL_UNKNOWN
|
||||
if (transport == MidiManager.TRANSPORT_UNIVERSAL_MIDI_PACKETS) {
|
||||
if (device.getDeviceInfo().getDefaultProtocol()
|
||||
@@ -1029,6 +1091,9 @@ public class MidiService extends IMidiManager.Stub {
|
||||
if (!device.isUidAllowed(Binder.getCallingUid())) {
|
||||
throw new SecurityException("Attempt to open private device with wrong UID");
|
||||
}
|
||||
if (!device.isUserIdAllowed(getCallingUserId())) {
|
||||
throw new SecurityException("Attempt to open virtual device with wrong user id");
|
||||
}
|
||||
}
|
||||
|
||||
if (deviceInfo.getType() == MidiDeviceInfo.TYPE_USB) {
|
||||
@@ -1044,7 +1109,7 @@ public class MidiService extends IMidiManager.Stub {
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
Log.i(TAG, "addDeviceConnection() [B] device:" + device);
|
||||
client.addDeviceConnection(device, callback);
|
||||
client.addDeviceConnection(device, callback, getCallingUserId());
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
@@ -1106,7 +1171,7 @@ public class MidiService extends IMidiManager.Stub {
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
Log.i(TAG, "addDeviceConnection() [C] device:" + device);
|
||||
client.addDeviceConnection(device, callback);
|
||||
client.addDeviceConnection(device, callback, getCallingUserId());
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
@@ -1124,6 +1189,7 @@ public class MidiService extends IMidiManager.Stub {
|
||||
int numOutputPorts, String[] inputPortNames, String[] outputPortNames,
|
||||
Bundle properties, int type, int defaultProtocol) {
|
||||
int uid = Binder.getCallingUid();
|
||||
int userId = getCallingUserId();
|
||||
if (type == MidiDeviceInfo.TYPE_USB && uid != Process.SYSTEM_UID) {
|
||||
throw new SecurityException("only system can create USB devices");
|
||||
} else if (type == MidiDeviceInfo.TYPE_BLUETOOTH && uid != mBluetoothServiceUid) {
|
||||
@@ -1133,7 +1199,7 @@ public class MidiService extends IMidiManager.Stub {
|
||||
synchronized (mDevicesByInfo) {
|
||||
return addDeviceLocked(type, numInputPorts, numOutputPorts, inputPortNames,
|
||||
outputPortNames, properties, server, null, false, uid,
|
||||
defaultProtocol);
|
||||
defaultProtocol, userId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1210,7 +1276,8 @@ public class MidiService extends IMidiManager.Stub {
|
||||
private MidiDeviceInfo addDeviceLocked(int type, int numInputPorts, int numOutputPorts,
|
||||
String[] inputPortNames, String[] outputPortNames, Bundle properties,
|
||||
IMidiDeviceServer server, ServiceInfo serviceInfo,
|
||||
boolean isPrivate, int uid, int defaultProtocol) {
|
||||
boolean isPrivate, int uid, int defaultProtocol, int userId) {
|
||||
Log.d(TAG, "addDeviceLocked()" + uid + " type:" + type);
|
||||
|
||||
// Limit the number of devices per app.
|
||||
int deviceCountForApp = 0;
|
||||
@@ -1250,7 +1317,7 @@ public class MidiService extends IMidiManager.Stub {
|
||||
}
|
||||
}
|
||||
if (device == null) {
|
||||
device = new Device(server, deviceInfo, serviceInfo, uid);
|
||||
device = new Device(server, deviceInfo, serviceInfo, uid, userId);
|
||||
}
|
||||
mDevicesByInfo.put(deviceInfo, device);
|
||||
if (bluetoothDevice != null) {
|
||||
@@ -1281,12 +1348,14 @@ public class MidiService extends IMidiManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private void addPackageDeviceServers(String packageName) {
|
||||
@RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS)
|
||||
private void addPackageDeviceServers(String packageName, int userId) {
|
||||
PackageInfo info;
|
||||
|
||||
try {
|
||||
info = mPackageManager.getPackageInfo(packageName,
|
||||
PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
|
||||
info = mPackageManager.getPackageInfoAsUser(packageName,
|
||||
PackageManager.GET_SERVICES | PackageManager.GET_META_DATA
|
||||
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.e(TAG, "handlePackageUpdate could not find package " + packageName, e);
|
||||
return;
|
||||
@@ -1295,13 +1364,14 @@ public class MidiService extends IMidiManager.Stub {
|
||||
ServiceInfo[] services = info.services;
|
||||
if (services == null) return;
|
||||
for (int i = 0; i < services.length; i++) {
|
||||
addPackageDeviceServer(services[i]);
|
||||
addPackageDeviceServer(services[i], userId);
|
||||
}
|
||||
}
|
||||
|
||||
private static final String[] EMPTY_STRING_ARRAY = new String[0];
|
||||
|
||||
private void addPackageDeviceServer(ServiceInfo serviceInfo) {
|
||||
private void addPackageDeviceServer(ServiceInfo serviceInfo, int userId) {
|
||||
Log.d(TAG, "addPackageDeviceServer()" + userId);
|
||||
XmlResourceParser parser = null;
|
||||
|
||||
try {
|
||||
@@ -1404,8 +1474,8 @@ public class MidiService extends IMidiManager.Stub {
|
||||
|
||||
int uid;
|
||||
try {
|
||||
ApplicationInfo appInfo = mPackageManager.getApplicationInfo(
|
||||
serviceInfo.packageName, 0);
|
||||
ApplicationInfo appInfo = mPackageManager.getApplicationInfoAsUser(
|
||||
serviceInfo.packageName, 0, userId);
|
||||
uid = appInfo.uid;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.e(TAG, "could not fetch ApplicationInfo for "
|
||||
@@ -1419,7 +1489,7 @@ public class MidiService extends IMidiManager.Stub {
|
||||
inputPortNames.toArray(EMPTY_STRING_ARRAY),
|
||||
outputPortNames.toArray(EMPTY_STRING_ARRAY),
|
||||
properties, null, serviceInfo, isPrivate, uid,
|
||||
MidiDeviceInfo.PROTOCOL_UNKNOWN);
|
||||
MidiDeviceInfo.PROTOCOL_UNKNOWN, userId);
|
||||
}
|
||||
// setting properties to null signals that we are no longer
|
||||
// processing a <device>
|
||||
@@ -1437,12 +1507,13 @@ public class MidiService extends IMidiManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private void removePackageDeviceServers(String packageName) {
|
||||
private void removePackageDeviceServers(String packageName, int userId) {
|
||||
synchronized (mDevicesByInfo) {
|
||||
Iterator<Device> iterator = mDevicesByInfo.values().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Device device = iterator.next();
|
||||
if (packageName.equals(device.getPackageName())) {
|
||||
if (packageName.equals(device.getPackageName())
|
||||
&& (device.getUserId() == userId)) {
|
||||
iterator.remove();
|
||||
removeDeviceLocked(device);
|
||||
}
|
||||
@@ -1571,4 +1642,11 @@ public class MidiService extends IMidiManager.Stub {
|
||||
String extractUsbDeviceTag(String propertyName) {
|
||||
return propertyName.substring(propertyName.length() - MIDI_LEGACY_STRING.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the user id of the calling user.
|
||||
*/
|
||||
private int getCallingUserId() {
|
||||
return UserHandle.getUserId(Binder.getCallingUid());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user