Bug 849739 2/4: DOM. r=mounir,mrbkap

This commit is contained in:
Vicamo Yang 2013-04-10 00:37:54 +08:00
parent 09c6cb1e03
commit eb4c6b5710
16 changed files with 290 additions and 167 deletions

View File

@ -335,6 +335,7 @@ using mozilla::dom::workers::ResolveWorkerClasses;
#include "nsIDOMSmsRequest.h"
#include "nsIDOMSmsFilter.h"
#include "nsIDOMSmsSegmentInfo.h"
#include "nsIDOMMozMobileMessageThread.h"
#include "nsIDOMConnection.h"
#include "mozilla/dom/network/Utils.h"
@ -920,6 +921,9 @@ static nsDOMClassInfoData sClassInfoData[] = {
NS_DEFINE_CLASSINFO_DATA(MozSmsSegmentInfo, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(MozMobileMessageThread, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(MozConnection, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
@ -2367,6 +2371,10 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozSmsSegmentInfo)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(MozMobileMessageThread, nsIDOMMozMobileMessageThread)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozMobileMessageThread)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(MozConnection, nsIDOMMozConnection)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozConnection)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)

View File

@ -193,6 +193,7 @@ DOMCI_CLASS(MozMmsMessage)
DOMCI_CLASS(MozSmsRequest)
DOMCI_CLASS(MozSmsFilter)
DOMCI_CLASS(MozSmsSegmentInfo)
DOMCI_CLASS(MozMobileMessageThread)
DOMCI_CLASS(MozConnection)
#ifdef MOZ_B2G_RIL

View File

@ -8,6 +8,7 @@ XPIDL_SOURCES += [
'nsIDOMMobileMessageManager.idl',
'nsIDOMMozMmsEvent.idl',
'nsIDOMMozMmsMessage.idl',
'nsIDOMMozMobileMessageThread.idl',
'nsIDOMMozSmsEvent.idl',
'nsIDOMMozSmsMessage.idl',
'nsIDOMNavigatorMobileMessage.idl',

View File

@ -54,6 +54,7 @@ EXPORTS_mozilla/dom/mobilemessage = \
CPPSRCS = \
MobileMessageCursorCallback.cpp \
MobileMessageThread.cpp \
SmsManager.cpp \
MobileMessageManager.cpp \
SmsService.cpp \

View File

@ -330,7 +330,10 @@ MmsMessage::GetReceivers(JSContext* aCx, JS::Value* aReceivers)
NS_IMETHODIMP
MmsMessage::GetTimestamp(JSContext* cx, JS::Value* aDate)
{
*aDate = OBJECT_TO_JSVAL(JS_NewDateObjectMsec(cx, mTimestamp));
JSObject *obj = JS_NewDateObjectMsec(cx, mTimestamp);
NS_ENSURE_TRUE(obj, NS_ERROR_FAILURE);
*aDate = OBJECT_TO_JSVAL(obj);
return NS_OK;
}

View File

@ -139,18 +139,6 @@ MobileMessageCallback::NotifyMarkMessageReadFailed(int32_t aError)
return NotifyError(aError);
}
NS_IMETHODIMP
MobileMessageCallback::NotifyThreadList(const JS::Value& aThreadList, JSContext* aCx)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
MobileMessageCallback::NotifyThreadListFailed(int32_t aError)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
} // namesapce mobilemessage
} // namespace dom
} // namespace mozilla

View File

