Merge changes from topic 'usb_bugfixes'

* changes:
  Automatically turn on adb for userdebug and eng builds.
  Fixed handling of usb state during adb changes.
  Refactored setCurrentFunction and setUsbDataUnlocked into single method.
  Remove the kick from config switches in UsbDeviceManager
This commit is contained in:
Jerry Zhang
2016-10-14 18:24:32 +00:00
committed by Android (Google) Code Review
6 changed files with 80 additions and 91 deletions

View File

@@ -50,7 +50,7 @@ public class UsbCommand extends Svc.Command {
IUsbManager usbMgr = IUsbManager.Stub.asInterface(ServiceManager.getService(
Context.USB_SERVICE));
try {
usbMgr.setCurrentFunction((args.length >=3 ? args[2] : null));
usbMgr.setCurrentFunction((args.length >=3 ? args[2] : null), false);
} catch (RemoteException e) {
System.err.println("Error communicating with UsbManager: " + e);
}

View File

@@ -88,15 +88,13 @@ interface IUsbManager
/* Returns true if the specified USB function is enabled. */
boolean isFunctionEnabled(String function);
/* Sets the current USB function. */
void setCurrentFunction(String function);
/* Sets whether USB data (for example, MTP exposed pictures) should be made
* available on the USB connection. Unlocking data should only be done with
* user involvement, since exposing pictures or other data could leak sensitive
* user information.
/* Sets the current USB function as well as whether USB data
* (for example, MTP exposed pictures) should be made available
* on the USB connection. Unlocking data should only be done with
* 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
* the public key to list of host keys that the user has approved.

View File

@@ -542,33 +542,23 @@ public class UsbManager {
* {@link #USB_FUNCTION_MIDI}, {@link #USB_FUNCTION_MTP}, {@link #USB_FUNCTION_PTP},
* or {@link #USB_FUNCTION_RNDIS}.
* </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
* the requested changes.
* </p>
*
* @param function name of the USB function, or null to restore the default function
* @param usbDataUnlocked whether user data is accessible
*
* {@hide}
*/
public void setCurrentFunction(String function) {
public void setCurrentFunction(String function, boolean usbDataUnlocked) {
try {
mService.setCurrentFunction(function);
} 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);
mService.setCurrentFunction(function, usbDataUnlocked);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}

View File

@@ -897,7 +897,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
}
} else {
mUsbTetherRequested = true;
usbManager.setCurrentFunction(UsbManager.USB_FUNCTION_RNDIS);
usbManager.setCurrentFunction(UsbManager.USB_FUNCTION_RNDIS, false);
}
} else {
final long ident = Binder.clearCallingIdentity();
@@ -907,7 +907,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering
Binder.restoreCallingIdentity(ident);
}
if (mRndisEnabled) {
usbManager.setCurrentFunction(null);
usbManager.setCurrentFunction(null, false);
}
mUsbTetherRequested = false;
}

View File

