Merge "Write descriptors for Mtp in UsbService" into pi-dev
This commit is contained in:
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -86,6 +86,7 @@ cc_defaults {
|
||||
"libhardware_legacy",
|
||||
"libhidlbase",
|
||||
"libkeystore_binder",
|
||||
"libmtp",
|
||||
"libnativehelper",
|
||||
"libutils",
|
||||
"libui",
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user