@ -318,16 +318,23 @@ MobileMessageManager::MarkMessageRead(int32_t aId, bool aValue,
}
NS_IMETHODIMP
MobileMessageManager::GetThreadList(nsIDOMMozSmsRequest** aRequest)
MobileMessageManager::GetThreads(nsIDOMDOMCursor** aCursor)
{
nsCOMPtr<nsIDOMMozSmsRequest> req = SmsRequest::Create(this);
nsCOMPtr<nsIMobileMessageDatabaseService> mobileMessageDBService =
nsCOMPtr<nsIMobileMessageDatabaseService> dbService =
do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID);
NS_ENSURE_TRUE(mobileMessageDBService, NS_ERROR_FAILURE);
nsCOMPtr<nsIMobileMessageCallback> forwarder =
new SmsRequestForwarder(static_cast<SmsRequest*>(req.get()));
mobileMessageDBService->GetThreadList(forwarder);
req.forget(aRequest);
NS_ENSURE_TRUE(dbService, NS_ERROR_FAILURE);
nsRefPtr<MobileMessageCursorCallback> cursorCallback =
new MobileMessageCursorCallback();
nsCOMPtr<nsICursorContinueCallback> continueCallback;
nsresult rv = dbService->CreateThreadCursor(cursorCallback,
getter_AddRefs(continueCallback));
NS_ENSURE_SUCCESS(rv, rv);
cursorCallback->mDOMCursor = new DOMCursor(GetOwner(), continueCallback);
NS_ADDREF(*aCursor = cursorCallback->mDOMCursor);
return NS_OK;
}

View File