@@ -83,6 +83,14 @@ public class UsbDeviceManager {
*/
private static final String USB_CONFIG_PROPERTY = "sys.usb.config";
/**
* The property which stores the current build type (user/userdebug/eng).
*/
private static final String BUILD_TYPE_PROPERTY = "ro.build.type";
private static final String BUILD_TYPE_USERDEBUG = "userdebug";
private static final String BUILD_TYPE_ENG = "eng";
/**
* The non-persistent property which stores the current USB actual state.
*/
@@ -109,9 +117,8 @@ public class UsbDeviceManager {
private static final int MSG_SYSTEM_READY = 3;
private static final int MSG_BOOT_COMPLETED = 4;
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 = 7;
private static final int MSG_UPDATE_HOST_STATE = 8;
private static final int MSG_UPDATE_USER_RESTRICTIONS = 6;
private static final int MSG_UPDATE_HOST_STATE = 7;
private static final int AUDIO_MODE_SOURCE = 1;
@@ -291,7 +298,7 @@ public class UsbDeviceManager {
if (functions != null) {
mAccessoryModeRequestTime = SystemClock.elapsedRealtime();
setCurrentFunctions(functions);
setCurrentFunctions(functions, false);
}
}
@@ -340,14 +347,17 @@ public class UsbDeviceManager {
// Restore default functions.
mCurrentFunctions = SystemProperties.get(USB_CONFIG_PROPERTY,
UsbManager.USB_FUNCTION_NONE);
if (UsbManager.USB_FUNCTION_NONE.equals(mCurrentFunctions)) {
mCurrentFunctions = UsbManager.USB_FUNCTION_MTP;
}
mCurrentFunctionsApplied = mCurrentFunctions.equals(
SystemProperties.get(USB_STATE_PROPERTY));
mAdbEnabled = UsbManager.containsFunction(getDefaultFunctions(),
UsbManager.USB_FUNCTION_ADB);
setEnabledFunctions(null, false);
String buildType = SystemProperties.get(BUILD_TYPE_PROPERTY);
if (buildType.equals(BUILD_TYPE_USERDEBUG) || buildType.equals(BUILD_TYPE_ENG)) {
setAdbEnabled(true);
}
setEnabledFunctions(null, false, false);
String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim();
updateState(state);
@@ -379,6 +389,14 @@ public class UsbDeviceManager {
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) {
int connected, configured;
@@ -443,29 +461,28 @@ public class UsbDeviceManager {
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) {
if (DEBUG) Slog.d(TAG, "setAdbEnabled: " + enable);
if (enable != mAdbEnabled) {
mAdbEnabled = enable;
String oldFunctions = mCurrentFunctions;
// Due to the persist.sys.usb.config property trigger, changing adb state requires
// persisting default function
String oldFunctions = getDefaultFunctions();
String newFunctions = applyAdbFunction(oldFunctions);
if (!oldFunctions.equals(newFunctions)) {
SystemProperties.set(USB_PERSISTENT_CONFIG_PROPERTY, newFunctions);
// Persist the adb setting
String newFunction = applyAdbFunction(SystemProperties.get(
USB_PERSISTENT_CONFIG_PROPERTY, UsbManager.USB_FUNCTION_NONE));
SystemProperties.set(USB_PERSISTENT_CONFIG_PROPERTY, newFunction);
// Changing the persistent config also changes the normal
// config. Wait for this to happen before changing again.
waitForState(newFunction);
// 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(mCurrentFunctions, false);
setEnabledFunctions(oldFunctions, false, mUsbDataUnlocked);
updateAdbNotification();
}
@@ -477,10 +494,17 @@ public class UsbDeviceManager {
/**
* 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 + ", "
+ "forceRestart=" + forceRestart);
if (usbDataUnlocked != mUsbDataUnlocked) {
mUsbDataUnlocked = usbDataUnlocked;
updateUsbNotification();
forceRestart = true;
}
// Try to set the enabled functions.
final String oldFunctions = mCurrentFunctions;
final boolean oldFunctionsApplied = mCurrentFunctionsApplied;
@@ -517,7 +541,8 @@ public class UsbDeviceManager {
}
private boolean trySetEnabledFunctions(String functions, boolean forceRestart) {
if (functions == null) {
if (functions == null || applyAdbFunction(functions)
.equals(UsbManager.USB_FUNCTION_NONE)) {
functions = getDefaultFunctions();
}
functions = applyAdbFunction(functions);
@@ -529,9 +554,6 @@ public class UsbDeviceManager {
mCurrentFunctions = functions;
mCurrentFunctionsApplied = false;
// Kick the USB stack to close existing connections.
setUsbConfig(UsbManager.USB_FUNCTION_NONE);
// Set the new USB configuration.
if (!setUsbConfig(functions)) {
Slog.e(TAG, "Failed to switch USB config to " + functions);
@@ -583,7 +605,7 @@ public class UsbDeviceManager {
// make sure accessory mode is off
// and restore default functions
Slog.d(TAG, "exited USB accessory mode");
setEnabledFunctions(null, false);
setEnabledFunctions(null, false, false);
if (mCurrentAccessory != null) {
if (mBootCompleted) {
@@ -600,10 +622,6 @@ public class UsbDeviceManager {
if (mBroadcastedIntent == null) {
for (String key : keySet) {
if (intent.getBooleanExtra(key, false)) {
// MTP function is enabled by default.
if (UsbManager.USB_FUNCTION_MTP.equals(key)) {
continue;
}
return true;
}
}
@@ -716,10 +734,7 @@ public class UsbDeviceManager {
case MSG_UPDATE_STATE:
mConnected = (msg.arg1 == 1);
mConfigured = (msg.arg2 == 1);
if (!mConnected) {
// When a disconnect occurs, relock access to sensitive user data
mUsbDataUnlocked = false;
}
updateUsbNotification();
updateAdbNotification();
if (UsbManager.containsFunction(mCurrentFunctions,
@@ -727,7 +742,7 @@ public class UsbDeviceManager {
updateCurrentAccessory();
} else if (!mConnected) {
// restore defaults when USB is disconnected
setEnabledFunctions(null, false);
setEnabledFunctions(null, false, false);
}
if (mBootCompleted) {
updateUsbStateBroadcastIfNeeded();
@@ -750,13 +765,10 @@ public class UsbDeviceManager {
break;
case MSG_SET_CURRENT_FUNCTIONS:
String functions = (String)msg.obj;
setEnabledFunctions(functions, false);
setEnabledFunctions(functions, false, msg.arg1 == 1);
break;
case MSG_UPDATE_USER_RESTRICTIONS:
setEnabledFunctions(mCurrentFunctions, false);
break;
case MSG_SET_USB_DATA_UNLOCKED:
setUsbDataUnlocked(msg.arg1 == 1);
setEnabledFunctions(mCurrentFunctions, false, mUsbDataUnlocked);
break;
case MSG_SYSTEM_READY:
updateUsbNotification();
@@ -784,8 +796,7 @@ public class UsbDeviceManager {
Slog.v(TAG, "Current user switched to " + mCurrentUser
+ "; resetting USB host stack for MTP or PTP");
// avoid leaking sensitive data from previous user
mUsbDataUnlocked = false;
setEnabledFunctions(mCurrentFunctions, true);
setEnabledFunctions(mCurrentFunctions, true, false);
}
mCurrentUser = msg.arg1;
}
@@ -969,14 +980,10 @@ public class UsbDeviceManager {
return UsbManager.containsFunction(SystemProperties.get(USB_CONFIG_PROPERTY), function);
}
public void setCurrentFunctions(String functions) {
if (DEBUG) Slog.d(TAG, "setCurrentFunctions(" + functions + ")");
mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions);
}
public void setUsbDataUnlocked(boolean unlocked) {
if (DEBUG) Slog.d(TAG, "setUsbDataUnlocked(" + unlocked + ")");
mHandler.sendMessage(MSG_SET_USB_DATA_UNLOCKED, unlocked);
public void setCurrentFunctions(String functions, boolean usbDataUnlocked) {
if (DEBUG) Slog.d(TAG, "setCurrentFunctions(" + functions + ", " +
usbDataUnlocked + ")");
mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions, usbDataUnlocked);
}
private void readOemUsbOverrideConfig() {

View File

@@ -372,7 +372,7 @@ public class UsbService extends IUsbManager.Stub {
}
@Override
public void setCurrentFunction(String function) {
public void setCurrentFunction(String function, boolean usbDataUnlocked) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
if (!isSupportedCurrentFunction(function)) {
@@ -382,7 +382,7 @@ public class UsbService extends IUsbManager.Stub {
}
if (mDeviceManager != null) {
mDeviceManager.setCurrentFunctions(function);
mDeviceManager.setCurrentFunctions(function, usbDataUnlocked);
} else {
throw new IllegalStateException("USB device mode not supported");
}
@@ -404,12 +404,6 @@ public class UsbService extends IUsbManager.Stub {
return false;
}
@Override
public void setUsbDataUnlocked(boolean unlocked) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
mDeviceManager.setUsbDataUnlocked(unlocked);
}
@Override
public void allowUsbDebugging(boolean alwaysAllow, String publicKey) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);