Loading core/java/android/hardware/usb/IUsbManager.aidl +13 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,19 @@ interface IUsbManager */ ParcelFileDescriptor openAccessory(in UsbAccessory accessory); /* Returns a file descriptor for reading from the USB accessory. * This file descriptor can be used with standard Java file operations. */ ParcelFileDescriptor openAccessoryForInputStream(in UsbAccessory accessory); /* Returns a file descriptor for writing to the USB accessory. * This file descriptor can be used with standard Java file operations. */ ParcelFileDescriptor openAccessoryForOutputStream(in UsbAccessory accessory); /* Returns the max packet size of the USB accessory.*/ int getMaxPacketSize(in UsbAccessory accessory); /* 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 +61 −33 Original line number Diff line number Diff line Loading @@ -48,6 +48,8 @@ import android.hardware.usb.gadget.UsbSpeed; import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.system.ErrnoException; import android.system.Os; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.RemoteException; Loading @@ -60,6 +62,7 @@ import com.android.internal.annotations.GuardedBy; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InterruptedIOException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; Loading Loading @@ -959,35 +962,9 @@ 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()) { closeHandleForAccessory(mAccessory, true); } @Override public int read() throws IOException { final int result = super.read(); checkError(result); return result; } @Override public int read(byte[] b) throws IOException { final int result = super.read(b); checkError(result); return result; } @Override public int read(byte[] b, int off, int len) throws IOException { final int result = super.read(b, off, len); checkError(result); return result; } private void checkError(int result) throws IOException { if (result == -1 && mPfd.canDetectErrors()) { mPfd.checkError(); } } } Loading @@ -998,10 +975,35 @@ public class UsbManager { */ private class AccessoryAutoCloseOutputStream extends FileOutputStream { private final UsbAccessory mAccessory; private final int mMaxPacketSize; private final ParcelFileDescriptor mPfd; AccessoryAutoCloseOutputStream( UsbAccessory accessory, ParcelFileDescriptor pfd, int maxPacketSize) { super(pfd.getFileDescriptor()); mMaxPacketSize = maxPacketSize; mAccessory = accessory; mPfd = pfd; } AccessoryAutoCloseOutputStream(UsbAccessory accessory, ParcelFileDescriptor pfd) { super(pfd.getFileDescriptor()); mMaxPacketSize = -1; mAccessory = accessory; mPfd = pfd; } @Override public void write(byte[] b, int off, int len) throws IOException { super.write(b, off, len); if (!android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation()) { return; } // Check if a ZLP is needed for this specific write operation if (len > 0 && (len % mMaxPacketSize == 0)) { sendZlp(); } } @Override Loading @@ -1009,10 +1011,26 @@ 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()) { closeHandleForAccessory(mAccessory, false); } } /** Sends a Zero-Length Packet. This is done by writing a 0-byte array. */ private void sendZlp() { byte[] emptyBuffer = new byte[0]; // Or any buffer, as count will be 0 // This should make a write(2) syscall with count = 0 try { // TODO: febinthattil - Try this with native code Os.write(mPfd.getFileDescriptor(), emptyBuffer, 0, 0); } catch (ErrnoException e) { Log.e(TAG, "ZLP failed to send.", e); } catch (InterruptedIOException e) { Log.e(TAG, "ZLP failed to send.", e); } } } /** * Holds file descriptor and marks whether input and output streams have been opened for it. */ Loading Loading @@ -1179,8 +1197,12 @@ public class UsbManager { @RequiresFeature(PackageManager.FEATURE_USB_ACCESSORY) public @NonNull InputStream openAccessoryInputStream(@NonNull UsbAccessory accessory) { try { return new AccessoryAutoCloseInputStream(accessory, openHandleForAccessory(accessory, true).getPfd()); if (android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation()) { return new AccessoryAutoCloseInputStream( accessory, mService.openAccessoryForInputStream(accessory)); } return new AccessoryAutoCloseInputStream( accessory, openHandleForAccessory(accessory, true).getPfd()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); Loading @@ -1199,6 +1221,12 @@ public class UsbManager { @RequiresFeature(PackageManager.FEATURE_USB_ACCESSORY) public @NonNull OutputStream openAccessoryOutputStream(@NonNull UsbAccessory accessory) { try { if (android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation()) { return new AccessoryAutoCloseOutputStream( accessory, mService.openAccessoryForOutputStream(accessory), mService.getMaxPacketSize(accessory)); } return new AccessoryAutoCloseOutputStream(accessory, openHandleForAccessory(accessory, false).getPfd()); } catch (RemoteException e) { Loading services/core/jni/com_android_server_UsbDeviceManager.cpp +61 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,8 @@ #define FFS_VENDOR_CTRL_REQUEST_EP0 "/dev/usb-ffs/ctrl/ep0" #define FFS_ACCESSORY_EP0 "/dev/usb-ffs/aoa/ep0" #define FFS_ACCESSORY_EP1 "/dev/usb-ffs/aoa/ep1" #define FFS_ACCESSORY_EP2 "/dev/usb-ffs/aoa/ep2" namespace { struct func_desc { Loading Loading @@ -669,6 +671,11 @@ public: return mAccessoryFields.maxPacketSize; } void setMaxPacketSize(int maxPacketSize) { std::lock_guard<std::mutex> lock(mAccessoryFieldsMutex); mAccessoryFields.maxPacketSize = maxPacketSize; } ~NativeVendorControlRequestMonitorThread() { stop(); close(mShutdownPipefd[0]); Loading Loading @@ -705,6 +712,16 @@ static void set_accessory_string_from_ffs(JNIEnv *env, jobjectArray strArray, in } } static int get_max_packet_size(int ffs_fd) { struct usb_endpoint_descriptor desc{}; if (ioctl(ffs_fd, FUNCTIONFS_ENDPOINT_DESC, reinterpret_cast<unsigned long>(&desc))) { ALOGE("Could not get FFS bulk-in descriptor"); return 512; } else { return desc.wMaxPacketSize; } } static jobjectArray android_server_UsbDeviceManager_getAccessoryStrings(JNIEnv *env, jobject /* thiz */) { Loading Loading @@ -743,6 +760,11 @@ static jobjectArray android_server_UsbDeviceManager_getAccessoryStringsFromFfs(J return strArray; } static jint android_server_UsbDeviceManager_getMaxPacketSize(JNIEnv * /* env */, jobject /* thiz */) { return static_cast<jint>(sVendorControlRequestMonitorThread->getMaxPacketSize()); } static jobject android_server_UsbDeviceManager_openAccessory(JNIEnv *env, jobject /* thiz */) { int fd = open(DRIVER_NAME, O_RDWR); Loading @@ -759,6 +781,40 @@ static jobject android_server_UsbDeviceManager_openAccessory(JNIEnv *env, jobjec gParcelFileDescriptorOffsets.mConstructor, fileDescriptor); } static jobject android_server_UsbDeviceManager_openAccessoryForInputStream(JNIEnv *env, jobject /* thiz */) { int readFd = open(FFS_ACCESSORY_EP1, O_RDONLY); if (readFd < 0) { ALOGE("could not open %s", FFS_ACCESSORY_EP1); return nullptr; } jobject readFileDescriptor = jniCreateFileDescriptor(env, readFd); if (readFileDescriptor == nullptr) { close(readFd); return nullptr; } return env->NewObject(gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, readFileDescriptor); } static jobject android_server_UsbDeviceManager_openAccessoryForOutputStream(JNIEnv *env, jobject /* thiz */) { int writeFd = open(FFS_ACCESSORY_EP2, O_WRONLY); if (writeFd < 0) { ALOGE("could not open %s", FFS_ACCESSORY_EP2); return nullptr; } sVendorControlRequestMonitorThread->setMaxPacketSize(get_max_packet_size(writeFd)); jobject writeFileDescriptor = jniCreateFileDescriptor(env, writeFd); if (writeFileDescriptor == nullptr) { close(writeFd); return nullptr; } return env->NewObject(gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, writeFileDescriptor); } static jboolean android_server_UsbDeviceManager_isStartRequested(JNIEnv* /* env */, jobject /* thiz */) { Loading Loading @@ -896,8 +952,13 @@ static const JNINativeMethod method_table[] = { (void *)android_server_UsbDeviceManager_getAccessoryStrings}, {"nativeGetAccessoryStringsFromFfs", "()[Ljava/lang/String;", (void *)android_server_UsbDeviceManager_getAccessoryStringsFromFfs}, {"nativeGetMaxPacketSize", "()I", (void *)android_server_UsbDeviceManager_getMaxPacketSize}, {"nativeOpenAccessory", "()Landroid/os/ParcelFileDescriptor;", (void *)android_server_UsbDeviceManager_openAccessory}, {"nativeOpenAccessoryForInputStream", "()Landroid/os/ParcelFileDescriptor;", (void *)android_server_UsbDeviceManager_openAccessoryForInputStream}, {"nativeOpenAccessoryForOutputStream", "()Landroid/os/ParcelFileDescriptor;", (void *)android_server_UsbDeviceManager_openAccessoryForOutputStream}, {"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 +66 −0 Original line number Diff line number Diff line Loading @@ -2607,6 +2607,66 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser return nativeOpenAccessory(); } /** * opens the currently attached USB accessory to read from. * * @param accessory accessory to be opened. * @param permissions UsbUserPermissionManager to check permissions. * @param pid Pid of the caller * @param uid Uid of the caller */ public ParcelFileDescriptor openAccessoryForInputStream( UsbAccessory accessory, UsbUserPermissionManager permissions, int pid, int uid) { UsbAccessory currentAccessory = mHandler.getCurrentAccessory(); if (currentAccessory == null) { throw new IllegalArgumentException("no accessory attached"); } if (!currentAccessory.equals(accessory)) { String error = accessory.toString() + " does not match current accessory " + currentAccessory; throw new IllegalArgumentException(error); } permissions.checkPermission(accessory, pid, uid); return nativeOpenAccessoryForInputStream(); } /** * opens the currently attached USB accessory to write to. * * @param accessory accessory to be opened. * @param permissions UsbUserPermissionManager to check permissions. * @param pid Pid of the caller * @param uid Uid of the caller */ public ParcelFileDescriptor openAccessoryForOutputStream( UsbAccessory accessory, UsbUserPermissionManager permissions, int pid, int uid) { UsbAccessory currentAccessory = mHandler.getCurrentAccessory(); if (currentAccessory == null) { throw new IllegalArgumentException("no accessory attached"); } if (!currentAccessory.equals(accessory)) { String error = accessory.toString() + " does not match current accessory " + currentAccessory; throw new IllegalArgumentException(error); } permissions.checkPermission(accessory, pid, uid); return nativeOpenAccessoryForOutputStream(); } public int getMaxPacketSize(UsbAccessory accessory) { UsbAccessory currentAccessory = mHandler.getCurrentAccessory(); if (currentAccessory == null) { throw new IllegalArgumentException("no accessory attached"); } if (!currentAccessory.equals(accessory)) { String error = accessory.toString() + " does not match current accessory " + currentAccessory; throw new IllegalArgumentException(error); } return nativeGetMaxPacketSize(); } public long getCurrentFunctions() { return mHandler.getEnabledFunctions(); } Loading Loading @@ -2769,8 +2829,14 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser private native String[] nativeGetAccessoryStringsFromFfs(); private native int nativeGetMaxPacketSize(); private native ParcelFileDescriptor nativeOpenAccessory(); private native ParcelFileDescriptor nativeOpenAccessoryForInputStream(); private native ParcelFileDescriptor nativeOpenAccessoryForOutputStream(); private native String nativeWaitAndGetProperty(String propName); private native FileDescriptor nativeOpenControl(String usbFunction); Loading services/usb/java/com/android/server/usb/UsbService.java +82 −0 Original line number Diff line number Diff line Loading @@ -404,6 +404,88 @@ public class UsbService extends IUsbManager.Stub { return null; } /* opens the currently attached USB accessory to read from (device mode) */ @Override public ParcelFileDescriptor openAccessoryForInputStream(UsbAccessory accessory) { if (mDeviceManager != null) { int uid = Binder.getCallingUid(); int pid = Binder.getCallingPid(); int user = UserHandle.getUserId(uid); final long ident = clearCallingIdentity(); try { synchronized (mLock) { if (mUserManager.isSameProfileGroup(user, mCurrentUserId)) { return mDeviceManager.openAccessoryForInputStream( accessory, getPermissionsForUser(user), pid, uid); } else { Slog.w(TAG, "Cannot open " + accessory + " for user " + user + " as user is not active."); } } } finally { restoreCallingIdentity(ident); } } return null; } /* opens the currently attached USB accessory to write to (device mode) */ @Override public ParcelFileDescriptor openAccessoryForOutputStream(UsbAccessory accessory) { if (mDeviceManager != null) { int uid = Binder.getCallingUid(); int pid = Binder.getCallingPid(); int user = UserHandle.getUserId(uid); final long ident = clearCallingIdentity(); try { synchronized (mLock) { if (mUserManager.isSameProfileGroup(user, mCurrentUserId)) { return mDeviceManager.openAccessoryForOutputStream( accessory, getPermissionsForUser(user), pid, uid); } else { Slog.w( TAG, "Cannot open " + accessory + " for user " + user + " as user is not active."); } } } finally { restoreCallingIdentity(ident); } } return null; } /* Gets the currently attached USB accessory max packet size (device mode) */ @Override public int getMaxPacketSize(UsbAccessory accessory) { Preconditions.checkNotNull(mDeviceManager, "DeviceManager must not be null"); int uid = Binder.getCallingUid(); int user = UserHandle.getUserId(uid); final long ident = clearCallingIdentity(); try { synchronized (mLock) { int maxPacketSize = -1; if (mUserManager.isSameProfileGroup(user, mCurrentUserId)) { maxPacketSize = mDeviceManager.getMaxPacketSize(accessory); } else { Slog.w( TAG, "Cannot open " + accessory + " for user " + user + " as user is not active."); } return maxPacketSize; } } 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 +13 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,19 @@ interface IUsbManager */ ParcelFileDescriptor openAccessory(in UsbAccessory accessory); /* Returns a file descriptor for reading from the USB accessory. * This file descriptor can be used with standard Java file operations. */ ParcelFileDescriptor openAccessoryForInputStream(in UsbAccessory accessory); /* Returns a file descriptor for writing to the USB accessory. * This file descriptor can be used with standard Java file operations. */ ParcelFileDescriptor openAccessoryForOutputStream(in UsbAccessory accessory); /* Returns the max packet size of the USB accessory.*/ int getMaxPacketSize(in UsbAccessory accessory); /* 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 +61 −33 Original line number Diff line number Diff line Loading @@ -48,6 +48,8 @@ import android.hardware.usb.gadget.UsbSpeed; import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.system.ErrnoException; import android.system.Os; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.RemoteException; Loading @@ -60,6 +62,7 @@ import com.android.internal.annotations.GuardedBy; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InterruptedIOException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; Loading Loading @@ -959,35 +962,9 @@ 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()) { closeHandleForAccessory(mAccessory, true); } @Override public int read() throws IOException { final int result = super.read(); checkError(result); return result; } @Override public int read(byte[] b) throws IOException { final int result = super.read(b); checkError(result); return result; } @Override public int read(byte[] b, int off, int len) throws IOException { final int result = super.read(b, off, len); checkError(result); return result; } private void checkError(int result) throws IOException { if (result == -1 && mPfd.canDetectErrors()) { mPfd.checkError(); } } } Loading @@ -998,10 +975,35 @@ public class UsbManager { */ private class AccessoryAutoCloseOutputStream extends FileOutputStream { private final UsbAccessory mAccessory; private final int mMaxPacketSize; private final ParcelFileDescriptor mPfd; AccessoryAutoCloseOutputStream( UsbAccessory accessory, ParcelFileDescriptor pfd, int maxPacketSize) { super(pfd.getFileDescriptor()); mMaxPacketSize = maxPacketSize; mAccessory = accessory; mPfd = pfd; } AccessoryAutoCloseOutputStream(UsbAccessory accessory, ParcelFileDescriptor pfd) { super(pfd.getFileDescriptor()); mMaxPacketSize = -1; mAccessory = accessory; mPfd = pfd; } @Override public void write(byte[] b, int off, int len) throws IOException { super.write(b, off, len); if (!android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation()) { return; } // Check if a ZLP is needed for this specific write operation if (len > 0 && (len % mMaxPacketSize == 0)) { sendZlp(); } } @Override Loading @@ -1009,10 +1011,26 @@ 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()) { closeHandleForAccessory(mAccessory, false); } } /** Sends a Zero-Length Packet. This is done by writing a 0-byte array. */ private void sendZlp() { byte[] emptyBuffer = new byte[0]; // Or any buffer, as count will be 0 // This should make a write(2) syscall with count = 0 try { // TODO: febinthattil - Try this with native code Os.write(mPfd.getFileDescriptor(), emptyBuffer, 0, 0); } catch (ErrnoException e) { Log.e(TAG, "ZLP failed to send.", e); } catch (InterruptedIOException e) { Log.e(TAG, "ZLP failed to send.", e); } } } /** * Holds file descriptor and marks whether input and output streams have been opened for it. */ Loading Loading @@ -1179,8 +1197,12 @@ public class UsbManager { @RequiresFeature(PackageManager.FEATURE_USB_ACCESSORY) public @NonNull InputStream openAccessoryInputStream(@NonNull UsbAccessory accessory) { try { return new AccessoryAutoCloseInputStream(accessory, openHandleForAccessory(accessory, true).getPfd()); if (android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation()) { return new AccessoryAutoCloseInputStream( accessory, mService.openAccessoryForInputStream(accessory)); } return new AccessoryAutoCloseInputStream( accessory, openHandleForAccessory(accessory, true).getPfd()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); Loading @@ -1199,6 +1221,12 @@ public class UsbManager { @RequiresFeature(PackageManager.FEATURE_USB_ACCESSORY) public @NonNull OutputStream openAccessoryOutputStream(@NonNull UsbAccessory accessory) { try { if (android.hardware.usb.flags.Flags.enableAoaUserspaceImplementation()) { return new AccessoryAutoCloseOutputStream( accessory, mService.openAccessoryForOutputStream(accessory), mService.getMaxPacketSize(accessory)); } return new AccessoryAutoCloseOutputStream(accessory, openHandleForAccessory(accessory, false).getPfd()); } catch (RemoteException e) { Loading
services/core/jni/com_android_server_UsbDeviceManager.cpp +61 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,8 @@ #define FFS_VENDOR_CTRL_REQUEST_EP0 "/dev/usb-ffs/ctrl/ep0" #define FFS_ACCESSORY_EP0 "/dev/usb-ffs/aoa/ep0" #define FFS_ACCESSORY_EP1 "/dev/usb-ffs/aoa/ep1" #define FFS_ACCESSORY_EP2 "/dev/usb-ffs/aoa/ep2" namespace { struct func_desc { Loading Loading @@ -669,6 +671,11 @@ public: return mAccessoryFields.maxPacketSize; } void setMaxPacketSize(int maxPacketSize) { std::lock_guard<std::mutex> lock(mAccessoryFieldsMutex); mAccessoryFields.maxPacketSize = maxPacketSize; } ~NativeVendorControlRequestMonitorThread() { stop(); close(mShutdownPipefd[0]); Loading Loading @@ -705,6 +712,16 @@ static void set_accessory_string_from_ffs(JNIEnv *env, jobjectArray strArray, in } } static int get_max_packet_size(int ffs_fd) { struct usb_endpoint_descriptor desc{}; if (ioctl(ffs_fd, FUNCTIONFS_ENDPOINT_DESC, reinterpret_cast<unsigned long>(&desc))) { ALOGE("Could not get FFS bulk-in descriptor"); return 512; } else { return desc.wMaxPacketSize; } } static jobjectArray android_server_UsbDeviceManager_getAccessoryStrings(JNIEnv *env, jobject /* thiz */) { Loading Loading @@ -743,6 +760,11 @@ static jobjectArray android_server_UsbDeviceManager_getAccessoryStringsFromFfs(J return strArray; } static jint android_server_UsbDeviceManager_getMaxPacketSize(JNIEnv * /* env */, jobject /* thiz */) { return static_cast<jint>(sVendorControlRequestMonitorThread->getMaxPacketSize()); } static jobject android_server_UsbDeviceManager_openAccessory(JNIEnv *env, jobject /* thiz */) { int fd = open(DRIVER_NAME, O_RDWR); Loading @@ -759,6 +781,40 @@ static jobject android_server_UsbDeviceManager_openAccessory(JNIEnv *env, jobjec gParcelFileDescriptorOffsets.mConstructor, fileDescriptor); } static jobject android_server_UsbDeviceManager_openAccessoryForInputStream(JNIEnv *env, jobject /* thiz */) { int readFd = open(FFS_ACCESSORY_EP1, O_RDONLY); if (readFd < 0) { ALOGE("could not open %s", FFS_ACCESSORY_EP1); return nullptr; } jobject readFileDescriptor = jniCreateFileDescriptor(env, readFd); if (readFileDescriptor == nullptr) { close(readFd); return nullptr; } return env->NewObject(gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, readFileDescriptor); } static jobject android_server_UsbDeviceManager_openAccessoryForOutputStream(JNIEnv *env, jobject /* thiz */) { int writeFd = open(FFS_ACCESSORY_EP2, O_WRONLY); if (writeFd < 0) { ALOGE("could not open %s", FFS_ACCESSORY_EP2); return nullptr; } sVendorControlRequestMonitorThread->setMaxPacketSize(get_max_packet_size(writeFd)); jobject writeFileDescriptor = jniCreateFileDescriptor(env, writeFd); if (writeFileDescriptor == nullptr) { close(writeFd); return nullptr; } return env->NewObject(gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, writeFileDescriptor); } static jboolean android_server_UsbDeviceManager_isStartRequested(JNIEnv* /* env */, jobject /* thiz */) { Loading Loading @@ -896,8 +952,13 @@ static const JNINativeMethod method_table[] = { (void *)android_server_UsbDeviceManager_getAccessoryStrings}, {"nativeGetAccessoryStringsFromFfs", "()[Ljava/lang/String;", (void *)android_server_UsbDeviceManager_getAccessoryStringsFromFfs}, {"nativeGetMaxPacketSize", "()I", (void *)android_server_UsbDeviceManager_getMaxPacketSize}, {"nativeOpenAccessory", "()Landroid/os/ParcelFileDescriptor;", (void *)android_server_UsbDeviceManager_openAccessory}, {"nativeOpenAccessoryForInputStream", "()Landroid/os/ParcelFileDescriptor;", (void *)android_server_UsbDeviceManager_openAccessoryForInputStream}, {"nativeOpenAccessoryForOutputStream", "()Landroid/os/ParcelFileDescriptor;", (void *)android_server_UsbDeviceManager_openAccessoryForOutputStream}, {"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 +66 −0 Original line number Diff line number Diff line Loading @@ -2607,6 +2607,66 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser return nativeOpenAccessory(); } /** * opens the currently attached USB accessory to read from. * * @param accessory accessory to be opened. * @param permissions UsbUserPermissionManager to check permissions. * @param pid Pid of the caller * @param uid Uid of the caller */ public ParcelFileDescriptor openAccessoryForInputStream( UsbAccessory accessory, UsbUserPermissionManager permissions, int pid, int uid) { UsbAccessory currentAccessory = mHandler.getCurrentAccessory(); if (currentAccessory == null) { throw new IllegalArgumentException("no accessory attached"); } if (!currentAccessory.equals(accessory)) { String error = accessory.toString() + " does not match current accessory " + currentAccessory; throw new IllegalArgumentException(error); } permissions.checkPermission(accessory, pid, uid); return nativeOpenAccessoryForInputStream(); } /** * opens the currently attached USB accessory to write to. * * @param accessory accessory to be opened. * @param permissions UsbUserPermissionManager to check permissions. * @param pid Pid of the caller * @param uid Uid of the caller */ public ParcelFileDescriptor openAccessoryForOutputStream( UsbAccessory accessory, UsbUserPermissionManager permissions, int pid, int uid) { UsbAccessory currentAccessory = mHandler.getCurrentAccessory(); if (currentAccessory == null) { throw new IllegalArgumentException("no accessory attached"); } if (!currentAccessory.equals(accessory)) { String error = accessory.toString() + " does not match current accessory " + currentAccessory; throw new IllegalArgumentException(error); } permissions.checkPermission(accessory, pid, uid); return nativeOpenAccessoryForOutputStream(); } public int getMaxPacketSize(UsbAccessory accessory) { UsbAccessory currentAccessory = mHandler.getCurrentAccessory(); if (currentAccessory == null) { throw new IllegalArgumentException("no accessory attached"); } if (!currentAccessory.equals(accessory)) { String error = accessory.toString() + " does not match current accessory " + currentAccessory; throw new IllegalArgumentException(error); } return nativeGetMaxPacketSize(); } public long getCurrentFunctions() { return mHandler.getEnabledFunctions(); } Loading Loading @@ -2769,8 +2829,14 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser private native String[] nativeGetAccessoryStringsFromFfs(); private native int nativeGetMaxPacketSize(); private native ParcelFileDescriptor nativeOpenAccessory(); private native ParcelFileDescriptor nativeOpenAccessoryForInputStream(); private native ParcelFileDescriptor nativeOpenAccessoryForOutputStream(); private native String nativeWaitAndGetProperty(String propName); private native FileDescriptor nativeOpenControl(String usbFunction); Loading
services/usb/java/com/android/server/usb/UsbService.java +82 −0 Original line number Diff line number Diff line Loading @@ -404,6 +404,88 @@ public class UsbService extends IUsbManager.Stub { return null; } /* opens the currently attached USB accessory to read from (device mode) */ @Override public ParcelFileDescriptor openAccessoryForInputStream(UsbAccessory accessory) { if (mDeviceManager != null) { int uid = Binder.getCallingUid(); int pid = Binder.getCallingPid(); int user = UserHandle.getUserId(uid); final long ident = clearCallingIdentity(); try { synchronized (mLock) { if (mUserManager.isSameProfileGroup(user, mCurrentUserId)) { return mDeviceManager.openAccessoryForInputStream( accessory, getPermissionsForUser(user), pid, uid); } else { Slog.w(TAG, "Cannot open " + accessory + " for user " + user + " as user is not active."); } } } finally { restoreCallingIdentity(ident); } } return null; } /* opens the currently attached USB accessory to write to (device mode) */ @Override public ParcelFileDescriptor openAccessoryForOutputStream(UsbAccessory accessory) { if (mDeviceManager != null) { int uid = Binder.getCallingUid(); int pid = Binder.getCallingPid(); int user = UserHandle.getUserId(uid); final long ident = clearCallingIdentity(); try { synchronized (mLock) { if (mUserManager.isSameProfileGroup(user, mCurrentUserId)) { return mDeviceManager.openAccessoryForOutputStream( accessory, getPermissionsForUser(user), pid, uid); } else { Slog.w( TAG, "Cannot open " + accessory + " for user " + user + " as user is not active."); } } } finally { restoreCallingIdentity(ident); } } return null; } /* Gets the currently attached USB accessory max packet size (device mode) */ @Override public int getMaxPacketSize(UsbAccessory accessory) { Preconditions.checkNotNull(mDeviceManager, "DeviceManager must not be null"); int uid = Binder.getCallingUid(); int user = UserHandle.getUserId(uid); final long ident = clearCallingIdentity(); try { synchronized (mLock) { int maxPacketSize = -1; if (mUserManager.isSameProfileGroup(user, mCurrentUserId)) { maxPacketSize = mDeviceManager.getMaxPacketSize(accessory); } else { Slog.w( TAG, "Cannot open " + accessory + " for user " + user + " as user is not active."); } return maxPacketSize; } } 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