@ -4,6 +4,7 @@
#include "SmsMessage.h"
#include "MmsMessage.h"
#include "MobileMessageThread.h"
#include "MobileMessageService.h"
#include "SmsSegmentInfo.h"
#include "jsapi.h"
@ -98,6 +99,24 @@ MobileMessageService::CreateSmsSegmentInfo(int32_t aSegments,
return NS_OK;
}
NS_IMETHODIMP
MobileMessageService::CreateThread(uint64_t aId,
const JS::Value& aParticipants,
const JS::Value& aTimestamp,
const nsAString& aBody,
uint64_t aUnreadCount,
JSContext* aCx,
nsIDOMMozMobileMessageThread** aThread)
{
return MobileMessageThread::Create(aId,
aParticipants,
aTimestamp,
aBody,
aUnreadCount,
aCx,
aThread);
}
} // namespace mobilemessage
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,161 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 "MobileMessageThread.h"
#include "nsIDOMClassInfo.h"
#include "jsapi.h" // For OBJECT_TO_JSVAL and JS_NewDateObjectMsec
#include "jsfriendapi.h" // For js_DateGetMsecSinceEpoch
#include "nsJSUtils.h" // For nsDependentJSString
#include "nsContentUtils.h" // For nsTArrayHelpers.h
#include "nsTArrayHelpers.h" // For nsTArrayToJSArray
using namespace mozilla::dom::mobilemessage;
DOMCI_DATA(MozMobileMessageThread, mozilla::dom::MobileMessageThread)
namespace mozilla {
namespace dom {
NS_INTERFACE_MAP_BEGIN(MobileMessageThread)
NS_INTERFACE_MAP_ENTRY(nsIDOMMozMobileMessageThread)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozMobileMessageThread)
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(MobileMessageThread)
NS_IMPL_RELEASE(MobileMessageThread)
/* static */ nsresult
MobileMessageThread::Create(const uint64_t aId,
const JS::Value& aParticipants,
const JS::Value& aTimestamp,
const nsAString& aBody,
const uint64_t aUnreadCount,
JSContext* aCx,
nsIDOMMozMobileMessageThread** aThread)
{
*aThread = nullptr;
// ThreadData exposes these as references, so we can simply assign
// to them.
ThreadData data;
data.id() = aId;
data.body().Assign(aBody);
data.unreadCount() = aUnreadCount;
// Participants.
{
if (!aParticipants.isObject()) {
return NS_ERROR_INVALID_ARG;
}
JSObject* obj = &aParticipants.toObject();
if (!JS_IsArrayObject(aCx, obj)) {
return NS_ERROR_INVALID_ARG;
}
uint32_t length;
JS_ALWAYS_TRUE(JS_GetArrayLength(aCx, obj, &length));
NS_ENSURE_TRUE(length, NS_ERROR_INVALID_ARG);
for (uint32_t i = 0; i < length; ++i) {
JS::Value val;
if (!JS_GetElement(aCx, obj, i, &val) || !val.isString()) {
return NS_ERROR_INVALID_ARG;
}
nsDependentJSString str;
str.init(aCx, val.toString());
data.participants().AppendElement(str);
}
}
// We support both a Date object and a millisecond timestamp as a number.
if (aTimestamp.isObject()) {
JSObject& obj = aTimestamp.toObject();
if (!JS_ObjectIsDate(aCx, &obj)) {
return NS_ERROR_INVALID_ARG;
}
data.timestamp() = js_DateGetMsecSinceEpoch(&obj);
} else {
if (!aTimestamp.isNumber()) {
return NS_ERROR_INVALID_ARG;
}
double number = aTimestamp.toNumber();
if (static_cast<uint64_t>(number) != number) {
return NS_ERROR_INVALID_ARG;
}
data.timestamp() = static_cast<uint64_t>(number);
}
nsCOMPtr<nsIDOMMozMobileMessageThread> thread = new MobileMessageThread(data);
thread.forget(aThread);
return NS_OK;
}
MobileMessageThread::MobileMessageThread(const uint64_t aId,
const nsTArray<nsString>& aParticipants,
const uint64_t aTimestamp,
const nsString& aBody,
const uint64_t aUnreadCount)
: mData(aId, aParticipants, aTimestamp, aBody, aUnreadCount)
{
MOZ_ASSERT(aParticipants.Length());
}
MobileMessageThread::MobileMessageThread(const ThreadData& aData)
: mData(aData)
{
MOZ_ASSERT(aData.participants().Length());
}
NS_IMETHODIMP
MobileMessageThread::GetId(uint64_t* aId)
{
*aId = mData.id();
return NS_OK;
}
NS_IMETHODIMP
MobileMessageThread::GetBody(nsAString& aBody)
{
aBody = mData.body();
return NS_OK;
}
NS_IMETHODIMP
MobileMessageThread::GetUnreadCount(uint64_t* aUnreadCount)
{
*aUnreadCount = mData.unreadCount();
return NS_OK;
}
NS_IMETHODIMP
MobileMessageThread::GetParticipants(JSContext* aCx,
JS::Value* aParticipants)
{
JSObject* obj;
nsresult rv = nsTArrayToJSArray(aCx, mData.participants(), &obj);
NS_ENSURE_SUCCESS(rv, rv);
aParticipants->setObject(*obj);
return NS_OK;
}
NS_IMETHODIMP
MobileMessageThread::GetTimestamp(JSContext* aCx,
JS::Value* aDate)
{
JSObject *obj = JS_NewDateObjectMsec(aCx, mData.timestamp());
NS_ENSURE_TRUE(obj, NS_ERROR_FAILURE);
*aDate = OBJECT_TO_JSVAL(obj);
return NS_OK;
}
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,55 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 mozilla_dom_mobilemessage_MobileMessageThread_h
#define mozilla_dom_mobilemessage_MobileMessageThread_h
#include "mozilla/Attributes.h"
#include "mozilla/dom/mobilemessage/SmsTypes.h"
#include "nsIDOMMozMobileMessageThread.h"
#include "nsString.h"
#include "jspubtd.h"
namespace mozilla {
namespace dom {
class MobileMessageThread MOZ_FINAL : public nsIDOMMozMobileMessageThread
{
private:
typedef mobilemessage::ThreadData ThreadData;
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMMOZMOBILEMESSAGETHREAD
MobileMessageThread(const uint64_t aId,
const nsTArray<nsString>& aParticipants,
const uint64_t aTimestamp,
const nsString& aBody,
const uint64_t aUnreadCount);
MobileMessageThread(const ThreadData& aData);
static nsresult Create(const uint64_t aId,
const JS::Value& aParticipants,
const JS::Value& aTimestamp,
const nsAString& aBody,
const uint64_t aUnreadCount,
JSContext* aCx,
nsIDOMMozMobileMessageThread** aThread);
const ThreadData& GetData() const { return mData; }
private:
// Don't try to use the default constructor.
MobileMessageThread() MOZ_DELETE;
ThreadData mData;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_mobilemessage_MobileMessageThread_h

View File

@ -314,16 +314,23 @@ SmsManager::MarkMessageRead(int32_t aId, bool aValue,
}
NS_IMETHODIMP
SmsManager::GetThreadList(nsIDOMMozSmsRequest** aRequest)
SmsManager::GetThreads(nsIDOMDOMCursor** aCursor)
{
nsCOMPtr<nsIDOMMozSmsRequest> req = SmsRequest::Create(this);
nsCOMPtr<nsIMobileMessageDatabaseService> mobileMessageDBService =
nsCOMPtr<nsIMobileMessageDatabaseService> dbService =
do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID);
NS_ENSURE_TRUE(mobileMessageDBService, NS_ERROR_FAILURE);
nsCOMPtr<nsIMobileMessageCallback> forwarder =
new SmsRequestForwarder(static_cast<SmsRequest*>(req.get()));
mobileMessageDBService->GetThreadList(forwarder);
req.forget(aRequest);
NS_ENSURE_TRUE(dbService, NS_ERROR_FAILURE);
nsRefPtr<MobileMessageCursorCallback> cursorCallback =
new MobileMessageCursorCallback();
nsCOMPtr<nsICursorContinueCallback> continueCallback;
nsresult rv = dbService->CreateThreadCursor(cursorCallback,
getter_AddRefs(continueCallback));
NS_ENSURE_SUCCESS(rv, rv);
cursorCallback->mDOMCursor = new DOMCursor(GetOwner(), continueCallback);
NS_ADDREF(*aCursor = cursorCallback->mDOMCursor);
return NS_OK;
}

View File

@ -261,7 +261,10 @@ SmsMessage::GetMessageClass(nsAString& aMessageClass)
NS_IMETHODIMP
SmsMessage::GetTimestamp(JSContext* cx, JS::Value* aDate)
{
*aDate = OBJECT_TO_JSVAL(JS_NewDateObjectMsec(cx, mData.timestamp()));
JSObject *obj = JS_NewDateObjectMsec(cx, mData.timestamp());
NS_ENSURE_TRUE(obj, NS_ERROR_FAILURE);
*aDate = OBJECT_TO_JSVAL(obj);
return NS_OK;
}

View File

@ -376,139 +376,5 @@ SmsRequest::NotifyMarkMessageReadFailed(int32_t aError)
return NotifyError(aError);
}
NS_IMETHODIMP
SmsRequest::NotifyThreadList(const JS::Value& aThreadList, JSContext* aCx)
{
MOZ_ASSERT(aThreadList.isObject());
if (mParent) {
JSObject* array = const_cast<JSObject*>(&aThreadList.toObject());
uint32_t length;
bool ok = JS_GetArrayLength(aCx, array, &length);
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
ReplyThreadList reply;
InfallibleTArray<ThreadListItem>& ipcItems = reply.items();
if (length) {
ipcItems.SetCapacity(length);
for (uint32_t i = 0; i < length; i++) {
JS::Value arrayEntry;
ok = JS_GetElement(aCx, array, i, &arrayEntry);
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
MOZ_ASSERT(arrayEntry.isObject());
mozilla::idl::SmsThreadListItem item;
nsresult rv = item.Init(aCx, &arrayEntry);
NS_ENSURE_SUCCESS(rv, rv);
ThreadListItem* ipcItem = ipcItems.AppendElement();
ipcItem->id() = item.id;
ipcItem->senderOrReceiver() = item.senderOrReceiver;
ipcItem->timestamp() = item.timestamp;
ipcItem->body() = item.body;
ipcItem->unreadCount() = item.unreadCount;
}
}
return SendMessageReply(reply);
}
return NotifySuccess(aThreadList);
}
NS_IMETHODIMP
SmsRequest::NotifyThreadListFailed(int32_t aError)
{
if (mParent) {
return SendMessageReply(MessageReply(ReplyThreadListFail(aError)));
}
return NotifyError(aError);
}
void
SmsRequest::NotifyThreadList(const InfallibleTArray<ThreadListItem>& aItems)
{
MOZ_ASSERT(!mParent);
MOZ_ASSERT(GetOwner());
nsresult rv;
nsIScriptContext* sc = GetContextForEventHandlers(&rv);
NS_ENSURE_SUCCESS_VOID(rv);
NS_ENSURE_TRUE_VOID(sc);
AutoPushJSContext cx(sc->GetNativeContext());
MOZ_ASSERT(cx);
nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(GetOwner());
JSObject* ownerObj = sgo->GetGlobalJSObject();
NS_ENSURE_TRUE_VOID(ownerObj);
nsCxPusher pusher;
pusher.Push(cx);
JSAutoRequest ar(cx);
JSAutoCompartment ac(cx, ownerObj);
JSObject* array = JS_NewArrayObject(cx, aItems.Length(), nullptr);
NS_ENSURE_TRUE_VOID(array);
bool ok;
for (uint32_t i = 0; i < aItems.Length(); i++) {
const ThreadListItem& source = aItems[i];
JS::Value id = JS_NumberValue(double(source.id()));
nsString temp = source.senderOrReceiver();
JS::Value senderOrReceiver;
ok = xpc::StringToJsval(cx, temp, &senderOrReceiver);
NS_ENSURE_TRUE_VOID(ok);
JSObject* timestampObj = JS_NewDateObjectMsec(cx, source.timestamp());
NS_ENSURE_TRUE_VOID(timestampObj);
JS::Value timestamp = OBJECT_TO_JSVAL(timestampObj);
temp = source.body();
JS::Value body;
ok = xpc::StringToJsval(cx, temp, &body);
NS_ENSURE_TRUE_VOID(ok);
JS::Value unreadCount = JS_NumberValue(double(source.unreadCount()));
JSObject* elementObj = JS_NewObject(cx, nullptr, nullptr, nullptr);
NS_ENSURE_TRUE_VOID(elementObj);
ok = JS_SetProperty(cx, elementObj, "id", &id);
NS_ENSURE_TRUE_VOID(ok);
ok = JS_SetProperty(cx, elementObj, "senderOrReceiver", &senderOrReceiver);
NS_ENSURE_TRUE_VOID(ok);
ok = JS_SetProperty(cx, elementObj, "timestamp", &timestamp);
NS_ENSURE_TRUE_VOID(ok);
ok = JS_SetProperty(cx, elementObj, "body", &body);
NS_ENSURE_TRUE_VOID(ok);
ok = JS_SetProperty(cx, elementObj, "unreadCount", &unreadCount);
NS_ENSURE_TRUE_VOID(ok);
JS::Value element = OBJECT_TO_JSVAL(elementObj);
ok = JS_SetElement(cx, array, i, &element);
NS_ENSURE_TRUE_VOID(ok);
}
NotifyThreadList(OBJECT_TO_JSVAL(array), cx);
}
} // namespace dom
} // namespace mozilla

