Bug 674725 - Part AF - Implement delete() on Android. r=cjones

This commit is contained in:
Mounir Lamouri 2011-12-22 23:15:28 +01:00
parent 39f3969aee
commit 92cf45e8cd
14 changed files with 159 additions and 8 deletions

View File

@ -151,6 +151,17 @@ SmsRequest::SetSuccess(nsIDOMMozSmsMessage* aMessage)
mDone = true;
}
void
SmsRequest::SetSuccess(bool aResult)
{
NS_PRECONDITION(!mDone, "mDone shouldn't have been set to true already!");
NS_PRECONDITION(mError == eNoError, "mError shouldn't have been set!");
NS_PRECONDITION(mResult == JSVAL_NULL, "mResult shouldn't have been set!");
mResult.setBoolean(aResult);
mDone = true;
}
void
SmsRequest::SetError(ErrorType aError)
{

View File

@ -95,6 +95,11 @@ private:
*/
void SetSuccess(nsIDOMMozSmsMessage* aMessage);
/**
* Set the object in a success state with the result being a boolean.
*/
void SetSuccess(bool aResult);
/**
* Set the object in an error state with the error type being aError.
*/

View File

@ -117,9 +117,9 @@ SmsRequestManager::DispatchTrustedEventToRequest(const nsAString& aEventName,
return aRequest->DispatchEvent(event, &dummy);
}
template <class T>
void
SmsRequestManager::NotifySuccessWithMessage(PRInt32 aRequestId,
nsIDOMMozSmsMessage* aMessage)
SmsRequestManager::NotifySuccess(PRInt32 aRequestId, T aParam)
{
NS_ASSERTION(mRequests.Count() > aRequestId && mRequests[aRequestId],
"Got an invalid request id or it has been already deleted!");
@ -127,7 +127,7 @@ SmsRequestManager::NotifySuccessWithMessage(PRInt32 aRequestId,
// It's safe to use the static_cast here given that we did call
// |new SmsRequest()|.
SmsRequest* request = static_cast<SmsRequest*>(mRequests[aRequestId]);
request->SetSuccess(aMessage);
request->SetSuccess(aParam);
DispatchTrustedEventToRequest(SUCCESS_EVENT_NAME, request);
@ -153,7 +153,7 @@ SmsRequestManager::NotifyError(PRInt32 aRequestId, SmsRequest::ErrorType aError)
void
SmsRequestManager::NotifySmsSent(PRInt32 aRequestId, nsIDOMMozSmsMessage* aMessage)
{
NotifySuccessWithMessage(aRequestId, aMessage);
NotifySuccess<nsIDOMMozSmsMessage*>(aRequestId, aMessage);
}
void
@ -165,7 +165,7 @@ SmsRequestManager::NotifySmsSendFailed(PRInt32 aRequestId, SmsRequest::ErrorType
void
SmsRequestManager::NotifyGotSms(PRInt32 aRequestId, nsIDOMMozSmsMessage* aMessage)
{
NotifySuccessWithMessage(aRequestId, aMessage);
NotifySuccess<nsIDOMMozSmsMessage*>(aRequestId, aMessage);
}
void
@ -175,6 +175,12 @@ SmsRequestManager::NotifyGetSmsFailed(PRInt32 aRequestId,
NotifyError(aRequestId, aError);
}
void
SmsRequestManager::NotifySmsDeleted(PRInt32 aRequestId, bool aDeleted)
{
NotifySuccess<bool>(aRequestId, aDeleted);
}
} // namespace sms
} // namespace dom
} // namespace mozilla

View File

@ -66,14 +66,15 @@ public:
void NotifySmsSendFailed(PRInt32 aRequestId, SmsRequest::ErrorType aError);
void NotifyGotSms(PRInt32 aRequestId, nsIDOMMozSmsMessage* aMessage);
void NotifyGetSmsFailed(PRInt32 aRequestId, SmsRequest::ErrorType aError);
void NotifySmsDeleted(PRInt32 aRequestId, bool aDeleted);
private:
static SmsRequestManager* sInstance;
nsresult DispatchTrustedEventToRequest(const nsAString& aEventName,
nsIDOMMozSmsRequest* aRequest);
void NotifySuccessWithMessage(PRInt32 aRequestId,
nsIDOMMozSmsMessage* aMessage);
template <class T>
void NotifySuccess(PRInt32 aRequestId, T aParam);
void NotifyError(PRInt32 aRequestId, SmsRequest::ErrorType aError);
nsCOMArray<nsIDOMMozSmsRequest> mRequests;

View File

@ -75,7 +75,11 @@ NS_IMETHODIMP
SmsDatabaseService::DeleteMessage(PRInt32 aMessageId, PRInt32 aRequestId,
PRUint64 aProcessId)
{
// TODO: implement
if (!AndroidBridge::Bridge()) {
return NS_OK;
}
AndroidBridge::Bridge()->DeleteMessage(aMessageId, aRequestId, aProcessId);
return NS_OK;
}

View File

@ -77,6 +77,9 @@ child:
NotifyRequestGetSmsFailed(PRInt32 aError, PRInt32 aRequestId,
PRUint64 aProcessId);
NotifyRequestSmsDeleted(bool aDeleted, PRInt32 aRequestId,
PRUint64 aProcessId);
parent:
sync HasSupport()
returns (bool aHasSupport);

View File

@ -150,6 +150,20 @@ SmsChild::RecvNotifyRequestGetSmsFailed(const PRInt32& aError,
return true;
}
bool
SmsChild::RecvNotifyRequestSmsDeleted(const bool& aDeleted,
const PRInt32& aRequestId,
const PRUint64& aProcessId)
{
if (ContentChild::GetSingleton()->GetID() != aProcessId) {
return true;
}
SmsRequestManager::GetInstance()->NotifySmsDeleted(aRequestId, aDeleted);
return true;
}
} // namespace sms
} // namespace dom
} // namespace mozilla

