Loading core/java/android/hardware/usb/IUsbManager.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,9 @@ interface IUsbManager /* Returns the max packet size of the USB accessory.*/ int getMaxPacketSize(in UsbAccessory accessory); /* Returns true if accessory FFS is enabled. */ boolean isAccessoryFfsEnabled(); /* Sets the default package for a USB device * (or clears it if the package name is null) */ Loading core/java/android/hardware/usb/UsbManager.java +29 −8 Original line number Diff line number Diff line Loading @@ -950,11 +950,21 @@ public class UsbManager { private final ParcelFileDescriptor mPfd; private final UsbAccessory mAccessory; private final boolean mIsAccessoryFfsEnabled; AccessoryAutoCloseInputStream( UsbAccessory accessory, ParcelFileDescriptor pfd, boolean isAccessoryFfsEnabled) { super(pfd.getFileDescriptor()); this.mAccessory = accessory; this.mPfd = pfd; this.mIsAccessoryFfsEnabled = isAccessoryFfsEnabled; } AccessoryAutoCloseInputStream(UsbAccessory accessory, ParcelFileDescriptor pfd) { super(pfd.getFileDescriptor()); this.mAccessory = accessory; this.mPfd = pfd; this.mIsAccessoryFfsEnabled = false; } @Override Loading @@ -962,7 +972,7 @@ public class UsbManager { /* TODO(b/377850642) : Ensure the stream is closed even if client does not explicitly close the stream to avoid corrupt FDs*/ super.close(); if (!android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation()) { if (!mIsAccessoryFfsEnabled) { closeHandleForAccessory(mAccessory, true); } } Loading @@ -977,13 +987,18 @@ public class UsbManager { private final UsbAccessory mAccessory; private final int mMaxPacketSize; private final ParcelFileDescriptor mPfd; private final boolean mIsAccessoryFfsEnabled; AccessoryAutoCloseOutputStream( UsbAccessory accessory, ParcelFileDescriptor pfd, int maxPacketSize) { UsbAccessory accessory, ParcelFileDescriptor pfd, int maxPacketSize, boolean isAccessoryFfsEnabled) { super(pfd.getFileDescriptor()); mMaxPacketSize = maxPacketSize; mAccessory = accessory; mPfd = pfd; mIsAccessoryFfsEnabled = isAccessoryFfsEnabled; } AccessoryAutoCloseOutputStream(UsbAccessory accessory, ParcelFileDescriptor pfd) { Loading @@ -991,13 +1006,14 @@ public class UsbManager { mMaxPacketSize = -1; mAccessory = accessory; mPfd = pfd; mIsAccessoryFfsEnabled = false; } @Override public void write(byte[] b, int off, int len) throws IOException { super.write(b, off, len); if (!android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation()) { if (!mIsAccessoryFfsEnabled) { return; } // Check if a ZLP is needed for this specific write operation Loading @@ -1011,7 +1027,7 @@ public class UsbManager { /* TODO(b/377850642) : Ensure the stream is closed even if client does not explicitly close the stream to avoid corrupt FDs*/ super.close(); if (!android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation()) { if (!mIsAccessoryFfsEnabled) { closeHandleForAccessory(mAccessory, false); } } Loading Loading @@ -1197,9 +1213,12 @@ public class UsbManager { @RequiresFeature(PackageManager.FEATURE_USB_ACCESSORY) public @NonNull InputStream openAccessoryInputStream(@NonNull UsbAccessory accessory) { try { if (android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation()) { boolean isAccessoryFfsEnabled = mService.isAccessoryFfsEnabled(); if (isAccessoryFfsEnabled) { return new AccessoryAutoCloseInputStream( accessory, mService.openAccessoryForInputStream(accessory)); accessory, mService.openAccessoryForInputStream(accessory), isAccessoryFfsEnabled); } return new AccessoryAutoCloseInputStream( accessory, openHandleForAccessory(accessory, true).getPfd()); Loading @@ -1221,11 +1240,13 @@ public class UsbManager { @RequiresFeature(PackageManager.FEATURE_USB_ACCESSORY) public @NonNull OutputStream openAccessoryOutputStream(@NonNull UsbAccessory accessory) { try { if (android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation()) { boolean isAccessoryFfsEnabled = mService.isAccessoryFfsEnabled(); if (isAccessoryFfsEnabled) { return new AccessoryAutoCloseOutputStream( accessory, mService.openAccessoryForOutputStream(accessory), mService.getMaxPacketSize(accessory)); mService.getMaxPacketSize(accessory), isAccessoryFfsEnabled); } return new AccessoryAutoCloseOutputStream(accessory, openHandleForAccessory(accessory, false).getPfd()); Loading services/core/jni/com_android_server_UsbDeviceManager.cpp +61 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,9 @@ #include <asyncio/AsyncIO.h> #include <core_jni_helpers.h> #include <fcntl.h> #include <fstream> #include <linux/aio_abi.h> #include <linux/uhid.h> #include <linux/usb/f_accessory.h> #include <nativehelper/JNIPlatformHelp.h> Loading @@ -33,7 +36,6 @@ #include <sys/socket.h> #include <sys/stat.h> #include <sys/types.h> #include <map> #include <thread> Loading Loading @@ -1504,6 +1506,62 @@ static jboolean android_server_UsbDeviceManager_openAccessoryControl(JNIEnv * /* return JNI_TRUE; } // Function to check if a given path is a functionfs mount point bool is_path_mounted_as_functionfs(std::string path) { std::ifstream mounts_file("/proc/mounts"); if (!mounts_file.is_open()) { ALOGE("Could not open /proc/mounts"); return false; } std::string line; while (std::getline(mounts_file, line)) { std::stringstream ss(line); std::string device, mount_point, fs_type; ss >> device >> mount_point >> fs_type; if (mount_point == path && fs_type == "functionfs") { return true; } } return false; } std::string get_parent_directory(std::string path) { std::string parent_dir = path; size_t pos = path.find_last_of('/'); if (pos != std::string::npos) { parent_dir = path.substr(0, pos); } return parent_dir; } static jboolean android_server_UsbDeviceManager_checkAccessoryFfsDirectories(JNIEnv * /* env */, jobject /* thiz */) { if (access(FFS_VENDOR_CTRL_REQUEST_EP0, F_OK) != 0) { ALOGE("Cannot access %s", FFS_VENDOR_CTRL_REQUEST_EP0); return JNI_FALSE; } if (!is_path_mounted_as_functionfs(get_parent_directory(FFS_VENDOR_CTRL_REQUEST_EP0))) { return JNI_FALSE; } if (access(FFS_ACCESSORY_EP0, F_OK) != 0) { ALOGE("Cannot access %s", FFS_ACCESSORY_EP0); return JNI_FALSE; } if (!is_path_mounted_as_functionfs(get_parent_directory(FFS_ACCESSORY_EP0))) { return JNI_FALSE; } return JNI_TRUE; } static jstring android_server_UsbDeviceManager_waitAndGetProperty(JNIEnv *env, jobject thiz, jstring jPropName) { ScopedUtfChars propName(env, jPropName); Loading @@ -1527,6 +1585,8 @@ static const JNINativeMethod method_table[] = { (void *)android_server_UsbDeviceManager_openAccessoryForInputStream}, {"nativeOpenAccessoryForOutputStream", "()Landroid/os/ParcelFileDescriptor;", (void *)android_server_UsbDeviceManager_openAccessoryForOutputStream}, {"nativeCheckAccessoryFfsDirectories", "()Z", (void *)android_server_UsbDeviceManager_checkAccessoryFfsDirectories}, {"nativeIsStartRequested", "()Z", (void *)android_server_UsbDeviceManager_isStartRequested}, {"nativeOpenControl", "(Ljava/lang/String;)Ljava/io/FileDescriptor;", (void *)android_server_UsbDeviceManager_openControl}, Loading services/usb/java/com/android/server/usb/UsbDeviceManager.java +19 −4 Original line number Diff line number Diff line Loading @@ -241,6 +241,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser private final boolean mEnableUdcSysfsUsbStateUpdate; private String mUdcName = ""; private boolean mEnableAoaUserspaceImplementation = false; /** * Counter for tracking UsbOperation operations. */ Loading Loading @@ -361,7 +363,12 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser } mControlFds.put(UsbManager.FUNCTION_PTP, ptpFd); if (android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation()) { // TODO: b/440091110 - Add check for device property. mEnableAoaUserspaceImplementation = android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation() && nativeCheckAccessoryFfsDirectories(); if (mEnableAoaUserspaceImplementation) { if (!nativeOpenAccessoryControl()) { Slog.e(TAG, "Failed to open control for accessory"); } Loading Loading @@ -476,9 +483,10 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser mUEventObserver.startObserving(USB_STATE_MATCH); } if (android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation()) { if (mEnableAoaUserspaceImplementation) { nativeStartVendorControlRequestMonitor(); } sEventLogger = new EventLogger(DUMPSYS_LOG_BUFFER, "UsbDeviceManager activity"); } Loading Loading @@ -541,7 +549,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser int operationId = sUsbOperationCount.incrementAndGet(); if (android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation()) { if (mEnableAoaUserspaceImplementation) { mAccessoryStrings = nativeGetAccessoryStringsFromFfs(); } else { mAccessoryStrings = nativeGetAccessoryStrings(); Loading Loading @@ -2667,6 +2675,10 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser return nativeGetMaxPacketSize(); } public boolean isAccessoryFfsEnabled() { return mEnableAoaUserspaceImplementation; } public long getCurrentFunctions() { return mHandler.getEnabledFunctions(); } Loading Loading @@ -2802,7 +2814,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser /** Update accessory control state (Called by native code). */ @Keep private void updateAccessoryState(String state) { if (!android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation()) { if (!mEnableAoaUserspaceImplementation) { Slog.w(TAG, "Accessory state update from userspace is not supported!"); return; } Loading Loading @@ -2850,4 +2862,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser private native boolean nativeStartVendorControlRequestMonitor(); private native boolean nativeOpenAccessoryControl(); private native boolean nativeCheckAccessoryFfsDirectories(); } services/usb/java/com/android/server/usb/UsbService.java +16 −0 Original line number Diff line number Diff line Loading @@ -533,6 +533,22 @@ public class UsbService extends IUsbManager.Stub { } } /* Checks if accessory FFS is enabled */ @Override public boolean isAccessoryFfsEnabled() { Preconditions.checkNotNull(mDeviceManager, "DeviceManager must not be null"); final long ident = clearCallingIdentity(); try { synchronized (mLock) { return mDeviceManager.isAccessoryFfsEnabled(); } } finally { restoreCallingIdentity(ident); } } @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_MTP) /* Returns a dup of the control file descriptor for the given function. */ @Override Loading Loading
core/java/android/hardware/usb/IUsbManager.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,9 @@ interface IUsbManager /* Returns the max packet size of the USB accessory.*/ int getMaxPacketSize(in UsbAccessory accessory); /* Returns true if accessory FFS is enabled. */ boolean isAccessoryFfsEnabled(); /* Sets the default package for a USB device * (or clears it if the package name is null) */ Loading
core/java/android/hardware/usb/UsbManager.java +29 −8 Original line number Diff line number Diff line Loading @@ -950,11 +950,21 @@ public class UsbManager { private final ParcelFileDescriptor mPfd; private final UsbAccessory mAccessory; private final boolean mIsAccessoryFfsEnabled; AccessoryAutoCloseInputStream( UsbAccessory accessory, ParcelFileDescriptor pfd, boolean isAccessoryFfsEnabled) { super(pfd.getFileDescriptor()); this.mAccessory = accessory; this.mPfd = pfd; this.mIsAccessoryFfsEnabled = isAccessoryFfsEnabled; } AccessoryAutoCloseInputStream(UsbAccessory accessory, ParcelFileDescriptor pfd) { super(pfd.getFileDescriptor()); this.mAccessory = accessory; this.mPfd = pfd; this.mIsAccessoryFfsEnabled = false; } @Override Loading @@ -962,7 +972,7 @@ public class UsbManager { /* TODO(b/377850642) : Ensure the stream is closed even if client does not explicitly close the stream to avoid corrupt FDs*/ super.close(); if (!android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation()) { if (!mIsAccessoryFfsEnabled) { closeHandleForAccessory(mAccessory, true); } } Loading @@ -977,13 +987,18 @@ public class UsbManager { private final UsbAccessory mAccessory; private final int mMaxPacketSize; private final ParcelFileDescriptor mPfd; private final boolean mIsAccessoryFfsEnabled; AccessoryAutoCloseOutputStream( UsbAccessory accessory, ParcelFileDescriptor pfd, int maxPacketSize) { UsbAccessory accessory, ParcelFileDescriptor pfd, int maxPacketSize, boolean isAccessoryFfsEnabled) { super(pfd.getFileDescriptor()); mMaxPacketSize = maxPacketSize; mAccessory = accessory; mPfd = pfd; mIsAccessoryFfsEnabled = isAccessoryFfsEnabled; } AccessoryAutoCloseOutputStream(UsbAccessory accessory, ParcelFileDescriptor pfd) { Loading @@ -991,13 +1006,14 @@ public class UsbManager { mMaxPacketSize = -1; mAccessory = accessory; mPfd = pfd; mIsAccessoryFfsEnabled = false; } @Override public void write(byte[] b, int off, int len) throws IOException { super.write(b, off, len); if (!android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation()) { if (!mIsAccessoryFfsEnabled) { return; } // Check if a ZLP is needed for this specific write operation Loading @@ -1011,7 +1027,7 @@ public class UsbManager { /* TODO(b/377850642) : Ensure the stream is closed even if client does not explicitly close the stream to avoid corrupt FDs*/ super.close(); if (!android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation()) { if (!mIsAccessoryFfsEnabled) { closeHandleForAccessory(mAccessory, false); } } Loading Loading @@ -1197,9 +1213,12 @@ public class UsbManager { @RequiresFeature(PackageManager.FEATURE_USB_ACCESSORY) public @NonNull InputStream openAccessoryInputStream(@NonNull UsbAccessory accessory) { try { if (android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation()) { boolean isAccessoryFfsEnabled = mService.isAccessoryFfsEnabled(); if (isAccessoryFfsEnabled) { return new AccessoryAutoCloseInputStream( accessory, mService.openAccessoryForInputStream(accessory)); accessory, mService.openAccessoryForInputStream(accessory), isAccessoryFfsEnabled); } return new AccessoryAutoCloseInputStream( accessory, openHandleForAccessory(accessory, true).getPfd()); Loading @@ -1221,11 +1240,13 @@ public class UsbManager { @RequiresFeature(PackageManager.FEATURE_USB_ACCESSORY) public @NonNull OutputStream openAccessoryOutputStream(@NonNull UsbAccessory accessory) { try { if (android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation()) { boolean isAccessoryFfsEnabled = mService.isAccessoryFfsEnabled(); if (isAccessoryFfsEnabled) { return new AccessoryAutoCloseOutputStream( accessory, mService.openAccessoryForOutputStream(accessory), mService.getMaxPacketSize(accessory)); mService.getMaxPacketSize(accessory), isAccessoryFfsEnabled); } return new AccessoryAutoCloseOutputStream(accessory, openHandleForAccessory(accessory, false).getPfd()); Loading
services/core/jni/com_android_server_UsbDeviceManager.cpp +61 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,9 @@ #include <asyncio/AsyncIO.h> #include <core_jni_helpers.h> #include <fcntl.h> #include <fstream> #include <linux/aio_abi.h> #include <linux/uhid.h> #include <linux/usb/f_accessory.h> #include <nativehelper/JNIPlatformHelp.h> Loading @@ -33,7 +36,6 @@ #include <sys/socket.h> #include <sys/stat.h> #include <sys/types.h> #include <map> #include <thread> Loading Loading @@ -1504,6 +1506,62 @@ static jboolean android_server_UsbDeviceManager_openAccessoryControl(JNIEnv * /* return JNI_TRUE; } // Function to check if a given path is a functionfs mount point bool is_path_mounted_as_functionfs(std::string path) { std::ifstream mounts_file("/proc/mounts"); if (!mounts_file.is_open()) { ALOGE("Could not open /proc/mounts"); return false; } std::string line; while (std::getline(mounts_file, line)) { std::stringstream ss(line); std::string device, mount_point, fs_type; ss >> device >> mount_point >> fs_type; if (mount_point == path && fs_type == "functionfs") { return true; } } return false; } std::string get_parent_directory(std::string path) { std::string parent_dir = path; size_t pos = path.find_last_of('/'); if (pos != std::string::npos) { parent_dir = path.substr(0, pos); } return parent_dir; } static jboolean android_server_UsbDeviceManager_checkAccessoryFfsDirectories(JNIEnv * /* env */, jobject /* thiz */) { if (access(FFS_VENDOR_CTRL_REQUEST_EP0, F_OK) != 0) { ALOGE("Cannot access %s", FFS_VENDOR_CTRL_REQUEST_EP0); return JNI_FALSE; } if (!is_path_mounted_as_functionfs(get_parent_directory(FFS_VENDOR_CTRL_REQUEST_EP0))) { return JNI_FALSE; } if (access(FFS_ACCESSORY_EP0, F_OK) != 0) { ALOGE("Cannot access %s", FFS_ACCESSORY_EP0); return JNI_FALSE; } if (!is_path_mounted_as_functionfs(get_parent_directory(FFS_ACCESSORY_EP0))) { return JNI_FALSE; } return JNI_TRUE; } static jstring android_server_UsbDeviceManager_waitAndGetProperty(JNIEnv *env, jobject thiz, jstring jPropName) { ScopedUtfChars propName(env, jPropName); Loading @@ -1527,6 +1585,8 @@ static const JNINativeMethod method_table[] = { (void *)android_server_UsbDeviceManager_openAccessoryForInputStream}, {"nativeOpenAccessoryForOutputStream", "()Landroid/os/ParcelFileDescriptor;", (void *)android_server_UsbDeviceManager_openAccessoryForOutputStream}, {"nativeCheckAccessoryFfsDirectories", "()Z", (void *)android_server_UsbDeviceManager_checkAccessoryFfsDirectories}, {"nativeIsStartRequested", "()Z", (void *)android_server_UsbDeviceManager_isStartRequested}, {"nativeOpenControl", "(Ljava/lang/String;)Ljava/io/FileDescriptor;", (void *)android_server_UsbDeviceManager_openControl}, Loading
services/usb/java/com/android/server/usb/UsbDeviceManager.java +19 −4 Original line number Diff line number Diff line Loading @@ -241,6 +241,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser private final boolean mEnableUdcSysfsUsbStateUpdate; private String mUdcName = ""; private boolean mEnableAoaUserspaceImplementation = false; /** * Counter for tracking UsbOperation operations. */ Loading Loading @@ -361,7 +363,12 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser } mControlFds.put(UsbManager.FUNCTION_PTP, ptpFd); if (android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation()) { // TODO: b/440091110 - Add check for device property. mEnableAoaUserspaceImplementation = android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation() && nativeCheckAccessoryFfsDirectories(); if (mEnableAoaUserspaceImplementation) { if (!nativeOpenAccessoryControl()) { Slog.e(TAG, "Failed to open control for accessory"); } Loading Loading @@ -476,9 +483,10 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser mUEventObserver.startObserving(USB_STATE_MATCH); } if (android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation()) { if (mEnableAoaUserspaceImplementation) { nativeStartVendorControlRequestMonitor(); } sEventLogger = new EventLogger(DUMPSYS_LOG_BUFFER, "UsbDeviceManager activity"); } Loading Loading @@ -541,7 +549,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser int operationId = sUsbOperationCount.incrementAndGet(); if (android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation()) { if (mEnableAoaUserspaceImplementation) { mAccessoryStrings = nativeGetAccessoryStringsFromFfs(); } else { mAccessoryStrings = nativeGetAccessoryStrings(); Loading Loading @@ -2667,6 +2675,10 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser return nativeGetMaxPacketSize(); } public boolean isAccessoryFfsEnabled() { return mEnableAoaUserspaceImplementation; } public long getCurrentFunctions() { return mHandler.getEnabledFunctions(); } Loading Loading @@ -2802,7 +2814,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser /** Update accessory control state (Called by native code). */ @Keep private void updateAccessoryState(String state) { if (!android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation()) { if (!mEnableAoaUserspaceImplementation) { Slog.w(TAG, "Accessory state update from userspace is not supported!"); return; } Loading Loading @@ -2850,4 +2862,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser private native boolean nativeStartVendorControlRequestMonitor(); private native boolean nativeOpenAccessoryControl(); private native boolean nativeCheckAccessoryFfsDirectories(); }
services/usb/java/com/android/server/usb/UsbService.java +16 −0 Original line number Diff line number Diff line Loading @@ -533,6 +533,22 @@ public class UsbService extends IUsbManager.Stub { } } /* Checks if accessory FFS is enabled */ @Override public boolean isAccessoryFfsEnabled() { Preconditions.checkNotNull(mDeviceManager, "DeviceManager must not be null"); final long ident = clearCallingIdentity(); try { synchronized (mLock) { return mDeviceManager.isAccessoryFfsEnabled(); } } finally { restoreCallingIdentity(ident); } } @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_MTP) /* Returns a dup of the control file descriptor for the given function. */ @Override Loading