/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* 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 "MobileMessageManager.h" #include "DeletedMessageInfo.h" #include "DOMCursor.h" #include "DOMRequest.h" #include "MmsMessage.h" #include "MmsMessageInternal.h" #include "MobileMessageCallback.h" #include "MobileMessageCursorCallback.h" #include "SmsMessage.h" #include "SmsMessageInternal.h" #include "mozilla/dom/mobilemessage/Constants.h" // For kSms*ObserverTopic #include "mozilla/dom/MozMessageDeletedEvent.h" #include "mozilla/dom/MozMmsEvent.h" #include "mozilla/dom/MozMobileMessageManagerBinding.h" #include "mozilla/dom/MozSmsEvent.h" #include "mozilla/dom/Promise.h" #include "mozilla/dom/ToJSValue.h" #include "mozilla/Preferences.h" #include "mozilla/Services.h" #include "mozilla/UniquePtr.h" #include "nsIMmsService.h" #include "nsIMobileMessageCallback.h" #include "nsIMobileMessageDatabaseService.h" #include "nsIMobileMessageService.h" #include "nsIObserverService.h" #include "nsISmsService.h" #include "nsServiceManagerUtils.h" // For do_GetService() // Service instantiation #include "ipc/SmsIPCService.h" #include "MobileMessageService.h" #ifdef MOZ_WIDGET_ANDROID #include "android/MobileMessageDatabaseService.h" #include "android/SmsService.h" #elif defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL) #include "nsIGonkMobileMessageDatabaseService.h" #include "nsIGonkSmsService.h" #endif #include "nsXULAppAPI.h" // For XRE_GetProcessType() #define RECEIVED_EVENT_NAME NS_LITERAL_STRING("received") #define RETRIEVING_EVENT_NAME NS_LITERAL_STRING("retrieving") #define SENDING_EVENT_NAME NS_LITERAL_STRING("sending") #define SENT_EVENT_NAME NS_LITERAL_STRING("sent") #define FAILED_EVENT_NAME NS_LITERAL_STRING("failed") #define DELIVERY_SUCCESS_EVENT_NAME NS_LITERAL_STRING("deliverysuccess") #define DELIVERY_ERROR_EVENT_NAME NS_LITERAL_STRING("deliveryerror") #define READ_SUCCESS_EVENT_NAME NS_LITERAL_STRING("readsuccess") #define READ_ERROR_EVENT_NAME NS_LITERAL_STRING("readerror") #define DELETED_EVENT_NAME NS_LITERAL_STRING("deleted") using namespace mozilla::dom::mobilemessage; namespace mozilla { namespace dom { NS_INTERFACE_MAP_BEGIN(MobileMessageManager) NS_INTERFACE_MAP_ENTRY(nsIObserver) NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper) NS_IMPL_ADDREF_INHERITED(MobileMessageManager, DOMEventTargetHelper) NS_IMPL_RELEASE_INHERITED(MobileMessageManager, DOMEventTargetHelper) MobileMessageManager::MobileMessageManager(nsPIDOMWindowInner* aWindow) : DOMEventTargetHelper(aWindow) { } void MobileMessageManager::Init() { nsCOMPtr obs = services::GetObserverService(); // GetObserverService() can return null is some situations like shutdown. if (!obs) { return; } obs->AddObserver(this, kSmsReceivedObserverTopic, false); obs->AddObserver(this, kSmsRetrievingObserverTopic, false); obs->AddObserver(this, kSmsSendingObserverTopic, false); obs->AddObserver(this, kSmsSentObserverTopic, false); obs->AddObserver(this, kSmsFailedObserverTopic, false); obs->AddObserver(this, kSmsDeliverySuccessObserverTopic, false); obs->AddObserver(this, kSmsDeliveryErrorObserverTopic, false); obs->AddObserver(this, kSmsReadSuccessObserverTopic, false); obs->AddObserver(this, kSmsReadErrorObserverTopic, false); obs->AddObserver(this, kSmsDeletedObserverTopic, false); } void MobileMessageManager::Shutdown() { nsCOMPtr obs = services::GetObserverService(); // GetObserverService() can return null is some situations like shutdown. if (!obs) { return; } obs->RemoveObserver(this, kSmsReceivedObserverTopic); obs->RemoveObserver(this, kSmsRetrievingObserverTopic); obs->RemoveObserver(this, kSmsSendingObserverTopic); obs->RemoveObserver(this, kSmsSentObserverTopic); obs->RemoveObserver(this, kSmsFailedObserverTopic); obs->RemoveObserver(this, kSmsDeliverySuccessObserverTopic); obs->RemoveObserver(this, kSmsDeliveryErrorObserverTopic); obs->RemoveObserver(this, kSmsReadSuccessObserverTopic); obs->RemoveObserver(this, kSmsReadErrorObserverTopic); obs->RemoveObserver(this, kSmsDeletedObserverTopic); } JSObject* MobileMessageManager::WrapObject(JSContext* aCx, JS::Handle aGivenProto) { return MozMobileMessageManagerBinding::Wrap(aCx, this, aGivenProto); } already_AddRefed MobileMessageManager::GetSegmentInfoForText(const nsAString& aText, ErrorResult& aRv) { nsCOMPtr smsService = do_GetService(SMS_SERVICE_CONTRACTID); if (!smsService) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } nsCOMPtr window = GetOwner(); if (!window) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } RefPtr request = new DOMRequest(window); nsCOMPtr msgCallback = new MobileMessageCallback(request); nsresult rv = smsService->GetSegmentInfoForText(aText, msgCallback); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; } return request.forget(); } already_AddRefed MobileMessageManager::Send(nsISmsService* aSmsService, uint32_t aServiceId, const nsAString& aNumber, const nsAString& aText, ErrorResult& aRv) { nsCOMPtr window = GetOwner(); if (!window) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } RefPtr request = new DOMRequest(window); nsCOMPtr msgCallback = new MobileMessageCallback(request); // By default, we don't send silent messages via MobileMessageManager. nsresult rv = aSmsService->Send(aServiceId, aNumber, aText, false, msgCallback); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; } return request.forget(); } already_AddRefed MobileMessageManager::Send(const nsAString& aNumber, const nsAString& aText, const SmsSendParameters& aSendParams, ErrorResult& aRv) { nsCOMPtr smsService = do_GetService(SMS_SERVICE_CONTRACTID); if (!smsService) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } // Use the default one unless |aSendParams.serviceId| is available. uint32_t serviceId; if (aSendParams.mServiceId.WasPassed()) { serviceId = aSendParams.mServiceId.Value(); } else { nsresult rv = smsService->GetSmsDefaultServiceId(&serviceId); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; } } return Send(smsService, serviceId, aNumber, aText, aRv); } void MobileMessageManager::Send(const Sequence& aNumbers, const nsAString& aText, const SmsSendParameters& aSendParams, nsTArray>& aReturn, ErrorResult& aRv) { nsCOMPtr smsService = do_GetService(SMS_SERVICE_CONTRACTID); if (!smsService) { aRv.Throw(NS_ERROR_FAILURE); return; } // Use the default one unless |aSendParams.serviceId| is available. uint32_t serviceId; if (aSendParams.mServiceId.WasPassed()) { serviceId = aSendParams.mServiceId.Value(); } else { nsresult rv = smsService->GetSmsDefaultServiceId(&serviceId); if (NS_FAILED(rv)) { aRv.Throw(rv); return; } } const uint32_t size = aNumbers.Length(); for (uint32_t i = 0; i < size; ++i) { RefPtr request = Send(smsService, serviceId, aNumbers[i], aText, aRv); if (aRv.Failed()) { return; } aReturn.AppendElement(request); } } already_AddRefed MobileMessageManager::SendMMS(const MmsParameters& aParams, const MmsSendParameters& aSendParams, ErrorResult& aRv) { nsCOMPtr mmsService = do_GetService(MMS_SERVICE_CONTRACTID); if (!mmsService) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } // Use the default one unless |aSendParams.serviceId| is available. uint32_t serviceId; nsresult rv; if (aSendParams.mServiceId.WasPassed()) { serviceId = aSendParams.mServiceId.Value(); } else { rv = mmsService->GetMmsDefaultServiceId(&serviceId); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; } } nsCOMPtr window = GetOwner(); if (!window) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } AutoJSAPI jsapi; if (NS_WARN_IF(!jsapi.Init(window))) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } JSContext *cx = jsapi.cx(); JS::Rooted val(cx); if (!ToJSValue(cx, aParams, &val)) { aRv.Throw(NS_ERROR_TYPE_ERR); return nullptr; } RefPtr request = new DOMRequest(window); nsCOMPtr msgCallback = new MobileMessageCallback(request); rv = mmsService->Send(serviceId, val, msgCallback); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; } return request.forget(); } already_AddRefed MobileMessageManager::GetMessage(int32_t aId, ErrorResult& aRv) { nsCOMPtr dbService = do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID); if (!dbService) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } nsCOMPtr window = GetOwner(); if (!window) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } RefPtr request = new DOMRequest(window); nsCOMPtr msgCallback = new MobileMessageCallback(request); nsresult rv = dbService->GetMessageMoz(aId, msgCallback); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; } return request.forget(); } already_AddRefed MobileMessageManager::Delete(int32_t* aIdArray, uint32_t aSize, ErrorResult& aRv) { nsCOMPtr dbService = do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID); if (!dbService) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } nsCOMPtr window = GetOwner(); if (!window) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } RefPtr request = new DOMRequest(window); nsCOMPtr msgCallback = new MobileMessageCallback(request); nsresult rv = dbService->DeleteMessage(aIdArray, aSize, msgCallback); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; } return request.forget(); } already_AddRefed MobileMessageManager::Delete(int32_t aId, ErrorResult& aRv) { return Delete(&aId, 1, aRv); } already_AddRefed MobileMessageManager::Delete(SmsMessage& aMessage, ErrorResult& aRv) { return Delete(aMessage.Id(), aRv); } already_AddRefed MobileMessageManager::Delete(MmsMessage& aMessage, ErrorResult& aRv) { return Delete(aMessage.Id(), aRv); } already_AddRefed MobileMessageManager::Delete(const Sequence& aParams, ErrorResult& aRv) { const uint32_t size = aParams.Length(); FallibleTArray idArray; if (!idArray.SetLength(size, fallible)) { aRv.Throw(NS_ERROR_OUT_OF_MEMORY); return nullptr; } DebugOnly rv; for (uint32_t i = 0; i < size; i++) { const OwningLongOrSmsMessageOrMmsMessage& element = aParams[i]; int32_t &id = idArray[i]; if (element.IsLong()) { id = element.GetAsLong(); } else if (element.IsMmsMessage()) { id = element.GetAsMmsMessage()->Id(); } else /*if (element.IsSmsMessage())*/ { id = element.GetAsSmsMessage()->Id(); } } return Delete(idArray.Elements(), size, aRv); } already_AddRefed MobileMessageManager::GetMessages(const MobileMessageFilter& aFilter, bool aReverse, ErrorResult& aRv) { nsCOMPtr dbService = do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID); if (!dbService) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } bool hasStartDate = !aFilter.mStartDate.IsNull(); uint64_t startDate = 0; if (hasStartDate) { startDate = aFilter.mStartDate.Value(); } bool hasEndDate = !aFilter.mEndDate.IsNull(); uint64_t endDate = 0; if (hasEndDate) { endDate = aFilter.mEndDate.Value(); } UniquePtr ptrNumbers; uint32_t numbersCount = 0; if (!aFilter.mNumbers.IsNull() && aFilter.mNumbers.Value().Length()) { const FallibleTArray& numbers = aFilter.mNumbers.Value(); uint32_t index; numbersCount = numbers.Length(); ptrNumbers = MakeUnique(numbersCount); for (index = 0; index < numbersCount; index++) { ptrNumbers[index] = numbers[index].get(); } } nsString delivery; delivery.SetIsVoid(true); if (!aFilter.mDelivery.IsNull()) { const uint32_t index = static_cast(aFilter.mDelivery.Value()); const EnumEntry& entry = MobileMessageFilterDeliveryValues::strings[index]; delivery.AssignASCII(entry.value, entry.length); } bool hasRead = !aFilter.mRead.IsNull(); bool read = false; if (hasRead) { read = aFilter.mRead.Value(); } bool hasThreadId = !aFilter.mThreadId.IsNull(); uint64_t threadId = 0; if (hasThreadId) { threadId = aFilter.mThreadId.Value(); } RefPtr cursorCallback = new MobileMessageCursorCallback(); nsCOMPtr continueCallback; nsresult rv = dbService->CreateMessageCursor(hasStartDate, startDate, hasEndDate, endDate, ptrNumbers.get(), numbersCount, delivery, hasRead, read, hasThreadId, threadId, aReverse, cursorCallback, getter_AddRefs(continueCallback)); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; } nsCOMPtr window = GetOwner(); if (!window) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } cursorCallback->mDOMCursor = new MobileMessageCursor(window, continueCallback); RefPtr cursor(cursorCallback->mDOMCursor); return cursor.forget(); } already_AddRefed MobileMessageManager::MarkMessageRead(int32_t aId, bool aValue, bool aSendReadReport, ErrorResult& aRv) { nsCOMPtr dbService = do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID); if (!dbService) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } nsCOMPtr window = GetOwner(); if (!window) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } RefPtr request = new DOMRequest(window); nsCOMPtr msgCallback = new MobileMessageCallback(request); nsresult rv = dbService->MarkMessageRead(aId, aValue, aSendReadReport, msgCallback); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; } return request.forget(); } already_AddRefed MobileMessageManager::GetThreads(ErrorResult& aRv) { nsCOMPtr dbService = do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID); if (!dbService) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } RefPtr cursorCallback = new MobileMessageCursorCallback(); nsCOMPtr continueCallback; nsresult rv = dbService->CreateThreadCursor(cursorCallback, getter_AddRefs(continueCallback)); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; } nsCOMPtr window = GetOwner(); if (!window) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } cursorCallback->mDOMCursor = new MobileMessageCursor(window, continueCallback); RefPtr cursor(cursorCallback->mDOMCursor); return cursor.forget(); } already_AddRefed MobileMessageManager::RetrieveMMS(int32_t aId, ErrorResult& aRv) { nsCOMPtr mmsService = do_GetService(MMS_SERVICE_CONTRACTID); if (!mmsService) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } nsCOMPtr window = GetOwner(); if (!window) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } RefPtr request = new DOMRequest(window); nsCOMPtr msgCallback = new MobileMessageCallback(request); nsresult rv = mmsService->Retrieve(aId, msgCallback); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; } return request.forget(); } already_AddRefed MobileMessageManager::RetrieveMMS(MmsMessage& aMessage, ErrorResult& aRv) { return RetrieveMMS(aMessage.Id(), aRv); } nsresult MobileMessageManager::DispatchTrustedSmsEventToSelf(const char* aTopic, const nsAString& aEventName, nsISupports* aMsg) { nsCOMPtr window = GetOwner(); NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); nsCOMPtr sms = do_QueryInterface(aMsg); if (sms) { MozSmsEventInit init; init.mBubbles = false; init.mCancelable = false; init.mMessage = new SmsMessage(window, static_cast(sms.get())); RefPtr event = MozSmsEvent::Constructor(this, aEventName, init); return DispatchTrustedEvent(event); } nsCOMPtr mms = do_QueryInterface(aMsg); if (mms) { MozMmsEventInit init; init.mBubbles = false; init.mCancelable = false; init.mMessage = new MmsMessage(window, static_cast(mms.get())); RefPtr event = MozMmsEvent::Constructor(this, aEventName, init); return DispatchTrustedEvent(event); } nsAutoCString errorMsg; errorMsg.AssignLiteral("Got a '"); errorMsg.Append(aTopic); errorMsg.AppendLiteral("' topic without a valid message!"); NS_ERROR(errorMsg.get()); return NS_OK; } nsresult MobileMessageManager::DispatchTrustedDeletedEventToSelf(nsISupports* aDeletedInfo) { nsCOMPtr deletedInfo = do_QueryInterface(aDeletedInfo); if (deletedInfo) { MozMessageDeletedEventInit init; init.mBubbles = false; init.mCancelable = false; DeletedMessageInfo* info = static_cast(deletedInfo.get()); uint32_t msgIdLength = info->GetData().deletedMessageIds().Length(); if (msgIdLength) { Sequence& deletedMsgIds = init.mDeletedMessageIds.SetValue(); if (!deletedMsgIds.AppendElements(info->GetData().deletedMessageIds(), fallible)) { return NS_ERROR_OUT_OF_MEMORY; } } uint32_t threadIdLength = info->GetData().deletedThreadIds().Length(); if (threadIdLength) { Sequence& deletedThreadIds = init.mDeletedThreadIds.SetValue(); if (!deletedThreadIds.AppendElements(info->GetData().deletedThreadIds(), fallible)) { return NS_ERROR_OUT_OF_MEMORY; } } RefPtr event = MozMessageDeletedEvent::Constructor(this, DELETED_EVENT_NAME, init); return DispatchTrustedEvent(event); } NS_ERROR("Got a 'deleted' topic without a valid message!"); return NS_OK; } NS_IMETHODIMP MobileMessageManager::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData) { if (!strcmp(aTopic, kSmsReceivedObserverTopic)) { return DispatchTrustedSmsEventToSelf(aTopic, RECEIVED_EVENT_NAME, aSubject); } if (!strcmp(aTopic, kSmsRetrievingObserverTopic)) { return DispatchTrustedSmsEventToSelf(aTopic, RETRIEVING_EVENT_NAME, aSubject); } if (!strcmp(aTopic, kSmsSendingObserverTopic)) { return DispatchTrustedSmsEventToSelf(aTopic, SENDING_EVENT_NAME, aSubject); } if (!strcmp(aTopic, kSmsSentObserverTopic)) { return DispatchTrustedSmsEventToSelf(aTopic, SENT_EVENT_NAME, aSubject); } if (!strcmp(aTopic, kSmsFailedObserverTopic)) { return DispatchTrustedSmsEventToSelf(aTopic, FAILED_EVENT_NAME, aSubject); } if (!strcmp(aTopic, kSmsDeliverySuccessObserverTopic)) { return DispatchTrustedSmsEventToSelf(aTopic, DELIVERY_SUCCESS_EVENT_NAME, aSubject); } if (!strcmp(aTopic, kSmsDeliveryErrorObserverTopic)) { return DispatchTrustedSmsEventToSelf(aTopic, DELIVERY_ERROR_EVENT_NAME, aSubject); } if (!strcmp(aTopic, kSmsReadSuccessObserverTopic)) { return DispatchTrustedSmsEventToSelf(aTopic, READ_SUCCESS_EVENT_NAME, aSubject); } if (!strcmp(aTopic, kSmsReadErrorObserverTopic)) { return DispatchTrustedSmsEventToSelf(aTopic, READ_ERROR_EVENT_NAME, aSubject); } if (!strcmp(aTopic, kSmsDeletedObserverTopic)) { return DispatchTrustedDeletedEventToSelf(aSubject); } return NS_OK; } already_AddRefed MobileMessageManager::GetSmscAddress(const Optional& aServiceId, ErrorResult& aRv) { nsCOMPtr smsService = do_GetService(SMS_SERVICE_CONTRACTID); if (!smsService) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } // Use the default one unless |aSendParams.serviceId| is available. uint32_t serviceId; nsresult rv; if (aServiceId.WasPassed()) { serviceId = aServiceId.Value(); } else { rv = smsService->GetSmsDefaultServiceId(&serviceId); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; } } nsCOMPtr window = GetOwner(); if (!window) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } nsCOMPtr global = do_QueryInterface(window); if (!global) { aRv.Throw(NS_ERROR_UNEXPECTED); return nullptr; } RefPtr promise = Promise::Create(global, aRv); if (aRv.Failed()) { return nullptr; } nsCOMPtr msgCallback = new MobileMessageCallback(promise); rv = smsService->GetSmscAddress(serviceId, msgCallback); if (NS_FAILED(rv)) { promise->MaybeReject(rv); return promise.forget(); } return promise.forget(); } already_AddRefed MobileMessageManager::SetSmscAddress(const SmscAddress& aSmscAddress, const Optional& aServiceId, ErrorResult& aRv) { nsCOMPtr smsService = do_GetService(SMS_SERVICE_CONTRACTID); if (!smsService) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } // Use the default one unless |serviceId| is available. uint32_t serviceId; nsresult rv; if (aServiceId.WasPassed()) { serviceId = aServiceId.Value(); } else { rv = smsService->GetSmsDefaultServiceId(&serviceId); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; } } nsCOMPtr window = GetOwner(); if (!window) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } nsCOMPtr global = do_QueryInterface(window); if (!global) { aRv.Throw(NS_ERROR_UNEXPECTED); return nullptr; } RefPtr promise = Promise::Create(global, aRv); if (aRv.Failed()) { return nullptr; } if (!aSmscAddress.mAddress.WasPassed()) { NS_WARNING("SmscAddress.address is a mandatory field and can not be omitted."); promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR); return promise.forget(); } nsString address = aSmscAddress.mAddress.Value(); TypeOfNumber ton = aSmscAddress.mTypeOfAddress.mTypeOfNumber; NumberPlanIdentification npi = aSmscAddress.mTypeOfAddress.mNumberPlanIdentification; // If the address begins with +, set TON to international no matter what has // passed in. if (!address.IsEmpty() && address[0] == '+') { ton = TypeOfNumber::International; } nsCOMPtr msgCallback = new MobileMessageCallback(promise); rv = smsService->SetSmscAddress(serviceId, address, static_cast(ton), static_cast(npi), msgCallback); if (NS_FAILED(rv)) { promise->MaybeReject(rv); return promise.forget(); } return promise.forget(); } } // namespace dom } // namespace mozilla already_AddRefed NS_CreateSmsService() { nsCOMPtr smsService; if (XRE_IsContentProcess()) { smsService = SmsIPCService::GetSingleton(); } else { #ifdef MOZ_WIDGET_ANDROID smsService = new SmsService(); #elif defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL) smsService = do_GetService(GONK_SMSSERVICE_CONTRACTID); #endif } return smsService.forget(); } already_AddRefed NS_CreateMobileMessageDatabaseService() { nsCOMPtr mobileMessageDBService; if (XRE_IsContentProcess()) { mobileMessageDBService = SmsIPCService::GetSingleton(); } else { #ifdef MOZ_WIDGET_ANDROID mobileMessageDBService = new MobileMessageDatabaseService(); #elif defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL) mobileMessageDBService = do_CreateInstance(GONK_MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID); #endif } return mobileMessageDBService.forget(); } already_AddRefed NS_CreateMmsService() { nsCOMPtr mmsService; if (XRE_IsContentProcess()) { mmsService = SmsIPCService::GetSingleton(); } else { #if defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL) mmsService = do_CreateInstance("@mozilla.org/mms/gonkmmsservice;1"); #endif } return mmsService.forget(); } already_AddRefed NS_CreateMobileMessageService() { nsCOMPtr service = new MobileMessageService(); return service.forget(); }