Merge "Write descriptors for Mtp in UsbService" into pi-dev

This commit is contained in:
Jerry Zhang
2018-03-27 02:49:02 +00:00
committed by Android (Google) Code Review
9 changed files with 120 additions and 33 deletions

View File

@@ -105,6 +105,12 @@ interface IUsbManager
/* Gets the current screen unlocked functions. */
long getScreenUnlockedFunctions();
/* Get the functionfs control handle for the given function. Usb
* descriptors will already be written, and the handle will be
* ready to use.
*/
ParcelFileDescriptor getControlFd(long function);
/* Allow USB debugging from the attached host. If alwaysAllow is true, add the
* the public key to list of host keys that the user has approved.
*/

View File

@@ -191,14 +191,6 @@ public class UsbManager {
*/
public static final String USB_DATA_UNLOCKED = "unlocked";
/**
* Boolean extra indicating whether the intent represents a change in the usb
* configuration (as opposed to a state update).
*
* {@hide}
*/
public static final String USB_CONFIG_CHANGED = "config_changed";
/**
* A placeholder indicating that no USB function is being specified.
* Used for compatibility with old init scripts to indicate no functions vs. charging function.
@@ -470,6 +462,25 @@ public class UsbManager {
}
}
/**
* Gets the functionfs control file descriptor for the given function, with
* the usb descriptors and strings already written. The file descriptor is used
* by the function implementation to handle events and control requests.
*
* @param function to get control fd for. Currently {@link #FUNCTION_MTP} and
* {@link #FUNCTION_PTP} are supported.
* @return A ParcelFileDescriptor holding the valid fd, or null if the fd was not found.
*
* {@hide}
*/
public ParcelFileDescriptor getControlFd(long function) {
try {
return mService.getControlFd(function);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Returns true if the caller has permission to access the device.
* Permission might have been granted temporarily via

View File

@@ -652,7 +652,7 @@ public class ZygoteInit {
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,1065,3001,3002,3003,3006,3007,3009,3010",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",

View File

@@ -18,6 +18,8 @@ package android.mtp;
import com.android.internal.util.Preconditions;
import java.io.FileDescriptor;
/**
* Java wrapper for MTP/PTP support as USB responder.
* {@hide}
@@ -34,6 +36,7 @@ public class MtpServer implements Runnable {
public MtpServer(
MtpDatabase database,
FileDescriptor controlFd,
boolean usePtp,
Runnable onTerminate,
String deviceInfoManufacturer,
@@ -44,6 +47,7 @@ public class MtpServer implements Runnable {
mOnTerminate = Preconditions.checkNotNull(onTerminate);
native_setup(
database,
controlFd,
usePtp,
deviceInfoManufacturer,
deviceInfoModel,
@@ -92,6 +96,7 @@ public class MtpServer implements Runnable {
public static native final void native_configure(boolean usePtp);
private native final void native_setup(
MtpDatabase database,
FileDescriptor controlFd,
boolean usePtp,
String deviceInfoManufacturer,
String deviceInfoModel,

View File

@@ -55,22 +55,17 @@ static inline MtpServer* getMtpServer(JNIEnv *env, jobject thiz) {
return (MtpServer*)env->GetLongField(thiz, field_MtpServer_nativeContext);
}
static void android_mtp_configure(JNIEnv *, jobject, jboolean usePtp) {
MtpServer::configure(usePtp);
}
static void
android_mtp_MtpServer_setup(JNIEnv *env, jobject thiz, jobject javaDatabase, jboolean usePtp,
jstring deviceInfoManufacturer,
jstring deviceInfoModel,
jstring deviceInfoDeviceVersion,
jstring deviceInfoSerialNumber)
android_mtp_MtpServer_setup(JNIEnv *env, jobject thiz, jobject javaDatabase, jobject jControlFd,
jboolean usePtp, jstring deviceInfoManufacturer, jstring deviceInfoModel,
jstring deviceInfoDeviceVersion, jstring deviceInfoSerialNumber)
{
const char *deviceInfoManufacturerStr = env->GetStringUTFChars(deviceInfoManufacturer, NULL);
const char *deviceInfoModelStr = env->GetStringUTFChars(deviceInfoModel, NULL);
const char *deviceInfoDeviceVersionStr = env->GetStringUTFChars(deviceInfoDeviceVersion, NULL);
const char *deviceInfoSerialNumberStr = env->GetStringUTFChars(deviceInfoSerialNumber, NULL);
MtpServer* server = new MtpServer(getMtpDatabase(env, javaDatabase),
int controlFd = dup(jniGetFDFromFileDescriptor(env, jControlFd));
MtpServer* server = new MtpServer(getMtpDatabase(env, javaDatabase), controlFd,
usePtp,
MtpString((deviceInfoManufacturerStr != NULL) ? deviceInfoManufacturerStr : ""),
MtpString((deviceInfoModelStr != NULL) ? deviceInfoModelStr : ""),
@@ -201,8 +196,7 @@ android_mtp_MtpServer_remove_storage(JNIEnv *env, jobject thiz, jint storageId)
// ----------------------------------------------------------------------------
static const JNINativeMethod gMethods[] = {
{"native_configure", "(Z)V", (void *)android_mtp_configure},
{"native_setup", "(Landroid/mtp/MtpDatabase;ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
{"native_setup", "(Landroid/mtp/MtpDatabase;Ljava/io/FileDescriptor;ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
(void *)android_mtp_MtpServer_setup},
{"native_run", "()V", (void *)android_mtp_MtpServer_run},
{"native_cleanup", "()V", (void *)android_mtp_MtpServer_cleanup},

View File

@@ -86,6 +86,7 @@ cc_defaults {
"libhardware_legacy",
"libhidlbase",
"libkeystore_binder",
"libmtp",
"libnativehelper",
"libutils",
"libui",

View File

@@ -21,6 +21,7 @@
#include <nativehelper/JNIHelp.h>
#include "android_runtime/AndroidRuntime.h"
#include "android_runtime/Log.h"
#include "MtpDescriptors.h"
#include <stdio.h>
#include <asm/byteorder.h>
@@ -118,6 +119,38 @@ static jint android_server_UsbDeviceManager_getAudioMode(JNIEnv* /* env */, jobj
return result;
}
static jobject android_server_UsbDeviceManager_openControl(JNIEnv *env, jobject /* thiz */, jstring jFunction) {
const char *function = env->GetStringUTFChars(jFunction, NULL);
bool ptp = false;
int fd = -1;
if (!strcmp(function, "ptp")) {
ptp = true;
}
if (!strcmp(function, "mtp") || ptp) {
fd = TEMP_FAILURE_RETRY(open(ptp ? FFS_PTP_EP0 : FFS_MTP_EP0, O_RDWR));
if (fd < 0) {
ALOGE("could not open control for %s %s", function, strerror(errno));
goto error;
}
if (!writeDescriptors(fd, ptp)) {
goto error;
}
}
if (function != NULL) {
env->ReleaseStringUTFChars(jFunction, function);
}
return jniCreateFileDescriptor(env, fd);
error:
if (fd != -1) {
close(fd);
}
if (function != NULL) {
env->ReleaseStringUTFChars(jFunction, function);
}
return NULL;
}
static const JNINativeMethod method_table[] = {
{ "nativeGetAccessoryStrings", "()[Ljava/lang/String;",
(void*)android_server_UsbDeviceManager_getAccessoryStrings },
@@ -127,6 +160,8 @@ static const JNINativeMethod method_table[] = {
(void*)android_server_UsbDeviceManager_isStartRequested },
{ "nativeGetAudioMode", "()I",
(void*)android_server_UsbDeviceManager_getAudioMode },
{ "nativeOpenControl", "(Ljava/lang/String;)Ljava/io/FileDescriptor;",
(void*)android_server_UsbDeviceManager_openControl },
};
int register_android_server_UsbDeviceManager(JNIEnv *env)

View File

@@ -83,6 +83,7 @@ import com.android.server.FgThread;
import com.android.server.LocalServices;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
@@ -181,6 +182,7 @@ public class UsbDeviceManager implements ActivityManagerInternal.ScreenObserver
private final UEventObserver mUEventObserver;
private static Set<Integer> sBlackListedInterfaces;
private HashMap<Long, FileDescriptor> mControlFds;
static {
sBlackListedInterfaces = new HashSet<>();
@@ -270,6 +272,18 @@ public class UsbDeviceManager implements ActivityManagerInternal.ScreenObserver
Slog.i(TAG, "USB GADGET HAL not present in the device", e);
}
mControlFds = new HashMap<>();
FileDescriptor mtpFd = nativeOpenControl(UsbManager.USB_FUNCTION_MTP);
if (mtpFd == null) {
Slog.e(TAG, "Failed to open control for mtp");
}
mControlFds.put(UsbManager.FUNCTION_MTP, mtpFd);
FileDescriptor ptpFd = nativeOpenControl(UsbManager.USB_FUNCTION_PTP);
if (mtpFd == null) {
Slog.e(TAG, "Failed to open control for mtp");
}
mControlFds.put(UsbManager.FUNCTION_PTP, ptpFd);
boolean secureAdbEnabled = SystemProperties.getBoolean("ro.adb.secure", false);
boolean dataEncrypted = "1".equals(SystemProperties.get("vold.decrypt"));
if (secureAdbEnabled && !dataEncrypted) {
@@ -704,8 +718,7 @@ public class UsbDeviceManager implements ActivityManagerInternal.ScreenObserver
return false;
}
protected void updateUsbStateBroadcastIfNeeded(long functions,
boolean configChanged) {
protected void updateUsbStateBroadcastIfNeeded(long functions) {
// send a sticky broadcast containing current USB state
Intent intent = new Intent(UsbManager.ACTION_USB_STATE);
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
@@ -716,7 +729,6 @@ public class UsbDeviceManager implements ActivityManagerInternal.ScreenObserver
intent.putExtra(UsbManager.USB_CONFIGURED, mConfigured);
intent.putExtra(UsbManager.USB_DATA_UNLOCKED,
isUsbTransferAllowed() && isUsbDataTransferActive(mCurrentFunctions));
intent.putExtra(UsbManager.USB_CONFIG_CHANGED, configChanged);
long remainingFunctions = functions;
while (remainingFunctions != 0) {
@@ -726,7 +738,7 @@ public class UsbDeviceManager implements ActivityManagerInternal.ScreenObserver
}
// send broadcast intent only if the USB state has changed
if (!isUsbStateChanged(intent) && !configChanged) {
if (!isUsbStateChanged(intent)) {
if (DEBUG) {
Slog.d(TAG, "skip broadcasting " + intent + " extras: " + intent.getExtras());
}
@@ -798,8 +810,7 @@ public class UsbDeviceManager implements ActivityManagerInternal.ScreenObserver
updateUsbNotification(false);
updateAdbNotification(false);
if (mBootCompleted) {
updateUsbStateBroadcastIfNeeded(getAppliedFunctions(mCurrentFunctions),
false);
updateUsbStateBroadcastIfNeeded(getAppliedFunctions(mCurrentFunctions));
}
if ((mCurrentFunctions & UsbManager.FUNCTION_ACCESSORY) != 0) {
updateCurrentAccessory();
@@ -812,7 +823,7 @@ public class UsbDeviceManager implements ActivityManagerInternal.ScreenObserver
&& mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE) {
setScreenUnlockedFunctions();
} else {
setEnabledFunctions(UsbManager.FUNCTION_NONE, !mAdbEnabled);
setEnabledFunctions(UsbManager.FUNCTION_NONE, false);
}
}
updateUsbFunctions();
@@ -847,8 +858,7 @@ public class UsbDeviceManager implements ActivityManagerInternal.ScreenObserver
updateUsbNotification(false);
if (mBootCompleted) {
if (mHostConnected || prevHostConnected) {
updateUsbStateBroadcastIfNeeded(getAppliedFunctions(mCurrentFunctions),
false);
updateUsbStateBroadcastIfNeeded(getAppliedFunctions(mCurrentFunctions));
}
} else {
mPendingBootBroadcast = true;
@@ -994,7 +1004,7 @@ public class UsbDeviceManager implements ActivityManagerInternal.ScreenObserver
protected void finishBoot() {
if (mBootCompleted && mCurrentUsbFunctionsReceived && mSystemReady) {
if (mPendingBootBroadcast) {
updateUsbStateBroadcastIfNeeded(getAppliedFunctions(mCurrentFunctions), false);
updateUsbStateBroadcastIfNeeded(getAppliedFunctions(mCurrentFunctions));
mPendingBootBroadcast = false;
}
if (!mScreenLocked
@@ -1597,7 +1607,7 @@ public class UsbDeviceManager implements ActivityManagerInternal.ScreenObserver
/**
* Start up dependent services.
*/
updateUsbStateBroadcastIfNeeded(getAppliedFunctions(mCurrentFunctions), true);
updateUsbStateBroadcastIfNeeded(getAppliedFunctions(mCurrentFunctions));
}
if (!waitForState(oemFunctions)) {
@@ -1943,7 +1953,7 @@ public class UsbDeviceManager implements ActivityManagerInternal.ScreenObserver
if (mBootCompleted && isUsbDataTransferActive(functions)) {
// Start up dependent services.
updateUsbStateBroadcastIfNeeded(functions, true);
updateUsbStateBroadcastIfNeeded(functions);
}
}
}
@@ -1979,6 +1989,22 @@ public class UsbDeviceManager implements ActivityManagerInternal.ScreenObserver
return mHandler.getEnabledFunctions();
}
/**
* Returns a dup of the control file descriptor for the given function.
*/
public ParcelFileDescriptor getControlFd(long usbFunction) {
FileDescriptor fd = mControlFds.get(usbFunction);
if (fd == null) {
return null;
}
try {
return ParcelFileDescriptor.dup(fd);
} catch (IOException e) {
Slog.e(TAG, "Could not dup fd for " + usbFunction);
return null;
}
}
public long getScreenUnlockedFunctions() {
return mHandler.getScreenUnlockedFunctions();
}
@@ -2063,6 +2089,8 @@ public class UsbDeviceManager implements ActivityManagerInternal.ScreenObserver
private native ParcelFileDescriptor nativeOpenAccessory();
private native FileDescriptor nativeOpenControl(String usbFunction);
private native boolean nativeIsStartRequested();
private native int nativeGetAudioMode();

View File

@@ -304,6 +304,13 @@ public class UsbService extends IUsbManager.Stub {
return null;
}
/* Returns a dup of the control file descriptor for the given function. */
@Override
public ParcelFileDescriptor getControlFd(long function) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_MTP, null);
return mDeviceManager.getControlFd(function);
}
@Override
public void setDevicePackage(UsbDevice device, String packageName, int userId) {
device = Preconditions.checkNotNull(device);