Merge "MTP: Add support for sending events to the host when objects are added and removed"
This commit is contained in:
committed by
Android (Google) Code Review
commit
e2ce261674
@@ -47,6 +47,14 @@ public class MtpServer {
|
||||
native_stop();
|
||||
}
|
||||
|
||||
public void sendObjectAdded(int handle) {
|
||||
native_send_object_added(handle);
|
||||
}
|
||||
|
||||
public void sendObjectRemoved(int handle) {
|
||||
native_send_object_removed(handle);
|
||||
}
|
||||
|
||||
// used by the JNI code
|
||||
private int mNativeContext;
|
||||
|
||||
@@ -54,4 +62,6 @@ public class MtpServer {
|
||||
private native final void native_finalize();
|
||||
private native final void native_start();
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -50,12 +50,14 @@ static bool ExceptionCheck(void* env)
|
||||
class MtpThread : public Thread {
|
||||
private:
|
||||
MtpDatabase* mDatabase;
|
||||
MtpServer* mServer;
|
||||
String8 mStoragePath;
|
||||
bool mDone;
|
||||
Mutex mMutex;
|
||||
|
||||
public:
|
||||
MtpThread(MtpDatabase* database, const char* storagePath)
|
||||
: mDatabase(database), mStoragePath(storagePath), mDone(false)
|
||||
: mDatabase(database), mServer(NULL), mStoragePath(storagePath), mDone(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -67,14 +69,19 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
MtpServer* server = new MtpServer(fd, mDatabase, AID_SDCARD_RW, 0664, 0775);
|
||||
server->addStorage(mStoragePath);
|
||||
mMutex.lock();
|
||||
mServer = new MtpServer(fd, mDatabase, AID_SDCARD_RW, 0664, 0775);
|
||||
mServer->addStorage(mStoragePath);
|
||||
mMutex.unlock();
|
||||
|
||||
// temporary
|
||||
LOGD("MtpThread server->run");
|
||||
server->run();
|
||||
LOGD("MtpThread mServer->run");
|
||||
mServer->run();
|
||||
close(fd);
|
||||
delete server;
|
||||
|
||||
mMutex.lock();
|
||||
delete mServer;
|
||||
mServer = NULL;
|
||||
mMutex.unlock();
|
||||
|
||||
bool done = mDone;
|
||||
if (done)
|
||||
@@ -84,6 +91,24 @@ public:
|
||||
}
|
||||
|
||||
void setDone() { mDone = true; }
|
||||
|
||||
void sendObjectAdded(MtpObjectHandle handle) {
|
||||
mMutex.lock();
|
||||
if (mServer)
|
||||
mServer->sendObjectAdded(handle);
|
||||
else
|
||||
LOGE("sendObjectAdded called while disconnected\n");
|
||||
mMutex.unlock();
|
||||
}
|
||||
|
||||
void sendObjectRemoved(MtpObjectHandle handle) {
|
||||
mMutex.lock();
|
||||
if (mServer)
|
||||
mServer->sendObjectRemoved(handle);
|
||||
else
|
||||
LOGE("sendObjectRemoved called while disconnected\n");
|
||||
mMutex.unlock();
|
||||
}
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -126,14 +151,38 @@ android_media_MtpServer_stop(JNIEnv *env, jobject thiz)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
android_media_MtpServer_send_object_added(JNIEnv *env, jobject thiz, jint handle)
|
||||
{
|
||||
LOGD("send_object_added %d\n", handle);
|
||||
MtpThread *thread = (MtpThread *)env->GetIntField(thiz, field_context);
|
||||
if (thread)
|
||||
thread->sendObjectAdded(handle);
|
||||
else
|
||||
LOGE("sendObjectAdded called while disconnected\n");
|
||||
}
|
||||
|
||||
static void
|
||||
android_media_MtpServer_send_object_removed(JNIEnv *env, jobject thiz, jint handle)
|
||||
{
|
||||
LOGD("send_object_removed %d\n", handle);
|
||||
MtpThread *thread = (MtpThread *)env->GetIntField(thiz, field_context);
|
||||
if (thread)
|
||||
thread->sendObjectRemoved(handle);
|
||||
else
|
||||
LOGE("sendObjectRemoved called while disconnected\n");
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static JNINativeMethod gMethods[] = {
|
||||
{"native_setup", "(Landroid/media/MtpDatabase;Ljava/lang/String;)V",
|
||||
{"native_setup", "(Landroid/media/MtpDatabase;Ljava/lang/String;)V",
|
||||
(void *)android_media_MtpServer_setup},
|
||||
{"native_finalize", "()V", (void *)android_media_MtpServer_finalize},
|
||||
{"native_start", "()V", (void *)android_media_MtpServer_start},
|
||||
{"native_stop", "()V", (void *)android_media_MtpServer_stop},
|
||||
{"native_finalize", "()V", (void *)android_media_MtpServer_finalize},
|
||||
{"native_start", "()V", (void *)android_media_MtpServer_start},
|
||||
{"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},
|
||||
};
|
||||
|
||||
static const char* const kClassPathName = "android/media/MtpServer";
|
||||
|
||||
@@ -23,6 +23,7 @@ LOCAL_SRC_FILES:= \
|
||||
MtpDataPacket.cpp \
|
||||
MtpDebug.cpp \
|
||||
MtpDevice.cpp \
|
||||
MtpEventPacket.cpp \
|
||||
MtpDeviceInfo.cpp \
|
||||
MtpObjectInfo.cpp \
|
||||
MtpPacket.cpp \
|
||||
|
||||
65
media/mtp/MtpEventPacket.cpp
Normal file
65
media/mtp/MtpEventPacket.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "MtpEventPacket"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <f_mtp.h>
|
||||
|
||||
#include "MtpEventPacket.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
MtpEventPacket::MtpEventPacket()
|
||||
: MtpPacket(512)
|
||||
{
|
||||
}
|
||||
|
||||
MtpEventPacket::~MtpEventPacket() {
|
||||
}
|
||||
|
||||
#ifdef MTP_DEVICE
|
||||
int MtpEventPacket::write(int fd) {
|
||||
struct mtp_event event;
|
||||
|
||||
putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize);
|
||||
putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_EVENT);
|
||||
|
||||
event.data = mBuffer;
|
||||
event.length = mPacketSize;
|
||||
int ret = ::ioctl(fd, MTP_SEND_EVENT, (unsigned long)&event);
|
||||
return (ret < 0 ? ret : 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MTP_HOST
|
||||
// read our buffer from the given endpoint
|
||||
int MtpEventPacket::read(struct usb_endpoint *ep) {
|
||||
int ret = transfer(ep, mBuffer, mBufferSize);
|
||||
if (ret >= 0)
|
||||
mPacketSize = ret;
|
||||
else
|
||||
mPacketSize = 0;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace android
|
||||
|
||||
48
media/mtp/MtpEventPacket.h
Normal file
48
media/mtp/MtpEventPacket.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _MTP_EVENT_PACKET_H
|
||||
#define _MTP_EVENT_PACKET_H
|
||||
|
||||
#include "MtpPacket.h"
|
||||
#include "mtp.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
class MtpEventPacket : public MtpPacket {
|
||||
|
||||
public:
|
||||
MtpEventPacket();
|
||||
virtual ~MtpEventPacket();
|
||||
|
||||
#ifdef MTP_DEVICE
|
||||
// write our data to the given file descriptor
|
||||
int write(int fd);
|
||||
#endif
|
||||
|
||||
#ifdef MTP_HOST
|
||||
// read our buffer from the given endpoint
|
||||
int read(struct usb_endpoint *ep);
|
||||
#endif
|
||||
|
||||
inline MtpEventCode getEventCode() const { return getContainerCode(); }
|
||||
inline void setEventCode(MtpEventCode code)
|
||||
{ return setContainerCode(code); }
|
||||
};
|
||||
|
||||
}; // namespace android
|
||||
|
||||
#endif // _MTP_EVENT_PACKET_H
|
||||
@@ -73,6 +73,11 @@ static const MtpOperationCode kSupportedOperationCodes[] = {
|
||||
// MTP_OPERATION_SKIP,
|
||||
};
|
||||
|
||||
static const MtpEventCode kSupportedEventCodes[] = {
|
||||
MTP_EVENT_OBJECT_ADDED,
|
||||
MTP_EVENT_OBJECT_REMOVED,
|
||||
};
|
||||
|
||||
static const MtpObjectProperty kSupportedObjectProperties[] = {
|
||||
MTP_PROPERTY_STORAGE_ID,
|
||||
MTP_PROPERTY_OBJECT_FORMAT,
|
||||
@@ -239,6 +244,24 @@ MtpProperty* MtpServer::getDeviceProperty(MtpPropertyCode propCode) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void MtpServer::sendObjectAdded(MtpObjectHandle handle) {
|
||||
LOGD("sendObjectAdded %d\n", handle);
|
||||
mEvent.setEventCode(MTP_EVENT_OBJECT_ADDED);
|
||||
mEvent.setTransactionID(mRequest.getTransactionID());
|
||||
mEvent.setParameter(1, handle);
|
||||
int ret = mEvent.write(mFD);
|
||||
LOGD("mEvent.write returned %d\n", ret);
|
||||
}
|
||||
|
||||
void MtpServer::sendObjectRemoved(MtpObjectHandle handle) {
|
||||
LOGD("sendObjectRemoved %d\n", handle);
|
||||
mEvent.setEventCode(MTP_EVENT_OBJECT_REMOVED);
|
||||
mEvent.setTransactionID(mRequest.getTransactionID());
|
||||
mEvent.setParameter(1, handle);
|
||||
int ret = mEvent.write(mFD);
|
||||
LOGD("mEvent.write returned %d\n", ret);
|
||||
}
|
||||
|
||||
void MtpServer::initObjectProperties() {
|
||||
mObjectProperties.push(new MtpProperty(MTP_PROPERTY_STORAGE_ID, MTP_TYPE_UINT16));
|
||||
mObjectProperties.push(new MtpProperty(MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16));
|
||||
@@ -326,7 +349,8 @@ MtpResponseCode MtpServer::doGetDeviceInfo() {
|
||||
mData.putUInt16(0); //Functional Mode
|
||||
mData.putAUInt16(kSupportedOperationCodes,
|
||||
sizeof(kSupportedOperationCodes) / sizeof(uint16_t)); // Operations Supported
|
||||
mData.putEmptyArray(); // Events Supported
|
||||
mData.putAUInt16(kSupportedEventCodes,
|
||||
sizeof(kSupportedEventCodes) / sizeof(uint16_t)); // Events Supported
|
||||
mData.putEmptyArray(); // Device Properties Supported
|
||||
mData.putEmptyArray(); // Capture Formats
|
||||
mData.putAUInt16(kSupportedPlaybackFormats,
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "MtpRequestPacket.h"
|
||||
#include "MtpDataPacket.h"
|
||||
#include "MtpResponsePacket.h"
|
||||
#include "MtpEventPacket.h"
|
||||
#include "mtp.h"
|
||||
|
||||
#include "MtpUtils.h"
|
||||
@@ -52,6 +53,7 @@ private:
|
||||
MtpRequestPacket mRequest;
|
||||
MtpDataPacket mData;
|
||||
MtpResponsePacket mResponse;
|
||||
MtpEventPacket mEvent;
|
||||
|
||||
MtpStorageList mStorages;
|
||||
|
||||
@@ -77,6 +79,9 @@ public:
|
||||
MtpProperty* getObjectProperty(MtpPropertyCode propCode);
|
||||
MtpProperty* getDeviceProperty(MtpPropertyCode propCode);
|
||||
|
||||
void sendObjectAdded(MtpObjectHandle handle);
|
||||
void sendObjectRemoved(MtpObjectHandle handle);
|
||||
|
||||
private:
|
||||
void initObjectProperties();
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ typedef uint32_t uint128_t[4];
|
||||
|
||||
typedef uint16_t MtpOperationCode;
|
||||
typedef uint16_t MtpResponseCode;
|
||||
typedef uint16_t MtpEventCode;
|
||||
typedef uint32_t MtpSessionID;
|
||||
typedef uint32_t MtpStorageID;
|
||||
typedef uint32_t MtpTransactionID;
|
||||
|
||||
@@ -32,6 +32,13 @@ struct mtp_file_range {
|
||||
size_t length;
|
||||
};
|
||||
|
||||
struct mtp_event {
|
||||
/* size of the event */
|
||||
size_t length;
|
||||
/* event data to send */
|
||||
void *data;
|
||||
};
|
||||
|
||||
/* Sends the specified file range to the host */
|
||||
#define MTP_SEND_FILE _IOW('M', 0, struct mtp_file_range)
|
||||
/* Receives data from the host and writes it to a file.
|
||||
@@ -40,5 +47,7 @@ struct mtp_file_range {
|
||||
#define MTP_RECEIVE_FILE _IOW('M', 1, struct mtp_file_range)
|
||||
/* Sets the driver mode to either MTP or PTP */
|
||||
#define MTP_SET_INTERFACE_MODE _IOW('M', 2, int)
|
||||
/* Sends an event to the host via the interrupt endpoint */
|
||||
#define MTP_SEND_EVENT _IOW('M', 3, struct mtp_event)
|
||||
|
||||
#endif /* __LINUX_USB_F_MTP_H */
|
||||
|
||||
Reference in New Issue
Block a user