am 1ed299f8: Merge "Make USB services multi-user aware." into jb-mr1-dev
* commit '1ed299f822b22998b7236e3147d8cf4707bced08': Make USB services multi-user aware.
This commit is contained in:
@@ -1703,6 +1703,7 @@ class ContextImpl extends Context {
|
|||||||
if (packageName.equals("system") || packageName.equals("android")) {
|
if (packageName.equals("system") || packageName.equals("android")) {
|
||||||
final ContextImpl context = new ContextImpl(mMainThread.getSystemContext());
|
final ContextImpl context = new ContextImpl(mMainThread.getSystemContext());
|
||||||
context.mBasePackageName = mBasePackageName;
|
context.mBasePackageName = mBasePackageName;
|
||||||
|
context.mUser = user;
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,12 +44,12 @@ interface IUsbManager
|
|||||||
/* Sets the default package for a USB device
|
/* Sets the default package for a USB device
|
||||||
* (or clears it if the package name is null)
|
* (or clears it if the package name is null)
|
||||||
*/
|
*/
|
||||||
void setDevicePackage(in UsbDevice device, String packageName);
|
void setDevicePackage(in UsbDevice device, String packageName, int userId);
|
||||||
|
|
||||||
/* Sets the default package for a USB accessory
|
/* Sets the default package for a USB accessory
|
||||||
* (or clears it if the package name is null)
|
* (or clears it if the package name is null)
|
||||||
*/
|
*/
|
||||||
void setAccessoryPackage(in UsbAccessory accessory, String packageName);
|
void setAccessoryPackage(in UsbAccessory accessory, String packageName, int userId);
|
||||||
|
|
||||||
/* Returns true if the caller has permission to access the device. */
|
/* Returns true if the caller has permission to access the device. */
|
||||||
boolean hasDevicePermission(in UsbDevice device);
|
boolean hasDevicePermission(in UsbDevice device);
|
||||||
@@ -77,10 +77,10 @@ interface IUsbManager
|
|||||||
void grantAccessoryPermission(in UsbAccessory accessory, int uid);
|
void grantAccessoryPermission(in UsbAccessory accessory, int uid);
|
||||||
|
|
||||||
/* Returns true if the USB manager has default preferences or permissions for the package */
|
/* Returns true if the USB manager has default preferences or permissions for the package */
|
||||||
boolean hasDefaults(String packageName);
|
boolean hasDefaults(String packageName, int userId);
|
||||||
|
|
||||||
/* Clears default preferences and permissions for the package */
|
/* Clears default preferences and permissions for the package */
|
||||||
void clearDefaults(String packageName);
|
void clearDefaults(String packageName, int userId);
|
||||||
|
|
||||||
/* Sets the current USB function. */
|
/* Sets the current USB function. */
|
||||||
void setCurrentFunction(String function, boolean makeDefault);
|
void setCurrentFunction(String function, boolean makeDefault);
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import android.net.Uri;
|
|||||||
import android.hardware.usb.UsbAccessory;
|
import android.hardware.usb.UsbAccessory;
|
||||||
import android.hardware.usb.UsbManager;
|
import android.hardware.usb.UsbManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.UserHandle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.internal.app.AlertActivity;
|
import com.android.internal.app.AlertActivity;
|
||||||
@@ -90,7 +91,7 @@ public class UsbAccessoryUriActivity extends AlertActivity
|
|||||||
intent.addCategory(Intent.CATEGORY_BROWSABLE);
|
intent.addCategory(Intent.CATEGORY_BROWSABLE);
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
try {
|
try {
|
||||||
startActivity(intent);
|
startActivityAsUser(intent, UserHandle.CURRENT);
|
||||||
} catch (ActivityNotFoundException e) {
|
} catch (ActivityNotFoundException e) {
|
||||||
Log.e(TAG, "startActivity failed for " + mUri);
|
Log.e(TAG, "startActivity failed for " + mUri);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,23 +16,21 @@
|
|||||||
|
|
||||||
package com.android.systemui.usb;
|
package com.android.systemui.usb;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.ApplicationInfo;
|
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
import android.hardware.usb.IUsbManager;
|
import android.hardware.usb.IUsbManager;
|
||||||
import android.hardware.usb.UsbDevice;
|
|
||||||
import android.hardware.usb.UsbAccessory;
|
import android.hardware.usb.UsbAccessory;
|
||||||
|
import android.hardware.usb.UsbDevice;
|
||||||
import android.hardware.usb.UsbManager;
|
import android.hardware.usb.UsbManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
|
import android.os.UserHandle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -42,7 +40,6 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import com.android.internal.app.AlertActivity;
|
import com.android.internal.app.AlertActivity;
|
||||||
import com.android.internal.app.AlertController;
|
import com.android.internal.app.AlertController;
|
||||||
|
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
|
|
||||||
public class UsbConfirmActivity extends AlertActivity
|
public class UsbConfirmActivity extends AlertActivity
|
||||||
@@ -62,10 +59,10 @@ public class UsbConfirmActivity extends AlertActivity
|
|||||||
public void onCreate(Bundle icicle) {
|
public void onCreate(Bundle icicle) {
|
||||||
super.onCreate(icicle);
|
super.onCreate(icicle);
|
||||||
|
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
mDevice = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
|
mDevice = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
|
||||||
mAccessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
|
mAccessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
|
||||||
mResolveInfo = (ResolveInfo)intent.getParcelableExtra("rinfo");
|
mResolveInfo = (ResolveInfo) intent.getParcelableExtra("rinfo");
|
||||||
|
|
||||||
PackageManager packageManager = getPackageManager();
|
PackageManager packageManager = getPackageManager();
|
||||||
String appName = mResolveInfo.loadLabel(packageManager).toString();
|
String appName = mResolveInfo.loadLabel(packageManager).toString();
|
||||||
@@ -117,7 +114,8 @@ public class UsbConfirmActivity extends AlertActivity
|
|||||||
try {
|
try {
|
||||||
IBinder b = ServiceManager.getService(USB_SERVICE);
|
IBinder b = ServiceManager.getService(USB_SERVICE);
|
||||||
IUsbManager service = IUsbManager.Stub.asInterface(b);
|
IUsbManager service = IUsbManager.Stub.asInterface(b);
|
||||||
int uid = mResolveInfo.activityInfo.applicationInfo.uid;
|
final int uid = mResolveInfo.activityInfo.applicationInfo.uid;
|
||||||
|
final int userId = UserHandle.myUserId();
|
||||||
boolean alwaysUse = mAlwaysUse.isChecked();
|
boolean alwaysUse = mAlwaysUse.isChecked();
|
||||||
Intent intent = null;
|
Intent intent = null;
|
||||||
|
|
||||||
@@ -129,9 +127,10 @@ public class UsbConfirmActivity extends AlertActivity
|
|||||||
service.grantDevicePermission(mDevice, uid);
|
service.grantDevicePermission(mDevice, uid);
|
||||||
// set or clear default setting
|
// set or clear default setting
|
||||||
if (alwaysUse) {
|
if (alwaysUse) {
|
||||||
service.setDevicePackage(mDevice, mResolveInfo.activityInfo.packageName);
|
service.setDevicePackage(
|
||||||
|
mDevice, mResolveInfo.activityInfo.packageName, userId);
|
||||||
} else {
|
} else {
|
||||||
service.setDevicePackage(mDevice, null);
|
service.setDevicePackage(mDevice, null, userId);
|
||||||
}
|
}
|
||||||
} else if (mAccessory != null) {
|
} else if (mAccessory != null) {
|
||||||
intent = new Intent(UsbManager.ACTION_USB_ACCESSORY_ATTACHED);
|
intent = new Intent(UsbManager.ACTION_USB_ACCESSORY_ATTACHED);
|
||||||
@@ -141,10 +140,10 @@ public class UsbConfirmActivity extends AlertActivity
|
|||||||
service.grantAccessoryPermission(mAccessory, uid);
|
service.grantAccessoryPermission(mAccessory, uid);
|
||||||
// set or clear default setting
|
// set or clear default setting
|
||||||
if (alwaysUse) {
|
if (alwaysUse) {
|
||||||
service.setAccessoryPackage(mAccessory,
|
service.setAccessoryPackage(
|
||||||
mResolveInfo.activityInfo.packageName);
|
mAccessory, mResolveInfo.activityInfo.packageName, userId);
|
||||||
} else {
|
} else {
|
||||||
service.setAccessoryPackage(mAccessory, null);
|
service.setAccessoryPackage(mAccessory, null, userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +151,7 @@ public class UsbConfirmActivity extends AlertActivity
|
|||||||
intent.setComponent(
|
intent.setComponent(
|
||||||
new ComponentName(mResolveInfo.activityInfo.packageName,
|
new ComponentName(mResolveInfo.activityInfo.packageName,
|
||||||
mResolveInfo.activityInfo.name));
|
mResolveInfo.activityInfo.name));
|
||||||
startActivity(intent);
|
startActivityAsUser(intent, new UserHandle(userId));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "Unable to start activity", e);
|
Log.e(TAG, "Unable to start activity", e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import android.os.Bundle;
|
|||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
|
import android.os.UserHandle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -67,7 +68,7 @@ public class UsbPermissionActivity extends AlertActivity
|
|||||||
mDevice = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
|
mDevice = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
|
||||||
mAccessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
|
mAccessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
|
||||||
mPendingIntent = (PendingIntent)intent.getParcelableExtra(Intent.EXTRA_INTENT);
|
mPendingIntent = (PendingIntent)intent.getParcelableExtra(Intent.EXTRA_INTENT);
|
||||||
mUid = intent.getIntExtra("uid", 0);
|
mUid = intent.getIntExtra(Intent.EXTRA_UID, -1);
|
||||||
mPackageName = intent.getStringExtra("package");
|
mPackageName = intent.getStringExtra("package");
|
||||||
|
|
||||||
PackageManager packageManager = getPackageManager();
|
PackageManager packageManager = getPackageManager();
|
||||||
@@ -128,7 +129,8 @@ public class UsbPermissionActivity extends AlertActivity
|
|||||||
if (mPermissionGranted) {
|
if (mPermissionGranted) {
|
||||||
service.grantDevicePermission(mDevice, mUid);
|
service.grantDevicePermission(mDevice, mUid);
|
||||||
if (mAlwaysUse.isChecked()) {
|
if (mAlwaysUse.isChecked()) {
|
||||||
service.setDevicePackage(mDevice, mPackageName);
|
final int userId = UserHandle.getUserId(mUid);
|
||||||
|
service.setDevicePackage(mDevice, mPackageName, userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -137,7 +139,8 @@ public class UsbPermissionActivity extends AlertActivity
|
|||||||
if (mPermissionGranted) {
|
if (mPermissionGranted) {
|
||||||
service.grantAccessoryPermission(mAccessory, mUid);
|
service.grantAccessoryPermission(mAccessory, mUid);
|
||||||
if (mAlwaysUse.isChecked()) {
|
if (mAlwaysUse.isChecked()) {
|
||||||
service.setAccessoryPackage(mAccessory, mPackageName);
|
final int userId = UserHandle.getUserId(mUid);
|
||||||
|
service.setAccessoryPackage(mAccessory, mPackageName, userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package com.android.systemui.usb;
|
package com.android.systemui.usb;
|
||||||
|
|
||||||
import com.android.internal.app.ResolverActivity;
|
|
||||||
|
|
||||||
import android.content.ActivityNotFoundException;
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
@@ -30,9 +28,11 @@ import android.os.IBinder;
|
|||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
|
import android.os.UserHandle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
|
|
||||||
|
import com.android.internal.app.ResolverActivity;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -92,34 +92,36 @@ public class UsbResolverActivity extends ResolverActivity {
|
|||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected void onIntentSelected(ResolveInfo ri, Intent intent, boolean alwaysCheck) {
|
protected void onIntentSelected(ResolveInfo ri, Intent intent, boolean alwaysCheck) {
|
||||||
try {
|
try {
|
||||||
IBinder b = ServiceManager.getService(USB_SERVICE);
|
IBinder b = ServiceManager.getService(USB_SERVICE);
|
||||||
IUsbManager service = IUsbManager.Stub.asInterface(b);
|
IUsbManager service = IUsbManager.Stub.asInterface(b);
|
||||||
int uid = ri.activityInfo.applicationInfo.uid;
|
final int uid = ri.activityInfo.applicationInfo.uid;
|
||||||
|
final int userId = UserHandle.myUserId();
|
||||||
|
|
||||||
if (mDevice != null) {
|
if (mDevice != null) {
|
||||||
// grant permission for the device
|
// grant permission for the device
|
||||||
service.grantDevicePermission(mDevice, uid);
|
service.grantDevicePermission(mDevice, uid);
|
||||||
// set or clear default setting
|
// set or clear default setting
|
||||||
if (alwaysCheck) {
|
if (alwaysCheck) {
|
||||||
service.setDevicePackage(mDevice, ri.activityInfo.packageName);
|
service.setDevicePackage(mDevice, ri.activityInfo.packageName, userId);
|
||||||
} else {
|
} else {
|
||||||
service.setDevicePackage(mDevice, null);
|
service.setDevicePackage(mDevice, null, userId);
|
||||||
}
|
}
|
||||||
} else if (mAccessory != null) {
|
} else if (mAccessory != null) {
|
||||||
// grant permission for the accessory
|
// grant permission for the accessory
|
||||||
service.grantAccessoryPermission(mAccessory, uid);
|
service.grantAccessoryPermission(mAccessory, uid);
|
||||||
// set or clear default setting
|
// set or clear default setting
|
||||||
if (alwaysCheck) {
|
if (alwaysCheck) {
|
||||||
service.setAccessoryPackage(mAccessory, ri.activityInfo.packageName);
|
service.setAccessoryPackage(mAccessory, ri.activityInfo.packageName, userId);
|
||||||
} else {
|
} else {
|
||||||
service.setAccessoryPackage(mAccessory, null);
|
service.setAccessoryPackage(mAccessory, null, userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
startActivity(intent);
|
startActivityAsUser(intent, new UserHandle(userId));
|
||||||
} catch (ActivityNotFoundException e) {
|
} catch (ActivityNotFoundException e) {
|
||||||
Log.e(TAG, "startActivity failed", e);
|
Log.e(TAG, "startActivity failed", e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,9 @@
|
|||||||
|
|
||||||
package com.android.server.usb;
|
package com.android.server.usb;
|
||||||
|
|
||||||
import android.app.PendingIntent;
|
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
|
import android.app.PendingIntent;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
@@ -30,23 +30,19 @@ import android.content.res.Resources;
|
|||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
import android.hardware.usb.UsbAccessory;
|
import android.hardware.usb.UsbAccessory;
|
||||||
import android.hardware.usb.UsbManager;
|
import android.hardware.usb.UsbManager;
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.FileUtils;
|
import android.os.FileUtils;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.Parcelable;
|
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.os.UserHandle;
|
|
||||||
import android.os.storage.StorageManager;
|
|
||||||
import android.os.storage.StorageVolume;
|
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.os.SystemProperties;
|
import android.os.SystemProperties;
|
||||||
import android.os.UEventObserver;
|
import android.os.UEventObserver;
|
||||||
|
import android.os.UserHandle;
|
||||||
|
import android.os.storage.StorageManager;
|
||||||
|
import android.os.storage.StorageVolume;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
@@ -56,10 +52,9 @@ import java.io.FileDescriptor;
|
|||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.ArrayList;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
|
||||||
@@ -106,9 +101,12 @@ public class UsbDeviceManager {
|
|||||||
private UsbHandler mHandler;
|
private UsbHandler mHandler;
|
||||||
private boolean mBootCompleted;
|
private boolean mBootCompleted;
|
||||||
|
|
||||||
|
private final Object mLock = new Object();
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final ContentResolver mContentResolver;
|
private final ContentResolver mContentResolver;
|
||||||
private final UsbSettingsManager mSettingsManager;
|
// @GuardedBy("mLock")
|
||||||
|
private UsbSettingsManager mCurrentSettings;
|
||||||
private NotificationManager mNotificationManager;
|
private NotificationManager mNotificationManager;
|
||||||
private final boolean mHasUsbAccessory;
|
private final boolean mHasUsbAccessory;
|
||||||
private boolean mUseUsbNotification;
|
private boolean mUseUsbNotification;
|
||||||
@@ -149,10 +147,9 @@ public class UsbDeviceManager {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public UsbDeviceManager(Context context, UsbSettingsManager settingsManager) {
|
public UsbDeviceManager(Context context) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mContentResolver = context.getContentResolver();
|
mContentResolver = context.getContentResolver();
|
||||||
mSettingsManager = settingsManager;
|
|
||||||
PackageManager pm = mContext.getPackageManager();
|
PackageManager pm = mContext.getPackageManager();
|
||||||
mHasUsbAccessory = pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY);
|
mHasUsbAccessory = pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY);
|
||||||
initRndisAddress();
|
initRndisAddress();
|
||||||
@@ -175,6 +172,18 @@ public class UsbDeviceManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setCurrentSettings(UsbSettingsManager settings) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
mCurrentSettings = settings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private UsbSettingsManager getCurrentSettings() {
|
||||||
|
synchronized (mLock) {
|
||||||
|
return mCurrentSettings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void systemReady() {
|
public void systemReady() {
|
||||||
if (DEBUG) Slog.d(TAG, "systemReady");
|
if (DEBUG) Slog.d(TAG, "systemReady");
|
||||||
|
|
||||||
@@ -516,7 +525,7 @@ public class UsbDeviceManager {
|
|||||||
Slog.d(TAG, "entering USB accessory mode: " + mCurrentAccessory);
|
Slog.d(TAG, "entering USB accessory mode: " + mCurrentAccessory);
|
||||||
// defer accessoryAttached if system is not ready
|
// defer accessoryAttached if system is not ready
|
||||||
if (mBootCompleted) {
|
if (mBootCompleted) {
|
||||||
mSettingsManager.accessoryAttached(mCurrentAccessory);
|
getCurrentSettings().accessoryAttached(mCurrentAccessory);
|
||||||
} // else handle in mBootCompletedReceiver
|
} // else handle in mBootCompletedReceiver
|
||||||
} else {
|
} else {
|
||||||
Slog.e(TAG, "nativeGetAccessoryStrings failed");
|
Slog.e(TAG, "nativeGetAccessoryStrings failed");
|
||||||
@@ -529,7 +538,7 @@ public class UsbDeviceManager {
|
|||||||
|
|
||||||
if (mCurrentAccessory != null) {
|
if (mCurrentAccessory != null) {
|
||||||
if (mBootCompleted) {
|
if (mBootCompleted) {
|
||||||
mSettingsManager.accessoryDetached(mCurrentAccessory);
|
getCurrentSettings().accessoryDetached(mCurrentAccessory);
|
||||||
}
|
}
|
||||||
mCurrentAccessory = null;
|
mCurrentAccessory = null;
|
||||||
mAccessoryStrings = null;
|
mAccessoryStrings = null;
|
||||||
@@ -618,7 +627,7 @@ public class UsbDeviceManager {
|
|||||||
case MSG_BOOT_COMPLETED:
|
case MSG_BOOT_COMPLETED:
|
||||||
mBootCompleted = true;
|
mBootCompleted = true;
|
||||||
if (mCurrentAccessory != null) {
|
if (mCurrentAccessory != null) {
|
||||||
mSettingsManager.accessoryAttached(mCurrentAccessory);
|
getCurrentSettings().accessoryAttached(mCurrentAccessory);
|
||||||
}
|
}
|
||||||
if (mDebuggingManager != null) {
|
if (mDebuggingManager != null) {
|
||||||
mDebuggingManager.setAdbEnabled(mAdbEnabled);
|
mDebuggingManager.setAdbEnabled(mAdbEnabled);
|
||||||
@@ -774,7 +783,7 @@ public class UsbDeviceManager {
|
|||||||
+ currentAccessory;
|
+ currentAccessory;
|
||||||
throw new IllegalArgumentException(error);
|
throw new IllegalArgumentException(error);
|
||||||
}
|
}
|
||||||
mSettingsManager.checkPermission(accessory);
|
getCurrentSettings().checkPermission(accessory);
|
||||||
return nativeOpenAccessory();
|
return nativeOpenAccessory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,35 +16,19 @@
|
|||||||
|
|
||||||
package com.android.server.usb;
|
package com.android.server.usb;
|
||||||
|
|
||||||
import android.app.PendingIntent;
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.hardware.usb.IUsbManager;
|
|
||||||
import android.hardware.usb.UsbConstants;
|
import android.hardware.usb.UsbConstants;
|
||||||
import android.hardware.usb.UsbDevice;
|
import android.hardware.usb.UsbDevice;
|
||||||
import android.hardware.usb.UsbEndpoint;
|
import android.hardware.usb.UsbEndpoint;
|
||||||
import android.hardware.usb.UsbInterface;
|
import android.hardware.usb.UsbInterface;
|
||||||
import android.hardware.usb.UsbManager;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Message;
|
|
||||||
import android.os.Parcelable;
|
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
import android.os.UEventObserver;
|
import android.os.Parcelable;
|
||||||
import android.provider.Settings;
|
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UsbHostManager manages USB state in host mode.
|
* UsbHostManager manages USB state in host mode.
|
||||||
@@ -54,22 +38,35 @@ public class UsbHostManager {
|
|||||||
private static final boolean LOG = false;
|
private static final boolean LOG = false;
|
||||||
|
|
||||||
// contains all connected USB devices
|
// contains all connected USB devices
|
||||||
private final HashMap<String,UsbDevice> mDevices = new HashMap<String,UsbDevice>();
|
private final HashMap<String, UsbDevice> mDevices = new HashMap<String, UsbDevice>();
|
||||||
|
|
||||||
// USB busses to exclude from USB host support
|
// USB busses to exclude from USB host support
|
||||||
private final String[] mHostBlacklist;
|
private final String[] mHostBlacklist;
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final Object mLock = new Object();
|
private final Object mLock = new Object();
|
||||||
private final UsbSettingsManager mSettingsManager;
|
|
||||||
|
|
||||||
public UsbHostManager(Context context, UsbSettingsManager settingsManager) {
|
// @GuardedBy("mLock")
|
||||||
|
private UsbSettingsManager mCurrentSettings;
|
||||||
|
|
||||||
|
public UsbHostManager(Context context) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mSettingsManager = settingsManager;
|
|
||||||
mHostBlacklist = context.getResources().getStringArray(
|
mHostBlacklist = context.getResources().getStringArray(
|
||||||
com.android.internal.R.array.config_usbHostBlacklist);
|
com.android.internal.R.array.config_usbHostBlacklist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setCurrentSettings(UsbSettingsManager settings) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
mCurrentSettings = settings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private UsbSettingsManager getCurrentSettings() {
|
||||||
|
synchronized (mLock) {
|
||||||
|
return mCurrentSettings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isBlackListed(String deviceName) {
|
private boolean isBlackListed(String deviceName) {
|
||||||
int count = mHostBlacklist.length;
|
int count = mHostBlacklist.length;
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
@@ -154,7 +151,7 @@ public class UsbHostManager {
|
|||||||
UsbDevice device = new UsbDevice(deviceName, vendorID, productID,
|
UsbDevice device = new UsbDevice(deviceName, vendorID, productID,
|
||||||
deviceClass, deviceSubclass, deviceProtocol, interfaces);
|
deviceClass, deviceSubclass, deviceProtocol, interfaces);
|
||||||
mDevices.put(deviceName, device);
|
mDevices.put(deviceName, device);
|
||||||
mSettingsManager.deviceAttached(device);
|
getCurrentSettings().deviceAttached(device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,7 +160,7 @@ public class UsbHostManager {
|
|||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
UsbDevice device = mDevices.remove(deviceName);
|
UsbDevice device = mDevices.remove(deviceName);
|
||||||
if (device != null) {
|
if (device != null) {
|
||||||
mSettingsManager.deviceDetached(device);
|
getCurrentSettings().deviceDetached(device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -202,7 +199,7 @@ public class UsbHostManager {
|
|||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"device " + deviceName + " does not exist or is restricted");
|
"device " + deviceName + " does not exist or is restricted");
|
||||||
}
|
}
|
||||||
mSettingsManager.checkPermission(device);
|
getCurrentSettings().checkPermission(device);
|
||||||
return nativeOpenDevice(deviceName);
|
return nativeOpenDevice(deviceName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,15 +17,20 @@
|
|||||||
package com.android.server.usb;
|
package com.android.server.usb;
|
||||||
|
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.hardware.usb.IUsbManager;
|
import android.hardware.usb.IUsbManager;
|
||||||
import android.hardware.usb.UsbAccessory;
|
import android.hardware.usb.UsbAccessory;
|
||||||
import android.hardware.usb.UsbDevice;
|
import android.hardware.usb.UsbDevice;
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
|
import android.os.UserHandle;
|
||||||
|
import android.util.SparseArray;
|
||||||
|
|
||||||
|
import com.android.internal.util.IndentingPrintWriter;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
@@ -37,21 +42,72 @@ import java.io.PrintWriter;
|
|||||||
* support is delegated to UsbDeviceManager.
|
* support is delegated to UsbDeviceManager.
|
||||||
*/
|
*/
|
||||||
public class UsbService extends IUsbManager.Stub {
|
public class UsbService extends IUsbManager.Stub {
|
||||||
|
private static final String TAG = "UsbService";
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
|
|
||||||
private UsbDeviceManager mDeviceManager;
|
private UsbDeviceManager mDeviceManager;
|
||||||
private UsbHostManager mHostManager;
|
private UsbHostManager mHostManager;
|
||||||
private final UsbSettingsManager mSettingsManager;
|
|
||||||
|
|
||||||
|
private final Object mLock = new Object();
|
||||||
|
|
||||||
|
/** Map from {@link UserHandle} to {@link UsbSettingsManager} */
|
||||||
|
// @GuardedBy("mLock")
|
||||||
|
private final SparseArray<UsbSettingsManager>
|
||||||
|
mSettingsByUser = new SparseArray<UsbSettingsManager>();
|
||||||
|
|
||||||
|
private UsbSettingsManager getSettingsForUser(int userId) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
UsbSettingsManager settings = mSettingsByUser.get(userId);
|
||||||
|
if (settings == null) {
|
||||||
|
settings = new UsbSettingsManager(mContext, new UserHandle(userId));
|
||||||
|
mSettingsByUser.put(userId, settings);
|
||||||
|
}
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public UsbService(Context context) {
|
public UsbService(Context context) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mSettingsManager = new UsbSettingsManager(context);
|
|
||||||
PackageManager pm = mContext.getPackageManager();
|
final PackageManager pm = mContext.getPackageManager();
|
||||||
if (pm.hasSystemFeature(PackageManager.FEATURE_USB_HOST)) {
|
if (pm.hasSystemFeature(PackageManager.FEATURE_USB_HOST)) {
|
||||||
mHostManager = new UsbHostManager(context, mSettingsManager);
|
mHostManager = new UsbHostManager(context);
|
||||||
}
|
}
|
||||||
if (new File("/sys/class/android_usb").exists()) {
|
if (new File("/sys/class/android_usb").exists()) {
|
||||||
mDeviceManager = new UsbDeviceManager(context, mSettingsManager);
|
mDeviceManager = new UsbDeviceManager(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
setCurrentUser(UserHandle.USER_OWNER);
|
||||||
|
|
||||||
|
final IntentFilter userFilter = new IntentFilter();
|
||||||
|
userFilter.addAction(Intent.ACTION_USER_SWITCHED);
|
||||||
|
userFilter.addAction(Intent.ACTION_USER_STOPPED);
|
||||||
|
mContext.registerReceiver(mUserReceiver, userFilter, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
|
||||||
|
final String action = intent.getAction();
|
||||||
|
if (Intent.ACTION_USER_SWITCHED.equals(action)) {
|
||||||
|
setCurrentUser(userId);
|
||||||
|
} else if (Intent.ACTION_USER_STOPPED.equals(action)) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
mSettingsByUser.remove(userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private void setCurrentUser(int userId) {
|
||||||
|
final UsbSettingsManager userSettings = getSettingsForUser(userId);
|
||||||
|
if (mHostManager != null) {
|
||||||
|
mHostManager.setCurrentSettings(userSettings);
|
||||||
|
}
|
||||||
|
if (mDeviceManager != null) {
|
||||||
|
mDeviceManager.setCurrentSettings(userSettings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,6 +121,7 @@ public class UsbService extends IUsbManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Returns a list of all currently attached USB devices (host mdoe) */
|
/* Returns a list of all currently attached USB devices (host mdoe) */
|
||||||
|
@Override
|
||||||
public void getDeviceList(Bundle devices) {
|
public void getDeviceList(Bundle devices) {
|
||||||
if (mHostManager != null) {
|
if (mHostManager != null) {
|
||||||
mHostManager.getDeviceList(devices);
|
mHostManager.getDeviceList(devices);
|
||||||
@@ -72,6 +129,7 @@ public class UsbService extends IUsbManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Opens the specified USB device (host mode) */
|
/* Opens the specified USB device (host mode) */
|
||||||
|
@Override
|
||||||
public ParcelFileDescriptor openDevice(String deviceName) {
|
public ParcelFileDescriptor openDevice(String deviceName) {
|
||||||
if (mHostManager != null) {
|
if (mHostManager != null) {
|
||||||
return mHostManager.openDevice(deviceName);
|
return mHostManager.openDevice(deviceName);
|
||||||
@@ -81,6 +139,7 @@ public class UsbService extends IUsbManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* returns the currently attached USB accessory (device mode) */
|
/* returns the currently attached USB accessory (device mode) */
|
||||||
|
@Override
|
||||||
public UsbAccessory getCurrentAccessory() {
|
public UsbAccessory getCurrentAccessory() {
|
||||||
if (mDeviceManager != null) {
|
if (mDeviceManager != null) {
|
||||||
return mDeviceManager.getCurrentAccessory();
|
return mDeviceManager.getCurrentAccessory();
|
||||||
@@ -90,6 +149,7 @@ public class UsbService extends IUsbManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* opens the currently attached USB accessory (device mode) */
|
/* opens the currently attached USB accessory (device mode) */
|
||||||
|
@Override
|
||||||
public ParcelFileDescriptor openAccessory(UsbAccessory accessory) {
|
public ParcelFileDescriptor openAccessory(UsbAccessory accessory) {
|
||||||
if (mDeviceManager != null) {
|
if (mDeviceManager != null) {
|
||||||
return mDeviceManager.openAccessory(accessory);
|
return mDeviceManager.openAccessory(accessory);
|
||||||
@@ -98,54 +158,70 @@ public class UsbService extends IUsbManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDevicePackage(UsbDevice device, String packageName) {
|
@Override
|
||||||
|
public void setDevicePackage(UsbDevice device, String packageName, int userId) {
|
||||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
||||||
mSettingsManager.setDevicePackage(device, packageName);
|
getSettingsForUser(userId).setDevicePackage(device, packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAccessoryPackage(UsbAccessory accessory, String packageName) {
|
@Override
|
||||||
|
public void setAccessoryPackage(UsbAccessory accessory, String packageName, int userId) {
|
||||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
||||||
mSettingsManager.setAccessoryPackage(accessory, packageName);
|
getSettingsForUser(userId).setAccessoryPackage(accessory, packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean hasDevicePermission(UsbDevice device) {
|
public boolean hasDevicePermission(UsbDevice device) {
|
||||||
return mSettingsManager.hasPermission(device);
|
final int userId = UserHandle.getCallingUserId();
|
||||||
|
return getSettingsForUser(userId).hasPermission(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean hasAccessoryPermission(UsbAccessory accessory) {
|
public boolean hasAccessoryPermission(UsbAccessory accessory) {
|
||||||
return mSettingsManager.hasPermission(accessory);
|
final int userId = UserHandle.getCallingUserId();
|
||||||
|
return getSettingsForUser(userId).hasPermission(accessory);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void requestDevicePermission(UsbDevice device, String packageName,
|
@Override
|
||||||
PendingIntent pi) {
|
public void requestDevicePermission(UsbDevice device, String packageName, PendingIntent pi) {
|
||||||
mSettingsManager.requestPermission(device, packageName, pi);
|
final int userId = UserHandle.getCallingUserId();
|
||||||
|
getSettingsForUser(userId).requestPermission(device, packageName, pi);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void requestAccessoryPermission(UsbAccessory accessory, String packageName,
|
@Override
|
||||||
PendingIntent pi) {
|
public void requestAccessoryPermission(
|
||||||
mSettingsManager.requestPermission(accessory, packageName, pi);
|
UsbAccessory accessory, String packageName, PendingIntent pi) {
|
||||||
|
final int userId = UserHandle.getCallingUserId();
|
||||||
|
getSettingsForUser(userId).requestPermission(accessory, packageName, pi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void grantDevicePermission(UsbDevice device, int uid) {
|
public void grantDevicePermission(UsbDevice device, int uid) {
|
||||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
||||||
mSettingsManager.grantDevicePermission(device, uid);
|
final int userId = UserHandle.getUserId(uid);
|
||||||
|
getSettingsForUser(userId).grantDevicePermission(device, uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void grantAccessoryPermission(UsbAccessory accessory, int uid) {
|
public void grantAccessoryPermission(UsbAccessory accessory, int uid) {
|
||||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
||||||
mSettingsManager.grantAccessoryPermission(accessory, uid);
|
final int userId = UserHandle.getUserId(uid);
|
||||||
|
getSettingsForUser(userId).grantAccessoryPermission(accessory, uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasDefaults(String packageName) {
|
@Override
|
||||||
|
public boolean hasDefaults(String packageName, int userId) {
|
||||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
||||||
return mSettingsManager.hasDefaults(packageName);
|
return getSettingsForUser(userId).hasDefaults(packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearDefaults(String packageName) {
|
@Override
|
||||||
|
public void clearDefaults(String packageName, int userId) {
|
||||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
||||||
mSettingsManager.clearDefaults(packageName);
|
getSettingsForUser(userId).clearDefaults(packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setCurrentFunction(String function, boolean makeDefault) {
|
public void setCurrentFunction(String function, boolean makeDefault) {
|
||||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
||||||
if (mDeviceManager != null) {
|
if (mDeviceManager != null) {
|
||||||
@@ -155,6 +231,7 @@ public class UsbService extends IUsbManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setMassStorageBackingFile(String path) {
|
public void setMassStorageBackingFile(String path) {
|
||||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
||||||
if (mDeviceManager != null) {
|
if (mDeviceManager != null) {
|
||||||
@@ -164,34 +241,41 @@ public class UsbService extends IUsbManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void allowUsbDebugging(boolean alwaysAllow, String publicKey) {
|
public void allowUsbDebugging(boolean alwaysAllow, String publicKey) {
|
||||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
||||||
mDeviceManager.allowUsbDebugging(alwaysAllow, publicKey);
|
mDeviceManager.allowUsbDebugging(alwaysAllow, publicKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void denyUsbDebugging() {
|
public void denyUsbDebugging() {
|
||||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
||||||
mDeviceManager.denyUsbDebugging();
|
mDeviceManager.denyUsbDebugging();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
|
||||||
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
|
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
|
||||||
!= PackageManager.PERMISSION_GRANTED) {
|
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
|
||||||
pw.println("Permission Denial: can't dump UsbManager from from pid="
|
|
||||||
+ Binder.getCallingPid()
|
|
||||||
+ ", uid=" + Binder.getCallingUid());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pw.println("USB Manager State:");
|
pw.println("USB Manager State:");
|
||||||
|
|
||||||
if (mDeviceManager != null) {
|
if (mDeviceManager != null) {
|
||||||
mDeviceManager.dump(fd, pw);
|
mDeviceManager.dump(fd, pw);
|
||||||
}
|
}
|
||||||
if (mHostManager != null) {
|
if (mHostManager != null) {
|
||||||
mHostManager.dump(fd, pw);
|
mHostManager.dump(fd, pw);
|
||||||
}
|
}
|
||||||
mSettingsManager.dump(fd, pw);
|
|
||||||
|
synchronized (mLock) {
|
||||||
|
for (int i = 0; i < mSettingsByUser.size(); i++) {
|
||||||
|
final int userId = mSettingsByUser.keyAt(i);
|
||||||
|
final UsbSettingsManager settings = mSettingsByUser.valueAt(i);
|
||||||
|
pw.increaseIndent();
|
||||||
|
pw.println("Settings for user " + userId + ":");
|
||||||
|
settings.dump(fd, pw);
|
||||||
|
pw.decreaseIndent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pw.decreaseIndent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,9 +33,10 @@ import android.hardware.usb.UsbDevice;
|
|||||||
import android.hardware.usb.UsbInterface;
|
import android.hardware.usb.UsbInterface;
|
||||||
import android.hardware.usb.UsbManager;
|
import android.hardware.usb.UsbManager;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.FileUtils;
|
import android.os.Environment;
|
||||||
import android.os.Process;
|
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
|
import android.util.AtomicFile;
|
||||||
|
import android.util.Log;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.SparseBooleanArray;
|
import android.util.SparseBooleanArray;
|
||||||
import android.util.Xml;
|
import android.util.Xml;
|
||||||
@@ -48,7 +49,6 @@ import org.xmlpull.v1.XmlPullParser;
|
|||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
import org.xmlpull.v1.XmlSerializer;
|
import org.xmlpull.v1.XmlSerializer;
|
||||||
|
|
||||||
import java.io.BufferedOutputStream;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@@ -60,13 +60,21 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
class UsbSettingsManager {
|
import libcore.io.IoUtils;
|
||||||
|
|
||||||
|
class UsbSettingsManager {
|
||||||
private static final String TAG = "UsbSettingsManager";
|
private static final String TAG = "UsbSettingsManager";
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
private static final File sSettingsFile = new File("/data/system/usb_device_manager.xml");
|
|
||||||
|
/** Legacy settings file, before multi-user */
|
||||||
|
private static final File sSingleUserSettingsFile = new File(
|
||||||
|
"/data/system/usb_device_manager.xml");
|
||||||
|
|
||||||
|
private final UserHandle mUser;
|
||||||
|
private final AtomicFile mSettingsFile;
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
|
private final Context mUserContext;
|
||||||
private final PackageManager mPackageManager;
|
private final PackageManager mPackageManager;
|
||||||
|
|
||||||
// Temporary mapping USB device name to list of UIDs with permissions for the device
|
// Temporary mapping USB device name to list of UIDs with permissions for the device
|
||||||
@@ -350,28 +358,49 @@ class UsbSettingsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class MyPackageMonitor extends PackageMonitor {
|
private class MyPackageMonitor extends PackageMonitor {
|
||||||
|
@Override
|
||||||
public void onPackageAdded(String packageName, int uid) {
|
public void onPackageAdded(String packageName, int uid) {
|
||||||
handlePackageUpdate(packageName);
|
handlePackageUpdate(packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onPackageChanged(String packageName, int uid, String[] components) {
|
public void onPackageChanged(String packageName, int uid, String[] components) {
|
||||||
handlePackageUpdate(packageName);
|
handlePackageUpdate(packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onPackageRemoved(String packageName, int uid) {
|
public void onPackageRemoved(String packageName, int uid) {
|
||||||
clearDefaults(packageName);
|
clearDefaults(packageName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MyPackageMonitor mPackageMonitor = new MyPackageMonitor();
|
MyPackageMonitor mPackageMonitor = new MyPackageMonitor();
|
||||||
|
|
||||||
public UsbSettingsManager(Context context) {
|
public UsbSettingsManager(Context context, UserHandle user) {
|
||||||
|
if (DEBUG) Slog.v(TAG, "Creating settings for " + user);
|
||||||
|
|
||||||
|
try {
|
||||||
|
mUserContext = context.createPackageContextAsUser("android", 0, user);
|
||||||
|
} catch (NameNotFoundException e) {
|
||||||
|
throw new RuntimeException("Missing android package");
|
||||||
|
}
|
||||||
|
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mPackageManager = context.getPackageManager();
|
mPackageManager = mUserContext.getPackageManager();
|
||||||
|
|
||||||
|
mUser = user;
|
||||||
|
mSettingsFile = new AtomicFile(new File(
|
||||||
|
Environment.getUserSystemDirectory(user.getIdentifier()),
|
||||||
|
"usb_device_manager.xml"));
|
||||||
|
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
|
if (UserHandle.OWNER.equals(user)) {
|
||||||
|
upgradeSingleUserLocked();
|
||||||
|
}
|
||||||
readSettingsLocked();
|
readSettingsLocked();
|
||||||
}
|
}
|
||||||
mPackageMonitor.register(context, null, true);
|
|
||||||
|
mPackageMonitor.register(mUserContext, null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readPreference(XmlPullParser parser)
|
private void readPreference(XmlPullParser parser)
|
||||||
@@ -395,10 +424,54 @@ class UsbSettingsManager {
|
|||||||
XmlUtils.nextElement(parser);
|
XmlUtils.nextElement(parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upgrade any single-user settings from {@link #sSingleUserSettingsFile}.
|
||||||
|
* Should only by called by owner.
|
||||||
|
*/
|
||||||
|
private void upgradeSingleUserLocked() {
|
||||||
|
if (sSingleUserSettingsFile.exists()) {
|
||||||
|
mDevicePreferenceMap.clear();
|
||||||
|
mAccessoryPreferenceMap.clear();
|
||||||
|
|
||||||
|
FileInputStream fis = null;
|
||||||
|
try {
|
||||||
|
fis = new FileInputStream(sSingleUserSettingsFile);
|
||||||
|
XmlPullParser parser = Xml.newPullParser();
|
||||||
|
parser.setInput(fis, null);
|
||||||
|
|
||||||
|
XmlUtils.nextElement(parser);
|
||||||
|
while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
|
||||||
|
final String tagName = parser.getName();
|
||||||
|
if ("preference".equals(tagName)) {
|
||||||
|
readPreference(parser);
|
||||||
|
} else {
|
||||||
|
XmlUtils.nextElement(parser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.wtf(TAG, "Failed to read single-user settings", e);
|
||||||
|
} catch (XmlPullParserException e) {
|
||||||
|
Log.wtf(TAG, "Failed to read single-user settings", e);
|
||||||
|
} finally {
|
||||||
|
IoUtils.closeQuietly(fis);
|
||||||
|
}
|
||||||
|
|
||||||
|
writeSettingsLocked();
|
||||||
|
|
||||||
|
// Success or failure, we delete single-user file
|
||||||
|
sSingleUserSettingsFile.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void readSettingsLocked() {
|
private void readSettingsLocked() {
|
||||||
|
if (DEBUG) Slog.v(TAG, "readSettingsLocked()");
|
||||||
|
|
||||||
|
mDevicePreferenceMap.clear();
|
||||||
|
mAccessoryPreferenceMap.clear();
|
||||||
|
|
||||||
FileInputStream stream = null;
|
FileInputStream stream = null;
|
||||||
try {
|
try {
|
||||||
stream = new FileInputStream(sSettingsFile);
|
stream = mSettingsFile.openRead();
|
||||||
XmlPullParser parser = Xml.newPullParser();
|
XmlPullParser parser = Xml.newPullParser();
|
||||||
parser.setInput(stream, null);
|
parser.setInput(stream, null);
|
||||||
|
|
||||||
@@ -407,7 +480,7 @@ class UsbSettingsManager {
|
|||||||
String tagName = parser.getName();
|
String tagName = parser.getName();
|
||||||
if ("preference".equals(tagName)) {
|
if ("preference".equals(tagName)) {
|
||||||
readPreference(parser);
|
readPreference(parser);
|
||||||
} else {
|
} else {
|
||||||
XmlUtils.nextElement(parser);
|
XmlUtils.nextElement(parser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -415,25 +488,21 @@ class UsbSettingsManager {
|
|||||||
if (DEBUG) Slog.d(TAG, "settings file not found");
|
if (DEBUG) Slog.d(TAG, "settings file not found");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Slog.e(TAG, "error reading settings file, deleting to start fresh", e);
|
Slog.e(TAG, "error reading settings file, deleting to start fresh", e);
|
||||||
sSettingsFile.delete();
|
mSettingsFile.delete();
|
||||||
} finally {
|
} finally {
|
||||||
if (stream != null) {
|
IoUtils.closeQuietly(stream);
|
||||||
try {
|
|
||||||
stream.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeSettingsLocked() {
|
private void writeSettingsLocked() {
|
||||||
|
if (DEBUG) Slog.v(TAG, "writeSettingsLocked()");
|
||||||
|
|
||||||
FileOutputStream fos = null;
|
FileOutputStream fos = null;
|
||||||
try {
|
try {
|
||||||
FileOutputStream fstr = new FileOutputStream(sSettingsFile);
|
fos = mSettingsFile.startWrite();
|
||||||
if (DEBUG) Slog.d(TAG, "writing settings to " + fstr);
|
|
||||||
BufferedOutputStream str = new BufferedOutputStream(fstr);
|
|
||||||
FastXmlSerializer serializer = new FastXmlSerializer();
|
FastXmlSerializer serializer = new FastXmlSerializer();
|
||||||
serializer.setOutput(str, "utf-8");
|
serializer.setOutput(fos, "utf-8");
|
||||||
serializer.startDocument(null, true);
|
serializer.startDocument(null, true);
|
||||||
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
|
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
|
||||||
serializer.startTag(null, "settings");
|
serializer.startTag(null, "settings");
|
||||||
@@ -455,12 +524,12 @@ class UsbSettingsManager {
|
|||||||
serializer.endTag(null, "settings");
|
serializer.endTag(null, "settings");
|
||||||
serializer.endDocument();
|
serializer.endDocument();
|
||||||
|
|
||||||
str.flush();
|
mSettingsFile.finishWrite(fos);
|
||||||
FileUtils.sync(fstr);
|
} catch (IOException e) {
|
||||||
str.close();
|
Slog.e(TAG, "Failed to write settings", e);
|
||||||
} catch (Exception e) {
|
if (fos != null) {
|
||||||
Slog.e(TAG, "error writing settings file, deleting to start fresh", e);
|
mSettingsFile.failWrite(fos);
|
||||||
sSettingsFile.delete();
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -547,7 +616,7 @@ class UsbSettingsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send broadcast to running activity with registered intent
|
// Send broadcast to running activity with registered intent
|
||||||
mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
|
mUserContext.sendBroadcast(intent);
|
||||||
|
|
||||||
// Start activity with registered intent
|
// Start activity with registered intent
|
||||||
resolveActivity(intent, matches, defaultPackage, device, null);
|
resolveActivity(intent, matches, defaultPackage, device, null);
|
||||||
@@ -608,7 +677,7 @@ class UsbSettingsManager {
|
|||||||
dialogIntent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory);
|
dialogIntent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory);
|
||||||
dialogIntent.putExtra("uri", uri);
|
dialogIntent.putExtra("uri", uri);
|
||||||
try {
|
try {
|
||||||
mContext.startActivity(dialogIntent);
|
mUserContext.startActivityAsUser(dialogIntent, mUser);
|
||||||
} catch (ActivityNotFoundException e) {
|
} catch (ActivityNotFoundException e) {
|
||||||
Slog.e(TAG, "unable to start UsbAccessoryUriActivity");
|
Slog.e(TAG, "unable to start UsbAccessoryUriActivity");
|
||||||
}
|
}
|
||||||
@@ -656,7 +725,7 @@ class UsbSettingsManager {
|
|||||||
intent.setComponent(
|
intent.setComponent(
|
||||||
new ComponentName(defaultRI.activityInfo.packageName,
|
new ComponentName(defaultRI.activityInfo.packageName,
|
||||||
defaultRI.activityInfo.name));
|
defaultRI.activityInfo.name));
|
||||||
mContext.startActivity(intent);
|
mUserContext.startActivityAsUser(intent, mUser);
|
||||||
} catch (ActivityNotFoundException e) {
|
} catch (ActivityNotFoundException e) {
|
||||||
Slog.e(TAG, "startActivity failed", e);
|
Slog.e(TAG, "startActivity failed", e);
|
||||||
}
|
}
|
||||||
@@ -683,7 +752,7 @@ class UsbSettingsManager {
|
|||||||
resolverIntent.putExtra(Intent.EXTRA_INTENT, intent);
|
resolverIntent.putExtra(Intent.EXTRA_INTENT, intent);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
mContext.startActivity(resolverIntent);
|
mUserContext.startActivityAsUser(resolverIntent, mUser);
|
||||||
} catch (ActivityNotFoundException e) {
|
} catch (ActivityNotFoundException e) {
|
||||||
Slog.e(TAG, "unable to start activity " + resolverIntent);
|
Slog.e(TAG, "unable to start activity " + resolverIntent);
|
||||||
}
|
}
|
||||||
@@ -814,7 +883,7 @@ class UsbSettingsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void requestPermissionDialog(Intent intent, String packageName, PendingIntent pi) {
|
private void requestPermissionDialog(Intent intent, String packageName, PendingIntent pi) {
|
||||||
int uid = Binder.getCallingUid();
|
final int uid = Binder.getCallingUid();
|
||||||
|
|
||||||
// compare uid with packageName to foil apps pretending to be someone else
|
// compare uid with packageName to foil apps pretending to be someone else
|
||||||
try {
|
try {
|
||||||
@@ -833,9 +902,9 @@ class UsbSettingsManager {
|
|||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
intent.putExtra(Intent.EXTRA_INTENT, pi);
|
intent.putExtra(Intent.EXTRA_INTENT, pi);
|
||||||
intent.putExtra("package", packageName);
|
intent.putExtra("package", packageName);
|
||||||
intent.putExtra("uid", uid);
|
intent.putExtra(Intent.EXTRA_UID, uid);
|
||||||
try {
|
try {
|
||||||
mContext.startActivity(intent);
|
mUserContext.startActivityAsUser(intent, mUser);
|
||||||
} catch (ActivityNotFoundException e) {
|
} catch (ActivityNotFoundException e) {
|
||||||
Slog.e(TAG, "unable to start UsbPermissionActivity");
|
Slog.e(TAG, "unable to start UsbPermissionActivity");
|
||||||
} finally {
|
} finally {
|
||||||
@@ -851,7 +920,7 @@ class UsbSettingsManager {
|
|||||||
intent.putExtra(UsbManager.EXTRA_DEVICE, device);
|
intent.putExtra(UsbManager.EXTRA_DEVICE, device);
|
||||||
intent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, true);
|
intent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, true);
|
||||||
try {
|
try {
|
||||||
pi.send(mContext, 0, intent);
|
pi.send(mUserContext, 0, intent);
|
||||||
} catch (PendingIntent.CanceledException e) {
|
} catch (PendingIntent.CanceledException e) {
|
||||||
if (DEBUG) Slog.d(TAG, "requestPermission PendingIntent was cancelled");
|
if (DEBUG) Slog.d(TAG, "requestPermission PendingIntent was cancelled");
|
||||||
}
|
}
|
||||||
@@ -864,14 +933,14 @@ class UsbSettingsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void requestPermission(UsbAccessory accessory, String packageName, PendingIntent pi) {
|
public void requestPermission(UsbAccessory accessory, String packageName, PendingIntent pi) {
|
||||||
Intent intent = new Intent();
|
Intent intent = new Intent();
|
||||||
|
|
||||||
// respond immediately if permission has already been granted
|
// respond immediately if permission has already been granted
|
||||||
if (hasPermission(accessory)) {
|
if (hasPermission(accessory)) {
|
||||||
intent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory);
|
intent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory);
|
||||||
intent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, true);
|
intent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, true);
|
||||||
try {
|
try {
|
||||||
pi.send(mContext, 0, intent);
|
pi.send(mUserContext, 0, intent);
|
||||||
} catch (PendingIntent.CanceledException e) {
|
} catch (PendingIntent.CanceledException e) {
|
||||||
if (DEBUG) Slog.d(TAG, "requestPermission PendingIntent was cancelled");
|
if (DEBUG) Slog.d(TAG, "requestPermission PendingIntent was cancelled");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user