Loading services/usb/java/com/android/server/usb/UsbPortManager.java +42 −12 Original line number Original line Diff line number Diff line Loading @@ -26,8 +26,13 @@ import android.hardware.usb.UsbPort; import android.hardware.usb.UsbPortStatus; import android.hardware.usb.UsbPortStatus; import android.os.Handler; import android.os.Handler; import android.os.Message; import android.os.Message; import android.os.SystemClock; import android.os.SystemProperties; import android.os.UEventObserver; import android.os.UEventObserver; import android.os.UserHandle; import android.os.UserHandle; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; import android.util.ArrayMap; import android.util.ArrayMap; import android.util.Log; import android.util.Log; import android.util.Slog; import android.util.Slog; Loading Loading @@ -89,6 +94,9 @@ public class UsbPortManager { private static final String PORT_DATA_ROLE_HOST = "host"; private static final String PORT_DATA_ROLE_HOST = "host"; private static final String PORT_DATA_ROLE_DEVICE = "device"; private static final String PORT_DATA_ROLE_DEVICE = "device"; private static final String USB_TYPEC_PROP_PREFIX = "sys.usb.typec."; private static final String USB_TYPEC_STATE = "sys.usb.typec.state"; // All non-trivial role combinations. // All non-trivial role combinations. private static final int COMBO_SOURCE_HOST = private static final int COMBO_SOURCE_HOST = UsbPort.combineRolesAsBit(UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_HOST); UsbPort.combineRolesAsBit(UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_HOST); Loading Loading @@ -621,16 +629,25 @@ public class UsbPortManager { return 0; return 0; } } private static boolean fileIsRootWritable(String path) { try { // If the file is user writable, then it is root writable. return (Os.stat(path).st_mode & OsConstants.S_IWUSR) != 0; } catch (ErrnoException e) { return false; } } private static boolean canChangeMode(File portDir) { private static boolean canChangeMode(File portDir) { return new File(portDir, SYSFS_PORT_MODE).canWrite(); return fileIsRootWritable(new File(portDir, SYSFS_PORT_MODE).getPath()); } } private static boolean canChangePowerRole(File portDir) { private static boolean canChangePowerRole(File portDir) { return new File(portDir, SYSFS_PORT_POWER_ROLE).canWrite(); return fileIsRootWritable(new File(portDir, SYSFS_PORT_POWER_ROLE).getPath()); } } private static boolean canChangeDataRole(File portDir) { private static boolean canChangeDataRole(File portDir) { return new File(portDir, SYSFS_PORT_DATA_ROLE).canWrite(); return fileIsRootWritable(new File(portDir, SYSFS_PORT_DATA_ROLE).getPath()); } } private static String readFile(File dir, String filename) { private static String readFile(File dir, String filename) { Loading @@ -642,16 +659,29 @@ public class UsbPortManager { } } } } private static boolean writeFile(File dir, String filename, String contents) { private static boolean waitForState(String property, String state) { final File file = new File(dir, filename); // wait for the transition to complete. try { // give up after 5 seconds. try (FileWriter writer = new FileWriter(file)) { // 5 seconds is probably too long, but we have seen hardware that takes writer.write(contents); // over 3 seconds to change states. String value = null; for (int i = 0; i < 100; i++) { // State transition is done when property is set to the new configuration value = SystemProperties.get(property); if (state.equals(value)) return true; SystemClock.sleep(50); } } return true; Slog.e(TAG, "waitForState(" + state + ") for " + property + " FAILED: got " + value); } catch (IOException ex) { return false; return false; } } private static String propertyFromFilename(String filename) { return USB_TYPEC_PROP_PREFIX + filename; } private static boolean writeFile(File dir, String filename, String contents) { SystemProperties.set(propertyFromFilename(filename), contents); return waitForState(USB_TYPEC_STATE, contents); } } private static void logAndPrint(int priority, IndentingPrintWriter pw, String msg) { private static void logAndPrint(int priority, IndentingPrintWriter pw, String msg) { Loading Loading
services/usb/java/com/android/server/usb/UsbPortManager.java +42 −12 Original line number Original line Diff line number Diff line Loading @@ -26,8 +26,13 @@ import android.hardware.usb.UsbPort; import android.hardware.usb.UsbPortStatus; import android.hardware.usb.UsbPortStatus; import android.os.Handler; import android.os.Handler; import android.os.Message; import android.os.Message; import android.os.SystemClock; import android.os.SystemProperties; import android.os.UEventObserver; import android.os.UEventObserver; import android.os.UserHandle; import android.os.UserHandle; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; import android.util.ArrayMap; import android.util.ArrayMap; import android.util.Log; import android.util.Log; import android.util.Slog; import android.util.Slog; Loading Loading @@ -89,6 +94,9 @@ public class UsbPortManager { private static final String PORT_DATA_ROLE_HOST = "host"; private static final String PORT_DATA_ROLE_HOST = "host"; private static final String PORT_DATA_ROLE_DEVICE = "device"; private static final String PORT_DATA_ROLE_DEVICE = "device"; private static final String USB_TYPEC_PROP_PREFIX = "sys.usb.typec."; private static final String USB_TYPEC_STATE = "sys.usb.typec.state"; // All non-trivial role combinations. // All non-trivial role combinations. private static final int COMBO_SOURCE_HOST = private static final int COMBO_SOURCE_HOST = UsbPort.combineRolesAsBit(UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_HOST); UsbPort.combineRolesAsBit(UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_HOST); Loading Loading @@ -621,16 +629,25 @@ public class UsbPortManager { return 0; return 0; } } private static boolean fileIsRootWritable(String path) { try { // If the file is user writable, then it is root writable. return (Os.stat(path).st_mode & OsConstants.S_IWUSR) != 0; } catch (ErrnoException e) { return false; } } private static boolean canChangeMode(File portDir) { private static boolean canChangeMode(File portDir) { return new File(portDir, SYSFS_PORT_MODE).canWrite(); return fileIsRootWritable(new File(portDir, SYSFS_PORT_MODE).getPath()); } } private static boolean canChangePowerRole(File portDir) { private static boolean canChangePowerRole(File portDir) { return new File(portDir, SYSFS_PORT_POWER_ROLE).canWrite(); return fileIsRootWritable(new File(portDir, SYSFS_PORT_POWER_ROLE).getPath()); } } private static boolean canChangeDataRole(File portDir) { private static boolean canChangeDataRole(File portDir) { return new File(portDir, SYSFS_PORT_DATA_ROLE).canWrite(); return fileIsRootWritable(new File(portDir, SYSFS_PORT_DATA_ROLE).getPath()); } } private static String readFile(File dir, String filename) { private static String readFile(File dir, String filename) { Loading @@ -642,16 +659,29 @@ public class UsbPortManager { } } } } private static boolean writeFile(File dir, String filename, String contents) { private static boolean waitForState(String property, String state) { final File file = new File(dir, filename); // wait for the transition to complete. try { // give up after 5 seconds. try (FileWriter writer = new FileWriter(file)) { // 5 seconds is probably too long, but we have seen hardware that takes writer.write(contents); // over 3 seconds to change states. String value = null; for (int i = 0; i < 100; i++) { // State transition is done when property is set to the new configuration value = SystemProperties.get(property); if (state.equals(value)) return true; SystemClock.sleep(50); } } return true; Slog.e(TAG, "waitForState(" + state + ") for " + property + " FAILED: got " + value); } catch (IOException ex) { return false; return false; } } private static String propertyFromFilename(String filename) { return USB_TYPEC_PROP_PREFIX + filename; } private static boolean writeFile(File dir, String filename, String contents) { SystemProperties.set(propertyFromFilename(filename), contents); return waitForState(USB_TYPEC_STATE, contents); } } private static void logAndPrint(int priority, IndentingPrintWriter pw, String msg) { private static void logAndPrint(int priority, IndentingPrintWriter pw, String msg) { Loading