summaryrefslogtreecommitdiffstats
path: root/services/usb/java/com
diff options
context:
space:
mode:
Diffstat (limited to 'services/usb/java/com')
-rw-r--r--services/usb/java/com/android/server/usb/UsbDeviceManager.java35
-rw-r--r--services/usb/java/com/android/server/usb/UsbPortManager.java54
2 files changed, 72 insertions, 17 deletions
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 7a2f1a3..29a1809 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -19,15 +19,19 @@ package com.android.server.usb;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbManager;
+import android.hardware.usb.UsbPort;
+import android.hardware.usb.UsbPortStatus;
import android.os.FileUtils;
import android.os.Handler;
import android.os.Looper;
@@ -105,6 +109,7 @@ public class UsbDeviceManager {
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 AUDIO_MODE_SOURCE = 1;
@@ -175,6 +180,15 @@ public class UsbDeviceManager {
}
};
+ private final BroadcastReceiver mHostReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ UsbPort port = intent.getParcelableExtra(UsbManager.EXTRA_PORT);
+ UsbPortStatus status = intent.getParcelableExtra(UsbManager.EXTRA_PORT_STATUS);
+ mHandler.updateHostState(port, status);
+ }
+ };
+
public UsbDeviceManager(Context context, UsbAlsaManager alsaManager) {
mContext = context;
mUsbAlsaManager = alsaManager;
@@ -197,6 +211,8 @@ public class UsbDeviceManager {
if (secureAdbEnabled && !dataEncrypted) {
mDebuggingManager = new UsbDebuggingManager(context);
}
+ mContext.registerReceiver(mHostReceiver,
+ new IntentFilter(UsbManager.ACTION_USB_PORT_CHANGED));
}
private UsbSettingsManager getCurrentSettings() {
@@ -299,6 +315,7 @@ public class UsbDeviceManager {
// current USB state
private boolean mConnected;
+ private boolean mHostConnected;
private boolean mConfigured;
private boolean mUsbDataUnlocked;
private String mCurrentFunctions;
@@ -391,6 +408,11 @@ public class UsbDeviceManager {
sendMessageDelayed(msg, (connected == 0) ? UPDATE_DELAY : 0);
}
+ public void updateHostState(UsbPort port, UsbPortStatus status) {
+ boolean hostConnected = status.getCurrentDataRole() == UsbPort.DATA_ROLE_HOST;
+ obtainMessage(MSG_UPDATE_HOST_STATE, hostConnected ? 1 :0, 0).sendToTarget();
+ }
+
private boolean waitForState(String state) {
// wait for the transition to complete.
// give up after 1 second.
@@ -408,10 +430,9 @@ public class UsbDeviceManager {
private boolean setUsbConfig(String config) {
if (DEBUG) Slog.d(TAG, "setUsbConfig(" + config + ")");
// set the new configuration
- String oldConfig = SystemProperties.get(USB_CONFIG_PROPERTY);
- if (!config.equals(oldConfig)) {
- SystemProperties.set(USB_CONFIG_PROPERTY, config);
- }
+ // we always set it due to b/23631400, where adbd was getting killed
+ // and not restarted due to property timeouts on some devices
+ SystemProperties.set(USB_CONFIG_PROPERTY, config);
return waitForState(config);
}
@@ -666,6 +687,10 @@ public class UsbDeviceManager {
updateUsbFunctions();
}
break;
+ case MSG_UPDATE_HOST_STATE:
+ mHostConnected = (msg.arg1 == 1);
+ updateUsbNotification();
+ break;
case MSG_ENABLE_ADB:
setAdbEnabled(msg.arg1 == 1);
break;
@@ -721,7 +746,7 @@ public class UsbDeviceManager {
if (mNotificationManager == null || !mUseUsbNotification) return;
int id = 0;
Resources r = mContext.getResources();
- if (mConnected) {
+ if (mConnected || mHostConnected) {
if (!mUsbDataUnlocked) {
id = com.android.internal.R.string.usb_charging_notification_title;
} else if (UsbManager.containsFunction(mCurrentFunctions,
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index 52abcfe..7f182a4 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -26,8 +26,13 @@ import android.hardware.usb.UsbPort;
import android.hardware.usb.UsbPortStatus;
import android.os.Handler;
import android.os.Message;
+import android.os.SystemClock;
+import android.os.SystemProperties;
import android.os.UEventObserver;
import android.os.UserHandle;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Slog;
@@ -89,6 +94,9 @@ public class UsbPortManager {
private static final String PORT_DATA_ROLE_HOST = "host";
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.
private static final int COMBO_SOURCE_HOST =
UsbPort.combineRolesAsBit(UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_HOST);
@@ -621,16 +629,25 @@ public class UsbPortManager {
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) {
- return new File(portDir, SYSFS_PORT_MODE).canWrite();
+ return fileIsRootWritable(new File(portDir, SYSFS_PORT_MODE).getPath());
}
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) {
- 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) {
@@ -642,16 +659,29 @@ public class UsbPortManager {
}
}
- private static boolean writeFile(File dir, String filename, String contents) {
- final File file = new File(dir, filename);
- try {
- try (FileWriter writer = new FileWriter(file)) {
- writer.write(contents);
- }
- return true;
- } catch (IOException ex) {
- return false;
+ private static boolean waitForState(String property, String state) {
+ // wait for the transition to complete.
+ // give up after 5 seconds.
+ // 5 seconds is probably too long, but we have seen hardware that takes
+ // 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);
}
+ Slog.e(TAG, "waitForState(" + state + ") for " + property + " FAILED: got " + value);
+ 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) {