View File

@ -54,6 +54,7 @@ public:
NS_OVERRIDE virtual bool RecvNotifyRequestSmsSendFailed(const PRInt32& aError, const PRInt32& aRequestId, const PRUint64& aProcessId);
NS_OVERRIDE virtual bool RecvNotifyRequestGotSms(const SmsMessageData& aMessage, const PRInt32& aRequestId, const PRUint64& aProcessId);
NS_OVERRIDE virtual bool RecvNotifyRequestGetSmsFailed(const PRInt32& aError, const PRInt32& aRequestId, const PRUint64& aProcessId);
NS_OVERRIDE virtual bool RecvNotifyRequestSmsDeleted(const bool& aDeleted, const PRInt32& aRequestId, const PRUint64& aProcessId);
};
} // namespace sms

View File

@ -128,6 +128,7 @@ public class GeckoAppShell
public static native void notifySmsSendFailed(int aError, int aRequestId, long aProcessId);
public static native void notifyGetSms(int aId, String aReceiver, String aSender, String aBody, long aTimestamp, int aRequestId, long aProcessId);
public static native void notifyGetSmsFailed(int aError, int aRequestId, long aProcessId);
public static native void notifySmsDeleted(boolean aDeleted, int aRequestId, long aProcessId);
// A looper thread, accessed by GeckoAppShell.getHandler
private static class LooperThread extends Thread {
@ -1710,6 +1711,10 @@ public class GeckoAppShell
GeckoSmsManager.getMessage(aMessageId, aRequestId, aProcessId);
}
public static void deleteMessage(int aMessageId, int aRequestId, long aProcessId) {
GeckoSmsManager.deleteMessage(aMessageId, aRequestId, aProcessId);
}
public static boolean isTablet() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
Configuration config = GeckoApp.mAppContext.getResources().getConfiguration();

View File

@ -612,6 +612,49 @@ public class GeckoSmsManager
}
}
public static void deleteMessage(int aMessageId, int aRequestId, long aProcessId) {
class DeleteMessageRunnable implements Runnable {
private int mMessageId;
private int mRequestId;
private long mProcessId;
DeleteMessageRunnable(int aMessageId, int aRequestId, long aProcessId) {
mMessageId = aMessageId;
mRequestId = aRequestId;
mProcessId = aProcessId;
}
@Override
public void run() {
class TooManyResultsException extends Exception { }
try {
ContentResolver cr = GeckoApp.surfaceView.getContext().getContentResolver();
Uri message = ContentUris.withAppendedId(kSmsContentUri, mMessageId);
int count = cr.delete(message, null, null);
if (count > 1) {
throw new TooManyResultsException();
}
GeckoAppShell.notifySmsDeleted(count == 1, mRequestId, mProcessId);
} catch (TooManyResultsException e) {
// TODO: Notify failure
Log.e("GeckoSmsManager", "Delete more than one message? " + e);
} catch (Exception e) {
// TODO: Notify failure
Log.e("GeckoSmsManager", "Error while trying to delete a message: " + e);
}
}
}
if (!SmsIOThread.getInstance().execute(new DeleteMessageRunnable(aMessageId, aRequestId, aProcessId))) {
Log.e("GeckoSmsManager", "Failed to add GetMessageRunnable to the SmsIOThread");
// TODO: Notify failure
}
}
public static void shutdown() {
SmsIOThread.getInstance().interrupt();
}

View File

@ -276,6 +276,7 @@ SHELL_WRAPPER4(notifySmsDelivered, jint, jstring, jstring, jlong);
SHELL_WRAPPER3(notifySmsSendFailed, jint, jint, jlong);
SHELL_WRAPPER7(notifyGetSms, jint, jstring, jstring, jstring, jlong, jint, jlong);
SHELL_WRAPPER3(notifyGetSmsFailed, jint, jint, jlong);
SHELL_WRAPPER3(notifySmsDeleted, jboolean, jint, jlong);
static void * xul_handle = NULL;
static time_t apk_mtime = 0;
@ -669,6 +670,7 @@ loadLibs(const char *apkName)
GETFUNC(notifySmsSendFailed);
GETFUNC(notifyGetSms);
GETFUNC(notifyGetSmsFailed);
GETFUNC(notifySmsDeleted);
#undef GETFUNC
sStartupTimeline = (uint64_t *)__wrap_dlsym(xul_handle, "_ZN7mozilla15StartupTimeline16sStartupTimelineE");
gettimeofday(&t1, 0);

View File

@ -170,6 +170,7 @@ AndroidBridge::Init(JNIEnv *jEnv,
jSendMessage = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "sendMessage", "(Ljava/lang/String;Ljava/lang/String;IJ)V");
jSaveSentMessage = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "saveSentMessage", "(Ljava/lang/String;Ljava/lang/String;J)I");
jGetMessage = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getMessage", "(IIJ)V");
jDeleteMessage = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "deleteMessage", "(IIJ)V");
jEGLContextClass = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("javax/microedition/khronos/egl/EGLContext"));
jEGL10Class = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("javax/microedition/khronos/egl/EGL10"));
@ -1375,6 +1376,14 @@ AndroidBridge::GetMessage(PRInt32 aMessageId, PRInt32 aRequestId, PRUint64 aProc
JNI()->CallStaticVoidMethod(mGeckoAppShellClass, jGetMessage, aMessageId, aRequestId, aProcessId);
}
void
AndroidBridge::DeleteMessage(PRInt32 aMessageId, PRInt32 aRequestId, PRUint64 aProcessId)
{
ALOG_BRIDGE("AndroidBridge::DeleteMessage");
JNI()->CallStaticVoidMethod(mGeckoAppShellClass, jDeleteMessage, aMessageId, aRequestId, aProcessId);
}
void *
AndroidBridge::LockBitmap(jobject bitmap)
{

View File

@ -338,6 +338,7 @@ public:
void SendMessage(const nsAString& aNumber, const nsAString& aText, PRInt32 aRequestId, PRUint64 aProcessId);
PRInt32 SaveSentMessage(const nsAString& aRecipient, const nsAString& aBody, PRUint64 aDate);
void GetMessage(PRInt32 aMessageId, PRInt32 aRequestId, PRUint64 aProcessId);
void DeleteMessage(PRInt32 aMessageId, PRInt32 aRequestId, PRUint64 aProcessId);
bool IsTablet();
@ -430,6 +431,7 @@ protected:
jmethodID jSendMessage;
jmethodID jSaveSentMessage;
jmethodID jGetMessage;
jmethodID jDeleteMessage;
// stuff we need for CallEglCreateWindowSurface
jclass jEGLSurfaceImplClass;

View File

@ -97,6 +97,7 @@ extern "C" {
NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_notifySmsSendFailed(JNIEnv* jenv, jclass, jint, jint, jlong);
NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_notifyGetSms(JNIEnv* jenv, jclass, jint, jstring, jstring, jstring, jlong, jint, jlong);
NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_notifyGetSmsFailed(JNIEnv* jenv, jclass, jint, jint, jlong);
NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_notifySmsDeleted(JNIEnv* jenv, jclass, jboolean, jint, jlong);
#ifdef MOZ_JAVA_COMPOSITOR
NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_bindWidgetTexture(JNIEnv* jenv, jclass);
@ -546,6 +547,50 @@ Java_org_mozilla_gecko_GeckoAppShell_notifyGetSmsFailed(JNIEnv* jenv, jclass,
NS_DispatchToMainThread(runnable);
}
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoAppShell_notifySmsDeleted(JNIEnv* jenv, jclass,
jboolean aDeleted,
jint aRequestId,
jlong aProcessId)
{
class NotifySmsDeletedRunnable : public nsRunnable {
public:
NotifySmsDeletedRunnable(bool aDeleted, PRInt32 aRequestId,
PRUint64 aProcessId)
: mDeleted(aDeleted)
, mRequestId(aRequestId)
, mProcessId(aProcessId)
{}
NS_IMETHODIMP Run() {
if (mProcessId == 0) { // Parent process.
SmsRequestManager::GetInstance()->NotifySmsDeleted(mRequestId, mDeleted);
} else { // Content process.
nsTArray<SmsParent*> spList;
SmsParent::GetAll(spList);
for (PRUint32 i=0; i<spList.Length(); ++i) {
unused << spList[i]->SendNotifyRequestSmsDeleted(mDeleted,
mRequestId,
mProcessId);
}
}
return NS_OK;
}
private:
bool mDeleted;
PRInt32 mRequestId;
PRUint64 mProcessId;
};
nsCOMPtr<nsIRunnable> runnable =
new NotifySmsDeletedRunnable(aDeleted, aRequestId, aProcessId);
NS_DispatchToMainThread(runnable);
}
#ifdef MOZ_JAVA_COMPOSITOR
NS_EXPORT void JNICALL