MTP: Send an Intent after an MTP session that resulted in media database modifications

Change-Id: Ib2796e9155350c67769502935a73cf98d6ae9c08
Signed-off-by: Mike Lockwood <lockwood@android.com>
This commit is contained in:
Mike Lockwood
2010-08-31 16:25:12 -04:00
parent 2cbe236138
commit 2837eefc54
5 changed files with 73 additions and 0 deletions

View File

@@ -34,6 +34,14 @@ public final class Mtp
private static final String CONTENT_AUTHORITY_SLASH = "content://" + AUTHORITY + "/";
private static final String CONTENT_AUTHORITY_DEVICE_SLASH = "content://" + AUTHORITY + "/device/";
/**
* Broadcast Action: A broadcast to indicate the end of an MTP session with the host.
* This broadcast is only sent if MTP activity has modified the media database during the
* most recent MTP session
*/
public static final String ACTION_MTP_SESSION_END = "android.provider.action.MTP_SESSION_END";
/**
* Contains list of all MTP/PTP devices
*/

View File

@@ -19,12 +19,14 @@ package android.media;
import android.content.Context;
import android.content.ContentValues;
import android.content.IContentProvider;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.RemoteException;
import android.provider.MediaStore.Audio;
import android.provider.MediaStore.MediaColumns;
import android.provider.MediaStore.MtpObjects;
import android.provider.Mtp;
import android.util.Log;
/**
@@ -34,10 +36,14 @@ public class MtpDatabase {
private static final String TAG = "MtpDatabase";
private final Context mContext;
private final IContentProvider mMediaProvider;
private final String mVolumeName;
private final Uri mObjectsUri;
// true if the database has been modified in the current MTP session
private boolean mDatabaseModified;
// FIXME - this should be passed in via the constructor
private final int mStorageID = 0x00010001;
@@ -72,6 +78,7 @@ public class MtpDatabase {
public MtpDatabase(Context context, String volumeName) {
native_setup();
mContext = context;
mMediaProvider = context.getContentResolver().acquireProvider("media");
mVolumeName = volumeName;
mObjectsUri = MtpObjects.getContentUri(volumeName);
@@ -89,6 +96,7 @@ public class MtpDatabase {
private int beginSendObject(String path, int format, int parent,
int storage, long size, long modified) {
mDatabaseModified = true;
ContentValues values = new ContentValues();
values.put(MtpObjects.ObjectColumns.DATA, path);
values.put(MtpObjects.ObjectColumns.FORMAT, format);
@@ -398,6 +406,7 @@ public class MtpDatabase {
private int deleteFile(int handle) {
Log.d(TAG, "deleteFile: " + handle);
mDatabaseModified = true;
Uri uri = MtpObjects.getContentUri(mVolumeName, handle);
try {
if (mMediaProvider.delete(uri, null, null) == 1) {
@@ -440,6 +449,7 @@ public class MtpDatabase {
}
private int setObjectReferences(int handle, int[] references) {
mDatabaseModified = true;
Uri uri = MtpObjects.getReferencesUri(mVolumeName, handle);
int count = references.length;
ContentValues[] valuesList = new ContentValues[count];
@@ -458,6 +468,20 @@ public class MtpDatabase {
return MtpConstants.RESPONSE_GENERAL_ERROR;
}
private void sessionStarted() {
Log.d(TAG, "sessionStarted");
mDatabaseModified = false;
}
private void sessionEnded() {
Log.d(TAG, "sessionEnded");
if (mDatabaseModified) {
Log.d(TAG, "sending ACTION_MTP_SESSION_END");
mContext.sendBroadcast(new Intent(Mtp.ACTION_MTP_SESSION_END));
mDatabaseModified = false;
}
}
// used by the JNI code
private int mNativeContext;

View File

@@ -52,6 +52,9 @@ static jmethodID method_getObjectFilePath;
static jmethodID method_deleteFile;
static jmethodID method_getObjectReferences;
static jmethodID method_setObjectReferences;
static jmethodID method_sessionStarted;
static jmethodID method_sessionEnded;
static jfieldID field_context;
MtpDatabase* getMtpDatabase(JNIEnv *env, jobject database) {
@@ -135,6 +138,10 @@ public:
MtpObjectFormat format);
virtual MtpProperty* getDevicePropertyDesc(MtpDeviceProperty property);
virtual void sessionStarted();
virtual void sessionEnded();
};
// ----------------------------------------------------------------------------
@@ -583,6 +590,18 @@ MtpProperty* MyMtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) {
return NULL;
}
void MyMtpDatabase::sessionStarted() {
JNIEnv* env = AndroidRuntime::getJNIEnv();
env->CallVoidMethod(mDatabase, method_sessionStarted);
checkAndClearExceptionFromCallback(env, __FUNCTION__);
}
void MyMtpDatabase::sessionEnded() {
JNIEnv* env = AndroidRuntime::getJNIEnv();
env->CallVoidMethod(mDatabase, method_sessionEnded);
checkAndClearExceptionFromCallback(env, __FUNCTION__);
}
#endif // HAVE_ANDROID_OS
// ----------------------------------------------------------------------------
@@ -701,6 +720,17 @@ int register_android_media_MtpDatabase(JNIEnv *env)
LOGE("Can't find setObjectReferences");
return -1;
}
method_sessionStarted = env->GetMethodID(clazz, "sessionStarted", "()V");
if (method_sessionStarted == NULL) {
LOGE("Can't find sessionStarted");
return -1;
}
method_sessionEnded = env->GetMethodID(clazz, "sessionEnded", "()V");
if (method_sessionEnded == NULL) {
LOGE("Can't find sessionEnded");
return -1;
}
field_context = env->GetFieldID(clazz, "mNativeContext", "I");
if (field_context == NULL) {
LOGE("Can't find MtpDatabase.mNativeContext");

View File

@@ -93,6 +93,10 @@ public:
MtpObjectFormat format) = 0;
virtual MtpProperty* getDevicePropertyDesc(MtpDeviceProperty property) = 0;
virtual void sessionStarted() = 0;
virtual void sessionEnded() = 0;
};
}; // namespace android

View File

@@ -185,6 +185,9 @@ void MtpServer::run() {
LOGV("skipping response\n");
}
}
if (mSessionOpen)
mDatabase->sessionEnded();
}
void MtpServer::sendObjectAdded(MtpObjectHandle handle) {
@@ -346,6 +349,9 @@ MtpResponseCode MtpServer::doOpenSession() {
}
mSessionID = mRequest.getParameter(1);
mSessionOpen = true;
mDatabase->sessionStarted();
return MTP_RESPONSE_OK;
}
@@ -354,6 +360,7 @@ MtpResponseCode MtpServer::doCloseSession() {
return MTP_RESPONSE_SESSION_NOT_OPEN;
mSessionID = 0;
mSessionOpen = false;
mDatabase->sessionEnded();
return MTP_RESPONSE_OK;
}