Bug 839436 - B2G MMS: make DB be able to save MMS messages. r=vicamo

This commit is contained in:
Gene Lian 2013-02-08 18:45:04 +08:00
Родитель c08133a60e
Коммит eb788b3c18
4 изменённых файлов: 174 добавлений и 152 удалений

Просмотреть файл

@ -2,30 +2,42 @@
* 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 "domstubs.idl"
#include "nsISupports.idl"
#include "nsIMobileMessageDatabaseService.idl"
interface nsIDOMMozSmsMessage;
[scriptable, function, uuid(9cd80750-6a08-11e2-ac93-bf895e53f40e)]
[scriptable, function, uuid(0bffae74-71db-11e2-962a-73cf64d6393e)]
interface nsIRilMobileMessageDatabaseCallback : nsISupports
{
void notify(in nsresult aRv, in nsIDOMMozSmsMessage aSms);
/**
* |aRecord| Object: the mobile-message database record
*/
void notify(in nsresult aRv, in jsval aRecord);
};
[scriptable, uuid(89528354-6a08-11e2-8243-af4cf90404a9)]
[scriptable, uuid(3592525a-71d6-11e2-82ca-f75ae6e08ee2)]
interface nsIRilMobileMessageDatabaseService : nsIMobileMessageDatabaseService
{
long saveReceivedMessage(in DOMString aSender,
in DOMString aBody,
in DOMString aMessageClass,
in unsigned long long aDate,
/**
* |aMessage| Object: should contain the following properties for internal use:
* - |type| DOMString: "sms" or "mms"
* - |sender| DOMString: the phone number of sender
* - |timestamp| Number: the timestamp of received message
* - |messageClass| DOMString: the message class of received message
*/
long saveReceivedMessage(in jsval aMessage,
[optional] in nsIRilMobileMessageDatabaseCallback aCallback);
long saveSendingMessage(in DOMString aReceiver,
in DOMString aBody,
in DOMString aDeliveryStatus,
in unsigned long long aDate,
/**
* |aMessage| Object: should contain the following properties for internal use:
* - |type| DOMString: "sms" or "mms"
* - |receiver| DOMString: the phone number of receiver
* - |timestamp| Number: the timestamp of sending message
* - |deliveryStatus| DOMString: the delivery status of sending message
*/
long saveSendingMessage(in jsval aMessage,
[optional] in nsIRilMobileMessageDatabaseCallback aCallback);
void setMessageDelivery(in long aMessageId,
in DOMString aDelivery,
in DOMString aDeliveryStatus,

Просмотреть файл

@ -413,8 +413,8 @@ MobileMessageDatabaseService.prototype = {
};
},
createMessageFromRecord: function createMessageFromRecord(aRecord) {
if (DEBUG) debug("createMessageFromRecord: " + JSON.stringify(aRecord));
createSmsMessageFromRecord: function createSmsMessageFromRecord(aRecord) {
if (DEBUG) debug("createSmsMessageFromRecord: " + JSON.stringify(aRecord));
return gSmsService.createSmsMessage(aRecord.id,
aRecord.delivery,
aRecord.deliveryStatus,
@ -482,7 +482,7 @@ MobileMessageDatabaseService.prototype = {
let getRequest = aObjectStore.get(firstMessageId);
let self = this;
getRequest.onsuccess = function onsuccess(event) {
let sms = self.createMessageFromRecord(event.target.result);
let sms = self.createSmsMessageFromRecord(event.target.result);
if (aMessageList.listId >= 0) {
if (DEBUG) {
debug("notifyNextMessageInListGot - listId: "
@ -657,8 +657,7 @@ MobileMessageDatabaseService.prototype = {
if (!aCallback) {
return;
}
let sms = self.createMessageFromRecord(aRecord);
aCallback.notify(rv, sms);
aCallback.notify(rv, aRecord);
}
this.newTxn(READ_WRITE, function(error, txn, stores) {
@ -678,9 +677,8 @@ MobileMessageDatabaseService.prototype = {
// First add to main objectStore.
stores[0].put(aRecord);
let number = getNumberFromRecord(aRecord);
// Next update the other objectStore.
let number = getNumberFromRecord(aRecord);
stores[1].get(number).onsuccess = function onsuccess(event) {
let mostRecentEntry = event.target.result;
if (mostRecentEntry) {
@ -713,100 +711,96 @@ MobileMessageDatabaseService.prototype = {
return aRecord.id;
},
getRilIccInfoMsisdn: function getRilIccInfoMsisdn() {
let iccInfo = this.mRIL.rilContext.iccInfo;
let number = iccInfo ? iccInfo.msisdn : null;
// Workaround an xpconnect issue with undefined string objects.
// See bug 808220
if (number === undefined || number === "undefined") {
return null;
}
return number;
},
makePhoneNumberInternational: function makePhoneNumberInternational(aNumber) {
if (!aNumber) {
return aNumber;
}
let parsedNumber = PhoneNumberUtils.parse(aNumber.toString());
if (!parsedNumber || !parsedNumber.internationalNumber) {
return aNumber;
}
return parsedNumber.internationalNumber;
},
/**
* nsIRilMobileMessageDatabaseService API
*/
saveReceivedMessage: function saveReceivedMessage(
aSender, aBody, aMessageClass, aDate, aCallback) {
let iccInfo = this.mRIL.rilContext.iccInfo;
let receiver = iccInfo ? iccInfo.msisdn : null;
// Workaround an xpconnect issue with undefined string objects.
// See bug 808220
if (receiver === undefined || receiver === "undefined") {
receiver = null;
saveReceivedMessage: function saveReceivedMessage(aMessage, aCallback) {
if (aMessage.type === undefined ||
aMessage.sender === undefined ||
aMessage.messageClass === undefined ||
aMessage.timestamp === undefined) {
if (aCallback) {
aCallback.notify(Cr.NS_ERROR_FAILURE, null);
}
return;
}
if (receiver) {
let parsedNumber = PhoneNumberUtils.parse(receiver);
receiver = (parsedNumber && parsedNumber.internationalNumber)
? parsedNumber.internationalNumber
: receiver;
}
let receiver = this.getRilIccInfoMsisdn();
receiver = this.makePhoneNumberInternational(receiver);
let sender = aSender;
if (sender) {
let parsedNumber = PhoneNumberUtils.parse(sender);
sender = (parsedNumber && parsedNumber.internationalNumber)
? parsedNumber.internationalNumber
: sender;
}
let sender = aMessage.sender =
this.makePhoneNumberInternational(aMessage.sender);
let record = {
deliveryIndex: [DELIVERY_RECEIVED, aDate],
numberIndex: [[sender, aDate], [receiver, aDate]],
readIndex: [FILTER_READ_UNREAD, aDate],
let timestamp = aMessage.timestamp;
delivery: DELIVERY_RECEIVED,
deliveryStatus: DELIVERY_STATUS_SUCCESS,
sender: sender,
receiver: receiver,
body: aBody,
messageClass: aMessageClass,
timestamp: aDate,
read: FILTER_READ_UNREAD
};
return this.saveRecord(record, aCallback);
// Adding needed indexes and extra attributes for internal use.
aMessage.deliveryIndex = [DELIVERY_RECEIVED, timestamp];
aMessage.numberIndex = [[sender, timestamp], [receiver, timestamp]];
aMessage.readIndex = [FILTER_READ_UNREAD, timestamp];
aMessage.delivery = DELIVERY_RECEIVED;
aMessage.deliveryStatus = DELIVERY_STATUS_SUCCESS;
aMessage.receiver = receiver;
aMessage.read = FILTER_READ_UNREAD;
return this.saveRecord(aMessage, aCallback);
},
saveSendingMessage: function saveSendingMessage(
aReceiver, aBody, aDeliveryStatus, aDate, aCallback) {
saveSendingMessage: function saveSendingMessage(aMessage, aCallback) {
if (aMessage.type === undefined ||
aMessage.receiver === undefined ||
aMessage.deliveryStatus === undefined ||
aMessage.timestamp === undefined) {
if (aCallback) {
aCallback.notify(Cr.NS_ERROR_FAILURE, null);
}
return;
}
let sender = this.getRilIccInfoMsisdn();
let receiver = aMessage.receiver;
let rilContext = this.mRIL.rilContext;
let sender = rilContext.iccInfo
? rilContext.iccInfo.msisdn
: null;
// Workaround an xpconnect issue with undefined string objects.
// See bug 808220
if (sender === undefined || sender === "undefined") {
sender = null;
}
let receiver = aReceiver;
if (rilContext.voice.network.mcc === rilContext.iccInfo.mcc) {
if (receiver) {
let parsedNumber = PhoneNumberUtils.parse(receiver.toString());
receiver = (parsedNumber && parsedNumber.internationalNumber)
? parsedNumber.internationalNumber
: receiver;
receiver = aMessage.receiver = this.makePhoneNumberInternational(receiver);
sender = this.makePhoneNumberInternational(sender);
}
if (sender) {
let parsedNumber = PhoneNumberUtils.parse(sender.toString());
sender = (parsedNumber && parsedNumber.internationalNumber)
? parsedNumber.internationalNumber
: sender;
}
}
let timestamp = aMessage.timestamp;
let record = {
deliveryIndex: [DELIVERY_SENDING, aDate],
numberIndex: [[sender, aDate], [receiver, aDate]],
readIndex: [FILTER_READ_READ, aDate],
// Adding needed indexes and extra attributes for internal use.
aMessage.deliveryIndex = [DELIVERY_SENDING, timestamp];
aMessage.numberIndex = [[sender, timestamp], [receiver, timestamp]];
aMessage.readIndex = [FILTER_READ_READ, timestamp];
aMessage.delivery = DELIVERY_SENDING;
aMessage.sender = sender;
aMessage.messageClass = MESSAGE_CLASS_NORMAL;
aMessage.read = FILTER_READ_READ;
delivery: DELIVERY_SENDING,
deliveryStatus: aDeliveryStatus,
sender: sender,
receiver: receiver,
body: aBody,
messageClass: MESSAGE_CLASS_NORMAL,
timestamp: aDate,
read: FILTER_READ_READ
};
return this.saveRecord(record, aCallback);
return this.saveRecord(aMessage, aCallback);
},
setMessageDelivery: function setMessageDelivery(
@ -822,11 +816,7 @@ MobileMessageDatabaseService.prototype = {
if (!callback) {
return;
}
let sms = null;
if (record) {
sms = self.createMessageFromRecord(record);
}
callback.notify(rv, sms);
callback.notify(rv, record);
}
this.newTxn(READ_WRITE, function (error, txn, store) {
@ -914,7 +904,7 @@ MobileMessageDatabaseService.prototype = {
aRequest.notifyGetMessageFailed(Ci.nsISmsRequest.UNKNOWN_ERROR);
return;
}
let sms = self.createMessageFromRecord(record);
let sms = self.createSmsMessageFromRecord(record);
aRequest.notifyMessageGot(sms);
};
@ -1327,7 +1317,7 @@ MobileMessageDatabaseService.prototype = {
if (DEBUG) debug("Could not get message id " + messageId);
aRequest.notifyReadMessageListFailed(Ci.nsISmsRequest.NOT_FOUND_ERROR);
}
let sms = self.createMessageFromRecord(record);
let sms = self.createSmsMessageFromRecord(record);
aRequest.notifyNextMessageInListGot(sms);
};

Просмотреть файл

@ -177,21 +177,27 @@ function newRandomId() {
let sms = [
{
type: "sms",
sender: "+34666000000",
receiver: "+34666111000",
body: "message 0",
messageClass: "normal",
timestamp: 1329999861762
},
{
type: "sms",
sender: "+34666000111",
receiver: "+34666111111",
body: "message 1",
messageClass: "normal",
timestamp: 1329999861763
},
{
type: "sms",
sender: "+34666000222",
receiver: "+34666111222",
body: "message 2",
messageClass: "normal",
timestamp: 1329999861764
},
];
@ -201,9 +207,7 @@ let sms = [
*/
add_test(function test_saveReceivedMessage() {
info("test_saveReceivedMessage");
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[0].sender,
sms[0].body,
sms[0].timestamp);
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[0]);
checkDB(function (store) {
let request = store.get(messageId);
request.onsuccess = function onsuccess() {
@ -262,9 +266,7 @@ add_test(function test_getMessage_success() {
run_next_test();
}
});
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[2].sender,
sms[2].body,
sms[2].timestamp);
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[2]);
SimpleTest.executeSoon(function () {
gMobileMessageDatabaseService.getMessage(messageId, fakeRequestId);
});
@ -821,9 +823,7 @@ add_test(function test_deleteMessage_success() {
run_next_test();
}
});
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[0].sender,
sms[0].body,
sms[0].timestamp);
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[0]);
SimpleTest.executeSoon(function () {
gMobileMessageDatabaseService.deleteMessage(messageId, fakeRequestId);
});
@ -852,9 +852,7 @@ add_test(function test_markMessageRead_success() {
run_next_test();
}
});
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[2].sender,
sms[2].body,
sms[2].timestamp);
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[2]);
SimpleTest.executeSoon(function () {
gMobileMessageDatabaseService.markMessageRead(messageId, true, fakeRequestId);
});

Просмотреть файл

@ -1476,6 +1476,18 @@ RadioInterfaceLayer.prototype = {
0, options);
},
createSmsMessageFromRecord: function createSmsMessageFromRecord(aRecord) {
return gSmsService.createSmsMessage(aRecord.id,
aRecord.delivery,
aRecord.deliveryStatus,
aRecord.sender,
aRecord.receiver,
aRecord.body,
aRecord.messageClass,
aRecord.timestamp,
aRecord.read);
},
portAddressedSmsApps: null,
handleSmsReceived: function handleSmsReceived(message) {
debug("handleSmsReceived: " + JSON.stringify(message));
@ -1501,6 +1513,11 @@ RadioInterfaceLayer.prototype = {
return true;
}
message.type = "sms";
message.sender = message.sender || null;
message.receiver = message.receiver || null;
message.body = message.fullBody = message.fullBody || null;
// TODO: Bug #768441
// For now we don't store indicators persistently. When the mwi.discard
// flag is false, we'll need to persist the indicator to EFmwis.
@ -1508,13 +1525,14 @@ RadioInterfaceLayer.prototype = {
let mwi = message.mwi;
if (mwi) {
mwi.returnNumber = message.sender || null;
mwi.returnMessage = message.fullBody || null;
mwi.returnNumber = message.sender;
mwi.returnMessage = message.fullBody;
this._sendTargetMessage("voicemail", "RIL:VoicemailNotification", mwi);
return true;
}
let notifyReceived = function notifyReceived(rv, sms) {
let notifyReceived = function notifyReceived(rv, record) {
let sms = this.createSmsMessageFromRecord(record);
let success = Components.isSuccessCode(rv);
// Acknowledge the reception of the SMS.
@ -1535,35 +1553,27 @@ RadioInterfaceLayer.prototype = {
id: message.id,
delivery: DOM_SMS_DELIVERY_RECEIVED,
deliveryStatus: RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS,
sender: message.sender || null,
receiver: message.receiver || null,
body: message.fullBody || null,
sender: message.sender,
receiver: message.receiver,
body: message.fullBody,
messageClass: message.messageClass,
timestamp: message.timestamp,
read: false
});
Services.obs.notifyObservers(sms, kSmsReceivedObserverTopic, null);
}.bind(this);
if (message.messageClass != RIL.GECKO_SMS_MESSAGE_CLASSES[RIL.PDU_DCS_MSG_CLASS_0]) {
message.id = gMobileMessageDatabaseService.saveReceivedMessage(
message.sender || null,
message.fullBody || null,
message.messageClass,
message.timestamp,
message.id = gMobileMessageDatabaseService.saveReceivedMessage(message,
notifyReceived);
} else {
message.id = -1;
let sms = gSmsService.createSmsMessage(message.id,
DOM_SMS_DELIVERY_RECEIVED,
RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS,
message.sender || null,
message.receiver || null,
message.fullBody || null,
message.messageClass,
message.timestamp,
false);
notifyReceived(Cr.NS_OK, sms);
message.delivery = DOM_SMS_DELIVERY_RECEIVED;
message.deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS;
message.read = false;
notifyReceived(Cr.NS_OK, message);
}
// SMS ACK will be sent in notifyReceived. Return false here.
@ -1596,7 +1606,8 @@ RadioInterfaceLayer.prototype = {
gMobileMessageDatabaseService.setMessageDelivery(options.sms.id,
DOM_SMS_DELIVERY_SENT,
options.sms.deliveryStatus,
function notifyResult(rv, sms) {
function notifyResult(rv, record) {
let sms = this.createSmsMessageFromRecord(record);
//TODO bug 832140 handle !Components.isSuccessCode(rv)
gSystemMessenger.broadcastMessage("sms-sent",
{id: options.sms.id,
@ -1634,13 +1645,14 @@ RadioInterfaceLayer.prototype = {
gMobileMessageDatabaseService.setMessageDelivery(options.sms.id,
options.sms.delivery,
message.deliveryStatus,
function notifyResult(rv, sms) {
function notifyResult(rv, record) {
let sms = this.createSmsMessageFromRecord(record);
//TODO bug 832140 handle !Components.isSuccessCode(rv)
let topic = (message.deliveryStatus == RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS)
? kSmsDeliverySuccessObserverTopic
: kSmsDeliveryErrorObserverTopic;
Services.obs.notifyObservers(sms, topic, null);
});
}.bind(this));
},
handleSmsSendFailed: function handleSmsSendFailed(message) {
@ -1662,11 +1674,12 @@ RadioInterfaceLayer.prototype = {
gMobileMessageDatabaseService.setMessageDelivery(options.sms.id,
DOM_SMS_DELIVERY_ERROR,
RIL.GECKO_SMS_DELIVERY_STATUS_ERROR,
function notifyResult(rv, sms) {
function notifyResult(rv, record) {
let sms = this.createSmsMessageFromRecord(record);
//TODO bug 832140 handle !Components.isSuccessCode(rv)
options.request.notifySendMessageFailed(error);
Services.obs.notifyObservers(sms, kSmsFailedObserverTopic, null);
});
}.bind(this));
},
/**
@ -2645,8 +2658,17 @@ RadioInterfaceLayer.prototype = {
let deliveryStatus = options.requestStatusReport
? RIL.GECKO_SMS_DELIVERY_STATUS_PENDING
: RIL.GECKO_SMS_DELIVERY_STATUS_NOT_APPLICABLE;
let id = gMobileMessageDatabaseService.saveSendingMessage(number, message, deliveryStatus, timestamp,
function notifyResult(rv, sms) {
let sendingMessage = {
type: "sms",
receiver: number,
body: message,
deliveryStatus: deliveryStatus,
timestamp: timestamp
};
let id = gMobileMessageDatabaseService.saveSendingMessage(sendingMessage,
function notifyResult(rv, record) {
let sms = this.createSmsMessageFromRecord(record);
//TODO bug 832140 handle !Components.isSuccessCode(rv)
Services.obs.notifyObservers(sms, kSmsSendingObserverTopic, null);