mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1057915 - 1/2: [MobileMessage] Ability to return multiple entries in getMessages/getThreads cursor.result. DOM & IPDL changes. r=smaug
This commit is contained in:
parent
7225df6731
commit
2b81c0632b
@ -8,11 +8,94 @@
|
||||
#include "nsIDOMDOMRequest.h"
|
||||
#include "nsIDOMMozSmsMessage.h"
|
||||
#include "nsIMobileMessageCallback.h"
|
||||
#include "DOMCursor.h"
|
||||
#include "nsServiceManagerUtils.h" // for do_GetService
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(MobileMessageCursor, DOMCursor,
|
||||
mPendingResults)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MobileMessageCursor)
|
||||
NS_INTERFACE_MAP_END_INHERITING(DOMCursor)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(MobileMessageCursor, DOMCursor)
|
||||
NS_IMPL_RELEASE_INHERITED(MobileMessageCursor, DOMCursor)
|
||||
|
||||
MobileMessageCursor::MobileMessageCursor(nsPIDOMWindow* aWindow,
|
||||
nsICursorContinueCallback* aCallback)
|
||||
: DOMCursor(aWindow, aCallback)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MobileMessageCursor::Continue()
|
||||
{
|
||||
// We have originally:
|
||||
//
|
||||
// DOMCursor::Continue()
|
||||
// +-> DOMCursor::Continue(ErrorResult& aRv)
|
||||
//
|
||||
// Now it becomes:
|
||||
//
|
||||
// MobileMessageCursor::Continue()
|
||||
// +-> DOMCursor::Continue()
|
||||
// +-> MobileMessageCursor::Continue(ErrorResult& aRv)
|
||||
// o-> DOMCursor::Continue(ErrorResult& aRv)
|
||||
return DOMCursor::Continue();
|
||||
}
|
||||
|
||||
void
|
||||
MobileMessageCursor::Continue(ErrorResult& aRv)
|
||||
{
|
||||
// An ordinary DOMCursor works in following flow:
|
||||
//
|
||||
// DOMCursor::Continue()
|
||||
// +-> DOMCursor::Reset()
|
||||
// +-> nsICursorContinueCallback::HandleContinue()
|
||||
// +-> nsIMobileMessageCursorCallback::NotifyCursorResult()
|
||||
// +-> DOMCursor::FireSuccess()
|
||||
//
|
||||
// With no pending result, we call to |DOMCursor::Continue()| as usual.
|
||||
if (!mPendingResults.Length()) {
|
||||
DOMCursor::Continue(aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, reset current result and fire a success event with the last
|
||||
// pending one.
|
||||
Reset();
|
||||
|
||||
nsresult rv = FireSuccessWithNextPendingResult();
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
MobileMessageCursor::FireSuccessWithNextPendingResult()
|
||||
{
|
||||
// We're going to pop the last element from mPendingResults, so it must not
|
||||
// be empty.
|
||||
MOZ_ASSERT(mPendingResults.Length());
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
if (NS_WARN_IF(!jsapi.Init(GetOwner()))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
JSContext* cx = jsapi.cx();
|
||||
JS::Rooted<JS::Value> val(cx);
|
||||
nsresult rv =
|
||||
nsContentUtils::WrapNative(cx, mPendingResults.LastElement(), &val);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mPendingResults.RemoveElementAt(mPendingResults.Length() - 1);
|
||||
|
||||
FireSuccess(val);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
namespace mobilemessage {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION(MobileMessageCursorCallback, mDOMCursor)
|
||||
@ -55,21 +138,29 @@ MobileMessageCursorCallback::NotifyCursorError(int32_t aError)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MobileMessageCursorCallback::NotifyCursorResult(nsISupports* aResult)
|
||||
MobileMessageCursorCallback::NotifyCursorResult(nsISupports** aResults,
|
||||
uint32_t aSize)
|
||||
{
|
||||
MOZ_ASSERT(mDOMCursor);
|
||||
// We should only be notified with valid results. Or, either
|
||||
// |NotifyCursorDone()| or |NotifyCursorError()| should be called instead.
|
||||
MOZ_ASSERT(aResults && *aResults && aSize);
|
||||
// There shouldn't be unexpected notifications before |Continue()| is called.
|
||||
nsTArray<nsCOMPtr<nsISupports>>& pending = mDOMCursor->mPendingResults;
|
||||
MOZ_ASSERT(pending.Length() == 0);
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
if (NS_WARN_IF(!jsapi.Init(mDOMCursor->GetOwner()))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
// Push pending results in reversed order.
|
||||
pending.SetCapacity(pending.Length() + aSize);
|
||||
while (aSize) {
|
||||
--aSize;
|
||||
pending.AppendElement(aResults[aSize]);
|
||||
}
|
||||
JSContext* cx = jsapi.cx();
|
||||
|
||||
JS::Rooted<JS::Value> wrappedResult(cx);
|
||||
nsresult rv = nsContentUtils::WrapNative(cx, aResult, &wrappedResult);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsresult rv = mDOMCursor->FireSuccessWithNextPendingResult();
|
||||
if (NS_FAILED(rv)) {
|
||||
NotifyCursorError(nsIMobileMessageCallback::INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
mDOMCursor->FireSuccess(wrappedResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,8 @@
|
||||
#ifndef mozilla_dom_mobilemessage_MobileMessageCursorCallback_h
|
||||
#define mozilla_dom_mobilemessage_MobileMessageCursorCallback_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/DOMCursor.h"
|
||||
#include "nsIMobileMessageCursorCallback.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsCOMPtr.h"
|
||||
@ -16,12 +18,46 @@ class nsICursorContinueCallback;
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class DOMCursor;
|
||||
class MobileMessageManager;
|
||||
|
||||
namespace mobilemessage {
|
||||
class MobileMessageCursorCallback;
|
||||
} // namespace mobilemessage
|
||||
|
||||
class MobileMessageCursorCallback : public nsIMobileMessageCursorCallback
|
||||
class MobileMessageCursor MOZ_FINAL : public DOMCursor
|
||||
{
|
||||
friend class mobilemessage::MobileMessageCursorCallback;
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MobileMessageCursor, DOMCursor)
|
||||
|
||||
MobileMessageCursor(nsPIDOMWindow* aWindow,
|
||||
nsICursorContinueCallback* aCallback);
|
||||
|
||||
// Override XPIDL continue function to suppress -Werror,-Woverloaded-virtual.
|
||||
NS_IMETHOD
|
||||
Continue(void) MOZ_OVERRIDE;
|
||||
|
||||
virtual void
|
||||
Continue(ErrorResult& aRv) MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
// MOZ_FINAL suppresses -Werror,-Wdelete-non-virtual-dtor
|
||||
~MobileMessageCursor() {}
|
||||
|
||||
private:
|
||||
// List of read-ahead results in reversed order.
|
||||
nsTArray<nsCOMPtr<nsISupports>> mPendingResults;
|
||||
|
||||
nsresult
|
||||
FireSuccessWithNextPendingResult();
|
||||
};
|
||||
|
||||
namespace mobilemessage {
|
||||
|
||||
class MobileMessageCursorCallback MOZ_FINAL : public nsIMobileMessageCursorCallback
|
||||
{
|
||||
friend class mozilla::dom::MobileMessageManager;
|
||||
|
||||
@ -37,12 +73,13 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
virtual ~MobileMessageCursorCallback()
|
||||
// MOZ_FINAL suppresses -Werror,-Wdelete-non-virtual-dtor
|
||||
~MobileMessageCursorCallback()
|
||||
{
|
||||
MOZ_COUNT_DTOR(MobileMessageCursorCallback);
|
||||
}
|
||||
|
||||
nsRefPtr<DOMCursor> mDOMCursor;
|
||||
nsRefPtr<MobileMessageCursor> mDOMCursor;
|
||||
};
|
||||
|
||||
} // namespace mobilemessage
|
||||
|
@ -439,9 +439,10 @@ MobileMessageManager::GetMessages(const MobileMessageFilter& aFilter,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
cursorCallback->mDOMCursor = new DOMCursor(GetOwner(), continueCallback);
|
||||
cursorCallback->mDOMCursor =
|
||||
new MobileMessageCursor(GetOwner(), continueCallback);
|
||||
|
||||
nsRefPtr<DOMCursor> cursor = cursorCallback->mDOMCursor;
|
||||
nsRefPtr<DOMCursor> cursor(cursorCallback->mDOMCursor);
|
||||
return cursor.forget();
|
||||
}
|
||||
|
||||
@ -491,9 +492,10 @@ MobileMessageManager::GetThreads(ErrorResult& aRv)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
cursorCallback->mDOMCursor = new DOMCursor(GetOwner(), continueCallback);
|
||||
cursorCallback->mDOMCursor =
|
||||
new MobileMessageCursor(GetOwner(), continueCallback);
|
||||
|
||||
nsRefPtr<DOMCursor> cursor = cursorCallback->mDOMCursor;
|
||||
nsRefPtr<DOMCursor> cursor(cursorCallback->mDOMCursor);
|
||||
return cursor.forget();
|
||||
}
|
||||
|
||||
|
@ -3807,7 +3807,7 @@ GetMessagesCursor.prototype = {
|
||||
}
|
||||
let domMessage =
|
||||
self.mmdb.createDomMessageFromRecord(event.target.result);
|
||||
self.callback.notifyCursorResult(domMessage);
|
||||
self.callback.notifyCursorResult([domMessage], 1);
|
||||
};
|
||||
getRequest.onerror = function(event) {
|
||||
if (DEBUG) {
|
||||
@ -3888,7 +3888,7 @@ GetThreadsCursor.prototype = {
|
||||
threadRecord.body,
|
||||
threadRecord.unreadCount,
|
||||
threadRecord.lastMessageType);
|
||||
self.callback.notifyCursorResult(thread);
|
||||
self.callback.notifyCursorResult([thread], 1);
|
||||
};
|
||||
getRequest.onerror = function(event) {
|
||||
if (DEBUG) {
|
||||
|
@ -4,10 +4,11 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, builtinclass, uuid(8fd0dba2-032e-4190-a751-07cc3782e93e)]
|
||||
[scriptable, builtinclass, uuid(134a6958-543b-46e2-b419-4631a2314164)]
|
||||
interface nsIMobileMessageCursorCallback : nsISupports
|
||||
{
|
||||
void notifyCursorError(in long error);
|
||||
void notifyCursorResult(in nsISupports result);
|
||||
void notifyCursorResult([array, size_is(size)] in nsISupports results,
|
||||
in uint32_t size);
|
||||
void notifyCursorDone();
|
||||
};
|
||||
|
@ -293,22 +293,17 @@ MobileMessageCursorChild::RecvNotifyResult(const MobileMessageCursorData& aData)
|
||||
{
|
||||
MOZ_ASSERT(mCursorCallback);
|
||||
|
||||
nsCOMPtr<nsISupports> result;
|
||||
switch(aData.type()) {
|
||||
case MobileMessageCursorData::TMmsMessageData:
|
||||
result = new MmsMessage(aData.get_MmsMessageData());
|
||||
case MobileMessageCursorData::TMobileMessageArrayData:
|
||||
DoNotifyResult(aData.get_MobileMessageArrayData().messages());
|
||||
break;
|
||||
case MobileMessageCursorData::TSmsMessageData:
|
||||
result = new SmsMessage(aData.get_SmsMessageData());
|
||||
break;
|
||||
case MobileMessageCursorData::TThreadData:
|
||||
result = new MobileMessageThread(aData.get_ThreadData());
|
||||
case MobileMessageCursorData::TThreadArrayData:
|
||||
DoNotifyResult(aData.get_ThreadArrayData().threads());
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Received invalid response parameters!");
|
||||
}
|
||||
|
||||
mCursorCallback->NotifyCursorResult(result);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -338,6 +333,48 @@ MobileMessageCursorChild::HandleContinue()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
MobileMessageCursorChild::DoNotifyResult(const nsTArray<MobileMessageData>& aDataArray)
|
||||
{
|
||||
const uint32_t length = aDataArray.Length();
|
||||
MOZ_ASSERT(length);
|
||||
|
||||
AutoFallibleTArray<nsISupports*, 1> autoArray;
|
||||
NS_ENSURE_TRUE_VOID(autoArray.SetCapacity(length));
|
||||
|
||||
AutoFallibleTArray<nsCOMPtr<nsISupports>, 1> messages;
|
||||
NS_ENSURE_TRUE_VOID(messages.SetCapacity(length));
|
||||
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
nsCOMPtr<nsISupports> message = CreateMessageFromMessageData(aDataArray[i]);
|
||||
NS_ENSURE_TRUE_VOID(messages.AppendElement(message));
|
||||
NS_ENSURE_TRUE_VOID(autoArray.AppendElement(message.get()));
|
||||
}
|
||||
|
||||
mCursorCallback->NotifyCursorResult(autoArray.Elements(), length);
|
||||
}
|
||||
|
||||
void
|
||||
MobileMessageCursorChild::DoNotifyResult(const nsTArray<ThreadData>& aDataArray)
|
||||
{
|
||||
const uint32_t length = aDataArray.Length();
|
||||
MOZ_ASSERT(length);
|
||||
|
||||
AutoFallibleTArray<nsISupports*, 1> autoArray;
|
||||
NS_ENSURE_TRUE_VOID(autoArray.SetCapacity(length));
|
||||
|
||||
AutoFallibleTArray<nsCOMPtr<nsISupports>, 1> threads;
|
||||
NS_ENSURE_TRUE_VOID(threads.SetCapacity(length));
|
||||
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
nsCOMPtr<nsISupports> thread = new MobileMessageThread(aDataArray[i]);
|
||||
NS_ENSURE_TRUE_VOID(threads.AppendElement(thread));
|
||||
NS_ENSURE_TRUE_VOID(autoArray.AppendElement(thread.get()));
|
||||
}
|
||||
|
||||
mCursorCallback->NotifyCursorResult(autoArray.Elements(), length);
|
||||
}
|
||||
|
||||
} // namespace mobilemessage
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -129,6 +129,13 @@ protected:
|
||||
|
||||
virtual bool
|
||||
Recv__delete__(const int32_t& aError) MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
void
|
||||
DoNotifyResult(const nsTArray<MobileMessageData>& aData);
|
||||
|
||||
void
|
||||
DoNotifyResult(const nsTArray<ThreadData>& aData);
|
||||
};
|
||||
|
||||
} // namespace mobilemessage
|
||||
|
@ -843,40 +843,59 @@ MobileMessageCursorParent::NotifyCursorError(int32_t aError)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MobileMessageCursorParent::NotifyCursorResult(nsISupports* aResult)
|
||||
MobileMessageCursorParent::NotifyCursorResult(nsISupports** aResults,
|
||||
uint32_t aSize)
|
||||
{
|
||||
MOZ_ASSERT(aResults && *aResults && aSize);
|
||||
|
||||
// The child process could die before this asynchronous notification, in which
|
||||
// case ActorDestroy() was called and mContinueCallback is now null. Return an
|
||||
// error here to avoid sending a message to the dead process.
|
||||
NS_ENSURE_TRUE(mContinueCallback, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIDOMMozSmsMessage> iSms = do_QueryInterface(aResult);
|
||||
if (iSms) {
|
||||
SmsMessage* message = static_cast<SmsMessage*>(aResult);
|
||||
return SendNotifyResult(MobileMessageCursorData(message->GetData()))
|
||||
nsCOMPtr<nsIDOMMozMobileMessageThread> iThread =
|
||||
do_QueryInterface(aResults[0]);
|
||||
if (iThread) {
|
||||
nsTArray<ThreadData> threads;
|
||||
|
||||
for (uint32_t i = 0; i < aSize; i++) {
|
||||
nsCOMPtr<nsIDOMMozMobileMessageThread> iThread =
|
||||
do_QueryInterface(aResults[i]);
|
||||
NS_ENSURE_TRUE(iThread, NS_ERROR_FAILURE);
|
||||
|
||||
MobileMessageThread* thread =
|
||||
static_cast<MobileMessageThread*>(iThread.get());
|
||||
threads.AppendElement(thread->GetData());
|
||||
}
|
||||
|
||||
return SendNotifyResult(MobileMessageCursorData(ThreadArrayData(threads)))
|
||||
? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMMozMmsMessage> iMms = do_QueryInterface(aResult);
|
||||
if (iMms) {
|
||||
MmsMessage* message = static_cast<MmsMessage*>(aResult);
|
||||
ContentParent* parent = static_cast<ContentParent*>(Manager()->Manager());
|
||||
MmsMessageData data;
|
||||
if (!message->GetData(parent, data)) {
|
||||
nsTArray<MobileMessageData> messages;
|
||||
for (uint32_t i = 0; i < aSize; i++) {
|
||||
nsCOMPtr<nsIDOMMozSmsMessage> iSms = do_QueryInterface(aResults[i]);
|
||||
if (iSms) {
|
||||
SmsMessage* sms = static_cast<SmsMessage*>(iSms.get());
|
||||
messages.AppendElement(sms->GetData());
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMMozMmsMessage> iMms = do_QueryInterface(aResults[i]);
|
||||
if (iMms) {
|
||||
MmsMessage* mms = static_cast<MmsMessage*>(iMms.get());
|
||||
MmsMessageData mmsData;
|
||||
NS_ENSURE_TRUE(mms->GetData(parent, mmsData), NS_ERROR_FAILURE);
|
||||
messages.AppendElement(mmsData);
|
||||
continue;
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return SendNotifyResult(MobileMessageCursorData(data))
|
||||
? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMMozMobileMessageThread> iThread = do_QueryInterface(aResult);
|
||||
if (iThread) {
|
||||
MobileMessageThread* thread = static_cast<MobileMessageThread*>(aResult);
|
||||
return SendNotifyResult(MobileMessageCursorData(thread->GetData()))
|
||||
return SendNotifyResult(MobileMessageCursorData(MobileMessageArrayData(messages)))
|
||||
? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
MOZ_CRASH("Received invalid response parameters!");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -99,11 +99,20 @@ struct ThreadData
|
||||
MessageType lastMessageType;
|
||||
};
|
||||
|
||||
struct MobileMessageArrayData
|
||||
{
|
||||
MobileMessageData[] messages;
|
||||
};
|
||||
|
||||
struct ThreadArrayData
|
||||
{
|
||||
ThreadData[] threads;
|
||||
};
|
||||
|
||||
union MobileMessageCursorData
|
||||
{
|
||||
MmsMessageData;
|
||||
SmsMessageData;
|
||||
ThreadData;
|
||||
MobileMessageArrayData;
|
||||
ThreadArrayData;
|
||||
};
|
||||
|
||||
struct DeletedMessageInfoData
|
||||
|
@ -303,9 +303,9 @@ function createMmdbCursor(aMmdb, aMethodName) {
|
||||
deferred.reject([aRv, results]);
|
||||
},
|
||||
|
||||
notifyCursorResult: function(aResult) {
|
||||
ok(true, "notifyCursorResult: " + aResult.id);
|
||||
results.push(aResult);
|
||||
notifyCursorResult: function(aResults, aSize) {
|
||||
ok(true, "notifyCursorResult: " + aResults.map(function(aElement) { return aElement.id; }));
|
||||
results = results.concat(aResults);
|
||||
cursor.handleContinue();
|
||||
},
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user