Bug 1197010 - Implement Android backend for createMessageCursor/createThreadCursor. r=snorp

This commit is contained in:
Reuben Morais
2015-10-06 19:40:38 -03:00
parent 30f0187722
commit b653b039b4
17 changed files with 1402 additions and 782 deletions

View File

@@ -5,7 +5,9 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */ * You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "MobileMessageDatabaseService.h" #include "MobileMessageDatabaseService.h"
#include "AndroidBridge.h" #include "AndroidBridge.h"
#include "SmsManager.h"
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
@@ -13,6 +15,11 @@ namespace mobilemessage {
NS_IMPL_ISUPPORTS(MobileMessageDatabaseService, nsIMobileMessageDatabaseService) NS_IMPL_ISUPPORTS(MobileMessageDatabaseService, nsIMobileMessageDatabaseService)
MobileMessageDatabaseService::MobileMessageDatabaseService()
{
SmsManager::Init();
}
NS_IMETHODIMP NS_IMETHODIMP
MobileMessageDatabaseService::GetMessageMoz(int32_t aMessageId, MobileMessageDatabaseService::GetMessageMoz(int32_t aMessageId,
nsIMobileMessageCallback* aRequest) nsIMobileMessageCallback* aRequest)
@@ -60,9 +67,29 @@ MobileMessageDatabaseService::CreateMessageCursor(bool aHasStartDate,
uint64_t aThreadId, uint64_t aThreadId,
bool aReverse, bool aReverse,
nsIMobileMessageCursorCallback* aCallback, nsIMobileMessageCursorCallback* aCallback,
nsICursorContinueCallback** aResult) nsICursorContinueCallback** aCursor)
{ {
return NS_ERROR_NOT_IMPLEMENTED; if (!AndroidBridge::Bridge()) {
*aCursor = nullptr;
return NS_OK;
}
nsCOMPtr<nsICursorContinueCallback> cursor =
AndroidBridge::Bridge()->CreateMessageCursor(aHasStartDate,
aStartDate,
aHasEndDate,
aEndDate,
aNumbers,
aNumbersCount,
aDelivery,
aHasRead,
aRead,
aHasThreadId,
aThreadId,
aReverse,
aCallback);
cursor.forget(aCursor);
return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
@@ -76,11 +103,18 @@ MobileMessageDatabaseService::MarkMessageRead(int32_t aMessageId,
} }
NS_IMETHODIMP NS_IMETHODIMP
MobileMessageDatabaseService::CreateThreadCursor(nsIMobileMessageCursorCallback* aCallback, MobileMessageDatabaseService::CreateThreadCursor(nsIMobileMessageCursorCallback* aRequest,
nsICursorContinueCallback** aResult) nsICursorContinueCallback** aCursor)
{ {
NS_NOTYETIMPLEMENTED("Implement me!"); if (!AndroidBridge::Bridge()) {
return NS_ERROR_NOT_IMPLEMENTED; *aCursor = nullptr;
return NS_OK;
}
nsCOMPtr<nsICursorContinueCallback> cursor =
AndroidBridge::Bridge()->CreateThreadCursor(aRequest);
cursor.forget(aCursor);
return NS_OK;
} }
} // namespace mobilemessage } // namespace mobilemessage

View File

@@ -20,6 +20,8 @@ private:
~MobileMessageDatabaseService() {} ~MobileMessageDatabaseService() {}
public: public:
MobileMessageDatabaseService();
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_DECL_NSIMOBILEMESSAGEDATABASESERVICE NS_DECL_NSIMOBILEMESSAGEDATABASESERVICE
}; };

View File

@@ -0,0 +1,397 @@
/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "SmsManager.h"
#include "mozilla/dom/mobilemessage/Constants.h"
#include "mozilla/dom/mobilemessage/PSms.h"
#include "mozilla/dom/mobilemessage/SmsParent.h"
#include "mozilla/dom/mobilemessage/SmsTypes.h"
#include "mozilla/dom/mobilemessage/Types.h"
#include "mozilla/dom/MobileMessageThread.h"
#include "mozilla/dom/SmsMessage.h"
#include "mozilla/Services.h"
#include "nsIMobileMessageDatabaseService.h"
#include "nsIObserverService.h"
using namespace mozilla::dom;
using namespace mozilla::dom::mobilemessage;
namespace mozilla {
/*static*/
void
SmsManager::NotifySmsReceived(jni::String::Param aSender,
jni::String::Param aBody,
int32_t aMessageClass,
int64_t aTimestamp)
{
// TODO Need to correct the message `threadId` parameter value. Bug 859098
SmsMessageData message;
message.id() = 0;
message.threadId() = 0;
message.iccId() = EmptyString();
message.delivery() = eDeliveryState_Received;
message.deliveryStatus() = eDeliveryStatus_Success;
message.sender() = aSender ? nsString(aSender) : EmptyString();
message.receiver() = EmptyString();
message.body() = aBody ? nsString(aBody) : EmptyString();
message.messageClass() = static_cast<MessageClass>(aMessageClass);
message.timestamp() = aTimestamp;
message.sentTimestamp() = aTimestamp;
message.deliveryTimestamp() = aTimestamp;
message.read() = false;
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=] () {
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (!obs) {
return;
}
nsCOMPtr<nsIDOMMozSmsMessage> domMessage = new SmsMessage(message);
obs->NotifyObservers(domMessage, kSmsReceivedObserverTopic, nullptr);
});
NS_DispatchToMainThread(runnable);
}
/*static*/
void
SmsManager::NotifySmsSent(int32_t aId,
jni::String::Param aReceiver,
jni::String::Param aBody,
int64_t aTimestamp,
int32_t aRequestId)
{
// TODO Need to add the message `messageClass` parameter value. Bug 804476
// TODO Need to correct the message `threadId` parameter value. Bug 859098
SmsMessageData message;
message.id() = aId;
message.threadId() = 0;
message.iccId() = EmptyString();
message.delivery() = eDeliveryState_Sent;
message.deliveryStatus() = eDeliveryStatus_Pending;
message.sender() = EmptyString();
message.receiver() = aReceiver ? nsString(aReceiver) : EmptyString();
message.body() = aBody ? nsString(aBody) : EmptyString();
message.messageClass() = eMessageClass_Normal;
message.timestamp() = aTimestamp;
message.sentTimestamp() = aTimestamp;
message.deliveryTimestamp() = aTimestamp;
message.read() = true;
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=]() {
/*
* First, we are going to notify all SmsManager that a message has
* been sent. Then, we will notify the SmsRequest object about it.
*/
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (!obs) {
return;
}
nsCOMPtr<nsIDOMMozSmsMessage> domMessage = new SmsMessage(message);
obs->NotifyObservers(domMessage, kSmsSentObserverTopic, nullptr);
nsCOMPtr<nsIMobileMessageCallback> request =
AndroidBridge::Bridge()->DequeueSmsRequest(aRequestId);
if (!request) {
return;
}
request->NotifyMessageSent(domMessage);
});
NS_DispatchToMainThread(runnable);
}
/*static*/
void
SmsManager::NotifySmsDelivery(int32_t aId,
int32_t aDeliveryStatus,
jni::String::Param aReceiver,
jni::String::Param aBody,
int64_t aTimestamp)
{
// TODO Need to add the message `messageClass` parameter value. Bug 804476
// TODO Need to correct the message `threadId` parameter value. Bug 859098
SmsMessageData message;
message.id() = aId;
message.threadId() = 0;
message.iccId() = EmptyString();
message.delivery() = eDeliveryState_Sent;
message.deliveryStatus() = static_cast<DeliveryStatus>(aDeliveryStatus);
message.sender() = EmptyString();
message.receiver() = aReceiver ? nsString(aReceiver) : EmptyString();
message.body() = aBody ? nsString(aBody) : EmptyString();
message.messageClass() = eMessageClass_Normal;
message.timestamp() = aTimestamp;
message.sentTimestamp() = aTimestamp;
message.deliveryTimestamp() = aTimestamp;
message.read() = true;
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=]() {
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (!obs) {
return;
}
nsCOMPtr<nsIDOMMozSmsMessage> domMessage = new SmsMessage(message);
const char* topic = (message.deliveryStatus() == eDeliveryStatus_Success)
? kSmsDeliverySuccessObserverTopic
: kSmsDeliveryErrorObserverTopic;
obs->NotifyObservers(domMessage, topic, nullptr);
});
NS_DispatchToMainThread(runnable);
}
/*static*/
void
SmsManager::NotifySmsSendFailed(int32_t aError, int32_t aRequestId)
{
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=]() {
nsCOMPtr<nsIMobileMessageCallback> request =
AndroidBridge::Bridge()->DequeueSmsRequest(aRequestId);
if(!request) {
return;
}
request->NotifySendMessageFailed(aError, nullptr);
});
NS_DispatchToMainThread(runnable);
}
/*static*/
void
SmsManager::NotifyGetSms(int32_t aId,
int32_t aDeliveryStatus,
jni::String::Param aReceiver,
jni::String::Param aSender,
jni::String::Param aBody,
int64_t aTimestamp,
bool aRead,
int32_t aRequestId)
{
nsString receiver(aReceiver);
DeliveryState state = receiver.IsEmpty() ? eDeliveryState_Received
: eDeliveryState_Sent;
// TODO Need to add the message `messageClass` parameter value. Bug 804476
// TODO Need to correct the message `threadId` parameter value. Bug 859098
SmsMessageData message;
message.id() = aId;
message.threadId() = 0;
message.iccId() = EmptyString();
message.delivery() = state;
message.deliveryStatus() = static_cast<DeliveryStatus>(aDeliveryStatus);
message.sender() = aSender ? nsString(aSender) : EmptyString();
message.receiver() = receiver;
message.body() = aBody ? nsString(aBody) : EmptyString();
message.messageClass() = eMessageClass_Normal;
message.timestamp() = aTimestamp;
message.sentTimestamp() = aTimestamp;
message.deliveryTimestamp() = aTimestamp;
message.read() = aRead;
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=]() {
nsCOMPtr<nsIMobileMessageCallback> request =
AndroidBridge::Bridge()->DequeueSmsRequest(aRequestId);
if (!request) {
return;
}
nsCOMPtr<nsIDOMMozSmsMessage> domMessage = new SmsMessage(message);
request->NotifyMessageGot(domMessage);
});
NS_DispatchToMainThread(runnable);
}
/*static*/
void
SmsManager::NotifyGetSmsFailed(int32_t aError, int32_t aRequestId)
{
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=]() {
nsCOMPtr<nsIMobileMessageCallback> request =
AndroidBridge::Bridge()->DequeueSmsRequest(aRequestId);
if (!request) {
return;
}
request->NotifyGetMessageFailed(aError);
});
NS_DispatchToMainThread(runnable);
}
/*static*/
void
SmsManager::NotifySmsDeleted(bool aDeleted, int32_t aRequestId)
{
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=]() {
nsCOMPtr<nsIMobileMessageCallback> request =
AndroidBridge::Bridge()->DequeueSmsRequest(aRequestId);
if (!request) {
return;
}
// For android, we support only single SMS deletion.
bool deleted = aDeleted;
request->NotifyMessageDeleted(&deleted, 1);
});
NS_DispatchToMainThread(runnable);
}
/*static*/
void
SmsManager::NotifySmsDeleteFailed(int32_t aError, int32_t aRequestId)
{
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=]() {
nsCOMPtr<nsIMobileMessageCallback> request =
AndroidBridge::Bridge()->DequeueSmsRequest(aRequestId);
if (!request) {
return;
}
request->NotifyDeleteMessageFailed(aError);
});
NS_DispatchToMainThread(runnable);
}
/*static*/
void
SmsManager::NotifyCursorError(int32_t aError, int32_t aRequestId)
{
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=]() {
nsCOMPtr<nsIMobileMessageCursorCallback> request =
AndroidBridge::Bridge()->DequeueSmsCursorRequest(aRequestId);
if (!request) {
return;
}
request->NotifyCursorError(aError);
});
NS_DispatchToMainThread(runnable);
}
/*static*/
void
SmsManager::NotifyThreadCursorResult(int64_t aId,
jni::String::Param aLastMessageSubject,
jni::String::Param aBody,
int64_t aUnreadCount,
jni::ObjectArray::Param aParticipants,
int64_t aTimestamp,
jni::String::Param aLastMessageType,
int32_t aRequestId)
{
ThreadData thread;
thread.id() = aId;
thread.lastMessageSubject() = aLastMessageSubject ?
nsString(aLastMessageSubject) :
EmptyString();
thread.body() = aBody ? nsString(aBody) : EmptyString();
thread.unreadCount() = aUnreadCount;
thread.timestamp() = aTimestamp;
thread.lastMessageType() = eMessageType_SMS;
JNIEnv* const env = jni::GetEnvForThread();
jobjectArray participants = aParticipants.Get();
jsize length = env->GetArrayLength(participants);
for (jsize i = 0; i < length; ++i) {
jstring participant =
static_cast<jstring>(env->GetObjectArrayElement(participants, i));
if (participant) {
thread.participants().AppendElement(nsJNIString(participant, env));
}
}
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=]() {
nsCOMPtr<nsIMobileMessageCursorCallback> request =
AndroidBridge::Bridge()->GetSmsCursorRequest(aRequestId);
if (!request) {
return;
}
nsCOMArray<nsIDOMMozMobileMessageThread> arr;
arr.AppendElement(new MobileMessageThread(thread));
nsIDOMMozMobileMessageThread** elements;
int32_t size;
size = arr.Forget(&elements);
request->NotifyCursorResult(reinterpret_cast<nsISupports**>(elements),
size);
});
NS_DispatchToMainThread(runnable);
}
/*static*/
void
SmsManager::NotifyMessageCursorResult(int32_t aMessageId,
int32_t aDeliveryStatus,
jni::String::Param aReceiver,
jni::String::Param aSender,
jni::String::Param aBody,
int64_t aTimestamp,
int64_t aThreadId,
bool aRead,
int32_t aRequestId)
{
nsString receiver = nsString(aReceiver);
DeliveryState state = receiver.IsEmpty() ? eDeliveryState_Received
: eDeliveryState_Sent;
// TODO Need to add the message `messageClass` parameter value. Bug 804476
SmsMessageData message;
message.id() = aMessageId;
message.threadId() = aThreadId;
message.iccId() = EmptyString();
message.delivery() = state;
message.deliveryStatus() = static_cast<DeliveryStatus>(aDeliveryStatus);
message.sender() = aSender ? nsString(aSender) : EmptyString();
message.receiver() = receiver;
message.body() = aBody ? nsString(aBody) : EmptyString();
message.messageClass() = eMessageClass_Normal;
message.timestamp() = aTimestamp;
message.sentTimestamp() = aTimestamp;
message.deliveryTimestamp() = aTimestamp;
message.read() = aRead;
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=]() {
nsCOMPtr<nsIMobileMessageCursorCallback> request =
AndroidBridge::Bridge()->GetSmsCursorRequest(aRequestId);
if (!request) {
return;
}
nsCOMArray<nsIDOMMozSmsMessage> arr;
arr.AppendElement(new SmsMessage(message));
nsIDOMMozSmsMessage** elements;
int32_t size;
size = arr.Forget(&elements);
request->NotifyCursorResult(reinterpret_cast<nsISupports**>(elements),
size);
});
NS_DispatchToMainThread(runnable);
}
/*static*/
void
SmsManager::NotifyCursorDone(int32_t aRequestId)
{
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=]() {
nsCOMPtr<nsIMobileMessageCursorCallback> request =
AndroidBridge::Bridge()->DequeueSmsCursorRequest(aRequestId);
if (!request) {
return;
}
request->NotifyCursorDone();
});
NS_DispatchToMainThread(runnable);
}
} // namespace

View File

@@ -0,0 +1,73 @@
/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef SmsManager_h__
#define SmsManager_h__
#include "GeneratedJNINatives.h"
namespace mozilla {
class SmsManager : public widget::GeckoSmsManager::Natives<SmsManager>
{
private:
SmsManager();
public:
static void NotifySmsReceived(jni::String::Param aSender,
jni::String::Param aBody,
int32_t aMessageClass,
int64_t aTimestamp);
static void NotifySmsSent(int32_t aId,
jni::String::Param aReceiver,
jni::String::Param aBody,
int64_t aTimestamp,
int32_t aRequestId);
static void NotifySmsDelivery(int32_t aId,
int32_t aDeliveryStatus,
jni::String::Param aReceiver,
jni::String::Param aBody,
int64_t aTimestamp);
static void NotifySmsSendFailed(int32_t aError,
int32_t aRequestId);
static void NotifyGetSms(int32_t aId,
int32_t aDeliveryStatus,
jni::String::Param aReceiver,
jni::String::Param aSender,
jni::String::Param aBody,
int64_t aTimestamp,
bool aRead,
int32_t aRequestId);
static void NotifyGetSmsFailed(int32_t aError,
int32_t aRequestId);
static void NotifySmsDeleted(bool aDeleted,
int32_t aRequestId);
static void NotifySmsDeleteFailed(int32_t aError,
int32_t aRequestId);
static void NotifyCursorError(int32_t aError,
int32_t aRequestId);
static void NotifyThreadCursorResult(int64_t aId,
jni::String::Param aLastMessageSubject,
jni::String::Param aBody,
int64_t aUnreadCount,
jni::ObjectArray::Param aParticipants,
int64_t aTimestamp,
jni::String::Param aLastMessageType,
int32_t aRequestId);
static void NotifyMessageCursorResult(int32_t aMessageId,
int32_t aDeliveryStatus,
jni::String::Param aReceiver,
jni::String::Param aSender,
jni::String::Param aBody,
int64_t aTimestamp,
int64_t aThreadId,
bool aRead,
int32_t aRequestId);
static void NotifyCursorDone(int32_t aRequestId);
};
} // namespace
#endif // SmsManager_h__

View File

@@ -19,6 +19,7 @@ EXPORTS.mozilla.dom.mobilemessage += [
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android': if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
SOURCES += [ SOURCES += [
'android/MobileMessageDatabaseService.cpp', 'android/MobileMessageDatabaseService.cpp',
'android/SmsManager.cpp',
'android/SmsService.cpp', 'android/SmsService.cpp',
] ]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_B2G_RIL']: elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_B2G_RIL']:
@@ -46,6 +47,7 @@ EXPORTS.mozilla.dom += [
'DOMMobileMessageError.h', 'DOMMobileMessageError.h',
'MmsMessage.h', 'MmsMessage.h',
'MobileMessageManager.h', 'MobileMessageManager.h',
'MobileMessageThread.h',
'SmsMessage.h', 'SmsMessage.h',
] ]
@@ -75,6 +77,7 @@ IPDL_SOURCES += [
LOCAL_INCLUDES += [ LOCAL_INCLUDES += [
'/dom/base', '/dom/base',
'/widget/android',
] ]
include('/ipc/chromium/chromium-config.mozbuild') include('/ipc/chromium/chromium-config.mozbuild')

View File

@@ -28,6 +28,14 @@
<uses-permission android:name="android.permission.WRITE_CONTACTS"/> <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/> <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<!-- WebSMS -->
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.WRITE_SMS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-feature android:name="android.hardware.telephony"/>
<!-- Tab Queue --> <!-- Tab Queue -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

View File

@@ -122,3 +122,5 @@ fi
MOZ_JSDOWNLOADS=1 MOZ_JSDOWNLOADS=1
MOZ_TIME_MANAGER=1 MOZ_TIME_MANAGER=1
MOZ_WEBSMS_BACKEND=1

View File

@@ -47,6 +47,8 @@
<uses-permission android:name="android.permission.RECEIVE_SMS"/> <uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.WRITE_SMS"/> <uses-permission android:name="android.permission.WRITE_SMS"/>
<uses-permission android:name="android.permission.READ_SMS"/> <uses-permission android:name="android.permission.READ_SMS"/>
<uses-feature android:name="android.hardware.telephony"/>
#endif #endif
<uses-feature android:name="android.hardware.location" android:required="false"/> <uses-feature android:name="android.hardware.location" android:required="false"/>

View File

@@ -2381,31 +2381,42 @@ public class GeckoAppShell
SmsManager.getInstance().deleteMessage(aMessageId, aRequestId); SmsManager.getInstance().deleteMessage(aMessageId, aRequestId);
} }
@WrapForJNI(stubName = "CreateMessageListWrapper") @WrapForJNI(stubName = "CreateMessageCursorWrapper")
public static void createMessageList(long aStartDate, long aEndDate, String[] aNumbers, int aNumbersCount, String aDelivery, boolean aHasRead, boolean aRead, long aThreadId, boolean aReverse, int aRequestId) { public static void createMessageCursor(long aStartDate, long aEndDate, String[] aNumbers, int aNumbersCount, String aDelivery, boolean aHasRead, boolean aRead, boolean aHasThreadId, long aThreadId, boolean aReverse, int aRequestId) {
if (!SmsManager.isEnabled()) { if (!SmsManager.isEnabled()) {
return; return;
} }
SmsManager.getInstance().createMessageList(aStartDate, aEndDate, aNumbers, aNumbersCount, aDelivery, aHasRead, aRead, aThreadId, aReverse, aRequestId); SmsManager.getInstance().createMessageCursor(aStartDate, aEndDate, aNumbers, aNumbersCount, aDelivery, aHasRead, aRead, aHasThreadId, aThreadId, aReverse, aRequestId);
} }
@WrapForJNI(stubName = "GetNextMessageInListWrapper") @WrapForJNI(stubName = "GetNextMessageWrapper")
public static void getNextMessageInList(int aListId, int aRequestId) { public static void getNextMessage(int aRequestId) {
if (!SmsManager.isEnabled()) { if (!SmsManager.isEnabled()) {
return; return;
} }
SmsManager.getInstance().getNextMessageInList(aListId, aRequestId); SmsManager.getInstance().getNextMessage(aRequestId);
} }
@WrapForJNI @WrapForJNI(stubName = "CreateThreadCursorWrapper")
public static void clearMessageList(int aListId) { public static void createThreadCursor(int aRequestId) {
Log.i("GeckoAppShell", "CreateThreadCursorWrapper!");
if (!SmsManager.isEnabled()) { if (!SmsManager.isEnabled()) {
return; return;
} }
SmsManager.getInstance().clearMessageList(aListId); SmsManager.getInstance().createThreadCursor(aRequestId);
}
@WrapForJNI(stubName = "GetNextThreadWrapper")
public static void getNextThread(int aRequestId) {
if (!SmsManager.isEnabled()) {
return;
}
SmsManager.getInstance().getNextThread(aRequestId);
} }
/* Called by JNI from AndroidBridge, and by reflection from tests/BaseTest.java.in */ /* Called by JNI from AndroidBridge, and by reflection from tests/BaseTest.java.in */

View File

@@ -5,6 +5,8 @@
package org.mozilla.gecko; package org.mozilla.gecko;
import org.mozilla.gecko.annotation.WrapForJNI;
import android.app.Activity; import android.app.Activity;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
@@ -18,7 +20,7 @@ import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.HandlerThread;
import android.telephony.SmsManager; import android.telephony.SmsManager;
import android.telephony.SmsMessage; import android.telephony.SmsMessage;
import android.util.Log; import android.util.Log;
@@ -27,6 +29,12 @@ import static android.telephony.SmsMessage.MessageClass;
import static org.mozilla.gecko.SmsManager.ISmsManager; import static org.mozilla.gecko.SmsManager.ISmsManager;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Formatter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
/** /**
@@ -183,7 +191,7 @@ class Postman
} }
} }
class SmsIOThread extends Thread { class SmsIOThread extends HandlerThread {
private final static SmsIOThread sInstance = new SmsIOThread(); private final static SmsIOThread sInstance = new SmsIOThread();
private Handler mHandler; private Handler mHandler;
@@ -192,17 +200,18 @@ class SmsIOThread extends Thread {
return sInstance; return sInstance;
} }
public boolean execute(Runnable r) { SmsIOThread() {
return mHandler.post(r); super("SmsIOThread");
} }
@Override @Override
public void run() { public void start() {
Looper.prepare(); super.start();
mHandler = new Handler(getLooper());
}
mHandler = new Handler(); public boolean execute(Runnable r) {
return mHandler.post(r);
Looper.loop();
} }
} }
@@ -214,57 +223,40 @@ class MessagesListManager
return sInstance; return sInstance;
} }
private final ArrayList<Cursor> mCursors = new ArrayList<>(); private final HashMap<Integer, Cursor> mCursors = new HashMap<>();
public int add(Cursor aCursor) { public void add(int id, Cursor aCursor) {
int size = mCursors.size(); if (mCursors.containsKey(id)) {
Log.e("GeckoSmsManager", "Trying to overwrite cursor!");
for (int i=0; i<size; ++i) { return;
if (mCursors.get(i) == null) {
mCursors.set(i, aCursor);
return i;
}
} }
mCursors.add(aCursor); mCursors.put(id, aCursor);
return size;
} }
public Cursor get(int aId) { public Cursor get(int aId) {
if (aId < 0 || mCursors.size() <= aId) { if (!mCursors.containsKey(aId)) {
Log.e("GeckoSmsManager", "Trying to get an unknown list!"); Log.e("GeckoSmsManager", "Cursor doesn't exist!");
return null; return null;
} }
Cursor cursor = mCursors.get(aId); return mCursors.get(aId);
if (cursor == null) {
Log.e("GeckoSmsManager", "Trying to get an empty list!");
}
return cursor;
} }
public void remove(int aId) { public void remove(int aId) {
if (aId < 0 || mCursors.size() <= aId) { if (!mCursors.containsKey(aId)) {
Log.e("GeckoSmsManager", "Trying to destroy an unknown list!"); Log.e("GeckoSmsManager", "Cursor doesn't exist!");
return; return;
} }
Cursor cursor = mCursors.set(aId, null); mCursors.remove(aId);
if (cursor == null) {
Log.e("GeckoSmsManager", "Trying to destroy an empty list!");
return;
}
cursor.close();
} }
public void clear() { public void clear() {
for (int i=0; i<mCursors.size(); ++i) { Set<Map.Entry<Integer, Cursor>> entries = mCursors.entrySet();
Cursor c = mCursors.get(i); Iterator<Map.Entry<Integer, Cursor>> it = entries.iterator();
if (c != null) { while (it.hasNext()) {
c.close(); it.next().getValue().close();
}
} }
mCursors.clear(); mCursors.clear();
@@ -282,7 +274,7 @@ public class GeckoSmsManager
/* /*
* Make sure that the following error codes are in sync with |ErrorType| in: * Make sure that the following error codes are in sync with |ErrorType| in:
* dom/mobilemessage/interfaces/nsIMobileMessageCallback.idl * dom/mobilemessage/interfaces/nsIMobileMessageCallback.idl
* The error code are owned by the DOM. * The error codes are owned by the DOM.
*/ */
public final static int kNoError = 0; public final static int kNoError = 0;
public final static int kNoSignalError = 1; public final static int kNoSignalError = 1;
@@ -305,8 +297,9 @@ public class GeckoSmsManager
private final static int kMaxMessageSize = 160; private final static int kMaxMessageSize = 160;
private final static Uri kSmsContentUri = Uri.parse("content://sms"); private final static Uri kSmsContentUri = Uri.parse("content://sms");
private final static Uri kSmsSentContentUri = Uri.parse("content://sms/sent"); private final static Uri kSmsSentContentUri = Uri.parse("content://sms/sent");
private final static Uri kSmsThreadsContentUri = Uri.parse("content://sms/conversations");
private final static int kSmsTypeInbox = 1; private final static int kSmsTypeInbox = 1;
private final static int kSmsTypeSentbox = 2; private final static int kSmsTypeSentbox = 2;
@@ -351,7 +344,9 @@ public class GeckoSmsManager
private final static int kMessageClassClass2 = 3; private final static int kMessageClassClass2 = 3;
private final static int kMessageClassClass3 = 4; private final static int kMessageClassClass3 = 4;
private final static String[] kRequiredMessageRows = { "_id", "address", "body", "date", "type", "status" }; private final static String[] kRequiredMessageRows = { "_id", "address", "body", "date", "type", "status", "read", "thread_id" };
private final static String[] kRequiredMessageRowsForThread = { "_id", "address", "body", "read", "subject", "date" };
private final static String[] kThreadProjection = { "thread_id" };
// Used to generate monotonically increasing GUIDs. // Used to generate monotonically increasing GUIDs.
private static final AtomicInteger pendingIntentGuid = new AtomicInteger(Integer.MIN_VALUE); private static final AtomicInteger pendingIntentGuid = new AtomicInteger(Integer.MIN_VALUE);
@@ -660,11 +655,14 @@ public class GeckoSmsManager
throw new InvalidTypeException(); throw new InvalidTypeException();
} }
boolean read = cursor.getInt(cursor.getColumnIndex("read")) != 0;
notifyGetSms(cursor.getInt(cursor.getColumnIndex("_id")), notifyGetSms(cursor.getInt(cursor.getColumnIndex("_id")),
deliveryStatus, deliveryStatus,
receiver, sender, receiver, sender,
cursor.getString(cursor.getColumnIndex("body")), cursor.getString(cursor.getColumnIndex("body")),
cursor.getLong(cursor.getColumnIndex("date")), cursor.getLong(cursor.getColumnIndex("date")),
read,
mRequestId); mRequestId);
} catch (NotFoundException e) { } catch (NotFoundException e) {
Log.i("GeckoSmsManager", "Message id " + mMessageId + " not found"); Log.i("GeckoSmsManager", "Message id " + mMessageId + " not found");
@@ -736,23 +734,55 @@ public class GeckoSmsManager
} }
} }
private void getMessageFromCursorAndNotify(Cursor aCursor, int aRequestId) throws Exception {
int type = aCursor.getInt(aCursor.getColumnIndex("type"));
int deliveryStatus = kDeliveryStateUnknown;
String sender = "";
String receiver = "";
if (type == kSmsTypeInbox) {
deliveryStatus = kDeliveryStatusSuccess;
sender = aCursor.getString(aCursor.getColumnIndex("address"));
} else if (type == kSmsTypeSentbox) {
deliveryStatus = getGeckoDeliveryStatus(aCursor.getInt(aCursor.getColumnIndex("status")));
receiver = aCursor.getString(aCursor.getColumnIndex("address"));
} else {
throw new Exception("Shouldn't ever get a message here that's not from inbox or sentbox");
}
boolean read = aCursor.getInt(aCursor.getColumnIndex("read")) != 0;
notifyMessageCursorResult(aCursor.getInt(aCursor.getColumnIndex("_id")),
deliveryStatus,
receiver, sender,
aCursor.getString(aCursor.getColumnIndex("body")),
aCursor.getLong(aCursor.getColumnIndex("date")),
aCursor.getLong(aCursor.getColumnIndex("thread_id")),
read,
aRequestId);
}
@Override @Override
public void createMessageList(long aStartDate, long aEndDate, String[] aNumbers, int aNumbersCount, String aDelivery, boolean aHasRead, boolean aRead, long aThreadId, boolean aReverse, int aRequestId) { public void createMessageCursor(long aStartDate, long aEndDate, String[] aNumbers, int aNumbersCount, String aDelivery, boolean aHasRead, boolean aRead, boolean aHasThreadId, long aThreadId, boolean aReverse, int aRequestId) {
class CreateMessageListRunnable implements Runnable { class CreateMessageCursorRunnable implements Runnable {
private final long mStartDate; private final long mStartDate;
private final long mEndDate; private final long mEndDate;
private final String[] mNumbers; private final String[] mNumbers;
private final int mNumbersCount; private final int mNumbersCount;
private final String mDelivery; private final String mDelivery;
private final boolean mHasThreadId;
private final long mThreadId;
private final boolean mReverse; private final boolean mReverse;
private final int mRequestId; private final int mRequestId;
CreateMessageListRunnable(long aStartDate, long aEndDate, String[] aNumbers, int aNumbersCount, String aDelivery, boolean aHasRead, boolean aRead, long aThreadId, boolean aReverse, int aRequestId) { CreateMessageCursorRunnable(long aStartDate, long aEndDate, String[] aNumbers, int aNumbersCount, String aDelivery, boolean aHasRead, boolean aRead, boolean aHasThreadId, long aThreadId, boolean aReverse, int aRequestId) {
mStartDate = aStartDate; mStartDate = aStartDate;
mEndDate = aEndDate; mEndDate = aEndDate;
mNumbers = aNumbers; mNumbers = aNumbers;
mNumbersCount = aNumbersCount; mNumbersCount = aNumbersCount;
mDelivery = aDelivery; mDelivery = aDelivery;
mHasThreadId = aHasThreadId;
mThreadId = aThreadId;
mReverse = aReverse; mReverse = aReverse;
mRequestId = aRequestId; mRequestId = aRequestId;
} }
@@ -763,169 +793,236 @@ public class GeckoSmsManager
boolean closeCursor = true; boolean closeCursor = true;
try { try {
// TODO: should use the |selectionArgs| argument in |ContentResolver.query()|. StringBuilder restrictions = new StringBuilder();
ArrayList<String> restrictions = new ArrayList<String>(); Formatter formatter = new Formatter(restrictions);
if (mStartDate >= 0) { if (mStartDate >= 0) {
restrictions.add("date >= " + mStartDate); formatter.format("date >= '%d' AND ", mStartDate);
} }
if (mEndDate >= 0) { if (mEndDate >= 0) {
restrictions.add("date <= " + mEndDate); formatter.format("date <= '%d' AND ", mEndDate);
} }
if (mNumbersCount > 0) { if (mNumbersCount > 0) {
final StringBuilder numberRestriction = new StringBuilder("address IN ('"); formatter.format("address IN ('%s'", mNumbers[0]);
numberRestriction.append(mNumbers[0]).append("'");
for (int i=1; i<mNumbersCount; ++i) { for (int i = 1; i < mNumbersCount; ++i) {
numberRestriction.append(", '").append(mNumbers[i]).append("'"); formatter.format(", '%s'", mNumbers[i]);
} }
numberRestriction.append(')');
formatter.format(") AND ");
restrictions.add(numberRestriction.toString());
} }
if (mDelivery == null) { if (mDelivery == null || mDelivery.isEmpty()) {
restrictions.add("type IN ('" + kSmsTypeSentbox + "', '" + kSmsTypeInbox + "')"); formatter.format("type IN ('%d', '%d') AND ", kSmsTypeSentbox, kSmsTypeInbox);
} else if (mDelivery.equals("sent")) { } else if (mDelivery.equals("sent")) {
restrictions.add("type = " + kSmsTypeSentbox); formatter.format("type = '%d' AND ", kSmsTypeSentbox);
} else if (mDelivery.equals("received")) { } else if (mDelivery.equals("received")) {
restrictions.add("type = " + kSmsTypeInbox); formatter.format("type = '%d' AND ", kSmsTypeInbox);
} else { } else {
throw new UnexpectedDeliveryStateException(); throw new Exception("Unexpected delivery state: " + mDelivery);
} }
final StringBuilder restrictionText = new StringBuilder(); if (mHasThreadId) {
if (!restrictions.isEmpty()) { formatter.format("thread_id = '%d' AND ", mThreadId);
restrictionText.append(restrictions.get(0));
} }
for (int i=1; i<restrictions.size(); ++i) { // Final 'AND 1' is a no-op so we don't have to special case the last
restrictionText.append(" AND ").append(restrictions.get(i)); // condition.
} formatter.format("1");
ContentResolver cr = GeckoAppShell.getContext().getContentResolver(); ContentResolver cr = GeckoAppShell.getContext().getContentResolver();
cursor = cr.query(kSmsContentUri, kRequiredMessageRows, restrictionText.toString(), null, cursor = cr.query(kSmsContentUri,
kRequiredMessageRows,
restrictions.toString(),
null,
mReverse ? "date DESC" : "date ASC"); mReverse ? "date DESC" : "date ASC");
if (cursor.getCount() == 0) { if (cursor.getCount() == 0) {
notifyNoMessageInList(mRequestId); notifyCursorDone(mRequestId);
return; return;
} }
MessagesListManager.getInstance().add(mRequestId, cursor);
cursor.moveToFirst(); cursor.moveToFirst();
getMessageFromCursorAndNotify(cursor, mRequestId);
int type = cursor.getInt(cursor.getColumnIndex("type"));
int deliveryStatus;
String sender = "";
String receiver = "";
if (type == kSmsTypeInbox) {
deliveryStatus = kDeliveryStatusSuccess;
sender = cursor.getString(cursor.getColumnIndex("address"));
} else if (type == kSmsTypeSentbox) {
deliveryStatus = getGeckoDeliveryStatus(cursor.getInt(cursor.getColumnIndex("status")));
receiver = cursor.getString(cursor.getColumnIndex("address"));
} else {
throw new UnexpectedDeliveryStateException();
}
int listId = MessagesListManager.getInstance().add(cursor);
closeCursor = false; closeCursor = false;
notifyListCreated(listId,
cursor.getInt(cursor.getColumnIndex("_id")),
deliveryStatus,
receiver, sender,
cursor.getString(cursor.getColumnIndex("body")),
cursor.getLong(cursor.getColumnIndex("date")),
mRequestId);
} catch (UnexpectedDeliveryStateException e) {
Log.e("GeckoSmsManager", "Unexcepted delivery state type", e);
notifyReadingMessageListFailed(kUnknownError, mRequestId);
} catch (Exception e) { } catch (Exception e) {
Log.e("GeckoSmsManager", "Error while trying to create a message list cursor", e); Log.e("GeckoSmsManager", "Error while trying to create a message list cursor", e);
notifyReadingMessageListFailed(kUnknownError, mRequestId); notifyCursorError(kUnknownError, mRequestId);
} finally { } finally {
// Close the cursor if MessagesListManager isn't taking care of it. if (closeCursor && cursor != null) {
// We could also just check if it is in the MessagesListManager list but
// that would be less efficient.
if (cursor != null && closeCursor) {
cursor.close(); cursor.close();
} }
} }
} }
} }
if (!SmsIOThread.getInstance().execute(new CreateMessageListRunnable(aStartDate, aEndDate, aNumbers, aNumbersCount, aDelivery, aHasRead, aRead, aThreadId, aReverse, aRequestId))) { if (!SmsIOThread.getInstance().execute(new CreateMessageCursorRunnable(aStartDate, aEndDate, aNumbers, aNumbersCount, aDelivery, aHasRead, aRead, aHasThreadId, aThreadId, aReverse, aRequestId))) {
Log.e("GeckoSmsManager", "Failed to add CreateMessageListRunnable to the SmsIOThread"); Log.e("GeckoSmsManager", "Failed to add CreateMessageCursorRunnable to the SmsIOThread");
notifyReadingMessageListFailed(kUnknownError, aRequestId); notifyCursorError(kUnknownError, aRequestId);
} }
} }
@Override @Override
public void getNextMessageInList(int aListId, int aRequestId) { public void getNextMessage(int aRequestId) {
class GetNextMessageInListRunnable implements Runnable { class GetNextMessageRunnable implements Runnable {
private final int mListId;
private final int mRequestId; private final int mRequestId;
GetNextMessageInListRunnable(int aListId, int aRequestId) { GetNextMessageRunnable(int aRequestId) {
mListId = aListId; mRequestId = aRequestId;
}
@Override
public void run() {
Cursor cursor = null;
boolean closeCursor = true;
try {
cursor = MessagesListManager.getInstance().get(mRequestId);
if (!cursor.moveToNext()) {
MessagesListManager.getInstance().remove(mRequestId);
notifyCursorDone(mRequestId);
return;
}
getMessageFromCursorAndNotify(cursor, mRequestId);
closeCursor = false;
} catch (Exception e) {
Log.e("GeckoSmsManager", "Error while trying to get the next message of a list", e);
notifyCursorError(kUnknownError, mRequestId);
} finally {
if (closeCursor) {
cursor.close();
}
}
}
}
if (!SmsIOThread.getInstance().execute(new GetNextMessageRunnable(aRequestId))) {
Log.e("GeckoSmsManager", "Failed to add GetNextMessageRunnable to the SmsIOThread");
notifyCursorError(kUnknownError, aRequestId);
}
}
private void getThreadFromCursorAndNotify(Cursor aCursor, int aRequestId) throws Exception {
ContentResolver cr = GeckoAppShell.getContext().getContentResolver();
long id = aCursor.getLong(aCursor.getColumnIndex("thread_id"));
Cursor msgCursor = cr.query(kSmsContentUri,
kRequiredMessageRowsForThread,
"thread_id = " + id,
null,
"date DESC");
if (msgCursor == null || msgCursor.getCount() == 0) {
throw new Exception("Empty thread " + id);
}
msgCursor.moveToFirst();
String lastMessageSubject = msgCursor.getString(msgCursor.getColumnIndex("subject"));
String body = msgCursor.getString(msgCursor.getColumnIndex("body"));
long timestamp = msgCursor.getLong(msgCursor.getColumnIndex("date"));
HashSet<String> participants = new HashSet<>();
do {
String p = msgCursor.getString(msgCursor.getColumnIndex("address"));
participants.add(p);
} while (msgCursor.moveToNext());
//TODO: handle MMS
String lastMessageType = "sms";
msgCursor = cr.query(kSmsContentUri,
kRequiredMessageRowsForThread,
"thread_id = " + id + " AND read = 0",
null,
null);
if (msgCursor == null) {
Log.e("GeckoSmsManager", "We should never get here, should have errored before");
throw new Exception("Empty thread " + id);
}
long unreadCount = msgCursor.getCount();
notifyThreadCursorResult(id, lastMessageSubject, body, unreadCount, participants.toArray(), timestamp, lastMessageType, aRequestId);
}
@Override
public void createThreadCursor(int aRequestId) {
class CreateThreadCursorRunnable implements Runnable {
private final int mRequestId;
CreateThreadCursorRunnable(int aRequestId) {
mRequestId = aRequestId; mRequestId = aRequestId;
} }
@Override @Override
public void run() { public void run() {
try { try {
Cursor cursor = MessagesListManager.getInstance().get(mListId); ContentResolver cr = GeckoAppShell.getContext().getContentResolver();
Cursor cursor = cr.query(kSmsThreadsContentUri,
if (!cursor.moveToNext()) { kThreadProjection,
MessagesListManager.getInstance().remove(mListId); null,
notifyNoMessageInList(mRequestId); null,
"date DESC");
if (cursor == null || !cursor.moveToFirst()) {
notifyCursorDone(mRequestId);
return; return;
} }
int type = cursor.getInt(cursor.getColumnIndex("type")); MessagesListManager.getInstance().add(mRequestId, cursor);
int deliveryStatus;
String sender = "";
String receiver = "";
if (type == kSmsTypeInbox) { getThreadFromCursorAndNotify(cursor, mRequestId);
deliveryStatus = kDeliveryStatusSuccess;
sender = cursor.getString(cursor.getColumnIndex("address"));
} else if (type == kSmsTypeSentbox) {
deliveryStatus = getGeckoDeliveryStatus(cursor.getInt(cursor.getColumnIndex("status")));
receiver = cursor.getString(cursor.getColumnIndex("address"));
} else {
throw new UnexpectedDeliveryStateException();
}
int listId = MessagesListManager.getInstance().add(cursor);
notifyGotNextMessage(cursor.getInt(cursor.getColumnIndex("_id")),
deliveryStatus,
receiver, sender,
cursor.getString(cursor.getColumnIndex("body")),
cursor.getLong(cursor.getColumnIndex("date")),
mRequestId);
} catch (UnexpectedDeliveryStateException e) {
Log.e("GeckoSmsManager", "Unexcepted delivery state type", e);
notifyReadingMessageListFailed(kUnknownError, mRequestId);
} catch (Exception e) { } catch (Exception e) {
Log.e("GeckoSmsManager", "Error while trying to get the next message of a list", e); Log.e("GeckoSmsManager", "Error while trying to create thread cursor: " + e);
notifyReadingMessageListFailed(kUnknownError, mRequestId); notifyCursorError(kUnknownError, mRequestId);
} }
} }
} }
if (!SmsIOThread.getInstance().execute(new GetNextMessageInListRunnable(aListId, aRequestId))) { if (!SmsIOThread.getInstance().execute(new CreateThreadCursorRunnable(aRequestId))) {
Log.e("GeckoSmsManager", "Failed to add GetNextMessageInListRunnable to the SmsIOThread"); Log.e("GeckoSmsManager", "Failed to add CreateThreadCursorRunnable to the SmsIOThread");
notifyReadingMessageListFailed(kUnknownError, aRequestId); notifyCursorError(kUnknownError, aRequestId);
} }
} }
@Override @Override
public void clearMessageList(int aListId) { public void getNextThread(int aRequestId) {
MessagesListManager.getInstance().remove(aListId); class GetNextThreadRunnable implements Runnable {
private final int mRequestId;
GetNextThreadRunnable(int aRequestId) {
mRequestId = aRequestId;
}
@Override
public void run() {
try {
Cursor cursor = MessagesListManager.getInstance().get(mRequestId);
if (!cursor.moveToNext()) {
MessagesListManager.getInstance().remove(mRequestId);
notifyCursorDone(mRequestId);
return;
}
getThreadFromCursorAndNotify(cursor, mRequestId);
} catch (Exception e) {
Log.e("GeckoSmsManager", "Error while trying to create thread cursor: " + e);
notifyCursorError(kUnknownError, mRequestId);
}
}
}
if (!SmsIOThread.getInstance().execute(new GetNextThreadRunnable(aRequestId))) {
Log.e("GeckoSmsManager", "Failed to add GetNextThreadRunnable to the SmsIOThread");
notifyCursorError(kUnknownError, aRequestId);
}
} }
@Override @Override
@@ -983,24 +1080,32 @@ public class GeckoSmsManager
private static final long serialVersionUID = 51883196784325305L; private static final long serialVersionUID = 51883196784325305L;
} }
static class UnexpectedDeliveryStateException extends Exception {
private static final long serialVersionUID = 494122763684005716L;
}
static class UnmatchingIdException extends Exception { static class UnmatchingIdException extends Exception {
private static final long serialVersionUID = 158467542575633280L; private static final long serialVersionUID = 158467542575633280L;
} }
@WrapForJNI
private static native void notifySmsReceived(String aSender, String aBody, int aMessageClass, long aTimestamp); private static native void notifySmsReceived(String aSender, String aBody, int aMessageClass, long aTimestamp);
@WrapForJNI
private static native void notifySmsSent(int aId, String aReceiver, String aBody, long aTimestamp, int aRequestId); private static native void notifySmsSent(int aId, String aReceiver, String aBody, long aTimestamp, int aRequestId);
@WrapForJNI
private static native void notifySmsDelivery(int aId, int aDeliveryStatus, String aReceiver, String aBody, long aTimestamp); private static native void notifySmsDelivery(int aId, int aDeliveryStatus, String aReceiver, String aBody, long aTimestamp);
@WrapForJNI
private static native void notifySmsSendFailed(int aError, int aRequestId); private static native void notifySmsSendFailed(int aError, int aRequestId);
private static native void notifyGetSms(int aId, int aDeliveryStatus, String aReceiver, String aSender, String aBody, long aTimestamp, int aRequestId); @WrapForJNI
private static native void notifyGetSms(int aId, int aDeliveryStatus, String aReceiver, String aSender, String aBody, long aTimestamp, boolean aRead, int aRequestId);
@WrapForJNI
private static native void notifyGetSmsFailed(int aError, int aRequestId); private static native void notifyGetSmsFailed(int aError, int aRequestId);
@WrapForJNI
private static native void notifySmsDeleted(boolean aDeleted, int aRequestId); private static native void notifySmsDeleted(boolean aDeleted, int aRequestId);
@WrapForJNI
private static native void notifySmsDeleteFailed(int aError, int aRequestId); private static native void notifySmsDeleteFailed(int aError, int aRequestId);
private static native void notifyNoMessageInList(int aRequestId); @WrapForJNI
private static native void notifyListCreated(int aListId, int aMessageId, int aDeliveryStatus, String aReceiver, String aSender, String aBody, long aTimestamp, int aRequestId); private static native void notifyCursorError(int aError, int aRequestId);
private static native void notifyGotNextMessage(int aMessageId, int aDeliveryStatus, String aReceiver, String aSender, String aBody, long aTimestamp, int aRequestId); @WrapForJNI
private static native void notifyReadingMessageListFailed(int aError, int aRequestId); private static native void notifyThreadCursorResult(long aId, String aLastMessageSubject, String aBody, long aUnreadCount, Object[] aParticipants, long aTimestamp, String aLastMessageType, int aRequestId);
@WrapForJNI
private static native void notifyMessageCursorResult(int aMessageId, int aDeliveryStatus, String aReceiver, String aSender, String aBody, long aTimestamp, long aThreadId, boolean aRead, int aRequestId);
@WrapForJNI
private static native void notifyCursorDone(int aRequestId);
} }

View File

@@ -31,9 +31,10 @@ public class SmsManager {
void send(String aNumber, String aMessage, int aRequestId); void send(String aNumber, String aMessage, int aRequestId);
void getMessage(int aMessageId, int aRequestId); void getMessage(int aMessageId, int aRequestId);
void deleteMessage(int aMessageId, int aRequestId); void deleteMessage(int aMessageId, int aRequestId);
void createMessageList(long aStartDate, long aEndDate, String[] aNumbers, int aNumbersCount, String aDelivery, boolean aHasRead, boolean aRead, long aThreadId, boolean aReverse, int aRequestId); void createMessageCursor(long aStartDate, long aEndDate, String[] aNumbers, int aNumbersCount, String aDelivery, boolean aHasRead, boolean aRead, boolean aHasThreadId, long aThreadId, boolean aReverse, int aRequestId);
void getNextMessageInList(int aListId, int aRequestId); void createThreadCursor(int aRequestId);
void clearMessageList(int aListId); void getNextThread(int aRequestId);
void getNextMessage(int aRequestId);
} }
} }

View File

@@ -1101,52 +1101,91 @@ AndroidBridge::DeleteMessage(int32_t aMessageId, nsIMobileMessageCallback* aRequ
GeckoAppShell::DeleteMessageWrapper(aMessageId, requestId); GeckoAppShell::DeleteMessageWrapper(aMessageId, requestId);
} }
void NS_IMPL_ISUPPORTS0(MessageCursorContinueCallback)
AndroidBridge::CreateMessageList(const dom::mobilemessage::SmsFilterData& aFilter, bool aReverse,
nsIMobileMessageCallback* aRequest) NS_IMETHODIMP
MessageCursorContinueCallback::HandleContinue()
{ {
ALOG_BRIDGE("AndroidBridge::CreateMessageList"); GeckoAppShell::GetNextMessageWrapper(mRequestId);
return NS_OK;
}
already_AddRefed<nsICursorContinueCallback>
AndroidBridge::CreateMessageCursor(bool aHasStartDate,
uint64_t aStartDate,
bool aHasEndDate,
uint64_t aEndDate,
const char16_t** aNumbers,
uint32_t aNumbersCount,
const nsAString& aDelivery,
bool aHasRead,
bool aRead,
bool aHasThreadId,
uint64_t aThreadId,
bool aReverse,
nsIMobileMessageCursorCallback* aRequest)
{
ALOG_BRIDGE("AndroidBridge::CreateMessageCursor");
JNIEnv* const env = jni::GetGeckoThreadEnv(); JNIEnv* const env = jni::GetGeckoThreadEnv();
uint32_t requestId; uint32_t requestId;
if (!QueueSmsRequest(aRequest, &requestId)) if (!QueueSmsCursorRequest(aRequest, &requestId))
return; return nullptr;
AutoLocalJNIFrame jniFrame(env, 2); AutoLocalJNIFrame jniFrame(env, 2);
jobjectArray numbers = jobjectArray numbers =
(jobjectArray)env->NewObjectArray(aFilter.numbers().Length(), (jobjectArray)env->NewObjectArray(aNumbersCount,
jStringClass, jStringClass,
NewJavaString(&jniFrame, EmptyString())); NewJavaString(&jniFrame, EmptyString()));
for (uint32_t i = 0; i < aFilter.numbers().Length(); ++i) { for (uint32_t i = 0; i < aNumbersCount; ++i) {
jstring elem = NewJavaString(&jniFrame, aFilter.numbers()[i]); jstring elem = NewJavaString(&jniFrame, nsDependentString(aNumbers[i]));
env->SetObjectArrayElement(numbers, i, elem); env->SetObjectArrayElement(numbers, i, elem);
env->DeleteLocalRef(elem); env->DeleteLocalRef(elem);
} }
int64_t startDate = aFilter.hasStartDate() ? aFilter.startDate() : -1; int64_t startDate = aHasStartDate ? aStartDate : -1;
int64_t endDate = aFilter.hasEndDate() ? aFilter.endDate() : -1; int64_t endDate = aHasEndDate ? aEndDate : -1;
GeckoAppShell::CreateMessageListWrapper(startDate, endDate, GeckoAppShell::CreateMessageCursorWrapper(startDate, endDate,
ObjectArray::Ref::From(numbers), ObjectArray::Ref::From(numbers),
aFilter.numbers().Length(), aNumbersCount,
aFilter.delivery(), aDelivery,
aFilter.hasRead(), aFilter.read(), aHasRead, aRead,
aFilter.threadId(), aHasThreadId, aThreadId,
aReverse, requestId); aReverse,
requestId);
nsCOMPtr<nsICursorContinueCallback> callback =
new MessageCursorContinueCallback(requestId);
return callback.forget();
} }
void NS_IMPL_ISUPPORTS0(ThreadCursorContinueCallback)
AndroidBridge::GetNextMessageInList(int32_t aListId, nsIMobileMessageCallback* aRequest)
NS_IMETHODIMP
ThreadCursorContinueCallback::HandleContinue()
{ {
ALOG_BRIDGE("AndroidBridge::GetNextMessageInList"); GeckoAppShell::GetNextThreadWrapper(mRequestId);
return NS_OK;
}
already_AddRefed<nsICursorContinueCallback>
AndroidBridge::CreateThreadCursor(nsIMobileMessageCursorCallback* aRequest)
{
ALOG_BRIDGE("AndroidBridge::CreateThreadCursor");
uint32_t requestId; uint32_t requestId;
if (!QueueSmsRequest(aRequest, &requestId)) if (!QueueSmsCursorRequest(aRequest, &requestId)) {
return; return nullptr;
}
GeckoAppShell::GetNextMessageInListWrapper(aListId, requestId); GeckoAppShell::CreateThreadCursorWrapper(requestId);
nsCOMPtr<nsICursorContinueCallback> callback =
new ThreadCursorContinueCallback(requestId);
return callback.forget();
} }
bool bool
@@ -1184,6 +1223,57 @@ AndroidBridge::DequeueSmsRequest(uint32_t aRequestId)
return mSmsRequests[aRequestId].forget(); return mSmsRequests[aRequestId].forget();
} }
bool
AndroidBridge::QueueSmsCursorRequest(nsIMobileMessageCursorCallback* aRequest,
uint32_t* aRequestIdOut)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
MOZ_ASSERT(aRequest && aRequestIdOut);
const uint32_t length = mSmsCursorRequests.Length();
for (uint32_t i = 0; i < length; i++) {
if (!(mSmsCursorRequests)[i]) {
(mSmsCursorRequests)[i] = aRequest;
*aRequestIdOut = i;
return true;
}
}
mSmsCursorRequests.AppendElement(aRequest);
// After AppendElement(), previous `length` points to the new tail element.
*aRequestIdOut = length;
return true;
}
nsCOMPtr<nsIMobileMessageCursorCallback>
AndroidBridge::GetSmsCursorRequest(uint32_t aRequestId)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
MOZ_ASSERT(aRequestId < mSmsCursorRequests.Length());
if (aRequestId >= mSmsCursorRequests.Length()) {
return nullptr;
}
// TODO: remove on final dequeue
return mSmsCursorRequests[aRequestId];
}
already_AddRefed<nsIMobileMessageCursorCallback>
AndroidBridge::DequeueSmsCursorRequest(uint32_t aRequestId)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
MOZ_ASSERT(aRequestId < mSmsCursorRequests.Length());
if (aRequestId >= mSmsCursorRequests.Length()) {
return nullptr;
}
// TODO: remove on final dequeue
return mSmsCursorRequests[aRequestId].forget();
}
void void
AndroidBridge::GetCurrentNetworkInformation(hal::NetworkInformation* aNetworkInfo) AndroidBridge::GetCurrentNetworkInformation(hal::NetworkInformation* aNetworkInfo)
{ {

View File

@@ -25,6 +25,8 @@
#include "nsIAndroidBridge.h" #include "nsIAndroidBridge.h"
#include "nsIMobileMessageCallback.h" #include "nsIMobileMessageCallback.h"
#include "nsIMobileMessageCursorCallback.h"
#include "nsIDOMDOMCursor.h"
#include "mozilla/Likely.h" #include "mozilla/Likely.h"
#include "mozilla/StaticPtr.h" #include "mozilla/StaticPtr.h"
@@ -74,15 +76,6 @@ typedef struct AndroidSystemColors {
nscolor panelColorBackground; nscolor panelColorBackground;
} AndroidSystemColors; } AndroidSystemColors;
class nsFilePickerCallback : nsISupports {
public:
NS_DECL_THREADSAFE_ISUPPORTS
virtual void handleResult(nsAString& filePath) = 0;
nsFilePickerCallback() {}
protected:
virtual ~nsFilePickerCallback() {}
};
class DelayedTask { class DelayedTask {
public: public:
DelayedTask(Task* aTask, int aDelayMs) { DelayedTask(Task* aTask, int aDelayMs) {
@@ -108,6 +101,42 @@ private:
mozilla::TimeStamp mRunTime; mozilla::TimeStamp mRunTime;
}; };
class ThreadCursorContinueCallback : public nsICursorContinueCallback
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSICURSORCONTINUECALLBACK
ThreadCursorContinueCallback(int aRequestId)
: mRequestId(aRequestId)
{
}
private:
virtual ~ThreadCursorContinueCallback()
{
}
int mRequestId;
};
class MessageCursorContinueCallback : public nsICursorContinueCallback
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSICURSORCONTINUECALLBACK
MessageCursorContinueCallback(int aRequestId)
: mRequestId(aRequestId)
{
}
private:
virtual ~MessageCursorContinueCallback()
{
}
int mRequestId;
};
class AndroidBridge final class AndroidBridge final
{ {
public: public:
@@ -241,10 +270,25 @@ public:
nsIMobileMessageCallback* aRequest); nsIMobileMessageCallback* aRequest);
void GetMessage(int32_t aMessageId, nsIMobileMessageCallback* aRequest); void GetMessage(int32_t aMessageId, nsIMobileMessageCallback* aRequest);
void DeleteMessage(int32_t aMessageId, nsIMobileMessageCallback* aRequest); void DeleteMessage(int32_t aMessageId, nsIMobileMessageCallback* aRequest);
void CreateMessageList(const dom::mobilemessage::SmsFilterData& aFilter, already_AddRefed<nsICursorContinueCallback>
bool aReverse, nsIMobileMessageCallback* aRequest); CreateMessageCursor(bool aHasStartDate,
void GetNextMessageInList(int32_t aListId, nsIMobileMessageCallback* aRequest); uint64_t aStartDate,
bool aHasEndDate,
uint64_t aEndDate,
const char16_t** aNumbers,
uint32_t aNumbersCount,
const nsAString& aDelivery,
bool aHasRead,
bool aRead,
bool aHasThreadId,
uint64_t aThreadId,
bool aReverse,
nsIMobileMessageCursorCallback* aRequest);
already_AddRefed<nsICursorContinueCallback>
CreateThreadCursor(nsIMobileMessageCursorCallback* aRequest);
already_AddRefed<nsIMobileMessageCallback> DequeueSmsRequest(uint32_t aRequestId); already_AddRefed<nsIMobileMessageCallback> DequeueSmsRequest(uint32_t aRequestId);
nsCOMPtr<nsIMobileMessageCursorCallback> GetSmsCursorRequest(uint32_t aRequestId);
already_AddRefed<nsIMobileMessageCursorCallback> DequeueSmsCursorRequest(uint32_t aRequestId);
void GetCurrentNetworkInformation(hal::NetworkInformation* aNetworkInfo); void GetCurrentNetworkInformation(hal::NetworkInformation* aNetworkInfo);
@@ -313,7 +357,8 @@ protected:
static pthread_t sJavaUiThread; static pthread_t sJavaUiThread;
static AndroidBridge* sBridge; static AndroidBridge* sBridge;
nsTArray<nsCOMPtr<nsIMobileMessageCallback> > mSmsRequests; nsTArray<nsCOMPtr<nsIMobileMessageCallback>> mSmsRequests;
nsTArray<nsCOMPtr<nsIMobileMessageCursorCallback>> mSmsCursorRequests;
widget::GeckoLayerClient::GlobalRef mLayerClient; widget::GeckoLayerClient::GlobalRef mLayerClient;
@@ -334,6 +379,7 @@ protected:
int mAPIVersion; int mAPIVersion;
bool QueueSmsRequest(nsIMobileMessageCallback* aRequest, uint32_t* aRequestIdOut); bool QueueSmsRequest(nsIMobileMessageCallback* aRequest, uint32_t* aRequestIdOut);
bool QueueSmsCursorRequest(nsIMobileMessageCursorCallback* aRequest, uint32_t* aRequestIdOut);
// intput stream // intput stream
jclass jReadableByteChannel; jclass jReadableByteChannel;

View File

@@ -33,20 +33,13 @@
#include "mozilla/MathAlgorithms.h" #include "mozilla/MathAlgorithms.h"
#include "mozilla/UniquePtr.h" #include "mozilla/UniquePtr.h"
#include "mozilla/dom/SmsMessage.h"
#include "mozilla/dom/mobilemessage/Constants.h"
#include "mozilla/dom/mobilemessage/Types.h"
#include "mozilla/dom/mobilemessage/PSms.h"
#include "mozilla/dom/mobilemessage/SmsParent.h"
#include "mozilla/layers/APZCTreeManager.h" #include "mozilla/layers/APZCTreeManager.h"
#include "nsIMobileMessageDatabaseService.h"
#include "nsPluginInstanceOwner.h" #include "nsPluginInstanceOwner.h"
#include "AndroidSurfaceTexture.h" #include "AndroidSurfaceTexture.h"
#include "nsMemoryPressure.h" #include "nsMemoryPressure.h"
using namespace mozilla; using namespace mozilla;
using namespace mozilla::dom; using namespace mozilla::dom;
using namespace mozilla::dom::mobilemessage;
using namespace mozilla::layers; using namespace mozilla::layers;
using namespace mozilla::widget; using namespace mozilla::widget;
using namespace mozilla::widget::android; using namespace mozilla::widget::android;
@@ -164,499 +157,6 @@ Java_org_mozilla_gecko_GeckoAppShell_notifyBatteryChange(JNIEnv* jenv, jclass,
NS_DispatchToMainThread(runnable); NS_DispatchToMainThread(runnable);
} }
#ifdef MOZ_WEBSMS_BACKEND
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoSmsManager_notifySmsReceived(JNIEnv* jenv, jclass,
jstring aSender,
jstring aBody,
jint aMessageClass,
jlong aTimestamp)
{
class NotifySmsReceivedRunnable : public nsRunnable {
public:
NotifySmsReceivedRunnable(const SmsMessageData& aMessageData)
: mMessageData(aMessageData)
{}
NS_IMETHODIMP Run() {
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (!obs) {
return NS_OK;
}
nsCOMPtr<nsIDOMMozSmsMessage> message = new SmsMessage(mMessageData);
obs->NotifyObservers(message, kSmsReceivedObserverTopic, nullptr);
return NS_OK;
}
private:
SmsMessageData mMessageData;
};
// TODO Need to correct the message `threadId` parameter value. Bug 859098
SmsMessageData message(0, 0, eDeliveryState_Received, eDeliveryStatus_Success,
nsJNIString(aSender, jenv), EmptyString(),
nsJNIString(aBody, jenv),
static_cast<MessageClass>(aMessageClass),
aTimestamp, false);
nsCOMPtr<nsIRunnable> runnable = new NotifySmsReceivedRunnable(message);
NS_DispatchToMainThread(runnable);
}
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoSmsManager_notifySmsSent(JNIEnv* jenv, jclass,
jint aId,
jstring aReceiver,
jstring aBody,
jlong aTimestamp,
jint aRequestId)
{
class NotifySmsSentRunnable : public nsRunnable {
public:
NotifySmsSentRunnable(const SmsMessageData& aMessageData,
int32_t aRequestId)
: mMessageData(aMessageData)
, mRequestId(aRequestId)
{}
NS_IMETHODIMP Run() {
/*
* First, we are going to notify all SmsManager that a message has
* been sent. Then, we will notify the SmsRequest object about it.
*/
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (!obs) {
return NS_OK;
}
nsCOMPtr<nsIDOMMozSmsMessage> message = new SmsMessage(mMessageData);
obs->NotifyObservers(message, kSmsSentObserverTopic, nullptr);
nsCOMPtr<nsIMobileMessageCallback> request =
AndroidBridge::Bridge()->DequeueSmsRequest(mRequestId);
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
request->NotifyMessageSent(message);
return NS_OK;
}
private:
SmsMessageData mMessageData;
int32_t mRequestId;
};
// TODO Need to add the message `messageClass` parameter value. Bug 804476
// TODO Need to correct the message `threadId` parameter value. Bug 859098
SmsMessageData message(aId, 0, eDeliveryState_Sent, eDeliveryStatus_Pending,
EmptyString(), nsJNIString(aReceiver, jenv),
nsJNIString(aBody, jenv), eMessageClass_Normal,
aTimestamp, true);
nsCOMPtr<nsIRunnable> runnable = new NotifySmsSentRunnable(message, aRequestId);
NS_DispatchToMainThread(runnable);
}
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoSmsManager_notifySmsDelivery(JNIEnv* jenv, jclass,
jint aId,
jint aDeliveryStatus,
jstring aReceiver,
jstring aBody,
jlong aTimestamp)
{
class NotifySmsDeliveredRunnable : public nsRunnable {
public:
NotifySmsDeliveredRunnable(const SmsMessageData& aMessageData)
: mMessageData(aMessageData)
{}
NS_IMETHODIMP Run() {
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (!obs) {
return NS_OK;
}
nsCOMPtr<nsIDOMMozSmsMessage> message = new SmsMessage(mMessageData);
const char* topic = (mMessageData.deliveryStatus() == eDeliveryStatus_Success)
? kSmsDeliverySuccessObserverTopic
: kSmsDeliveryErrorObserverTopic;
obs->NotifyObservers(message, topic, nullptr);
return NS_OK;
}
private:
SmsMessageData mMessageData;
};
// TODO Need to add the message `messageClass` parameter value. Bug 804476
// TODO Need to correct the message `threadId` parameter value. Bug 859098
SmsMessageData message(aId, 0, eDeliveryState_Sent,
static_cast<DeliveryStatus>(aDeliveryStatus),
EmptyString(), nsJNIString(aReceiver, jenv),
nsJNIString(aBody, jenv), eMessageClass_Normal,
aTimestamp, true);
nsCOMPtr<nsIRunnable> runnable = new NotifySmsDeliveredRunnable(message);
NS_DispatchToMainThread(runnable);
}
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoSmsManager_notifySmsSendFailed(JNIEnv* jenv, jclass,
jint aError,
jint aRequestId)
{
class NotifySmsSendFailedRunnable : public nsRunnable {
public:
NotifySmsSendFailedRunnable(int32_t aError,
int32_t aRequestId)
: mError(aError)
, mRequestId(aRequestId)
{}
NS_IMETHODIMP Run() {
nsCOMPtr<nsIMobileMessageCallback> request =
AndroidBridge::Bridge()->DequeueSmsRequest(mRequestId);
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
request->NotifySendMessageFailed(mError);
return NS_OK;
}
private:
int32_t mError;
int32_t mRequestId;
};
nsCOMPtr<nsIRunnable> runnable =
new NotifySmsSendFailedRunnable(aError, aRequestId);
NS_DispatchToMainThread(runnable);
}
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoSmsManager_notifyGetSms(JNIEnv* jenv, jclass,
jint aId,
jint aDeliveryStatus,
jstring aReceiver,
jstring aSender,
jstring aBody,
jlong aTimestamp,
jint aRequestId)
{
class NotifyGetSmsRunnable : public nsRunnable {
public:
NotifyGetSmsRunnable(const SmsMessageData& aMessageData,
int32_t aRequestId)
: mMessageData(aMessageData)
, mRequestId(aRequestId)
{}
NS_IMETHODIMP Run() {
nsCOMPtr<nsIMobileMessageCallback> request =
AndroidBridge::Bridge()->DequeueSmsRequest(mRequestId);
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMMozSmsMessage> message = new SmsMessage(mMessageData);
request->NotifyMessageGot(message);
return NS_OK;
}
private:
SmsMessageData mMessageData;
int32_t mRequestId;
};
nsJNIString receiver = nsJNIString(aReceiver, jenv);
DeliveryState state = receiver.IsEmpty() ? eDeliveryState_Received
: eDeliveryState_Sent;
// TODO Need to add the message `read` parameter value. Bug 748391
// TODO Need to add the message `messageClass` parameter value. Bug 804476
// TODO Need to correct the message `threadId` parameter value. Bug 859098
SmsMessageData message(aId, 0, state,
static_cast<DeliveryStatus>(aDeliveryStatus),
nsJNIString(aSender, jenv), receiver,
nsJNIString(aBody, jenv), eMessageClass_Normal,
aTimestamp, true);
nsCOMPtr<nsIRunnable> runnable = new NotifyGetSmsRunnable(message, aRequestId);
NS_DispatchToMainThread(runnable);
}
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoSmsManager_notifyGetSmsFailed(JNIEnv* jenv, jclass,
jint aError,
jint aRequestId)
{
class NotifyGetSmsFailedRunnable : public nsRunnable {
public:
NotifyGetSmsFailedRunnable(int32_t aError,
int32_t aRequestId)
: mError(aError)
, mRequestId(aRequestId)
{}
NS_IMETHODIMP Run() {
nsCOMPtr<nsIMobileMessageCallback> request =
AndroidBridge::Bridge()->DequeueSmsRequest(mRequestId);
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
request->NotifyGetMessageFailed(mError);
return NS_OK;
}
private:
int32_t mError;
int32_t mRequestId;
};
nsCOMPtr<nsIRunnable> runnable =
new NotifyGetSmsFailedRunnable(aError, aRequestId);
NS_DispatchToMainThread(runnable);
}
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoSmsManager_notifySmsDeleted(JNIEnv* jenv, jclass,
jboolean aDeleted,
jint aRequestId)
{
class NotifySmsDeletedRunnable : public nsRunnable {
public:
NotifySmsDeletedRunnable(bool aDeleted, int32_t aRequestId)
: mDeleted(aDeleted)
, mRequestId(aRequestId)
{}
NS_IMETHODIMP Run() {
nsCOMPtr<nsIMobileMessageCallback> request =
AndroidBridge::Bridge()->DequeueSmsRequest(mRequestId);
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
// For android, we support only single SMS deletion.
request->NotifyMessageDeleted(&mDeleted, 1);
return NS_OK;
}
private:
bool mDeleted;
int32_t mRequestId;
};
nsCOMPtr<nsIRunnable> runnable =
new NotifySmsDeletedRunnable(aDeleted, aRequestId);
NS_DispatchToMainThread(runnable);
}
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoSmsManager_notifySmsDeleteFailed(JNIEnv* jenv, jclass,
jint aError,
jint aRequestId)
{
class NotifySmsDeleteFailedRunnable : public nsRunnable {
public:
NotifySmsDeleteFailedRunnable(int32_t aError,
int32_t aRequestId)
: mError(aError)
, mRequestId(aRequestId)
{}
NS_IMETHODIMP Run() {
nsCOMPtr<nsIMobileMessageCallback> request =
AndroidBridge::Bridge()->DequeueSmsRequest(mRequestId);
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
request->NotifyDeleteMessageFailed(mError);
return NS_OK;
}
private:
int32_t mError;
int32_t mRequestId;
};
nsCOMPtr<nsIRunnable> runnable =
new NotifySmsDeleteFailedRunnable(aError, aRequestId);
NS_DispatchToMainThread(runnable);
}
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoSmsManager_notifyNoMessageInList(JNIEnv* jenv, jclass,
jint aRequestId)
{
class NotifyNoMessageInListRunnable : public nsRunnable {
public:
NotifyNoMessageInListRunnable(int32_t aRequestId)
: mRequestId(aRequestId)
{}
NS_IMETHODIMP Run() {
nsCOMPtr<nsIMobileMessageCallback> request =
AndroidBridge::Bridge()->DequeueSmsRequest(mRequestId);
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
request->NotifyNoMessageInList();
return NS_OK;
}
private:
int32_t mRequestId;
};
nsCOMPtr<nsIRunnable> runnable =
new NotifyNoMessageInListRunnable(aRequestId);
NS_DispatchToMainThread(runnable);
}
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoSmsManager_notifyListCreated(JNIEnv* jenv, jclass,
jint aListId,
jint aMessageId,
jint aDeliveryStatus,
jstring aReceiver,
jstring aSender,
jstring aBody,
jlong aTimestamp,
jint aRequestId)
{
class NotifyCreateMessageListRunnable : public nsRunnable {
public:
NotifyCreateMessageListRunnable(int32_t aListId,
const SmsMessageData& aMessageData,
int32_t aRequestId)
: mListId(aListId)
, mMessageData(aMessageData)
, mRequestId(aRequestId)
{}
NS_IMETHODIMP Run() {
nsCOMPtr<nsIMobileMessageCallback> request =
AndroidBridge::Bridge()->DequeueSmsRequest(mRequestId);
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMMozSmsMessage> message = new SmsMessage(mMessageData);
request->NotifyMessageListCreated(mListId, message);
return NS_OK;
}
private:
int32_t mListId;
SmsMessageData mMessageData;
int32_t mRequestId;
};
nsJNIString receiver = nsJNIString(aReceiver, jenv);
DeliveryState state = receiver.IsEmpty() ? eDeliveryState_Received
: eDeliveryState_Sent;
// TODO Need to add the message `read` parameter value. Bug 748391
// TODO Need to add the message `messageClass` parameter value. Bug 804476
// TODO Need to correct the message `threadId` parameter value. Bug 859098
SmsMessageData message(aMessageId, 0, state,
static_cast<DeliveryStatus>(aDeliveryStatus),
nsJNIString(aSender, jenv), receiver,
nsJNIString(aBody, jenv), eMessageClass_Normal,
aTimestamp, true);
nsCOMPtr<nsIRunnable> runnable =
new NotifyCreateMessageListRunnable(aListId, message, aRequestId);
NS_DispatchToMainThread(runnable);
}
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoSmsManager_notifyGotNextMessage(JNIEnv* jenv, jclass,
jint aMessageId,
jint aDeliveryStatus,
jstring aReceiver,
jstring aSender,
jstring aBody,
jlong aTimestamp,
jint aRequestId)
{
class NotifyGotNextMessageRunnable : public nsRunnable {
public:
NotifyGotNextMessageRunnable(const SmsMessageData& aMessageData,
int32_t aRequestId)
: mMessageData(aMessageData)
, mRequestId(aRequestId)
{}
NS_IMETHODIMP Run() {
nsCOMPtr<nsIMobileMessageCallback> request =
AndroidBridge::Bridge()->DequeueSmsRequest(mRequestId);
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMMozSmsMessage> message = new SmsMessage(mMessageData);
request->NotifyNextMessageInListGot(message);
return NS_OK;
}
private:
SmsMessageData mMessageData;
int32_t mRequestId;
};
nsJNIString receiver = nsJNIString(aReceiver, jenv);
DeliveryState state = receiver.IsEmpty() ? eDeliveryState_Received
: eDeliveryState_Sent;
// TODO Need to add the message `read` parameter value. Bug 748391
// TODO Need to add the message `messageClass` parameter value. Bug 804476
// TODO Need to correct the message `threadId` parameter value. Bug 859098
SmsMessageData message(aMessageId, 0, state,
static_cast<DeliveryStatus>(aDeliveryStatus),
nsJNIString(aSender, jenv), receiver,
nsJNIString(aBody, jenv), eMessageClass_Normal,
aTimestamp, true);
nsCOMPtr<nsIRunnable> runnable =
new NotifyGotNextMessageRunnable(message, aRequestId);
NS_DispatchToMainThread(runnable);
}
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoSmsManager_notifyReadingMessageListFailed(JNIEnv* jenv, jclass,
jint aError,
jint aRequestId)
{
class NotifyReadListFailedRunnable : public nsRunnable {
public:
NotifyReadListFailedRunnable(int32_t aError,
int32_t aRequestId)
: mError(aError)
, mRequestId(aRequestId)
{}
NS_IMETHODIMP Run() {
nsCOMPtr<nsIMobileMessageCallback> request =
AndroidBridge::Bridge()->DequeueSmsRequest(mRequestId);
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
request->NotifyReadMessageListFailed(mError);
return NS_OK;
}
private:
int32_t mError;
int32_t mRequestId;
};
nsCOMPtr<nsIRunnable> runnable =
new NotifyReadListFailedRunnable(aError, aRequestId);
NS_DispatchToMainThread(runnable);
}
#endif // MOZ_WEBSMS_BACKEND
NS_EXPORT void JNICALL NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoAppShell_invalidateAndScheduleComposite(JNIEnv*, jclass) Java_org_mozilla_gecko_GeckoAppShell_invalidateAndScheduleComposite(JNIEnv*, jclass)
{ {
@@ -675,31 +175,6 @@ Java_org_mozilla_gecko_GeckoAppShell_computeRenderIntegrity(JNIEnv*, jclass)
return nsWindow::ComputeRenderIntegrity(); return nsWindow::ComputeRenderIntegrity();
} }
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoAppShell_notifyFilePickerResult(JNIEnv* jenv, jclass, jstring filePath, jlong callback)
{
class NotifyFilePickerResultRunnable : public nsRunnable {
public:
NotifyFilePickerResultRunnable(nsString& fileDir, long callback) :
mFileDir(fileDir), mCallback(callback) {}
NS_IMETHODIMP Run() {
nsFilePickerCallback* handler = (nsFilePickerCallback*)mCallback;
handler->handleResult(mFileDir);
handler->Release();
return NS_OK;
}
private:
nsString mFileDir;
long mCallback;
};
nsString path = nsJNIString(filePath, jenv);
nsCOMPtr<nsIRunnable> runnable =
new NotifyFilePickerResultRunnable(path, (long)callback);
NS_DispatchToMainThread(runnable);
}
#define MAX_LOCK_ATTEMPTS 10 #define MAX_LOCK_ATTEMPTS 10
static bool LockWindowWithRetry(void* window, unsigned char** bits, int* width, int* height, int* format, int* stride) static bool LockWindowWithRetry(void* window, unsigned char** bits, int* width, int* height, int* format, int* stride)
@@ -873,7 +348,7 @@ Java_org_mozilla_gecko_gfx_NativePanZoomController_init(JNIEnv* env, jobject ins
NativePanZoomController::LocalRef oldRef = NativePanZoomController::LocalRef oldRef =
AndroidContentController::SetNativePanZoomController(newRef); AndroidContentController::SetNativePanZoomController(newRef);
MOZ_ASSERT(!oldRef, "Registering a new NPZC when we already have one"); // MOZ_ASSERT(!oldRef, "Registering a new NPZC when we already have one");
} }
NS_EXPORT jboolean JNICALL NS_EXPORT jboolean JNICALL

View File

@@ -66,6 +66,65 @@ public:
template<class Impl> template<class Impl>
constexpr JNINativeMethod GeckoJavaSampler::Natives<Impl>::methods[]; constexpr JNINativeMethod GeckoJavaSampler::Natives<Impl>::methods[];
template<class Impl>
class GeckoSmsManager::Natives : public mozilla::jni::NativeImpl<GeckoSmsManager, Impl>
{
public:
static constexpr JNINativeMethod methods[] = {
mozilla::jni::MakeNativeMethod<GeckoSmsManager::NotifyCursorDone_t>(
mozilla::jni::NativeStub<GeckoSmsManager::NotifyCursorDone_t, Impl>
::template Wrap<&Impl::NotifyCursorDone>),
mozilla::jni::MakeNativeMethod<GeckoSmsManager::NotifyCursorError_t>(
mozilla::jni::NativeStub<GeckoSmsManager::NotifyCursorError_t, Impl>
::template Wrap<&Impl::NotifyCursorError>),
mozilla::jni::MakeNativeMethod<GeckoSmsManager::NotifyGetSms_t>(
mozilla::jni::NativeStub<GeckoSmsManager::NotifyGetSms_t, Impl>
::template Wrap<&Impl::NotifyGetSms>),
mozilla::jni::MakeNativeMethod<GeckoSmsManager::NotifyGetSmsFailed_t>(
mozilla::jni::NativeStub<GeckoSmsManager::NotifyGetSmsFailed_t, Impl>
::template Wrap<&Impl::NotifyGetSmsFailed>),
mozilla::jni::MakeNativeMethod<GeckoSmsManager::NotifyMessageCursorResult_t>(
mozilla::jni::NativeStub<GeckoSmsManager::NotifyMessageCursorResult_t, Impl>
::template Wrap<&Impl::NotifyMessageCursorResult>),
mozilla::jni::MakeNativeMethod<GeckoSmsManager::NotifySmsDeleteFailed_t>(
mozilla::jni::NativeStub<GeckoSmsManager::NotifySmsDeleteFailed_t, Impl>
::template Wrap<&Impl::NotifySmsDeleteFailed>),
mozilla::jni::MakeNativeMethod<GeckoSmsManager::NotifySmsDeleted_t>(
mozilla::jni::NativeStub<GeckoSmsManager::NotifySmsDeleted_t, Impl>
::template Wrap<&Impl::NotifySmsDeleted>),
mozilla::jni::MakeNativeMethod<GeckoSmsManager::NotifySmsDelivery_t>(
mozilla::jni::NativeStub<GeckoSmsManager::NotifySmsDelivery_t, Impl>
::template Wrap<&Impl::NotifySmsDelivery>),
mozilla::jni::MakeNativeMethod<GeckoSmsManager::NotifySmsReceived_t>(
mozilla::jni::NativeStub<GeckoSmsManager::NotifySmsReceived_t, Impl>
::template Wrap<&Impl::NotifySmsReceived>),
mozilla::jni::MakeNativeMethod<GeckoSmsManager::NotifySmsSendFailed_t>(
mozilla::jni::NativeStub<GeckoSmsManager::NotifySmsSendFailed_t, Impl>
::template Wrap<&Impl::NotifySmsSendFailed>),
mozilla::jni::MakeNativeMethod<GeckoSmsManager::NotifySmsSent_t>(
mozilla::jni::NativeStub<GeckoSmsManager::NotifySmsSent_t, Impl>
::template Wrap<&Impl::NotifySmsSent>),
mozilla::jni::MakeNativeMethod<GeckoSmsManager::NotifyThreadCursorResult_t>(
mozilla::jni::NativeStub<GeckoSmsManager::NotifyThreadCursorResult_t, Impl>
::template Wrap<&Impl::NotifyThreadCursorResult>)
};
};
template<class Impl>
constexpr JNINativeMethod GeckoSmsManager::Natives<Impl>::methods[];
template<class Impl> template<class Impl>
class GeckoThread::Natives : public mozilla::jni::NativeImpl<GeckoThread, Impl> class GeckoThread::Natives : public mozilla::jni::NativeImpl<GeckoThread, Impl>
{ {

View File

@@ -78,14 +78,6 @@ auto GeckoAppShell::CheckURIVisited(mozilla::jni::String::Param a0) -> void
return mozilla::jni::Method<CheckURIVisited_t>::Call(nullptr, nullptr, a0); return mozilla::jni::Method<CheckURIVisited_t>::Call(nullptr, nullptr, a0);
} }
constexpr char GeckoAppShell::ClearMessageList_t::name[];
constexpr char GeckoAppShell::ClearMessageList_t::signature[];
auto GeckoAppShell::ClearMessageList(int32_t a0) -> void
{
return mozilla::jni::Method<ClearMessageList_t>::Call(nullptr, nullptr, a0);
}
constexpr char GeckoAppShell::CloseCamera_t::name[]; constexpr char GeckoAppShell::CloseCamera_t::name[];
constexpr char GeckoAppShell::CloseCamera_t::signature[]; constexpr char GeckoAppShell::CloseCamera_t::signature[];
@@ -118,12 +110,12 @@ auto GeckoAppShell::CreateInputStream(mozilla::jni::Object::Param a0) -> mozilla
return mozilla::jni::Method<CreateInputStream_t>::Call(nullptr, nullptr, a0); return mozilla::jni::Method<CreateInputStream_t>::Call(nullptr, nullptr, a0);
} }
constexpr char GeckoAppShell::CreateMessageListWrapper_t::name[]; constexpr char GeckoAppShell::CreateMessageCursorWrapper_t::name[];
constexpr char GeckoAppShell::CreateMessageListWrapper_t::signature[]; constexpr char GeckoAppShell::CreateMessageCursorWrapper_t::signature[];
auto GeckoAppShell::CreateMessageListWrapper(int64_t a0, int64_t a1, mozilla::jni::ObjectArray::Param a2, int32_t a3, mozilla::jni::String::Param a4, bool a5, bool a6, int64_t a7, bool a8, int32_t a9) -> void auto GeckoAppShell::CreateMessageCursorWrapper(int64_t a0, int64_t a1, mozilla::jni::ObjectArray::Param a2, int32_t a3, mozilla::jni::String::Param a4, bool a5, bool a6, bool a7, int64_t a8, bool a9, int32_t a10) -> void
{ {
return mozilla::jni::Method<CreateMessageListWrapper_t>::Call(nullptr, nullptr, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); return mozilla::jni::Method<CreateMessageCursorWrapper_t>::Call(nullptr, nullptr, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
} }
constexpr char GeckoAppShell::CreateShortcut_t::name[]; constexpr char GeckoAppShell::CreateShortcut_t::name[];
@@ -134,6 +126,14 @@ auto GeckoAppShell::CreateShortcut(mozilla::jni::String::Param a0, mozilla::jni:
return mozilla::jni::Method<CreateShortcut_t>::Call(nullptr, nullptr, a0, a1, a2); return mozilla::jni::Method<CreateShortcut_t>::Call(nullptr, nullptr, a0, a1, a2);
} }
constexpr char GeckoAppShell::CreateThreadCursorWrapper_t::name[];
constexpr char GeckoAppShell::CreateThreadCursorWrapper_t::signature[];
auto GeckoAppShell::CreateThreadCursorWrapper(int32_t a0) -> void
{
return mozilla::jni::Method<CreateThreadCursorWrapper_t>::Call(nullptr, nullptr, a0);
}
constexpr char GeckoAppShell::DeleteMessageWrapper_t::name[]; constexpr char GeckoAppShell::DeleteMessageWrapper_t::name[];
constexpr char GeckoAppShell::DeleteMessageWrapper_t::signature[]; constexpr char GeckoAppShell::DeleteMessageWrapper_t::signature[];
@@ -366,12 +366,20 @@ auto GeckoAppShell::GetMimeTypeFromExtensionsWrapper(mozilla::jni::String::Param
return mozilla::jni::Method<GetMimeTypeFromExtensionsWrapper_t>::Call(nullptr, nullptr, a0); return mozilla::jni::Method<GetMimeTypeFromExtensionsWrapper_t>::Call(nullptr, nullptr, a0);
} }
constexpr char GeckoAppShell::GetNextMessageInListWrapper_t::name[]; constexpr char GeckoAppShell::GetNextMessageWrapper_t::name[];
constexpr char GeckoAppShell::GetNextMessageInListWrapper_t::signature[]; constexpr char GeckoAppShell::GetNextMessageWrapper_t::signature[];
auto GeckoAppShell::GetNextMessageInListWrapper(int32_t a0, int32_t a1) -> void auto GeckoAppShell::GetNextMessageWrapper(int32_t a0) -> void
{ {
return mozilla::jni::Method<GetNextMessageInListWrapper_t>::Call(nullptr, nullptr, a0, a1); return mozilla::jni::Method<GetNextMessageWrapper_t>::Call(nullptr, nullptr, a0);
}
constexpr char GeckoAppShell::GetNextThreadWrapper_t::name[];
constexpr char GeckoAppShell::GetNextThreadWrapper_t::signature[];
auto GeckoAppShell::GetNextThreadWrapper(int32_t a0) -> void
{
return mozilla::jni::Method<GetNextThreadWrapper_t>::Call(nullptr, nullptr, a0);
} }
constexpr char GeckoAppShell::GetProxyForURIWrapper_t::name[]; constexpr char GeckoAppShell::GetProxyForURIWrapper_t::name[];
@@ -795,6 +803,44 @@ auto GeckoJavaSampler::UnpauseJavaProfiling() -> void
return mozilla::jni::Method<UnpauseJavaProfiling_t>::Call(nullptr, nullptr); return mozilla::jni::Method<UnpauseJavaProfiling_t>::Call(nullptr, nullptr);
} }
constexpr char GeckoSmsManager::name[];
constexpr char GeckoSmsManager::NotifyCursorDone_t::name[];
constexpr char GeckoSmsManager::NotifyCursorDone_t::signature[];
constexpr char GeckoSmsManager::NotifyCursorError_t::name[];
constexpr char GeckoSmsManager::NotifyCursorError_t::signature[];
constexpr char GeckoSmsManager::NotifyGetSms_t::name[];
constexpr char GeckoSmsManager::NotifyGetSms_t::signature[];
constexpr char GeckoSmsManager::NotifyGetSmsFailed_t::name[];
constexpr char GeckoSmsManager::NotifyGetSmsFailed_t::signature[];
constexpr char GeckoSmsManager::NotifyMessageCursorResult_t::name[];
constexpr char GeckoSmsManager::NotifyMessageCursorResult_t::signature[];
constexpr char GeckoSmsManager::NotifySmsDeleteFailed_t::name[];
constexpr char GeckoSmsManager::NotifySmsDeleteFailed_t::signature[];
constexpr char GeckoSmsManager::NotifySmsDeleted_t::name[];
constexpr char GeckoSmsManager::NotifySmsDeleted_t::signature[];
constexpr char GeckoSmsManager::NotifySmsDelivery_t::name[];
constexpr char GeckoSmsManager::NotifySmsDelivery_t::signature[];
constexpr char GeckoSmsManager::NotifySmsReceived_t::name[];
constexpr char GeckoSmsManager::NotifySmsReceived_t::signature[];
constexpr char GeckoSmsManager::NotifySmsSendFailed_t::name[];
constexpr char GeckoSmsManager::NotifySmsSendFailed_t::signature[];
constexpr char GeckoSmsManager::NotifySmsSent_t::name[];
constexpr char GeckoSmsManager::NotifySmsSent_t::signature[];
constexpr char GeckoSmsManager::NotifyThreadCursorResult_t::name[];
constexpr char GeckoSmsManager::NotifyThreadCursorResult_t::signature[];
constexpr char GeckoThread::name[]; constexpr char GeckoThread::name[];
constexpr char GeckoThread::PumpMessageLoop_t::name[]; constexpr char GeckoThread::PumpMessageLoop_t::name[];

View File

@@ -254,24 +254,6 @@ public:
static auto CheckURIVisited(mozilla::jni::String::Param) -> void; static auto CheckURIVisited(mozilla::jni::String::Param) -> void;
public:
struct ClearMessageList_t {
typedef GeckoAppShell Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
int32_t> Args;
static constexpr char name[] = "clearMessageList";
static constexpr char signature[] =
"(I)V";
static const bool isStatic = true;
static const bool isMultithreaded = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
static auto ClearMessageList(int32_t) -> void;
public: public:
struct CloseCamera_t { struct CloseCamera_t {
typedef GeckoAppShell Owner; typedef GeckoAppShell Owner;
@@ -344,7 +326,7 @@ public:
static auto CreateInputStream(mozilla::jni::Object::Param) -> mozilla::jni::Object::LocalRef; static auto CreateInputStream(mozilla::jni::Object::Param) -> mozilla::jni::Object::LocalRef;
public: public:
struct CreateMessageListWrapper_t { struct CreateMessageCursorWrapper_t {
typedef GeckoAppShell Owner; typedef GeckoAppShell Owner;
typedef void ReturnType; typedef void ReturnType;
typedef void SetterType; typedef void SetterType;
@@ -356,19 +338,20 @@ public:
mozilla::jni::String::Param, mozilla::jni::String::Param,
bool, bool,
bool, bool,
bool,
int64_t, int64_t,
bool, bool,
int32_t> Args; int32_t> Args;
static constexpr char name[] = "createMessageList"; static constexpr char name[] = "createMessageCursor";
static constexpr char signature[] = static constexpr char signature[] =
"(JJ[Ljava/lang/String;ILjava/lang/String;ZZJZI)V"; "(JJ[Ljava/lang/String;ILjava/lang/String;ZZZJZI)V";
static const bool isStatic = true; static const bool isStatic = true;
static const bool isMultithreaded = false; static const bool isMultithreaded = false;
static const mozilla::jni::ExceptionMode exceptionMode = static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT; mozilla::jni::ExceptionMode::ABORT;
}; };
static auto CreateMessageListWrapper(int64_t, int64_t, mozilla::jni::ObjectArray::Param, int32_t, mozilla::jni::String::Param, bool, bool, int64_t, bool, int32_t) -> void; static auto CreateMessageCursorWrapper(int64_t, int64_t, mozilla::jni::ObjectArray::Param, int32_t, mozilla::jni::String::Param, bool, bool, bool, int64_t, bool, int32_t) -> void;
public: public:
struct CreateShortcut_t { struct CreateShortcut_t {
@@ -390,6 +373,24 @@ public:
static auto CreateShortcut(mozilla::jni::String::Param, mozilla::jni::String::Param, mozilla::jni::String::Param) -> void; static auto CreateShortcut(mozilla::jni::String::Param, mozilla::jni::String::Param, mozilla::jni::String::Param) -> void;
public:
struct CreateThreadCursorWrapper_t {
typedef GeckoAppShell Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
int32_t> Args;
static constexpr char name[] = "createThreadCursor";
static constexpr char signature[] =
"(I)V";
static const bool isStatic = true;
static const bool isMultithreaded = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
static auto CreateThreadCursorWrapper(int32_t) -> void;
public: public:
struct DeleteMessageWrapper_t { struct DeleteMessageWrapper_t {
typedef GeckoAppShell Owner; typedef GeckoAppShell Owner;
@@ -904,23 +905,40 @@ public:
static auto GetMimeTypeFromExtensionsWrapper(mozilla::jni::String::Param) -> mozilla::jni::String::LocalRef; static auto GetMimeTypeFromExtensionsWrapper(mozilla::jni::String::Param) -> mozilla::jni::String::LocalRef;
public: public:
struct GetNextMessageInListWrapper_t { struct GetNextMessageWrapper_t {
typedef GeckoAppShell Owner; typedef GeckoAppShell Owner;
typedef void ReturnType; typedef void ReturnType;
typedef void SetterType; typedef void SetterType;
typedef mozilla::jni::Args< typedef mozilla::jni::Args<
int32_t,
int32_t> Args; int32_t> Args;
static constexpr char name[] = "getNextMessageInList"; static constexpr char name[] = "getNextMessage";
static constexpr char signature[] = static constexpr char signature[] =
"(II)V"; "(I)V";
static const bool isStatic = true; static const bool isStatic = true;
static const bool isMultithreaded = false; static const bool isMultithreaded = false;
static const mozilla::jni::ExceptionMode exceptionMode = static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT; mozilla::jni::ExceptionMode::ABORT;
}; };
static auto GetNextMessageInListWrapper(int32_t, int32_t) -> void; static auto GetNextMessageWrapper(int32_t) -> void;
public:
struct GetNextThreadWrapper_t {
typedef GeckoAppShell Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
int32_t> Args;
static constexpr char name[] = "getNextThread";
static constexpr char signature[] =
"(I)V";
static const bool isStatic = true;
static const bool isMultithreaded = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
static auto GetNextThreadWrapper(int32_t) -> void;
public: public:
struct GetProxyForURIWrapper_t { struct GetProxyForURIWrapper_t {
@@ -1906,6 +1924,254 @@ public:
template<class Impl> class Natives; template<class Impl> class Natives;
}; };
class GeckoSmsManager : public mozilla::jni::Class<GeckoSmsManager>
{
public:
typedef mozilla::jni::Ref<GeckoSmsManager> Ref;
typedef mozilla::jni::LocalRef<GeckoSmsManager> LocalRef;
typedef mozilla::jni::GlobalRef<GeckoSmsManager> GlobalRef;
typedef const mozilla::jni::Param<GeckoSmsManager>& Param;
static constexpr char name[] =
"org/mozilla/gecko/GeckoSmsManager";
protected:
GeckoSmsManager(jobject instance) : Class(instance) {}
public:
struct NotifyCursorDone_t {
typedef GeckoSmsManager Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
int32_t> Args;
static constexpr char name[] = "notifyCursorDone";
static constexpr char signature[] =
"(I)V";
static const bool isStatic = true;
static const bool isMultithreaded = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
public:
struct NotifyCursorError_t {
typedef GeckoSmsManager Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
int32_t,
int32_t> Args;
static constexpr char name[] = "notifyCursorError";
static constexpr char signature[] =
"(II)V";
static const bool isStatic = true;
static const bool isMultithreaded = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
public:
struct NotifyGetSms_t {
typedef GeckoSmsManager Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
int32_t,
int32_t,
mozilla::jni::String::Param,
mozilla::jni::String::Param,
mozilla::jni::String::Param,
int64_t,
bool,
int32_t> Args;
static constexpr char name[] = "notifyGetSms";
static constexpr char signature[] =
"(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;JZI)V";
static const bool isStatic = true;
static const bool isMultithreaded = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
public:
struct NotifyGetSmsFailed_t {
typedef GeckoSmsManager Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
int32_t,
int32_t> Args;
static constexpr char name[] = "notifyGetSmsFailed";
static constexpr char signature[] =
"(II)V";
static const bool isStatic = true;
static const bool isMultithreaded = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
public:
struct NotifyMessageCursorResult_t {
typedef GeckoSmsManager Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
int32_t,
int32_t,
mozilla::jni::String::Param,
mozilla::jni::String::Param,
mozilla::jni::String::Param,
int64_t,
int64_t,
bool,
int32_t> Args;
static constexpr char name[] = "notifyMessageCursorResult";
static constexpr char signature[] =
"(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;JJZI)V";
static const bool isStatic = true;
static const bool isMultithreaded = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
public:
struct NotifySmsDeleteFailed_t {
typedef GeckoSmsManager Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
int32_t,
int32_t> Args;
static constexpr char name[] = "notifySmsDeleteFailed";
static constexpr char signature[] =
"(II)V";
static const bool isStatic = true;
static const bool isMultithreaded = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
public:
struct NotifySmsDeleted_t {
typedef GeckoSmsManager Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
bool,
int32_t> Args;
static constexpr char name[] = "notifySmsDeleted";
static constexpr char signature[] =
"(ZI)V";
static const bool isStatic = true;
static const bool isMultithreaded = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
public:
struct NotifySmsDelivery_t {
typedef GeckoSmsManager Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
int32_t,
int32_t,
mozilla::jni::String::Param,
mozilla::jni::String::Param,
int64_t> Args;
static constexpr char name[] = "notifySmsDelivery";
static constexpr char signature[] =
"(IILjava/lang/String;Ljava/lang/String;J)V";
static const bool isStatic = true;
static const bool isMultithreaded = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
public:
struct NotifySmsReceived_t {
typedef GeckoSmsManager Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
mozilla::jni::String::Param,
mozilla::jni::String::Param,
int32_t,
int64_t> Args;
static constexpr char name[] = "notifySmsReceived";
static constexpr char signature[] =
"(Ljava/lang/String;Ljava/lang/String;IJ)V";
static const bool isStatic = true;
static const bool isMultithreaded = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
public:
struct NotifySmsSendFailed_t {
typedef GeckoSmsManager Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
int32_t,
int32_t> Args;
static constexpr char name[] = "notifySmsSendFailed";
static constexpr char signature[] =
"(II)V";
static const bool isStatic = true;
static const bool isMultithreaded = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
public:
struct NotifySmsSent_t {
typedef GeckoSmsManager Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
int32_t,
mozilla::jni::String::Param,
mozilla::jni::String::Param,
int64_t,
int32_t> Args;
static constexpr char name[] = "notifySmsSent";
static constexpr char signature[] =
"(ILjava/lang/String;Ljava/lang/String;JI)V";
static const bool isStatic = true;
static const bool isMultithreaded = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
public:
struct NotifyThreadCursorResult_t {
typedef GeckoSmsManager Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
int64_t,
mozilla::jni::String::Param,
mozilla::jni::String::Param,
int64_t,
mozilla::jni::ObjectArray::Param,
int64_t,
mozilla::jni::String::Param,
int32_t> Args;
static constexpr char name[] = "notifyThreadCursorResult";
static constexpr char signature[] =
"(JLjava/lang/String;Ljava/lang/String;J[Ljava/lang/Object;JLjava/lang/String;I)V";
static const bool isStatic = true;
static const bool isMultithreaded = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
public:
template<class Impl> class Natives;
};
class GeckoThread : public mozilla::jni::Class<GeckoThread> class GeckoThread : public mozilla::jni::Class<GeckoThread>
{ {
public: public: