diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml
index a332a160c836..feaafbb93466 100644
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index 8ad0c6f2a938..8b4a531b49ca 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,7 +19,7 @@
-
+
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index 7a095ece86d5..fa37d5d70e55 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,7 +17,7 @@
-
+
@@ -134,7 +134,7 @@
-
+
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index ed2102d4a01f..ff6b48609111 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index 8ad0c6f2a938..8b4a531b49ca 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,7 +19,7 @@
-
+
diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml
index 90cf921d6666..7db74a4d186a 100644
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -15,7 +15,7 @@
-
+
@@ -151,7 +151,7 @@
-
+
diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml
index bb3a9eeefb1a..2076adf92a1a 100644
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -17,7 +17,7 @@
-
+
@@ -145,7 +145,7 @@
-
+
diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index 423126337474..e89440c295b4 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
- "revision": "69b4d72a6b80008de044e535d9ff785631bd7f2b",
+ "revision": "291b607f32e6173d8fe225c644cc7397cdf82fa5",
"repo_path": "/integration/gaia-central"
}
diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml
index 0f562a1b1bf4..dc0128dfa926 100644
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml
index b166606dab89..51d5693379bf 100644
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index dab254806024..a5b5ee9fc4e3 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -17,7 +17,7 @@
-
+
@@ -129,7 +129,7 @@
-
+
diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml
index 1a3d431a85a1..373ecf9cc9bf 100644
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/dom/mobileconnection/gonk/MobileConnectionService.js b/dom/mobileconnection/gonk/MobileConnectionService.js
index 74786b3f3a6c..8d865d351e32 100644
--- a/dom/mobileconnection/gonk/MobileConnectionService.js
+++ b/dom/mobileconnection/gonk/MobileConnectionService.js
@@ -950,6 +950,11 @@ MobileConnectionService.prototype = {
} catch (e) {}
},
+ _broadcastCdmaInfoRecordSystemMessage: function(aMessage) {
+ // TODO: Bug 1072808, Broadcast System Message with proxy.
+ gSystemMessenger.broadcastMessage("cdma-info-rec-received", aMessage);
+ },
+
/**
* nsIMobileConnectionService interface.
*/
@@ -1167,6 +1172,111 @@ MobileConnectionService.prototype = {
aServiceClass);
},
+ notifyCdmaInfoRecDisplay: function(aClientId, aDisplay) {
+ this._broadcastCdmaInfoRecordSystemMessage({
+ clientId: aClientId,
+ display: aDisplay
+ });
+ },
+
+ notifyCdmaInfoRecCalledPartyNumber: function(aClientId, aType, aPlan, aNumber,
+ aPi, aSi) {
+ this._broadcastCdmaInfoRecordSystemMessage({
+ clientId: aClientId,
+ calledNumber: {
+ type: aType,
+ plan: aPlan,
+ number: aNumber,
+ pi: aPi,
+ si: aSi
+ }
+ });
+ },
+
+ notifyCdmaInfoRecCallingPartyNumber: function(aClientId, aType, aPlan, aNumber,
+ aPi, aSi) {
+ this._broadcastCdmaInfoRecordSystemMessage({
+ clientId: aClientId,
+ callingNumber: {
+ type: aType,
+ plan: aPlan,
+ number: aNumber,
+ pi: aPi,
+ si: aSi
+ }
+ });
+ },
+
+ notifyCdmaInfoRecConnectedPartyNumber: function(aClientId, aType, aPlan, aNumber,
+ aPi, aSi) {
+ this._broadcastCdmaInfoRecordSystemMessage({
+ clientId: aClientId,
+ connectedNumber: {
+ type: aType,
+ plan: aPlan,
+ number: aNumber,
+ pi: aPi,
+ si: aSi
+ }
+ });
+ },
+
+ notifyCdmaInfoRecSignal: function(aClientId, aType, aAlertPitch, aSignal){
+ this._broadcastCdmaInfoRecordSystemMessage({
+ clientId: aClientId,
+ signal: {
+ type: aType,
+ alertPitch: aAlertPitch,
+ signal: aSignal
+ }
+ });
+ },
+
+ notifyCdmaInfoRecRedirectingNumber: function(aClientId, aType, aPlan, aNumber,
+ aPi, aSi, aReason) {
+ this._broadcastCdmaInfoRecordSystemMessage({
+ clientId: aClientId,
+ redirect: {
+ type: aType,
+ plan: aPlan,
+ number: aNumber,
+ pi: aPi,
+ si: aSi,
+ reason: aReason
+ }
+ });
+ },
+
+ notifyCdmaInfoRecLineControl: function(aClientId, aPolarityIncluded, aToggle,
+ aReverse, aPowerDenial) {
+ this._broadcastCdmaInfoRecordSystemMessage({
+ clientId: aClientId,
+ lineControl: {
+ polarityIncluded: aPolarityIncluded,
+ toggle: aToggle,
+ reverse: aReverse,
+ powerDenial: aPowerDenial
+ }
+ });
+ },
+
+ notifyCdmaInfoRecClir: function(aClientId, aCause) {
+ this._broadcastCdmaInfoRecordSystemMessage({
+ clientId: aClientId,
+ clirCause: aCause
+ });
+ },
+
+ notifyCdmaInfoRecAudioControl: function(aClientId, aUplink, aDownLink) {
+ this._broadcastCdmaInfoRecordSystemMessage({
+ clientId: aClientId,
+ audioControl: {
+ upLink: aUplink,
+ downLink: aDownLink
+ }
+ });
+ },
+
/**
* nsIObserver interface.
*/
diff --git a/dom/mobileconnection/gonk/nsIGonkMobileConnectionService.idl b/dom/mobileconnection/gonk/nsIGonkMobileConnectionService.idl
index 1692e896a098..652ca4c66143 100644
--- a/dom/mobileconnection/gonk/nsIGonkMobileConnectionService.idl
+++ b/dom/mobileconnection/gonk/nsIGonkMobileConnectionService.idl
@@ -9,7 +9,7 @@
"@mozilla.org/mobileconnection/gonkmobileconnectionservice;1"
%}
-[scriptable, uuid(b0310517-e7f6-4fa5-a52e-fa6ff35c8fc1)]
+[scriptable, uuid(2d574f0e-4a02-11e4-b1b3-cbc14b7608ce)]
interface nsIGonkMobileConnectionService : nsIMobileConnectionService
{
void notifyNetworkInfoChanged(in unsigned long clientId, in jsval networkInfo);
@@ -53,4 +53,205 @@ interface nsIGonkMobileConnectionService : nsIMobileConnectionService
in DOMString number,
in unsigned short timeSeconds,
in unsigned short serviceClass);
+
+ /**
+ * Notify Display Info from received Cdma-Info-Record.
+ * See 3.7.4.1 Display in 3GPP2 C.S0005-F.
+ *
+ * @param clientId
+ * The ID of radioInterface where this info is notified from.
+ * @param display
+ The string to be displayed.
+ */
+ void notifyCdmaInfoRecDisplay(in unsigned long clientId,
+ in DOMString display);
+
+ /**
+ * Notify Called Party Number from received Cdma-Info-Record.
+ * See 3.7.4.2 Called Party Number in 3GPP2 C.S0005-F.
+ *
+ * @param clientId
+ * The ID of radioInterface where this info is notified from.
+ * @param type
+ * The type of number. (3-bit binary)
+ * See Table 2.7.1.3.2.4-2 in 3GPP2 C.S0005-F.
+ * @param plan
+ * The numbering plan. (4-bit binary)
+ * See Table 2.7.1.3.2.4-3 in 3GPP2 C.S0005-F.
+ * @param number
+ * The string presentation of the number.
+ * @param pi (2-bit binary)
+ * The Presentation indicator of the number.
+ * See Table 2.7.4.4-1 in 3GPP2 C.S0005-F.
+ * @param si (2-bit binary)
+ * The Screening Indicator of the number.
+ * See Table 2.7.4.4-2 in 3GPP2 C.S0005-F.
+ */
+ void notifyCdmaInfoRecCalledPartyNumber(in unsigned long clientId,
+ in unsigned short type,
+ in unsigned short plan,
+ in DOMString number,
+ in unsigned short pi,
+ in unsigned short si);
+
+ /**
+ * Notify Calling Party Number from received Cdma-Info-Record.
+ * See 3.7.4.3 Calling Party Number in 3GPP2 C.S0005-F.
+ *
+ * @param clientId
+ * The ID of radioInterface where this info is notified from.
+ * @param type
+ * The type of number. (3-bit binary)
+ * See Table 2.7.1.3.2.4-2 in 3GPP2 C.S0005-F.
+ * @param plan
+ * The numbering plan. (4-bit binary)
+ * See Table 2.7.1.3.2.4-3 in 3GPP2 C.S0005-F.
+ * @param number
+ * The string presentation of the number.
+ * @param pi (2-bit binary)
+ * The Presentation indicator of the number.
+ * See Table 2.7.4.4-1 in 3GPP2 C.S0005-F.
+ * @param si (2-bit binary)
+ * The Screening Indicator of the number.
+ * See Table 2.7.4.4-2 in 3GPP2 C.S0005-F.
+ */
+ void notifyCdmaInfoRecCallingPartyNumber(in unsigned long clientId,
+ in unsigned short type,
+ in unsigned short plan,
+ in DOMString number,
+ in unsigned short pi,
+ in unsigned short si);
+
+ /**
+ * Notify Connected Party Number from received Cdma-Info-Record.
+ * See 3.7.4.4 Connected Party Number in 3GPP2 C.S0005-F.
+ *
+ * @param clientId
+ * The ID of radioInterface where this info is notified from.
+ * @param type
+ * The type of number. (3-bit binary)
+ * See Table 2.7.1.3.2.4-2 in 3GPP2 C.S0005-F.
+ * @param plan
+ * The numbering plan. (4-bit binary)
+ * See Table 2.7.1.3.2.4-3 in 3GPP2 C.S0005-F.
+ * @param number
+ * The string presentation of the number.
+ * @param pi (2-bit binary)
+ * The Presentation indicator of the number.
+ * See Table 2.7.4.4-1 in 3GPP2 C.S0005-F.
+ * @param si (2-bit binary)
+ * The Screening Indicator of the number.
+ * See Table 2.7.4.4-2 in 3GPP2 C.S0005-F.
+ */
+ void notifyCdmaInfoRecConnectedPartyNumber(in unsigned long clientId,
+ in unsigned short type,
+ in unsigned short plan,
+ in DOMString number,
+ in unsigned short pi,
+ in unsigned short si);
+
+ /**
+ * Notify Signal Info from received Cdma-Info-Record.
+ * See 3.7.4.5 Signal in 3GPP2 C.S0005-F.
+ *
+ * @param clientId
+ * The ID of radioInterface where this info is notified from.
+ * @param type
+ * The signal type. (2-bit binary)
+ * See Table 3.7.5.5-1 in 3GPP2 C.S0005-F.
+ * @param alertPitch
+ * The pitch of the alerting signal. (2-bit binary)
+ * See Table 3.7.5.5-2 in 3GPP2 C.S0005-F.
+ * @param signal
+ * The signal code. (6-bit binary)
+ * See Table 3.7.5.5-3, 3.7.5.5-4, 3.7.5.5-5 in 3GPP2 C.S0005-F.
+ */
+ void notifyCdmaInfoRecSignal(in unsigned long clientId,
+ in unsigned short type,
+ in unsigned short alertPitch,
+ in unsigned short signal);
+
+ /**
+ * Notify Redirecting Number from received Cdma-Info-Record.
+ * See 3.7.4.11 Redirecting Number in 3GPP2 C.S0005-F.
+ *
+ * @param clientId
+ * The ID of radioInterface where this info is notified from.
+ * @param type
+ * The type of number. (3-bit binary)
+ * See Table 2.7.1.3.2.4-2 in 3GPP2 C.S0005-F.
+ * @param plan
+ * The numbering plan. (4-bit binary)
+ * See Table 2.7.1.3.2.4-3 in 3GPP2 C.S0005-F.
+ * @param number
+ * The string presentation of the number.
+ * @param pi (2-bit binary)
+ * The Presentation indicator of the number.
+ * See Table 2.7.4.4-1 in 3GPP2 C.S0005-F.
+ * @param si (2-bit binary)
+ * The Screening Indicator of the number.
+ * See Table 2.7.4.4-2 in 3GPP2 C.S0005-F.
+ * @param reason (4-bit binary)
+ * The redirection reason.
+ * See Table 3.7.5.11-1 in 3GPP2 C.S0005-F.
+ */
+ void notifyCdmaInfoRecRedirectingNumber(in unsigned long clientId,
+ in unsigned short type,
+ in unsigned short plan,
+ in DOMString number,
+ in unsigned short pi,
+ in unsigned short si,
+ in unsigned short reason);
+
+ /**
+ * Notify Line Control from received Cdma-Info-Record.
+ * See 3.7.4.15 Line Control in 3GPP2 C.S0005-F.
+ *
+ * @param clientId
+ * The ID of radioInterface where this info is notified from.
+ * @param polarityIncluded (1-bit)
+ * Polarity parameter included.
+ * @param toggle (1-bit)
+ * Toggle mode.
+ * @param reverse (1-bit)
+ * Reverse polarity.
+ * @param powerDenial (8-bit)
+ * Power denial timeout.
+ */
+ void notifyCdmaInfoRecLineControl(in unsigned long clientId,
+ in unsigned short polarityIncluded,
+ in unsigned short toggle,
+ in unsigned short reverse,
+ in unsigned short powerDenial);
+
+ /**
+ * Notify CLIR from received Cdma-Info-Record.
+ * See 'ANNEX 1 Country-Specific Record Type for Japan' in T53.
+ * http://www.arib.or.jp/english/html/overview/doc/T53v6_5_pdf/5_ANNEX_v6_5.pdf
+ *
+ * @param clientId
+ * The ID of radioInterface where this info is notified from.
+ * @param cause
+ * Reason code. (8-bit binary)
+ * See Table A 1.1-1 in T53.
+ */
+ void notifyCdmaInfoRecClir(in unsigned long clientId,
+ in unsigned short cause);
+
+ /**
+ * Notify Audio Control from received Cdma-Info-Record.
+ *
+ * Note: No information from ARIB about Audio Control.
+ * It seems obsolete according to ANNEX 1 in T53.
+ * upLink/downLink are 'byte' value according to ril.h.
+ * Treat them as 'signed short' to preserve the flexibility when needed.
+ *
+ * @param clientId
+ * The ID of radioInterface where this info is notified from.
+ * @param upLink
+ * @param downLink
+ */
+ void notifyCdmaInfoRecAudioControl(in unsigned long clientId,
+ in short upLink,
+ in short downLink);
};
diff --git a/dom/system/gonk/RadioInterfaceLayer.js b/dom/system/gonk/RadioInterfaceLayer.js
index 65578af7cafe..14999940d94d 100644
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -396,13 +396,6 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function() {
}
},
- sendMobileConnectionMessage: function(message, clientId, data) {
- this._sendTargetMessage("mobileconnection", message, {
- clientId: clientId,
- data: data
- });
- },
-
sendIccMessage: function(message, clientId, data) {
this._sendTargetMessage("icc", message, {
clientId: clientId,
@@ -1163,7 +1156,7 @@ DataConnectionHandler.prototype = {
_compareDataCallOptions: function(dataCall, newDataCall) {
return dataCall.apnProfile.apn == newDataCall.apn &&
dataCall.apnProfile.user == newDataCall.user &&
- dataCall.apnProfile.password == newDataCall.password &&
+ dataCall.apnProfile.password == newDataCall.passwd &&
dataCall.chappap == newDataCall.chappap &&
dataCall.pdptype == newDataCall.pdptype;
},
@@ -2091,8 +2084,7 @@ RadioInterface.prototype = {
gMessageManager.sendIccMessage("RIL:StkSessionEnd", this.clientId, null);
break;
case "cdma-info-rec-received":
- if (DEBUG) this.debug("cdma-info-rec-received: " + JSON.stringify(message));
- gSystemMessenger.broadcastMessage("cdma-info-rec-received", message);
+ this.handleCdmaInformationRecords(message.records);
break;
default:
throw new Error("Don't know about this message type: " +
@@ -2920,6 +2912,99 @@ RadioInterface.prototype = {
hasEtwsInfo ? etwsInfo.popup : false);
},
+ handleCdmaInformationRecords: function(aRecords) {
+ if (DEBUG) this.debug("cdma-info-rec-received: " + JSON.stringify(aRecords));
+
+ let clientId = this.clientId;
+
+ aRecords.forEach(function(aRecord) {
+ if (aRecord.display) {
+ gMobileConnectionService
+ .notifyCdmaInfoRecDisplay(clientId, aRecord.display);
+ return;
+ }
+
+ if (aRecord.calledNumber) {
+ gMobileConnectionService
+ .notifyCdmaInfoRecCalledPartyNumber(clientId,
+ aRecord.calledNumber.type,
+ aRecord.calledNumber.plan,
+ aRecord.calledNumber.number,
+ aRecord.calledNumber.pi,
+ aRecord.calledNumber.si);
+ return;
+ }
+
+ if (aRecord.callingNumber) {
+ gMobileConnectionService
+ .notifyCdmaInfoRecCallingPartyNumber(clientId,
+ aRecord.callingNumber.type,
+ aRecord.callingNumber.plan,
+ aRecord.callingNumber.number,
+ aRecord.callingNumber.pi,
+ aRecord.callingNumber.si);
+ return;
+ }
+
+ if (aRecord.connectedNumber) {
+ gMobileConnectionService
+ .notifyCdmaInfoRecConnectedPartyNumber(clientId,
+ aRecord.connectedNumber.type,
+ aRecord.connectedNumber.plan,
+ aRecord.connectedNumber.number,
+ aRecord.connectedNumber.pi,
+ aRecord.connectedNumber.si);
+ return;
+ }
+
+ if (aRecord.signal) {
+ gMobileConnectionService
+ .notifyCdmaInfoRecSignal(clientId,
+ aRecord.signal.type,
+ aRecord.signal.alertPitch,
+ aRecord.signal.signal);
+ return;
+ }
+
+ if (aRecord.redirect) {
+ gMobileConnectionService
+ .notifyCdmaInfoRecRedirectingNumber(clientId,
+ aRecord.redirect.type,
+ aRecord.redirect.plan,
+ aRecord.redirect.number,
+ aRecord.redirect.pi,
+ aRecord.redirect.si,
+ aRecord.redirect.reason);
+ return;
+ }
+
+ if (aRecord.lineControl) {
+ gMobileConnectionService
+ .notifyCdmaInfoRecLineControl(clientId,
+ aRecord.lineControl.polarityIncluded,
+ aRecord.lineControl.toggle,
+ aRecord.lineControl.reverse,
+ aRecord.lineControl.powerDenial);
+ return;
+ }
+
+ if (aRecord.clirCause) {
+ gMobileConnectionService
+ .notifyCdmaInfoRecClir(clientId,
+ aRecord.clirCause);
+ return;
+ }
+
+ if (aRecord.audioControl) {
+ gMobileConnectionService
+ .notifyCdmaInfoRecAudioControl(clientId,
+ aRecord.audioControl.upLink,
+ aRecord.audioControl.downLink);
+ return;
+ }
+ });
+ },
+
// nsIObserver
observe: function(subject, topic, data) {
diff --git a/dom/system/gonk/ril_worker.js b/dom/system/gonk/ril_worker.js
index 455ec31c4148..8970f8b07602 100644
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -6920,9 +6920,10 @@ RilObject.prototype[UNSOLICITED_CDMA_OTA_PROVISION_STATUS] = function UNSOLICITE
status: status});
};
RilObject.prototype[UNSOLICITED_CDMA_INFO_REC] = function UNSOLICITED_CDMA_INFO_REC(length) {
- let record = this.context.CdmaPDUHelper.decodeInformationRecord();
- record.rilMessageType = "cdma-info-rec-received";
- this.sendChromeMessage(record);
+ this.sendChromeMessage({
+ rilMessageType: "cdma-info-rec-received",
+ records: this.context.CdmaPDUHelper.decodeInformationRecord()
+ });
};
RilObject.prototype[UNSOLICITED_OEM_HOOK_RAW] = null;
RilObject.prototype[UNSOLICITED_RINGBACK_TONE] = null;
@@ -9987,11 +9988,13 @@ CdmaPDUHelperObject.prototype = {
*/
decodeInformationRecord: function() {
let Buf = this.context.Buf;
- let record = {};
+ let records = [];
let numOfRecords = Buf.readInt32();
let type;
+ let record;
for (let i = 0; i < numOfRecords; i++) {
+ record = {};
type = Buf.readInt32();
switch (type) {
@@ -9999,6 +10002,7 @@ CdmaPDUHelperObject.prototype = {
* Every type is encaped by ril, except extended display
*/
case PDU_CDMA_INFO_REC_TYPE_DISPLAY:
+ case PDU_CDMA_INFO_REC_TYPE_EXTENDED_DISPLAY:
record.display = Buf.readString();
break;
case PDU_CDMA_INFO_REC_TYPE_CALLED_PARTY_NUMBER:
@@ -10027,7 +10031,10 @@ CdmaPDUHelperObject.prototype = {
break;
case PDU_CDMA_INFO_REC_TYPE_SIGNAL:
record.signal = {};
- record.signal.present = Buf.readInt32();
+ if (!Buf.readInt32()) { // Non-zero if signal is present.
+ Buf.seekIncoming(3 * Buf.UINT32_SIZE);
+ continue;
+ }
record.signal.type = Buf.readInt32();
record.signal.alertPitch = Buf.readInt32();
record.signal.signal = Buf.readInt32();
@@ -10045,40 +10052,11 @@ CdmaPDUHelperObject.prototype = {
record.lineControl = {};
record.lineControl.polarityIncluded = Buf.readInt32();
record.lineControl.toggle = Buf.readInt32();
- record.lineControl.recerse = Buf.readInt32();
+ record.lineControl.reverse = Buf.readInt32();
record.lineControl.powerDenial = Buf.readInt32();
break;
- case PDU_CDMA_INFO_REC_TYPE_EXTENDED_DISPLAY:
- let length = Buf.readInt32();
- /*
- * Extended display is still in format defined in
- * C.S0005-F v1.0, 3.7.5.16
- */
- record.extendedDisplay = {};
-
- let headerByte = Buf.readInt32();
- length--;
- // Based on spec, headerByte must be 0x80 now
- record.extendedDisplay.indicator = (headerByte >> 7);
- record.extendedDisplay.type = (headerByte & 0x7F);
- record.extendedDisplay.records = [];
-
- while (length > 0) {
- let display = {};
-
- display.tag = Buf.readInt32();
- length--;
- if (display.tag !== INFO_REC_EXTENDED_DISPLAY_BLANK &&
- display.tag !== INFO_REC_EXTENDED_DISPLAY_SKIP) {
- display.content = Buf.readString();
- length -= (display.content.length + 1);
- }
-
- record.extendedDisplay.records.push(display);
- }
- break;
case PDU_CDMA_INFO_REC_TYPE_T53_CLIR:
- record.cause = Buf.readInt32();
+ record.clirCause = Buf.readInt32();
break;
case PDU_CDMA_INFO_REC_TYPE_T53_AUDIO_CONTROL:
record.audioControl = {};
@@ -10088,11 +10066,13 @@ CdmaPDUHelperObject.prototype = {
case PDU_CDMA_INFO_REC_TYPE_T53_RELEASE:
// Fall through
default:
- throw new Error("UNSOLICITED_CDMA_INFO_REC(), Unsupported information record type " + record.type + "\n");
+ throw new Error("UNSOLICITED_CDMA_INFO_REC(), Unsupported information record type " + type + "\n");
}
+
+ records.push(record);
}
- return record;
+ return records;
}
};
diff --git a/dom/system/gonk/tests/test_ril_worker_cdma_info_rec.js b/dom/system/gonk/tests/test_ril_worker_cdma_info_rec.js
index aa5f85caaa8c..3eaab37efaf0 100644
--- a/dom/system/gonk/tests/test_ril_worker_cdma_info_rec.js
+++ b/dom/system/gonk/tests/test_ril_worker_cdma_info_rec.js
@@ -36,6 +36,10 @@ function newWorkerWithParcel(parcelBuf) {
return buf[index++];
};
+ context.Buf.seekIncoming = function(offset) {
+ index += offset / context.Buf.UINT32_SIZE;
+ };
+
return worker;
}
@@ -53,9 +57,9 @@ add_test(function test_display() {
0x6F, 0x00]);
let context = worker.ContextPool._contexts[0];
let helper = context.CdmaPDUHelper;
- let record = helper.decodeInformationRecord();
+ let records = helper.decodeInformationRecord();
- do_check_eq(record.display, "Test Info");
+ do_check_eq(records[0].display, "Test Info");
run_next_test();
});
@@ -67,27 +71,19 @@ add_test(function test_extended_display() {
let worker = newWorkerWithParcel([
0x01, // one inforemation record
0x07, // type: extended display
- 0x0E, // length: 14
- 0x80, // header byte
- 0x80, // Blank
- 0x81, // Skip
- 0x9B, // Text
- 0x09, 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6E,
- 0x66, 0x6F, 0x00]);
+ 0x12, // length: 18
+ 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74,
+ 0x65, 0x6E, 0x64, 0x65, 0x64, 0x20, 0x49, 0x6E,
+ 0x66, 0x6F, 0x00, 0x00]);
let context = worker.ContextPool._contexts[0];
let helper = context.CdmaPDUHelper;
- let record = helper.decodeInformationRecord();
+ let records = helper.decodeInformationRecord();
- do_check_eq(record.extendedDisplay.indicator, 1);
- do_check_eq(record.extendedDisplay.type, 0);
- do_check_eq(record.extendedDisplay.records.length, 3);
- do_check_eq(record.extendedDisplay.records[0].tag, 0x80);
- do_check_eq(record.extendedDisplay.records[1].tag, 0x81);
- do_check_eq(record.extendedDisplay.records[2].tag, 0x9B);
- do_check_eq(record.extendedDisplay.records[2].content, "Test Info");
+ do_check_eq(records[0].display, "Test Extended Info");
run_next_test();
});
+
/**
* Verify decoder for mixed type
*/
@@ -95,29 +91,144 @@ add_test(function test_mixed() {
let worker = newWorkerWithParcel([
0x02, // two inforemation record
0x00, // type: display
- 0x09, // length: 9
+ 0x0B, // length: 11
0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6E, 0x66,
- 0x6F, 0x00,
+ 0x6F, 0x20, 0x31, 0x00,
0x07, // type: extended display
- 0x0E, // length: 14
- 0x80, // header byte
- 0x80, // Blank
- 0x81, // Skip
- 0x9B, // Text
- 0x09, 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6E,
- 0x66, 0x6F, 0x00]);
+ 0x0B, // length: 11
+ 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6E, 0x66,
+ 0x6F, 0x20, 0x32, 0x00]);
let context = worker.ContextPool._contexts[0];
let helper = context.CdmaPDUHelper;
- let record = helper.decodeInformationRecord();
+ let records = helper.decodeInformationRecord();
- do_check_eq(record.display, "Test Info");
- do_check_eq(record.extendedDisplay.indicator, 1);
- do_check_eq(record.extendedDisplay.type, 0);
- do_check_eq(record.extendedDisplay.records.length, 3);
- do_check_eq(record.extendedDisplay.records[0].tag, 0x80);
- do_check_eq(record.extendedDisplay.records[1].tag, 0x81);
- do_check_eq(record.extendedDisplay.records[2].tag, 0x9B);
- do_check_eq(record.extendedDisplay.records[2].content, "Test Info");
+ do_check_eq(records[0].display, "Test Info 1");
+ do_check_eq(records[1].display, "Test Info 2");
+
+ run_next_test();
+});
+
+/**
+ * Verify decoder for multiple types
+ */
+add_test(function test_multiple() {
+ let worker = newWorkerWithParcel([
+ 0x02, // two inforemation record
+ 0x00, // type: display
+ 0x0B, // length: 11
+ 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6E, 0x66,
+ 0x6F, 0x20, 0x31, 0x00,
+ 0x00, // type: display
+ 0x0B, // length: 11
+ 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6E, 0x66,
+ 0x6F, 0x20, 0x32, 0x00]);
+ let context = worker.ContextPool._contexts[0];
+ let helper = context.CdmaPDUHelper;
+ let records = helper.decodeInformationRecord();
+
+ do_check_eq(records[0].display, "Test Info 1");
+ do_check_eq(records[1].display, "Test Info 2");
+
+ run_next_test();
+});
+
+/**
+ * Verify decoder for Signal Type
+ */
+add_test(function test_signal() {
+ let worker = newWorkerWithParcel([
+ 0x01, // one inforemation record
+ 0x04, // type: signal
+ 0x01, // isPresent: non-zero
+ 0x00, // signalType: Tone signal (00)
+ 0x01, // alertPitch: High pitch
+ 0x03]); // signal: Abbreviated intercept (000011)
+ let context = worker.ContextPool._contexts[0];
+ let helper = context.CdmaPDUHelper;
+ let records = helper.decodeInformationRecord();
+
+ do_check_eq(records[0].signal.type, 0x00);
+ do_check_eq(records[0].signal.alertPitch, 0x01);
+ do_check_eq(records[0].signal.signal, 0x03);
+
+ run_next_test();
+});
+
+/**
+ * Verify decoder for Signal Type for Not Presented
+ */
+add_test(function test_signal_not_present() {
+ let worker = newWorkerWithParcel([
+ 0x01, // one inforemation record
+ 0x04, // type: signal
+ 0x00, // isPresent: zero
+ 0x00, // signalType: Tone signal (00)
+ 0x01, // alertPitch: High pitch
+ 0x03]); // signal: Abbreviated intercept (000011)
+ let context = worker.ContextPool._contexts[0];
+ let helper = context.CdmaPDUHelper;
+ let records = helper.decodeInformationRecord();
+
+ do_check_eq(records.length, 0);
+
+ run_next_test();
+});
+
+/**
+ * Verify decoder for Line Control
+ */
+add_test(function test_line_control() {
+ let worker = newWorkerWithParcel([
+ 0x01, // one inforemation record
+ 0x06, // type: line control
+ 0x01, // polarity included
+ 0x00, // not toggled
+ 0x01, // reversed
+ 0xFF]); // Power denial timeout: 255 * 5 ms
+ let context = worker.ContextPool._contexts[0];
+ let helper = context.CdmaPDUHelper;
+ let records = helper.decodeInformationRecord();
+
+ do_check_eq(records[0].lineControl.polarityIncluded, 1);
+ do_check_eq(records[0].lineControl.toggle, 0);
+ do_check_eq(records[0].lineControl.reverse, 1);
+ do_check_eq(records[0].lineControl.powerDenial, 255);
+
+ run_next_test();
+});
+
+/**
+ * Verify decoder for CLIR Cause
+ */
+add_test(function test_clir() {
+ let worker = newWorkerWithParcel([
+ 0x01, // one inforemation record
+ 0x08, // type: clir
+ 0x01]); // cause: Rejected by user
+ let context = worker.ContextPool._contexts[0];
+ let helper = context.CdmaPDUHelper;
+ let records = helper.decodeInformationRecord();
+
+ do_check_eq(records[0].clirCause, 1);
+
+ run_next_test();
+});
+
+/**
+ * Verify decoder for Audio Control
+ */
+add_test(function test_clir() {
+ let worker = newWorkerWithParcel([
+ 0x01, // one inforemation record
+ 0x0A, // type: audio control
+ 0x01, // uplink
+ 0xFF]); // downlink
+ let context = worker.ContextPool._contexts[0];
+ let helper = context.CdmaPDUHelper;
+ let records = helper.decodeInformationRecord();
+
+ do_check_eq(records[0].audioControl.upLink, 1);
+ do_check_eq(records[0].audioControl.downLink, 255);
run_next_test();
});
diff --git a/dom/wifi/WifiCertService.cpp b/dom/wifi/WifiCertService.cpp
index 23bca42f24e4..7ce7d0bcbd22 100644
--- a/dom/wifi/WifiCertService.cpp
+++ b/dom/wifi/WifiCertService.cpp
@@ -227,13 +227,6 @@ WifiCertService::Start(nsIWifiEventListener* aListener)
{
MOZ_ASSERT(aListener);
- nsresult rv = NS_NewThread(getter_AddRefs(mRequestThread));
- if (NS_FAILED(rv)) {
- NS_WARNING("Certn't create wifi control thread");
- Shutdown();
- return NS_ERROR_FAILURE;
- }
-
mListener = aListener;
return NS_OK;
@@ -243,10 +236,6 @@ NS_IMETHODIMP
WifiCertService::Shutdown()
{
MOZ_ASSERT(NS_IsMainThread());
- if (mRequestThread) {
- mRequestThread->Shutdown();
- mRequestThread = nullptr;
- }
mListener = nullptr;
diff --git a/dom/wifi/WifiCertService.h b/dom/wifi/WifiCertService.h
index 219764c57e39..7f7bff5c8812 100644
--- a/dom/wifi/WifiCertService.h
+++ b/dom/wifi/WifiCertService.h
@@ -27,7 +27,6 @@ public:
private:
WifiCertService();
~WifiCertService();
- nsCOMPtr mRequestThread;
nsCOMPtr mListener;
};
diff --git a/dom/wifi/WifiWorker.js b/dom/wifi/WifiWorker.js
index a778050eb4e6..ee636f1d1a40 100644
--- a/dom/wifi/WifiWorker.js
+++ b/dom/wifi/WifiWorker.js
@@ -1859,7 +1859,7 @@ function WifiWorker() {
var pub = new Network(ssid, security, password);
if (net.identity)
pub.identity = dequote(net.identity);
- if (net.netId)
+ if ("netId" in net)
pub.known = true;
if (net.scan_ssid === 1)
pub.hidden = true;
diff --git a/netwerk/protocol/rtsp/controller/RtspController.cpp b/netwerk/protocol/rtsp/controller/RtspController.cpp
index c01d33389677..5d5b9b703887 100644
--- a/netwerk/protocol/rtsp/controller/RtspController.cpp
+++ b/netwerk/protocol/rtsp/controller/RtspController.cpp
@@ -47,8 +47,6 @@ extern PRLogModuleInfo* gRtspLog;
#undef LOG
#define LOG(args) PR_LOG(gRtspLog, PR_LOG_DEBUG, args)
-const unsigned long kCommandDelayMs = 200;
-
namespace mozilla {
namespace net {
@@ -59,10 +57,7 @@ NS_IMPL_ISUPPORTS(RtspController,
nsIStreamingProtocolController)
RtspController::RtspController(nsIChannel *channel)
- : mState(INIT),
- mTimerLock("RtspController.mTimerLock"),
- mPlayTimer(nullptr),
- mPauseTimer(nullptr)
+ : mState(INIT)
{
LOG(("RtspController::RtspController()"));
}
@@ -99,26 +94,7 @@ RtspController::Play(void)
return NS_ERROR_NOT_CONNECTED;
}
- MutexAutoLock lock(mTimerLock);
- // Cancel the pause timer if it is active because successive pause-play in a
- // short duration is unnecessary but could impair playback smoothing.
- if (mPauseTimer) {
- mPauseTimer->Cancel();
- mPauseTimer = nullptr;
- }
-
- // Start a timer to delay the play operation for a short duration.
- if (!mPlayTimer) {
- mPlayTimer = do_CreateInstance("@mozilla.org/timer;1");
- if (!mPlayTimer) {
- return NS_ERROR_NOT_INITIALIZED;
- }
- mPlayTimer->InitWithFuncCallback(
- RtspController::PlayTimerCallback,
- this, kCommandDelayMs,
- nsITimer::TYPE_ONE_SHOT);
- }
-
+ mRtspSource->play();
return NS_OK;
}
@@ -135,26 +111,7 @@ RtspController::Pause(void)
return NS_ERROR_NOT_CONNECTED;
}
- MutexAutoLock lock(mTimerLock);
- // Cancel the play timer if it is active because successive play-pause in a
- // short duration is unnecessary but could impair playback smoothing.
- if (mPlayTimer) {
- mPlayTimer->Cancel();
- mPlayTimer = nullptr;
- }
-
- // Start a timer to delay the pause operation for a short duration.
- if (!mPauseTimer) {
- mPauseTimer = do_CreateInstance("@mozilla.org/timer;1");
- if (!mPauseTimer) {
- return NS_ERROR_NOT_INITIALIZED;
- }
- mPauseTimer->InitWithFuncCallback(
- RtspController::PauseTimerCallback,
- this, kCommandDelayMs,
- nsITimer::TYPE_ONE_SHOT);
- }
-
+ mRtspSource->pause();
return NS_OK;
}
@@ -360,19 +317,6 @@ RtspController::OnDisconnected(uint8_t index,
LOG(("RtspController::OnDisconnected() for track %d reason = 0x%x", index, reason));
mState = DISCONNECTED;
- // Ensure play and pause timer are stopped.
- {
- MutexAutoLock lock(mTimerLock);
- if (mPlayTimer) {
- mPlayTimer->Cancel();
- mPlayTimer = nullptr;
- }
- if (mPauseTimer) {
- mPauseTimer->Cancel();
- mPauseTimer = nullptr;
- }
- }
-
if (mListener) {
nsRefPtr task =
new SendOnDisconnectedTask(mListener, index, reason);
@@ -436,40 +380,5 @@ RtspController::PlaybackEnded()
return NS_OK;
}
-//-----------------------------------------------------------------------------
-// RtspController static member methods
-//-----------------------------------------------------------------------------
-//static
-void RtspController::PlayTimerCallback(nsITimer *aTimer, void *aClosure)
-{
- MOZ_ASSERT(aTimer);
- MOZ_ASSERT(aClosure);
-
- RtspController *self = static_cast(aClosure);
- MOZ_ASSERT(self->mRtspSource.get());
-
- MutexAutoLock lock(self->mTimerLock);
- if (self->mPlayTimer) {
- self->mRtspSource->play();
- self->mPlayTimer = nullptr;
- }
-}
-
-//static
-void RtspController::PauseTimerCallback(nsITimer *aTimer, void *aClosure)
-{
- MOZ_ASSERT(aTimer);
- MOZ_ASSERT(aClosure);
-
- RtspController *self = static_cast(aClosure);
- MOZ_ASSERT(self->mRtspSource.get());
-
- MutexAutoLock lock(self->mTimerLock);
- if (self->mPauseTimer) {
- self->mRtspSource->pause();
- self->mPauseTimer = nullptr;
- }
-}
-
} // namespace mozilla::net
} // namespace mozilla
diff --git a/netwerk/protocol/rtsp/controller/RtspController.h b/netwerk/protocol/rtsp/controller/RtspController.h
index 6700eedf821b..f938430944b2 100644
--- a/netwerk/protocol/rtsp/controller/RtspController.h
+++ b/netwerk/protocol/rtsp/controller/RtspController.h
@@ -7,12 +7,10 @@
#ifndef RtspController_h
#define RtspController_h
-#include "mozilla/Mutex.h"
#include "nsIStreamingProtocolController.h"
#include "nsIChannel.h"
#include "nsCOMPtr.h"
#include "nsString.h"
-#include "nsITimer.h"
#include "RTSPSource.h"
namespace mozilla {
@@ -29,10 +27,6 @@ public:
RtspController(nsIChannel *channel);
~RtspController();
- // These callbacks will be called when mPlayTimer/mPauseTimer fires.
- static void PlayTimerCallback(nsITimer *aTimer, void *aClosure);
- static void PauseTimerCallback(nsITimer *aTimer, void *aClosure);
-
private:
enum State {
INIT,
@@ -53,13 +47,6 @@ private:
State mState;
// Rtsp Streaming source.
android::sp mRtspSource;
- // This lock protects mPlayTimer and mPauseTimer.
- Mutex mTimerLock;
- // Timers to delay the play and pause operations.
- // They are used for optimization and avoid sending unnecessary requests to
- // the server.
- nsCOMPtr mPlayTimer;
- nsCOMPtr mPauseTimer;
};
}
diff --git a/netwerk/protocol/rtsp/controller/RtspControllerChild.cpp b/netwerk/protocol/rtsp/controller/RtspControllerChild.cpp
index 276e7dde9584..163619fa9330 100644
--- a/netwerk/protocol/rtsp/controller/RtspControllerChild.cpp
+++ b/netwerk/protocol/rtsp/controller/RtspControllerChild.cpp
@@ -21,6 +21,8 @@ PRLogModuleInfo* gRtspChildLog = nullptr;
#define LOG(args) PR_LOG(gRtspChildLog, PR_LOG_DEBUG, args)
const uint32_t kRtspTotalTracks = 2;
+const unsigned long kRtspCommandDelayMs = 200;
+
using namespace mozilla::ipc;
namespace mozilla {
@@ -64,6 +66,9 @@ RtspControllerChild::RtspControllerChild(nsIChannel *channel)
, mChannel(channel)
, mTotalTracks(0)
, mSuspendCount(0)
+ , mTimerLock("RtspControllerChild.mTimerLock")
+ , mPlayTimer(nullptr)
+ , mPauseTimer(nullptr)
{
#if defined(PR_LOGGING)
if (!gRtspChildLog)
@@ -108,6 +113,20 @@ RtspControllerChild::DisallowIPC()
mIPCAllowed = false;
}
+void
+RtspControllerChild::StopPlayAndPauseTimer()
+{
+ MutexAutoLock lock(mTimerLock);
+ if (mPlayTimer) {
+ mPlayTimer->Cancel();
+ mPlayTimer = nullptr;
+ }
+ if (mPauseTimer) {
+ mPauseTimer->Cancel();
+ mPauseTimer = nullptr;
+ }
+}
+
//-----------------------------------------------------------------------------
// RtspControllerChild::PRtspControllerChild
//-----------------------------------------------------------------------------
@@ -174,6 +193,7 @@ RtspControllerChild::RecvOnDisconnected(
const uint8_t& index,
const nsresult& reason)
{
+ StopPlayAndPauseTimer();
DisallowIPC();
LOG(("RtspControllerChild::RecvOnDisconnected for track %d reason = 0x%x", index, reason));
if (mListener) {
@@ -186,6 +206,7 @@ RtspControllerChild::RecvOnDisconnected(
bool
RtspControllerChild::RecvAsyncOpenFailed(const nsresult& reason)
{
+ StopPlayAndPauseTimer();
DisallowIPC();
LOG(("RtspControllerChild::RecvAsyncOpenFailed reason = 0x%x", reason));
if (mListener) {
@@ -234,8 +255,6 @@ enum IPCEvent
SendPlayEvent,
SendPauseEvent,
SendSeekEvent,
- SendResumeEvent,
- SendSuspendEvent,
SendStopEvent,
SendPlaybackEndedEvent
};
@@ -275,10 +294,6 @@ public:
rv = mController->SendPause();
} else if (mEvent == SendSeekEvent) {
rv = mController->SendSeek(mSeekTime);
- } else if (mEvent == SendResumeEvent) {
- rv = mController->SendResume();
- } else if (mEvent == SendSuspendEvent) {
- rv = mController->SendSuspend();
} else if (mEvent == SendStopEvent) {
rv = mController->SendStop();
} else if (mEvent == SendPlaybackEndedEvent) {
@@ -305,14 +320,30 @@ RtspControllerChild::Play(void)
{
LOG(("RtspControllerChild::Play()"));
- if (NS_IsMainThread()) {
- if (!OKToSendIPC() || !SendPlay()) {
- return NS_ERROR_FAILURE;
+ MutexAutoLock lock(mTimerLock);
+ // Cancel the pause timer if it is active because successive pause-play in a
+ // short duration is unncessary but could impair playback smoothing.
+ if (mPauseTimer) {
+ mPauseTimer->Cancel();
+ mPauseTimer = nullptr;
+ }
+
+ // Start a timer to delay the play operation for a short duration.
+ if (!mPlayTimer) {
+ mPlayTimer = do_CreateInstance("@mozilla.org/timer;1");
+ if (!mPlayTimer) {
+ return NS_ERROR_NOT_INITIALIZED;
}
- } else {
- nsresult rv = NS_DispatchToMainThread(
- new SendIPCEvent(this, SendPlayEvent));
- NS_ENSURE_SUCCESS(rv, rv);
+ // We have to dispatch the timer callback to the main thread because the
+ // decoder thread is a thread from nsIThreadPool and cannot be the timer
+ // target. Furthermore, IPC send functions should only be called from the
+ // main thread.
+ nsCOMPtr mainThread = do_GetMainThread();
+ mPlayTimer->SetTarget(mainThread);
+ mPlayTimer->InitWithFuncCallback(
+ RtspControllerChild::PlayTimerCallback,
+ this, kRtspCommandDelayMs,
+ nsITimer::TYPE_ONE_SHOT);
}
return NS_OK;
@@ -323,14 +354,29 @@ RtspControllerChild::Pause(void)
{
LOG(("RtspControllerChild::Pause()"));
- if (NS_IsMainThread()) {
- if (!OKToSendIPC() || !SendPause()) {
- return NS_ERROR_FAILURE;
+ MutexAutoLock lock(mTimerLock);
+ // Cancel the play timer if it is active because successive play-pause in a
+ // shrot duration is unnecessary but could impair playback smoothing.
+ if (mPlayTimer) {
+ mPlayTimer->Cancel();
+ mPlayTimer = nullptr;
+ }
+
+ // Start a timer to delay the pause operation for a short duration.
+ if (!mPauseTimer) {
+ mPauseTimer = do_CreateInstance("@mozilla.org/timer;1");
+ if (!mPauseTimer) {
+ return NS_ERROR_NOT_INITIALIZED;
}
- } else {
- nsresult rv = NS_DispatchToMainThread(
- new SendIPCEvent(this, SendPauseEvent));
- NS_ENSURE_SUCCESS(rv, rv);
+ // We have to dispatch the timer callback to the main thread because the
+ // decoder thread is a thread from nsIThreadPool and cannot be the timer
+ // target.
+ nsCOMPtr mainThread = do_GetMainThread();
+ mPauseTimer->SetTarget(mainThread);
+ mPauseTimer->InitWithFuncCallback(
+ RtspControllerChild::PauseTimerCallback,
+ this, kRtspCommandDelayMs,
+ nsITimer::TYPE_ONE_SHOT);
}
return NS_OK;
@@ -343,15 +389,7 @@ RtspControllerChild::Resume(void)
NS_ENSURE_TRUE(mSuspendCount > 0, NS_ERROR_UNEXPECTED);
if (!--mSuspendCount) {
- if (NS_IsMainThread()) {
- if (!OKToSendIPC() || !SendResume()) {
- return NS_ERROR_FAILURE;
- }
- } else {
- nsresult rv = NS_DispatchToMainThread(
- new SendIPCEvent(this, SendResumeEvent));
- NS_ENSURE_SUCCESS(rv, rv);
- }
+ return Play();
}
return NS_OK;
@@ -363,15 +401,7 @@ RtspControllerChild::Suspend(void)
LOG(("RtspControllerChild::Suspend()"));
if (!mSuspendCount++) {
- if (NS_IsMainThread()) {
- if (!OKToSendIPC() || !SendSuspend()) {
- return NS_ERROR_FAILURE;
- }
- } else {
- nsresult rv = NS_DispatchToMainThread(
- new SendIPCEvent(this, SendSuspendEvent));
- NS_ENSURE_SUCCESS(rv, rv);
- }
+ return Pause();
}
return NS_OK;
@@ -399,6 +429,7 @@ NS_IMETHODIMP
RtspControllerChild::Stop()
{
LOG(("RtspControllerChild::Stop()"));
+ StopPlayAndPauseTimer();
if (NS_IsMainThread()) {
if (!OKToSendIPC() || !SendStop()) {
@@ -542,5 +573,44 @@ RtspControllerChild::AsyncOpen(nsIStreamingProtocolListener *aListener)
return NS_OK;
}
+//-----------------------------------------------------------------------------
+// RtspControllerChild static member methods
+//-----------------------------------------------------------------------------
+//static
+void
+RtspControllerChild::PlayTimerCallback(nsITimer *aTimer, void *aClosure)
+{
+ MOZ_ASSERT(aTimer);
+ MOZ_ASSERT(aClosure);
+ MOZ_ASSERT(NS_IsMainThread());
+
+ RtspControllerChild *self = static_cast(aClosure);
+
+ MutexAutoLock lock(self->mTimerLock);
+ if (!self->mPlayTimer || !self->OKToSendIPC()) {
+ return;
+ }
+ self->SendPlay();
+ self->mPlayTimer = nullptr;
+}
+
+//static
+void
+RtspControllerChild::PauseTimerCallback(nsITimer *aTimer, void *aClosure)
+{
+ MOZ_ASSERT(aTimer);
+ MOZ_ASSERT(aClosure);
+ MOZ_ASSERT(NS_IsMainThread());
+
+ RtspControllerChild *self = static_cast(aClosure);
+
+ MutexAutoLock lock(self->mTimerLock);
+ if (!self->mPauseTimer || !self->OKToSendIPC()) {
+ return;
+ }
+ self->SendPause();
+ self->mPauseTimer = nullptr;
+}
+
} // namespace net
} // namespace mozilla
diff --git a/netwerk/protocol/rtsp/controller/RtspControllerChild.h b/netwerk/protocol/rtsp/controller/RtspControllerChild.h
index 298dc9e556ad..febae6ae21af 100644
--- a/netwerk/protocol/rtsp/controller/RtspControllerChild.h
+++ b/netwerk/protocol/rtsp/controller/RtspControllerChild.h
@@ -14,6 +14,8 @@
#include "nsString.h"
#include "nsTArray.h"
#include "mozilla/net/RtspChannelChild.h"
+#include "mozilla/Mutex.h"
+#include "nsITimer.h"
namespace mozilla {
namespace net {
@@ -52,6 +54,10 @@ class RtspControllerChild : public nsIStreamingProtocolController
void AllowIPC();
void DisallowIPC();
+ // These callbacks will be called when mPlayTimer/mPauseTimer fires.
+ static void PlayTimerCallback(nsITimer *aTimer, void *aClosure);
+ static void PauseTimerCallback(nsITimer *aTimer, void *aClosure);
+
private:
bool mIPCOpen;
// The intention of this variable is just to avoid any IPC message to be sent
@@ -73,6 +79,16 @@ class RtspControllerChild : public nsIStreamingProtocolController
uint32_t mSuspendCount;
// Detach channel-controller relationship.
void ReleaseChannel();
+ // This lock protects mPlayTimer and mPauseTimer.
+ Mutex mTimerLock;
+ // Timers to delay the play and pause operations.
+ // They are used for optimization and to avoid sending unnecessary requests to
+ // the server.
+ nsCOMPtr mPlayTimer;
+ nsCOMPtr mPauseTimer;
+ // Timers should be stopped if we are going to terminate, such as when
+ // receiving Stop command or OnDisconnected event.
+ void StopPlayAndPauseTimer();
};
} // namespace net
} // namespace mozilla