зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1072808 - Part 2: Add SmsMessenger as a Wrapper for Sms-Related System Messages. r=echen
This commit is contained in:
Родитель
17c1f46219
Коммит
24d942773e
|
@ -21,6 +21,7 @@ XPIDL_SOURCES += [
|
|||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_B2G_RIL']:
|
||||
XPIDL_SOURCES += [
|
||||
'nsIRilMobileMessageDatabaseService.idl',
|
||||
'nsISmsMessenger.idl',
|
||||
]
|
||||
|
||||
XPIDL_MODULE = 'dom_mobilemessage'
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/* 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 "domstubs.idl"
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(f77ad4d4-68a9-11e4-920f-0b26b7a5e713)]
|
||||
interface nsISmsMessenger : nsISupports
|
||||
{
|
||||
/* 'sms-received' system message */
|
||||
const unsigned short NOTIFICATION_TYPE_RECEIVED = 0;
|
||||
/* 'sms-sent' system message */
|
||||
const unsigned short NOTIFICATION_TYPE_SENT = 1;
|
||||
/* 'sms-delivery-success' system message */
|
||||
const unsigned short NOTIFICATION_TYPE_DELIVERY_SUCCESS = 2;
|
||||
|
||||
/**
|
||||
* To broadcast 'sms-received', 'sms-delivery-success', 'sms-sent' system message
|
||||
*
|
||||
* Note: Except aNotificationType, all parameters are the attributes of the
|
||||
* nsIDOMMozSmsMessage generated by nsIMobileMessageService.createSmsMessage().
|
||||
*
|
||||
* @param aNotificationType
|
||||
* A predefined constant of nsISmsMessenger.NOTIFICATION_TYPE_*.
|
||||
* @param aId
|
||||
* The unique identity of this message.
|
||||
* @param aThreadId
|
||||
* The unique identity of the thread this message belongs to.
|
||||
* @param aIccId
|
||||
* Integrated Circuit Card Identifier. null if ICC is not available.
|
||||
* @param aDelivery
|
||||
* A predefined constant of nsISmsService.DELIVERY_TYPE_*.
|
||||
* @param aDeliveryStatus
|
||||
* A predefined constant of nsISmsService.DELIVERY_STATUS_TYPE_*.
|
||||
* @param aSender
|
||||
* Sender address. null if not available.
|
||||
* @param aReceiver
|
||||
* Receiver address. null if not available.
|
||||
* @param aBody
|
||||
* Text message body. null if not available.
|
||||
* @param aMessageClass
|
||||
* A predefined constant of nsISmsService.MESSAGE_CLASS_TYPE_*.
|
||||
* @param aTimestamp
|
||||
* The device system time when creating or saving this message.
|
||||
* @param aSentTimestamp
|
||||
* The SMSC timestamp of the incoming message.
|
||||
* 0 if not available.
|
||||
* @param aDeliveryTimestamp
|
||||
* The delivery timestamp to the remote party of the sent message.
|
||||
* 0 if not available.
|
||||
* @param aRead
|
||||
* True if the message was read.
|
||||
*/
|
||||
void notifySms(in unsigned short aNotificationType,
|
||||
in long aId,
|
||||
in unsigned long long aThreadId,
|
||||
in DOMString aIccId,
|
||||
in unsigned long aDelivery,
|
||||
in unsigned long aDeliveryStatus,
|
||||
in DOMString aSender,
|
||||
in DOMString aReceiver,
|
||||
in DOMString aBody,
|
||||
in unsigned long aMessageClass,
|
||||
in DOMTimeStamp aTimestamp,
|
||||
in DOMTimeStamp aSentTimestamp,
|
||||
in DOMTimeStamp aDeliveryTimestamp,
|
||||
in boolean aRead);
|
||||
};
|
|
@ -12,9 +12,35 @@ interface nsIMobileMessageCallback;
|
|||
#define SMS_SERVICE_CONTRACTID "@mozilla.org/sms/smsservice;1"
|
||||
%}
|
||||
|
||||
[scriptable, builtinclass, uuid(cb7d7b60-01f1-4241-a0ae-2ff035c3fbe5)]
|
||||
[scriptable, builtinclass, uuid(8f86d068-698e-11e4-9470-8f75a088b84a)]
|
||||
interface nsISmsService : nsISupports
|
||||
{
|
||||
/**
|
||||
* Constant definitions of predefined GSM Message Class
|
||||
* See 3GPP TS 23.038 clause 4 SMS Data Coding Scheme
|
||||
*/
|
||||
const unsigned short MESSAGE_CLASS_TYPE_CLASS_0 = 0;
|
||||
const unsigned short MESSAGE_CLASS_TYPE_CLASS_1 = 1;
|
||||
const unsigned short MESSAGE_CLASS_TYPE_CLASS_2 = 2;
|
||||
const unsigned short MESSAGE_CLASS_TYPE_CLASS_3 = 3;
|
||||
const unsigned short MESSAGE_CLASS_TYPE_NORMAL = 6;
|
||||
|
||||
/**
|
||||
* Constant definitions of SMS Delivery
|
||||
*/
|
||||
const unsigned short DELIVERY_TYPE_RECEIVED = 0;
|
||||
const unsigned short DELIVERY_TYPE_SENDING = 1;
|
||||
const unsigned short DELIVERY_TYPE_SENT = 2;
|
||||
const unsigned short DELIVERY_TYPE_ERROR = 3;
|
||||
|
||||
/**
|
||||
* Constant definitions of SMS Delivery Status
|
||||
*/
|
||||
const unsigned short DELIVERY_STATUS_TYPE_NOT_APPLICABLE = 0;
|
||||
const unsigned short DELIVERY_STATUS_TYPE_SUCCESS = 1;
|
||||
const unsigned short DELIVERY_STATUS_TYPE_PENDING = 2;
|
||||
const unsigned short DELIVERY_STATUS_TYPE_ERROR = 3;
|
||||
|
||||
readonly attribute unsigned long smsDefaultServiceId;
|
||||
|
||||
void getSegmentInfoForText(in DOMString text,
|
||||
|
|
|
@ -4,6 +4,16 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "RIL", function () {
|
||||
let obj = {};
|
||||
Cu.import("resource://gre/modules/ril_consts.js", obj);
|
||||
return obj;
|
||||
});
|
||||
|
||||
/**
|
||||
* RILSystemMessenger
|
||||
*/
|
||||
|
@ -48,6 +58,54 @@ RILSystemMessenger.prototype = {
|
|||
}
|
||||
|
||||
this.broadcastMessage("telephony-call-ended", data);
|
||||
},
|
||||
|
||||
_convertSmsMessageClass: function(aMessageClass) {
|
||||
return RIL.GECKO_SMS_MESSAGE_CLASSES[aMessageClass] || null;
|
||||
},
|
||||
|
||||
_convertSmsDelivery: function(aDelivery) {
|
||||
return ["received", "sending", "sent", "error"][aDelivery] || null;
|
||||
},
|
||||
|
||||
_convertSmsDeliveryStatus: function(aDeliveryStatus) {
|
||||
return [
|
||||
RIL.GECKO_SMS_DELIVERY_STATUS_NOT_APPLICABLE,
|
||||
RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS,
|
||||
RIL.GECKO_SMS_DELIVERY_STATUS_PENDING,
|
||||
RIL.GECKO_SMS_DELIVERY_STATUS_ERROR
|
||||
][aDeliveryStatus] || null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Wrapper to send 'sms-received', 'sms-delivery-success', 'sms-sent' system message.
|
||||
*/
|
||||
notifySms: function(aNotificationType, aId, aThreadId, aIccId, aDelivery,
|
||||
aDeliveryStatus, aSender, aReceiver, aBody, aMessageClass,
|
||||
aTimestamp, aSentTimestamp, aDeliveryTimestamp, aRead) {
|
||||
let msgType =
|
||||
["sms-received", "sms-sent", "sms-delivery-success"][aNotificationType];
|
||||
|
||||
if (!msgType) {
|
||||
throw new Error("Invalid Notification Type: " + aNotificationType);
|
||||
}
|
||||
|
||||
this.broadcastMessage(msgType, {
|
||||
iccId: aIccId,
|
||||
type: "sms",
|
||||
id: aId,
|
||||
threadId: aThreadId,
|
||||
delivery: this._convertSmsDelivery(aDelivery),
|
||||
deliveryStatus: this._convertSmsDeliveryStatus(aDeliveryStatus),
|
||||
sender: aSender,
|
||||
receiver: aReceiver,
|
||||
body: aBody,
|
||||
messageClass: this._convertSmsMessageClass(aMessageClass),
|
||||
timestamp: aTimestamp,
|
||||
sentTimestamp: aSentTimestamp,
|
||||
deliveryTimestamp: aDeliveryTimestamp,
|
||||
read: aRead
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -49,7 +49,8 @@ function RILSystemMessengerHelper() {
|
|||
RILSystemMessengerHelper.prototype = {
|
||||
|
||||
classID: RILSYSTEMMESSENGERHELPER_CID,
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsITelephonyMessenger]),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsITelephonyMessenger,
|
||||
Ci.nsISmsMessenger]),
|
||||
|
||||
/**
|
||||
* RILSystemMessenger instance.
|
||||
|
@ -67,6 +68,17 @@ RILSystemMessengerHelper.prototype = {
|
|||
aDuration, aOutgoing, aHangUpLocal) {
|
||||
this.messenger.notifyCallEnded(aServiceId, aNumber, aCdmaWaitingNumber, aEmergency,
|
||||
aDuration, aOutgoing, aHangUpLocal);
|
||||
},
|
||||
|
||||
/**
|
||||
* nsISmsMessenger API
|
||||
*/
|
||||
notifySms: function(aNotificationType, aId, aThreadId, aIccId, aDelivery,
|
||||
aDeliveryStatus, aSender, aReceiver, aBody, aMessageClass,
|
||||
aTimestamp, aSentTimestamp, aDeliveryTimestamp, aRead) {
|
||||
this.messenger.notifySms(aNotificationType, aId, aThreadId, aIccId, aDelivery,
|
||||
aDeliveryStatus, aSender, aReceiver, aBody, aMessageClass,
|
||||
aTimestamp, aSentTimestamp, aDeliveryTimestamp, aRead);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -187,6 +187,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "gCellBroadcastService",
|
|||
"@mozilla.org/cellbroadcast/gonkservice;1",
|
||||
"nsIGonkCellBroadcastService");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "gSmsMessenger",
|
||||
"@mozilla.org/ril/system-messenger-helper;1",
|
||||
"nsISmsMessenger");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "WAP", function() {
|
||||
let wap = {};
|
||||
Cu.import("resource://gre/modules/WapPushManager.js", wap);
|
||||
|
@ -2171,6 +2175,42 @@ RadioInterface.prototype = {
|
|||
0, options);
|
||||
},
|
||||
|
||||
_convertSmsMessageClass: function(aMessageClass) {
|
||||
let index = RIL.GECKO_SMS_MESSAGE_CLASSES.indexOf(aMessageClass);
|
||||
|
||||
if (index < 0) {
|
||||
throw new Error("Invalid MessageClass: " + aMessageClass);
|
||||
}
|
||||
|
||||
return index;
|
||||
},
|
||||
|
||||
_convertSmsDelivery: function(aDelivery) {
|
||||
let index = [DOM_MOBILE_MESSAGE_DELIVERY_RECEIVED,
|
||||
DOM_MOBILE_MESSAGE_DELIVERY_SENDING,
|
||||
DOM_MOBILE_MESSAGE_DELIVERY_SENT,
|
||||
DOM_MOBILE_MESSAGE_DELIVERY_ERROR].indexOf(aDelivery);
|
||||
|
||||
if (index < 0) {
|
||||
throw new Error("Invalid Delivery: " + aDelivery);
|
||||
}
|
||||
|
||||
return index;
|
||||
},
|
||||
|
||||
_convertSmsDeliveryStatus: function(aDeliveryStatus) {
|
||||
let index = [RIL.GECKO_SMS_DELIVERY_STATUS_NOT_APPLICABLE,
|
||||
RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS,
|
||||
RIL.GECKO_SMS_DELIVERY_STATUS_PENDING,
|
||||
RIL.GECKO_SMS_DELIVERY_STATUS_ERROR].indexOf(aDeliveryStatus);
|
||||
|
||||
if (index < 0) {
|
||||
throw new Error("Invalid DeliveryStatus: " + aDeliveryStatus);
|
||||
}
|
||||
|
||||
return index;
|
||||
},
|
||||
|
||||
/**
|
||||
* A helper to broadcast the system message to launch registered apps
|
||||
* like Costcontrol, Notification and Message app... etc.
|
||||
|
@ -2180,28 +2220,35 @@ RadioInterface.prototype = {
|
|||
* @param aDomMessage
|
||||
* The nsIDOMMozSmsMessage object.
|
||||
*/
|
||||
broadcastSmsSystemMessage: function(aName, aDomMessage) {
|
||||
if (DEBUG) this.debug("Broadcasting the SMS system message: " + aName);
|
||||
broadcastSmsSystemMessage: function(aNotificationType, aDomMessage) {
|
||||
if (DEBUG) this.debug("Broadcasting the SMS system message: " + aNotificationType);
|
||||
|
||||
// Sadly we cannot directly broadcast the aDomMessage object
|
||||
// because the system message mechamism will rewrap the object
|
||||
// based on the content window, which needs to know the properties.
|
||||
gSystemMessenger.broadcastMessage(aName, {
|
||||
iccId: aDomMessage.iccId,
|
||||
type: aDomMessage.type,
|
||||
id: aDomMessage.id,
|
||||
threadId: aDomMessage.threadId,
|
||||
delivery: aDomMessage.delivery,
|
||||
deliveryStatus: aDomMessage.deliveryStatus,
|
||||
sender: aDomMessage.sender,
|
||||
receiver: aDomMessage.receiver,
|
||||
body: aDomMessage.body,
|
||||
messageClass: aDomMessage.messageClass,
|
||||
timestamp: aDomMessage.timestamp,
|
||||
sentTimestamp: aDomMessage.sentTimestamp,
|
||||
deliveryTimestamp: aDomMessage.deliveryTimestamp,
|
||||
read: aDomMessage.read
|
||||
});
|
||||
try {
|
||||
gSmsMessenger.notifySms(aNotificationType,
|
||||
aDomMessage.id,
|
||||
aDomMessage.threadId,
|
||||
aDomMessage.iccId,
|
||||
this._convertSmsDelivery(
|
||||
aDomMessage.delivery),
|
||||
this._convertSmsDeliveryStatus(
|
||||
aDomMessage.deliveryStatus),
|
||||
aDomMessage.sender,
|
||||
aDomMessage.receiver,
|
||||
aDomMessage.body,
|
||||
this._convertSmsMessageClass(
|
||||
aDomMessage.messageClass),
|
||||
aDomMessage.timestamp,
|
||||
aDomMessage.sentTimestamp,
|
||||
aDomMessage.deliveryTimestamp,
|
||||
aDomMessage.read);
|
||||
} catch (e) {
|
||||
if (DEBUG) {
|
||||
this.debug("Failed to broadcastSmsSystemMessage: " + e);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// The following attributes/functions are used for acquiring/releasing the
|
||||
|
@ -2546,7 +2593,8 @@ RadioInterface.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
this.broadcastSmsSystemMessage(kSmsReceivedObserverTopic, domMessage);
|
||||
this.broadcastSmsSystemMessage(
|
||||
Ci.nsISmsMessenger.NOTIFICATION_TYPE_RECEIVED, domMessage);
|
||||
Services.obs.notifyObservers(domMessage, kSmsReceivedObserverTopic, null);
|
||||
}.bind(this);
|
||||
|
||||
|
@ -3663,7 +3711,8 @@ RadioInterface.prototype = {
|
|||
|
||||
// Broadcasting a "sms-delivery-success" system message to open apps.
|
||||
if (topic == kSmsDeliverySuccessObserverTopic) {
|
||||
this.broadcastSmsSystemMessage(topic, domMessage);
|
||||
this.broadcastSmsSystemMessage(
|
||||
Ci.nsISmsMessenger.NOTIFICATION_TYPE_DELIVERY_SUCCESS, domMessage);
|
||||
}
|
||||
|
||||
// Notifying observers the delivery status is updated.
|
||||
|
@ -3711,7 +3760,8 @@ RadioInterface.prototype = {
|
|||
context.sms = domMessage;
|
||||
}
|
||||
|
||||
this.broadcastSmsSystemMessage(kSmsSentObserverTopic, domMessage);
|
||||
this.broadcastSmsSystemMessage(
|
||||
Ci.nsISmsMessenger.NOTIFICATION_TYPE_SENT, domMessage);
|
||||
context.request.notifyMessageSent(domMessage);
|
||||
Services.obs.notifyObservers(domMessage, kSmsSentObserverTopic, null);
|
||||
}).bind(this));
|
||||
|
|
|
@ -48,7 +48,11 @@ function run_test() {
|
|||
let telephonyMessenger = Cc["@mozilla.org/ril/system-messenger-helper;1"]
|
||||
.getService(Ci.nsITelephonyMessenger);
|
||||
|
||||
let smsMessenger = Cc["@mozilla.org/ril/system-messenger-helper;1"]
|
||||
.getService(Ci.nsISmsMessenger);
|
||||
|
||||
ok(telephonyMessenger !== null, "Get TelephonyMessenger.");
|
||||
ok(smsMessenger != null, "Get SmsMessenger.");
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
@ -109,3 +113,133 @@ add_test(function test_telephony_messenger_notify_call_ended() {
|
|||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify RILSystemMessenger.notifySms()
|
||||
*/
|
||||
add_test(function test_sms_messenger_notify_sms() {
|
||||
let messenger = newRILSystemMessenger();
|
||||
let timestamp = Date.now();
|
||||
let sentTimestamp = timestamp + 100;
|
||||
let deliveryTimestamp = sentTimestamp + 100;
|
||||
|
||||
// Verify 'sms-received' system message.
|
||||
messenger.notifySms(Ci.nsISmsMessenger.NOTIFICATION_TYPE_RECEIVED,
|
||||
1,
|
||||
2,
|
||||
"99887766554433221100",
|
||||
Ci.nsISmsService.DELIVERY_TYPE_RECEIVED,
|
||||
Ci.nsISmsService.DELIVERY_STATUS_TYPE_SUCCESS,
|
||||
"+0987654321",
|
||||
null,
|
||||
"Incoming message",
|
||||
Ci.nsISmsService.MESSAGE_CLASS_TYPE_CLASS_2,
|
||||
timestamp,
|
||||
sentTimestamp,
|
||||
0,
|
||||
false);
|
||||
|
||||
equal_received_system_message("sms-received", {
|
||||
iccId: "99887766554433221100",
|
||||
type: "sms",
|
||||
id: 1,
|
||||
threadId: 2,
|
||||
delivery: "received",
|
||||
deliveryStatus: "success",
|
||||
sender: "+0987654321",
|
||||
receiver: null,
|
||||
body: "Incoming message",
|
||||
messageClass: "class-2",
|
||||
timestamp: timestamp,
|
||||
sentTimestamp: sentTimestamp,
|
||||
deliveryTimestamp: 0,
|
||||
read: false
|
||||
});
|
||||
|
||||
// Verify 'sms-sent' system message.
|
||||
messenger.notifySms(Ci.nsISmsMessenger.NOTIFICATION_TYPE_SENT,
|
||||
3,
|
||||
4,
|
||||
"99887766554433221100",
|
||||
Ci.nsISmsService.DELIVERY_TYPE_SENT,
|
||||
Ci.nsISmsService.DELIVERY_STATUS_TYPE_PENDING,
|
||||
null,
|
||||
"+0987654321",
|
||||
"Outgoing message",
|
||||
Ci.nsISmsService.MESSAGE_CLASS_TYPE_NORMAL,
|
||||
timestamp,
|
||||
0,
|
||||
0,
|
||||
true);
|
||||
|
||||
equal_received_system_message("sms-sent", {
|
||||
iccId: "99887766554433221100",
|
||||
type: "sms",
|
||||
id: 3,
|
||||
threadId: 4,
|
||||
delivery: "sent",
|
||||
deliveryStatus: "pending",
|
||||
sender: null,
|
||||
receiver: "+0987654321",
|
||||
body: "Outgoing message",
|
||||
messageClass: "normal",
|
||||
timestamp: timestamp,
|
||||
sentTimestamp: 0,
|
||||
deliveryTimestamp: 0,
|
||||
read: true
|
||||
});
|
||||
|
||||
// Verify 'sms-delivery-success' system message.
|
||||
messenger.notifySms(Ci.nsISmsMessenger.NOTIFICATION_TYPE_DELIVERY_SUCCESS,
|
||||
5,
|
||||
6,
|
||||
"99887766554433221100",
|
||||
Ci.nsISmsService.DELIVERY_TYPE_SENT,
|
||||
Ci.nsISmsService.DELIVERY_STATUS_TYPE_SUCCESS,
|
||||
null,
|
||||
"+0987654321",
|
||||
"Outgoing message",
|
||||
Ci.nsISmsService.MESSAGE_CLASS_TYPE_NORMAL,
|
||||
timestamp,
|
||||
0,
|
||||
deliveryTimestamp,
|
||||
true);
|
||||
|
||||
equal_received_system_message("sms-delivery-success", {
|
||||
iccId: "99887766554433221100",
|
||||
type: "sms",
|
||||
id: 5,
|
||||
threadId: 6,
|
||||
delivery: "sent",
|
||||
deliveryStatus: "success",
|
||||
sender: null,
|
||||
receiver: "+0987654321",
|
||||
body: "Outgoing message",
|
||||
messageClass: "normal",
|
||||
timestamp: timestamp,
|
||||
sentTimestamp: 0,
|
||||
deliveryTimestamp: deliveryTimestamp,
|
||||
read: true
|
||||
});
|
||||
|
||||
// Verify the protection of invalid nsISmsMessenger.NOTIFICATION_TYPEs.
|
||||
try {
|
||||
messenger.notifySms(3,
|
||||
1,
|
||||
2,
|
||||
"99887766554433221100",
|
||||
Ci.nsISmsService.DELIVERY_TYPE_RECEIVED,
|
||||
Ci.nsISmsService.DELIVERY_STATUS_TYPE_SUCCESS,
|
||||
"+0987654321",
|
||||
null,
|
||||
"Incoming message",
|
||||
Ci.nsISmsService.MESSAGE_CLASS_TYPE_NORMAL,
|
||||
timestamp,
|
||||
sentTimestamp,
|
||||
0,
|
||||
false);
|
||||
ok(false, "Failed to verify the protection of invalid nsISmsMessenger.NOTIFICATION_TYPE!");
|
||||
} catch (e) {}
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче