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/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 6d3ca276..57fa463 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1686,6 +1686,12 @@
public static final String UNLOCK_SOUND = "unlock_sound";
/**
+ * True if we should appear as a PTP device instead of MTP.
+ * @hide
+ */
+ public static final String USE_PTP_INTERFACE = "use_ptp_interface";
+
+ /**
* Settings to backup. This is here so that it's in the same place as the settings
* keys and easy to update.
* @hide
@@ -1745,7 +1751,8 @@
DOCK_SOUNDS_ENABLED,
LOCKSCREEN_SOUNDS_ENABLED,
SHOW_WEB_SUGGESTIONS,
- NOTIFICATION_LIGHT_PULSE
+ NOTIFICATION_LIGHT_PULSE,
+ USE_PTP_INTERFACE,
};
// Settings moved to Settings.Secure
diff --git a/media/java/android/media/MtpServer.java b/media/java/android/media/MtpServer.java
index dcf08e2..7f15276 100644
--- a/media/java/android/media/MtpServer.java
+++ b/media/java/android/media/MtpServer.java
@@ -59,6 +59,10 @@
native_send_object_removed(handle);
}
+ public void setPtpMode(boolean usePtp) {
+ native_set_ptp_mode(usePtp);
+ }
+
// used by the JNI code
private int mNativeContext;
@@ -68,4 +72,5 @@
private native final void native_stop();
private native final void native_send_object_added(int handle);
private native final void native_send_object_removed(int handle);
+ private native final void native_set_ptp_mode(boolean usePtp);
}
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";
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 8349fe6..fbeaf4f 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -72,4 +72,6 @@
<!-- Default for Settings.System.VIBRATE_IN_SILENT -->
<bool name="def_vibrate_in_silent">true</bool>
+
+ <bool name="def_use_ptp_interface">false</bool>
</resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 7395233..a793106 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -1047,6 +1047,9 @@
loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT,
R.bool.def_vibrate_in_silent);
+
+ loadBooleanSetting(stmt, Settings.System.USE_PTP_INTERFACE,
+ R.bool.def_use_ptp_interface);
} finally {
if (stmt != null) stmt.close();
}