Add settings option for running MTP server in PTP mode.
This can be used as a compatibility workaround for host operating systems
without MTP support.
Change-Id: If4f1856206056ca8e40c3ffbfa382f185c413598
Signed-off-by: Mike Lockwood <lockwood@android.com>
diff --git a/media/jni/android_media_MtpServer.cpp b/media/jni/android_media_MtpServer.cpp
index 3305136..3da3165 100644
--- a/media/jni/android_media_MtpServer.cpp
+++ b/media/jni/android_media_MtpServer.cpp
@@ -22,8 +22,11 @@
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
+#include <sys/ioctl.h>
#include <utils/threads.h>
+#include <linux/usb/f_mtp.h>
+
#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
@@ -56,34 +59,54 @@
MtpServer* mServer;
String8 mStoragePath;
jobject mJavaServer;
+ int mFd;
public:
MtpThread(MtpDatabase* database, const char* storagePath, jobject javaServer)
- : mDatabase(database),
+ : mDatabase(database),
mServer(NULL),
mStoragePath(storagePath),
- mJavaServer(javaServer)
+ mJavaServer(javaServer),
+ mFd(-1)
{
}
+ void setPtpMode(bool usePtp) {
+ sMutex.lock();
+ if (mFd >= 0) {
+ ioctl(mFd, MTP_SET_INTERFACE_MODE,
+ (usePtp ? MTP_INTERFACE_MODE_PTP : MTP_INTERFACE_MODE_MTP));
+ } else {
+ int fd = open("/dev/mtp_usb", O_RDWR);
+ if (fd >= 0) {
+ ioctl(fd, MTP_SET_INTERFACE_MODE,
+ (usePtp ? MTP_INTERFACE_MODE_PTP : MTP_INTERFACE_MODE_MTP));
+ close(fd);
+ }
+ }
+ sMutex.unlock();
+ }
+
virtual bool threadLoop() {
- int fd = open("/dev/mtp_usb", O_RDWR);
- printf("open returned %d\n", fd);
- if (fd < 0) {
+ sMutex.lock();
+ mFd = open("/dev/mtp_usb", O_RDWR);
+ printf("open returned %d\n", mFd);
+ if (mFd < 0) {
LOGE("could not open MTP driver\n");
+ sMutex.unlock();
return false;
}
- sMutex.lock();
- mServer = new MtpServer(fd, mDatabase, AID_SDCARD_RW, 0664, 0775);
+ mServer = new MtpServer(mFd, mDatabase, AID_SDCARD_RW, 0664, 0775);
mServer->addStorage(mStoragePath);
sMutex.unlock();
LOGD("MtpThread mServer->run");
mServer->run();
- close(fd);
sMutex.lock();
+ close(mFd);
+ mFd = -1;
delete mServer;
mServer = NULL;
@@ -184,6 +207,17 @@
#endif
}
+static void
+android_media_MtpServer_set_ptp_mode(JNIEnv *env, jobject thiz, jboolean usePtp)
+{
+#ifdef HAVE_ANDROID_OS
+ LOGD("set_ptp_mode\n");
+ MtpThread *thread = (MtpThread *)env->GetIntField(thiz, field_context);
+ if (thread)
+ thread->setPtpMode(usePtp);
+ #endif
+}
+
// ----------------------------------------------------------------------------
static JNINativeMethod gMethods[] = {
@@ -194,6 +228,7 @@
{"native_stop", "()V", (void *)android_media_MtpServer_stop},
{"native_send_object_added", "(I)V", (void *)android_media_MtpServer_send_object_added},
{"native_send_object_removed", "(I)V", (void *)android_media_MtpServer_send_object_removed},
+ {"native_set_ptp_mode", "(Z)V", (void *)android_media_MtpServer_set_ptp_mode},
};
static const char* const kClassPathName = "android/media/MtpServer";