public void connectSimulatedPort( String portId, int mode, boolean canChangeMode, int powerRole, boolean canChangePowerRole, int dataRole, boolean canChangeDataRole, IndentingPrintWriter pw) { synchronized (mLock) { final SimulatedPortInfo portInfo = mSimulatedPorts.get(portId); if (portInfo == null) { pw.println("Cannot connect simulated port which does not exist."); return; } if (mode == 0 || powerRole == 0 || dataRole == 0) { pw.println("Cannot connect simulated port in null mode, " + "power role, or data role."); return; } if ((portInfo.mSupportedModes & mode) == 0) { pw.println("Simulated port does not support mode: " + UsbPort.modeToString(mode)); return; } pw.println( "Connecting simulated port: portId=" + portId + ", mode=" + UsbPort.modeToString(mode) + ", canChangeMode=" + canChangeMode + ", powerRole=" + UsbPort.powerRoleToString(powerRole) + ", canChangePowerRole=" + canChangePowerRole + ", dataRole=" + UsbPort.dataRoleToString(dataRole) + ", canChangeDataRole=" + canChangeDataRole); portInfo.mCurrentMode = mode; portInfo.mCanChangeMode = canChangeMode; portInfo.mCurrentPowerRole = powerRole; portInfo.mCanChangePowerRole = canChangePowerRole; portInfo.mCurrentDataRole = dataRole; portInfo.mCanChangeDataRole = canChangeDataRole; updatePortsLocked(pw); } }
public void setPortRoles( String portId, int newPowerRole, int newDataRole, IndentingPrintWriter pw) { synchronized (mLock) { final PortInfo portInfo = mPorts.get(portId); if (portInfo == null) { if (pw != null) { pw.println("No such USB port: " + portId); } return; } // Check whether the new role is actually supported. if (!portInfo.mUsbPortStatus.isRoleCombinationSupported(newPowerRole, newDataRole)) { logAndPrint( Log.ERROR, pw, "Attempted to set USB port into unsupported " + "role combination: portId=" + portId + ", newPowerRole=" + UsbPort.powerRoleToString(newPowerRole) + ", newDataRole=" + UsbPort.dataRoleToString(newDataRole)); return; } // Check whether anything actually changed. final int currentDataRole = portInfo.mUsbPortStatus.getCurrentDataRole(); final int currentPowerRole = portInfo.mUsbPortStatus.getCurrentPowerRole(); if (currentDataRole == newDataRole && currentPowerRole == newPowerRole) { if (pw != null) { pw.println("No change."); } return; } // Determine whether we need to change the mode in order to accomplish this goal. // We prefer not to do this since it's more likely to fail. // // Note: Arguably it might be worth allowing the client to influence this policy // decision so that we could show more powerful developer facing UI but let's // see how far we can get without having to do that. final boolean canChangeMode = portInfo.mCanChangeMode; final boolean canChangePowerRole = portInfo.mCanChangePowerRole; final boolean canChangeDataRole = portInfo.mCanChangeDataRole; final int currentMode = portInfo.mUsbPortStatus.getCurrentMode(); final int newMode; if ((!canChangePowerRole && currentPowerRole != newPowerRole) || (!canChangeDataRole && currentDataRole != newDataRole)) { if (canChangeMode && newPowerRole == UsbPort.POWER_ROLE_SOURCE && newDataRole == UsbPort.DATA_ROLE_HOST) { newMode = UsbPort.MODE_DFP; } else if (canChangeMode && newPowerRole == UsbPort.POWER_ROLE_SINK && newDataRole == UsbPort.DATA_ROLE_DEVICE) { newMode = UsbPort.MODE_UFP; } else { logAndPrint( Log.ERROR, pw, "Found mismatch in supported USB role combinations " + "while attempting to change role: " + portInfo + ", newPowerRole=" + UsbPort.powerRoleToString(newPowerRole) + ", newDataRole=" + UsbPort.dataRoleToString(newDataRole)); return; } } else { newMode = currentMode; } // Make it happen. logAndPrint( Log.INFO, pw, "Setting USB port mode and role: portId=" + portId + ", currentMode=" + UsbPort.modeToString(currentMode) + ", currentPowerRole=" + UsbPort.powerRoleToString(currentPowerRole) + ", currentDataRole=" + UsbPort.dataRoleToString(currentDataRole) + ", newMode=" + UsbPort.modeToString(newMode) + ", newPowerRole=" + UsbPort.powerRoleToString(newPowerRole) + ", newDataRole=" + UsbPort.dataRoleToString(newDataRole)); SimulatedPortInfo sim = mSimulatedPorts.get(portId); if (sim != null) { // Change simulated state. sim.mCurrentMode = newMode; sim.mCurrentPowerRole = newPowerRole; sim.mCurrentDataRole = newDataRole; } else if (mHaveKernelSupport) { // Change actual state. final File portDir = new File(SYSFS_CLASS, portId); if (!portDir.exists()) { logAndPrint(Log.ERROR, pw, "USB port not found: portId=" + portId); return; } if (currentMode != newMode) { // Changing the mode will have the side-effect of also changing // the power and data roles but it might take some time to apply // and the renegotiation might fail. Due to limitations of the USB // hardware, we have no way of knowing whether it will work apriori // which is why we would prefer to set the power and data roles // directly instead. if (!writeFile( portDir, SYSFS_PORT_MODE, newMode == UsbPort.MODE_DFP ? PORT_MODE_DFP : PORT_MODE_UFP)) { logAndPrint( Log.ERROR, pw, "Failed to set the USB port mode: " + "portId=" + portId + ", newMode=" + UsbPort.modeToString(newMode)); return; } } else { // Change power and data role independently as needed. if (currentPowerRole != newPowerRole) { if (!writeFile( portDir, SYSFS_PORT_POWER_ROLE, newPowerRole == UsbPort.POWER_ROLE_SOURCE ? PORT_POWER_ROLE_SOURCE : PORT_POWER_ROLE_SINK)) { logAndPrint( Log.ERROR, pw, "Failed to set the USB port power role: " + "portId=" + portId + ", newPowerRole=" + UsbPort.powerRoleToString(newPowerRole)); return; } } if (currentDataRole != newDataRole) { if (!writeFile( portDir, SYSFS_PORT_DATA_ROLE, newDataRole == UsbPort.DATA_ROLE_HOST ? PORT_DATA_ROLE_HOST : PORT_DATA_ROLE_DEVICE)) { logAndPrint( Log.ERROR, pw, "Failed to set the USB port data role: " + "portId=" + portId + ", newDataRole=" + UsbPort.dataRoleToString(newDataRole)); return; } } } } updatePortsLocked(pw); } }