Merge changes from topic 'usb_bugfixes-mirror-aosp-master'
* changes: Refactored setCurrentFunction and setUsbDataUnlocked into single method. Clean up persistent usb state on boot. Fixed handling of usb state during adb changes.
This commit is contained in:
@@ -50,7 +50,7 @@ public class UsbCommand extends Svc.Command {
|
|||||||
IUsbManager usbMgr = IUsbManager.Stub.asInterface(ServiceManager.getService(
|
IUsbManager usbMgr = IUsbManager.Stub.asInterface(ServiceManager.getService(
|
||||||
Context.USB_SERVICE));
|
Context.USB_SERVICE));
|
||||||
try {
|
try {
|
||||||
usbMgr.setCurrentFunction((args.length >=3 ? args[2] : null));
|
usbMgr.setCurrentFunction((args.length >=3 ? args[2] : null), false);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
System.err.println("Error communicating with UsbManager: " + e);
|
System.err.println("Error communicating with UsbManager: " + e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,15 +87,13 @@ interface IUsbManager
|
|||||||
/* Returns true if the specified USB function is enabled. */
|
/* Returns true if the specified USB function is enabled. */
|
||||||
boolean isFunctionEnabled(String function);
|
boolean isFunctionEnabled(String function);
|
||||||
|
|
||||||
/* Sets the current USB function. */
|
/* Sets the current USB function as well as whether USB data
|
||||||
void setCurrentFunction(String function);
|
* (for example, MTP exposed pictures) should be made available
|
||||||
|
* on the USB connection. Unlocking data should only be done with
|
||||||
/* Sets whether USB data (for example, MTP exposed pictures) should be made
|
* user involvement, since exposing pictures or other data could
|
||||||
* available on the USB connection. Unlocking data should only be done with
|
* leak sensitive user information.
|
||||||
* user involvement, since exposing pictures or other data could leak sensitive
|
|
||||||
* user information.
|
|
||||||
*/
|
*/
|
||||||
void setUsbDataUnlocked(boolean unlock);
|
void setCurrentFunction(String function, boolean usbDataUnlocked);
|
||||||
|
|
||||||
/* Allow USB debugging from the attached host. If alwaysAllow is true, add the
|
/* Allow USB debugging from the attached host. If alwaysAllow is true, add the
|
||||||
* the public key to list of host keys that the user has approved.
|
* the public key to list of host keys that the user has approved.
|
||||||
|
|||||||
@@ -509,33 +509,23 @@ public class UsbManager {
|
|||||||
* {@link #USB_FUNCTION_MIDI}, {@link #USB_FUNCTION_MTP}, {@link #USB_FUNCTION_PTP},
|
* {@link #USB_FUNCTION_MIDI}, {@link #USB_FUNCTION_MTP}, {@link #USB_FUNCTION_PTP},
|
||||||
* or {@link #USB_FUNCTION_RNDIS}.
|
* or {@link #USB_FUNCTION_RNDIS}.
|
||||||
* </p><p>
|
* </p><p>
|
||||||
|
* Also sets whether USB data (for example, MTP exposed pictures) should be made available
|
||||||
|
* on the USB connection when in device mode. Unlocking usb data should only be done with
|
||||||
|
* user involvement, since exposing pictures or other data could leak sensitive
|
||||||
|
* user information.
|
||||||
|
* </p><p>
|
||||||
* Note: This function is asynchronous and may fail silently without applying
|
* Note: This function is asynchronous and may fail silently without applying
|
||||||
* the requested changes.
|
* the requested changes.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param function name of the USB function, or null to restore the default function
|
* @param function name of the USB function, or null to restore the default function
|
||||||
|
* @param usbDataUnlocked whether user data is accessible
|
||||||
*
|
*
|
||||||
* {@hide}
|
* {@hide}
|
||||||
*/
|
*/
|
||||||
public void setCurrentFunction(String function) {
|
public void setCurrentFunction(String function, boolean usbDataUnlocked) {
|
||||||
try {
|
try {
|
||||||
mService.setCurrentFunction(function);
|
mService.setCurrentFunction(function, usbDataUnlocked);
|
||||||
} catch (RemoteException e) {
|
|
||||||
throw e.rethrowFromSystemServer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets whether USB data (for example, MTP exposed pictures) should be made available
|
|
||||||
* on the USB connection when in device mode. Unlocking usb data should only be done with
|
|
||||||
* user involvement, since exposing pictures or other data could leak sensitive
|
|
||||||
* user information.
|
|
||||||
*
|
|
||||||
* {@hide}
|
|
||||||
*/
|
|
||||||
public void setUsbDataUnlocked(boolean unlocked) {
|
|
||||||
try {
|
|
||||||
mService.setUsbDataUnlocked(unlocked);
|
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
throw e.rethrowFromSystemServer();
|
throw e.rethrowFromSystemServer();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -900,7 +900,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mUsbTetherRequested = true;
|
mUsbTetherRequested = true;
|
||||||
usbManager.setCurrentFunction(UsbManager.USB_FUNCTION_RNDIS);
|
usbManager.setCurrentFunction(UsbManager.USB_FUNCTION_RNDIS, false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final long ident = Binder.clearCallingIdentity();
|
final long ident = Binder.clearCallingIdentity();
|
||||||
@@ -910,7 +910,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
|
|||||||
Binder.restoreCallingIdentity(ident);
|
Binder.restoreCallingIdentity(ident);
|
||||||
}
|
}
|
||||||
if (mRndisEnabled) {
|
if (mRndisEnabled) {
|
||||||
usbManager.setCurrentFunction(null);
|
usbManager.setCurrentFunction(null, false);
|
||||||
}
|
}
|
||||||
mUsbTetherRequested = false;
|
mUsbTetherRequested = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,9 +108,8 @@ public class UsbDeviceManager {
|
|||||||
private static final int MSG_SYSTEM_READY = 3;
|
private static final int MSG_SYSTEM_READY = 3;
|
||||||
private static final int MSG_BOOT_COMPLETED = 4;
|
private static final int MSG_BOOT_COMPLETED = 4;
|
||||||
private static final int MSG_USER_SWITCHED = 5;
|
private static final int MSG_USER_SWITCHED = 5;
|
||||||
private static final int MSG_SET_USB_DATA_UNLOCKED = 6;
|
private static final int MSG_UPDATE_USER_RESTRICTIONS = 6;
|
||||||
private static final int MSG_UPDATE_USER_RESTRICTIONS = 7;
|
private static final int MSG_UPDATE_HOST_STATE = 7;
|
||||||
private static final int MSG_UPDATE_HOST_STATE = 8;
|
|
||||||
|
|
||||||
private static final int AUDIO_MODE_SOURCE = 1;
|
private static final int AUDIO_MODE_SOURCE = 1;
|
||||||
|
|
||||||
@@ -287,7 +286,7 @@ public class UsbDeviceManager {
|
|||||||
|
|
||||||
if (functions != null) {
|
if (functions != null) {
|
||||||
mAccessoryModeRequestTime = SystemClock.elapsedRealtime();
|
mAccessoryModeRequestTime = SystemClock.elapsedRealtime();
|
||||||
setCurrentFunctions(functions);
|
setCurrentFunctions(functions, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,14 +334,22 @@ public class UsbDeviceManager {
|
|||||||
// Restore default functions.
|
// Restore default functions.
|
||||||
mCurrentFunctions = SystemProperties.get(USB_CONFIG_PROPERTY,
|
mCurrentFunctions = SystemProperties.get(USB_CONFIG_PROPERTY,
|
||||||
UsbManager.USB_FUNCTION_NONE);
|
UsbManager.USB_FUNCTION_NONE);
|
||||||
if (UsbManager.USB_FUNCTION_NONE.equals(mCurrentFunctions)) {
|
|
||||||
mCurrentFunctions = UsbManager.USB_FUNCTION_MTP;
|
|
||||||
}
|
|
||||||
mCurrentFunctionsApplied = mCurrentFunctions.equals(
|
mCurrentFunctionsApplied = mCurrentFunctions.equals(
|
||||||
SystemProperties.get(USB_STATE_PROPERTY));
|
SystemProperties.get(USB_STATE_PROPERTY));
|
||||||
mAdbEnabled = UsbManager.containsFunction(getDefaultFunctions(),
|
mAdbEnabled = UsbManager.containsFunction(getDefaultFunctions(),
|
||||||
UsbManager.USB_FUNCTION_ADB);
|
UsbManager.USB_FUNCTION_ADB);
|
||||||
setEnabledFunctions(null, false);
|
|
||||||
|
/**
|
||||||
|
* Remove MTP from persistent config, to bring usb to a good state
|
||||||
|
* after fixes to b/31814300. This block can be removed after the update
|
||||||
|
*/
|
||||||
|
String persisted = SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY);
|
||||||
|
if (UsbManager.containsFunction(persisted, UsbManager.USB_FUNCTION_MTP)) {
|
||||||
|
SystemProperties.set(USB_PERSISTENT_CONFIG_PROPERTY,
|
||||||
|
UsbManager.removeFunction(persisted, UsbManager.USB_FUNCTION_MTP));
|
||||||
|
}
|
||||||
|
|
||||||
|
setEnabledFunctions(null, false, false);
|
||||||
|
|
||||||
String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim();
|
String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim();
|
||||||
updateState(state);
|
updateState(state);
|
||||||
@@ -374,6 +381,14 @@ public class UsbDeviceManager {
|
|||||||
sendMessage(m);
|
sendMessage(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void sendMessage(int what, Object arg, boolean arg1) {
|
||||||
|
removeMessages(what);
|
||||||
|
Message m = Message.obtain(this, what);
|
||||||
|
m.obj = arg;
|
||||||
|
m.arg1 = (arg1 ? 1 : 0);
|
||||||
|
sendMessage(m);
|
||||||
|
}
|
||||||
|
|
||||||
public void updateState(String state) {
|
public void updateState(String state) {
|
||||||
int connected, configured;
|
int connected, configured;
|
||||||
|
|
||||||
@@ -427,29 +442,24 @@ public class UsbDeviceManager {
|
|||||||
return waitForState(config);
|
return waitForState(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUsbDataUnlocked(boolean enable) {
|
|
||||||
if (DEBUG) Slog.d(TAG, "setUsbDataUnlocked: " + enable);
|
|
||||||
mUsbDataUnlocked = enable;
|
|
||||||
updateUsbNotification();
|
|
||||||
updateUsbStateBroadcastIfNeeded();
|
|
||||||
setEnabledFunctions(mCurrentFunctions, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setAdbEnabled(boolean enable) {
|
private void setAdbEnabled(boolean enable) {
|
||||||
if (DEBUG) Slog.d(TAG, "setAdbEnabled: " + enable);
|
if (DEBUG) Slog.d(TAG, "setAdbEnabled: " + enable);
|
||||||
if (enable != mAdbEnabled) {
|
if (enable != mAdbEnabled) {
|
||||||
mAdbEnabled = enable;
|
mAdbEnabled = enable;
|
||||||
|
String oldFunctions = mCurrentFunctions;
|
||||||
|
|
||||||
// Due to the persist.sys.usb.config property trigger, changing adb state requires
|
// Persist the adb setting
|
||||||
// persisting default function
|
String newFunction = applyAdbFunction(SystemProperties.get(
|
||||||
String oldFunctions = getDefaultFunctions();
|
USB_PERSISTENT_CONFIG_PROPERTY, UsbManager.USB_FUNCTION_NONE));
|
||||||
String newFunctions = applyAdbFunction(oldFunctions);
|
SystemProperties.set(USB_PERSISTENT_CONFIG_PROPERTY, newFunction);
|
||||||
if (!oldFunctions.equals(newFunctions)) {
|
|
||||||
SystemProperties.set(USB_PERSISTENT_CONFIG_PROPERTY, newFunctions);
|
// Remove mtp from the config if file transfer is not enabled
|
||||||
|
if (oldFunctions.equals(UsbManager.USB_FUNCTION_MTP) &&
|
||||||
|
!mUsbDataUnlocked && enable) {
|
||||||
|
oldFunctions = UsbManager.USB_FUNCTION_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// After persisting them use the lock-down aware function set
|
setEnabledFunctions(oldFunctions, true, mUsbDataUnlocked);
|
||||||
setEnabledFunctions(mCurrentFunctions, false);
|
|
||||||
updateAdbNotification();
|
updateAdbNotification();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -461,10 +471,17 @@ public class UsbDeviceManager {
|
|||||||
/**
|
/**
|
||||||
* Evaluates USB function policies and applies the change accordingly.
|
* Evaluates USB function policies and applies the change accordingly.
|
||||||
*/
|
*/
|
||||||
private void setEnabledFunctions(String functions, boolean forceRestart) {
|
private void setEnabledFunctions(String functions, boolean forceRestart,
|
||||||
|
boolean usbDataUnlocked) {
|
||||||
if (DEBUG) Slog.d(TAG, "setEnabledFunctions functions=" + functions + ", "
|
if (DEBUG) Slog.d(TAG, "setEnabledFunctions functions=" + functions + ", "
|
||||||
+ "forceRestart=" + forceRestart);
|
+ "forceRestart=" + forceRestart);
|
||||||
|
|
||||||
|
if (usbDataUnlocked != mUsbDataUnlocked) {
|
||||||
|
mUsbDataUnlocked = usbDataUnlocked;
|
||||||
|
updateUsbNotification();
|
||||||
|
forceRestart = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Try to set the enabled functions.
|
// Try to set the enabled functions.
|
||||||
final String oldFunctions = mCurrentFunctions;
|
final String oldFunctions = mCurrentFunctions;
|
||||||
final boolean oldFunctionsApplied = mCurrentFunctionsApplied;
|
final boolean oldFunctionsApplied = mCurrentFunctionsApplied;
|
||||||
@@ -501,7 +518,8 @@ public class UsbDeviceManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean trySetEnabledFunctions(String functions, boolean forceRestart) {
|
private boolean trySetEnabledFunctions(String functions, boolean forceRestart) {
|
||||||
if (functions == null) {
|
if (functions == null || applyAdbFunction(functions)
|
||||||
|
.equals(UsbManager.USB_FUNCTION_NONE)) {
|
||||||
functions = getDefaultFunctions();
|
functions = getDefaultFunctions();
|
||||||
}
|
}
|
||||||
functions = applyAdbFunction(functions);
|
functions = applyAdbFunction(functions);
|
||||||
@@ -566,7 +584,7 @@ public class UsbDeviceManager {
|
|||||||
// make sure accessory mode is off
|
// make sure accessory mode is off
|
||||||
// and restore default functions
|
// and restore default functions
|
||||||
Slog.d(TAG, "exited USB accessory mode");
|
Slog.d(TAG, "exited USB accessory mode");
|
||||||
setEnabledFunctions(null, false);
|
setEnabledFunctions(null, false, false);
|
||||||
|
|
||||||
if (mCurrentAccessory != null) {
|
if (mCurrentAccessory != null) {
|
||||||
if (mBootCompleted) {
|
if (mBootCompleted) {
|
||||||
@@ -583,10 +601,6 @@ public class UsbDeviceManager {
|
|||||||
if (mBroadcastedIntent == null) {
|
if (mBroadcastedIntent == null) {
|
||||||
for (String key : keySet) {
|
for (String key : keySet) {
|
||||||
if (intent.getBooleanExtra(key, false)) {
|
if (intent.getBooleanExtra(key, false)) {
|
||||||
// MTP function is enabled by default.
|
|
||||||
if (UsbManager.USB_FUNCTION_MTP.equals(key)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -699,10 +713,7 @@ public class UsbDeviceManager {
|
|||||||
case MSG_UPDATE_STATE:
|
case MSG_UPDATE_STATE:
|
||||||
mConnected = (msg.arg1 == 1);
|
mConnected = (msg.arg1 == 1);
|
||||||
mConfigured = (msg.arg2 == 1);
|
mConfigured = (msg.arg2 == 1);
|
||||||
if (!mConnected) {
|
|
||||||
// When a disconnect occurs, relock access to sensitive user data
|
|
||||||
mUsbDataUnlocked = false;
|
|
||||||
}
|
|
||||||
updateUsbNotification();
|
updateUsbNotification();
|
||||||
updateAdbNotification();
|
updateAdbNotification();
|
||||||
if (UsbManager.containsFunction(mCurrentFunctions,
|
if (UsbManager.containsFunction(mCurrentFunctions,
|
||||||
@@ -710,7 +721,7 @@ public class UsbDeviceManager {
|
|||||||
updateCurrentAccessory();
|
updateCurrentAccessory();
|
||||||
} else if (!mConnected) {
|
} else if (!mConnected) {
|
||||||
// restore defaults when USB is disconnected
|
// restore defaults when USB is disconnected
|
||||||
setEnabledFunctions(null, false);
|
setEnabledFunctions(null, false, false);
|
||||||
}
|
}
|
||||||
if (mBootCompleted) {
|
if (mBootCompleted) {
|
||||||
updateUsbStateBroadcastIfNeeded();
|
updateUsbStateBroadcastIfNeeded();
|
||||||
@@ -730,13 +741,10 @@ public class UsbDeviceManager {
|
|||||||
break;
|
break;
|
||||||
case MSG_SET_CURRENT_FUNCTIONS:
|
case MSG_SET_CURRENT_FUNCTIONS:
|
||||||
String functions = (String)msg.obj;
|
String functions = (String)msg.obj;
|
||||||
setEnabledFunctions(functions, false);
|
setEnabledFunctions(functions, false, msg.arg1 == 1);
|
||||||
break;
|
break;
|
||||||
case MSG_UPDATE_USER_RESTRICTIONS:
|
case MSG_UPDATE_USER_RESTRICTIONS:
|
||||||
setEnabledFunctions(mCurrentFunctions, false);
|
setEnabledFunctions(mCurrentFunctions, false, mUsbDataUnlocked);
|
||||||
break;
|
|
||||||
case MSG_SET_USB_DATA_UNLOCKED:
|
|
||||||
setUsbDataUnlocked(msg.arg1 == 1);
|
|
||||||
break;
|
break;
|
||||||
case MSG_SYSTEM_READY:
|
case MSG_SYSTEM_READY:
|
||||||
updateUsbNotification();
|
updateUsbNotification();
|
||||||
@@ -764,8 +772,7 @@ public class UsbDeviceManager {
|
|||||||
Slog.v(TAG, "Current user switched to " + mCurrentUser
|
Slog.v(TAG, "Current user switched to " + mCurrentUser
|
||||||
+ "; resetting USB host stack for MTP or PTP");
|
+ "; resetting USB host stack for MTP or PTP");
|
||||||
// avoid leaking sensitive data from previous user
|
// avoid leaking sensitive data from previous user
|
||||||
mUsbDataUnlocked = false;
|
setEnabledFunctions(mCurrentFunctions, true, false);
|
||||||
setEnabledFunctions(mCurrentFunctions, true);
|
|
||||||
}
|
}
|
||||||
mCurrentUser = msg.arg1;
|
mCurrentUser = msg.arg1;
|
||||||
}
|
}
|
||||||
@@ -944,14 +951,10 @@ public class UsbDeviceManager {
|
|||||||
return UsbManager.containsFunction(SystemProperties.get(USB_CONFIG_PROPERTY), function);
|
return UsbManager.containsFunction(SystemProperties.get(USB_CONFIG_PROPERTY), function);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCurrentFunctions(String functions) {
|
public void setCurrentFunctions(String functions, boolean usbDataUnlocked) {
|
||||||
if (DEBUG) Slog.d(TAG, "setCurrentFunctions(" + functions + ")");
|
if (DEBUG) Slog.d(TAG, "setCurrentFunctions(" + functions + ", " +
|
||||||
mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions);
|
usbDataUnlocked + ")");
|
||||||
}
|
mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions, usbDataUnlocked);
|
||||||
|
|
||||||
public void setUsbDataUnlocked(boolean unlocked) {
|
|
||||||
if (DEBUG) Slog.d(TAG, "setUsbDataUnlocked(" + unlocked + ")");
|
|
||||||
mHandler.sendMessage(MSG_SET_USB_DATA_UNLOCKED, unlocked);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readOemUsbOverrideConfig() {
|
private void readOemUsbOverrideConfig() {
|
||||||
|
|||||||
@@ -287,7 +287,7 @@ public class UsbService extends IUsbManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setCurrentFunction(String function) {
|
public void setCurrentFunction(String function, boolean usbDataUnlocked) {
|
||||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
||||||
|
|
||||||
if (!isSupportedCurrentFunction(function)) {
|
if (!isSupportedCurrentFunction(function)) {
|
||||||
@@ -297,7 +297,7 @@ public class UsbService extends IUsbManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mDeviceManager != null) {
|
if (mDeviceManager != null) {
|
||||||
mDeviceManager.setCurrentFunctions(function);
|
mDeviceManager.setCurrentFunctions(function, usbDataUnlocked);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException("USB device mode not supported");
|
throw new IllegalStateException("USB device mode not supported");
|
||||||
}
|
}
|
||||||
@@ -319,12 +319,6 @@ public class UsbService extends IUsbManager.Stub {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUsbDataUnlocked(boolean unlocked) {
|
|
||||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
|
|
||||||
mDeviceManager.setUsbDataUnlocked(unlocked);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@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);
|
||||||
|
|||||||
Reference in New Issue
Block a user