View File

@ -56,7 +56,8 @@ MobileMessageDatabaseService::MarkMessageRead(int32_t aMessageId,
}
NS_IMETHODIMP
MobileMessageDatabaseService::GetThreadList(nsIMobileMessageCallback* aRequest)
MobileMessageDatabaseService::CreateThreadCursor(nsIMobileMessageCursorCallback* aCallback,
nsICursorContinueCallback** aResult)
{
NS_NOTYETIMPLEMENTED("Implement me!");
return NS_ERROR_NOT_IMPLEMENTED;

View File

@ -47,7 +47,8 @@ MobileMessageDatabaseService::MarkMessageRead(int32_t aMessageId,
}
NS_IMETHODIMP
MobileMessageDatabaseService::GetThreadList(nsIMobileMessageCallback* aRequest)
MobileMessageDatabaseService::CreateThreadCursor(nsIMobileMessageCursorCallback* aCallback,
nsICursorContinueCallback** aResult)
{
NS_ERROR("We should not be here!");
return NS_OK;

View File

@ -549,7 +549,8 @@ var interfaceNamesInGlobalScope =
"SpeechSynthesisEvent",
"PushManager",
"StyleSheetAddedEvent",
"StyleSheetRemovedEvent"
"StyleSheetRemovedEvent",
"MozMobileMessageThread",
]
for (var i in SpecialPowers.Components.interfaces) {