mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-11 01:57:00 +00:00
Bug 1123580 - Reorganize mmi parsing related code. r=hsinyi
This commit is contained in:
parent
84c5c2d1fc
commit
48960dace8
128
dom/telephony/gonk/DialNumberUtils.jsm
Normal file
128
dom/telephony/gonk/DialNumberUtils.jsm
Normal file
@ -0,0 +1,128 @@
|
||||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["DialNumberUtils"];
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/systemlibs.js");
|
||||
|
||||
const DEFAULT_EMERGENCY_NUMBERS = ["112", "911"];
|
||||
|
||||
const MMI_MATCH_GROUP_FULL_MMI = 1;
|
||||
const MMI_MATCH_GROUP_PROCEDURE = 2;
|
||||
const MMI_MATCH_GROUP_SERVICE_CODE = 3;
|
||||
const MMI_MATCH_GROUP_SIA = 4;
|
||||
const MMI_MATCH_GROUP_SIB = 5;
|
||||
const MMI_MATCH_GROUP_SIC = 6;
|
||||
const MMI_MATCH_GROUP_PWD_CONFIRM = 7;
|
||||
const MMI_MATCH_GROUP_DIALING_NUMBER = 8;
|
||||
|
||||
this.DialNumberUtils = {
|
||||
/**
|
||||
* Check a given number against the list of emergency numbers provided by the
|
||||
* RIL.
|
||||
*/
|
||||
isEmergency: function(aNumber) {
|
||||
// Check ril provided numbers first.
|
||||
let numbers = libcutils.property_get("ril.ecclist") ||
|
||||
libcutils.property_get("ro.ril.ecclist");
|
||||
if (numbers) {
|
||||
numbers = numbers.split(",");
|
||||
} else {
|
||||
// No ecclist system property, so use our own list.
|
||||
numbers = DEFAULT_EMERGENCY_NUMBERS;
|
||||
}
|
||||
return numbers.indexOf(aNumber) != -1;
|
||||
},
|
||||
|
||||
_mmiRegExp: (function() {
|
||||
// Procedure, which could be *, #, *#, **, ##
|
||||
let procedure = "(\\*[*#]?|##?)";
|
||||
|
||||
// Service code, which is a 2 or 3 digits that uniquely specifies the
|
||||
// Supplementary Service associated with the MMI code.
|
||||
let serviceCode = "(\\d{2,3})";
|
||||
|
||||
// Supplementary Information SIA, SIB and SIC.
|
||||
// Where a particular service request does not require any SI, "*SI" is
|
||||
// not entered. The use of SIA, SIB and SIC is optional and shall be
|
||||
// entered in any of the following formats:
|
||||
// - *SIA*SIB*SIC#
|
||||
// - *SIA*SIB#
|
||||
// - *SIA**SIC#
|
||||
// - *SIA#
|
||||
// - **SIB*SIC#
|
||||
// - ***SIC#
|
||||
//
|
||||
// Also catch the additional NEW_PASSWORD for the case of a password
|
||||
// registration procedure. Ex:
|
||||
// - * 03 * ZZ * OLD_PASSWORD * NEW_PASSWORD * NEW_PASSWORD #
|
||||
// - ** 03 * ZZ * OLD_PASSWORD * NEW_PASSWORD * NEW_PASSWORD #
|
||||
// - * 03 ** OLD_PASSWORD * NEW_PASSWORD * NEW_PASSWORD #
|
||||
// - ** 03 ** OLD_PASSWORD * NEW_PASSWORD * NEW_PASSWORD #
|
||||
let si = "\\*([^*#]*)";
|
||||
let allSi = "";
|
||||
for (let i = 0; i < 4; ++i) {
|
||||
allSi = "(?:" + si + allSi + ")?";
|
||||
}
|
||||
|
||||
let fullmmi = "(" + procedure + serviceCode + allSi + "#)";
|
||||
|
||||
// Dial string after the #.
|
||||
let optionalDialString = "([^#]+)?";
|
||||
|
||||
return new RegExp("^" + fullmmi + optionalDialString + "$");
|
||||
})(),
|
||||
|
||||
_isPoundString: function(aString) {
|
||||
return aString && aString[aString.length - 1] === "#";
|
||||
},
|
||||
|
||||
_isShortString: function(aString) {
|
||||
if (!aString || this.isEmergency(aString) || aString.length > 2 ||
|
||||
(aString.length == 2 && aString[0] === "1")) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check parse the given string as an MMI code.
|
||||
*
|
||||
* An MMI code should be:
|
||||
* - Activation (*SC*SI#).
|
||||
* - Deactivation (#SC*SI#).
|
||||
* - Interrogation (*#SC*SI#).
|
||||
* - Registration (**SC*SI#).
|
||||
* - Erasure (##SC*SI#).
|
||||
* where SC = Service Code (2 or 3 digits) and SI = Supplementary Info
|
||||
* (variable length).
|
||||
*/
|
||||
parseMMI: function(aString) {
|
||||
let matches = this._mmiRegExp.exec(aString);
|
||||
if (matches) {
|
||||
return {
|
||||
fullMMI: matches[MMI_MATCH_GROUP_FULL_MMI],
|
||||
procedure: matches[MMI_MATCH_GROUP_PROCEDURE],
|
||||
serviceCode: matches[MMI_MATCH_GROUP_SERVICE_CODE],
|
||||
sia: matches[MMI_MATCH_GROUP_SIA],
|
||||
sib: matches[MMI_MATCH_GROUP_SIB],
|
||||
sic: matches[MMI_MATCH_GROUP_SIC],
|
||||
pwd: matches[MMI_MATCH_GROUP_PWD_CONFIRM],
|
||||
dialNumber: matches[MMI_MATCH_GROUP_DIALING_NUMBER]
|
||||
};
|
||||
}
|
||||
|
||||
if (this._isPoundString(aString) || this._isShortString(aString)) {
|
||||
return {
|
||||
fullMMI: aString
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
@ -10,7 +10,6 @@ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
Cu.import("resource://gre/modules/systemlibs.js");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "RIL", function () {
|
||||
let obj = {};
|
||||
@ -48,20 +47,9 @@ const DIAL_ERROR_INVALID_STATE_ERROR = "InvalidStateError";
|
||||
const DIAL_ERROR_OTHER_CONNECTION_IN_USE = "OtherConnectionInUse";
|
||||
const DIAL_ERROR_BAD_NUMBER = RIL.GECKO_CALL_ERROR_BAD_NUMBER;
|
||||
|
||||
const DEFAULT_EMERGENCY_NUMBERS = ["112", "911"];
|
||||
|
||||
const TONES_GAP_DURATION = 70;
|
||||
|
||||
// MMI match groups
|
||||
const MMI_MATCH_GROUP_FULL_MMI = 1;
|
||||
const MMI_MATCH_GROUP_PROCEDURE = 2;
|
||||
const MMI_MATCH_GROUP_SERVICE_CODE = 3;
|
||||
const MMI_MATCH_GROUP_SIA = 4;
|
||||
const MMI_MATCH_GROUP_SIB = 5;
|
||||
const MMI_MATCH_GROUP_SIC = 6;
|
||||
const MMI_MATCH_GROUP_PWD_CONFIRM = 7;
|
||||
const MMI_MATCH_GROUP_DIALING_NUMBER = 8;
|
||||
|
||||
let DEBUG;
|
||||
function debug(s) {
|
||||
dump("TelephonyService: " + s + "\n");
|
||||
@ -93,6 +81,12 @@ XPCOMUtils.defineLazyGetter(this, "gPhoneNumberUtils", function() {
|
||||
return ns.PhoneNumberUtils;
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gDialNumberUtils", function() {
|
||||
let ns = {};
|
||||
Cu.import("resource://gre/modules/DialNumberUtils.jsm", ns);
|
||||
return ns.DialNumberUtils;
|
||||
});
|
||||
|
||||
function MobileCallForwardingOptions(aOptions) {
|
||||
for (let key in aOptions) {
|
||||
this[key] = aOptions[key];
|
||||
@ -160,8 +154,6 @@ function TelephonyService() {
|
||||
this._numClients = gRadioInterfaceLayer.numRadioInterfaces;
|
||||
this._listeners = [];
|
||||
|
||||
this._mmiRegExp = null;
|
||||
|
||||
this._isDialing = false;
|
||||
this._cachedDialRequest = null;
|
||||
this._currentCalls = {};
|
||||
@ -343,26 +335,6 @@ TelephonyService.prototype = {
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Check a given number against the list of emergency numbers provided by the
|
||||
* RIL.
|
||||
*
|
||||
* @param aNumber
|
||||
* The number to look up.
|
||||
*/
|
||||
_isEmergencyNumber: function(aNumber) {
|
||||
// Check ril provided numbers first.
|
||||
let numbers = libcutils.property_get("ril.ecclist") ||
|
||||
libcutils.property_get("ro.ril.ecclist");
|
||||
if (numbers) {
|
||||
numbers = numbers.split(",");
|
||||
} else {
|
||||
// No ecclist system property, so use our own list.
|
||||
numbers = DEFAULT_EMERGENCY_NUMBERS;
|
||||
}
|
||||
return numbers.indexOf(aNumber) != -1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks whether to temporarily suppress caller id for the call.
|
||||
*
|
||||
@ -553,7 +525,7 @@ TelephonyService.prototype = {
|
||||
isDialEmergency: aIsDialEmergency }, aCallback);
|
||||
}
|
||||
} else {
|
||||
let mmi = this._parseMMI(aNumber);
|
||||
let mmi = gDialNumberUtils.parseMMI(aNumber);
|
||||
if (!mmi) {
|
||||
this._dialCall(aClientId,
|
||||
{ number: aNumber,
|
||||
@ -602,7 +574,7 @@ TelephonyService.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
aOptions.isEmergency = this._isEmergencyNumber(aOptions.number);
|
||||
aOptions.isEmergency = gDialNumberUtils.isEmergency(aOptions.number);
|
||||
if (aOptions.isEmergency) {
|
||||
// Automatically select a proper clientId for emergency call.
|
||||
aClientId = gRadioInterfaceLayer.getClientIdForEmergencyCall() ;
|
||||
@ -750,138 +722,6 @@ TelephonyService.prototype = {
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Build the regex to parse MMI string. TS.22.030
|
||||
*
|
||||
* The resulting groups after matching will be:
|
||||
* 1 = full MMI string that might be used as a USSD request.
|
||||
* 2 = MMI procedure.
|
||||
* 3 = Service code.
|
||||
* 4 = SIA.
|
||||
* 5 = SIB.
|
||||
* 6 = SIC.
|
||||
* 7 = Password registration.
|
||||
* 8 = Dialing number.
|
||||
*/
|
||||
_buildMMIRegExp: function() {
|
||||
// The general structure of the codes is as follows:
|
||||
// - Activation (*SC*SI#).
|
||||
// - Deactivation (#SC*SI#).
|
||||
// - Interrogation (*#SC*SI#).
|
||||
// - Registration (**SC*SI#).
|
||||
// - Erasure (##SC*SI#).
|
||||
//
|
||||
// where SC = Service Code (2 or 3 digits) and SI = Supplementary Info
|
||||
// (variable length).
|
||||
|
||||
// Procedure, which could be *, #, *#, **, ##
|
||||
let procedure = "(\\*[*#]?|##?)";
|
||||
|
||||
// Service code, which is a 2 or 3 digits that uniquely specifies the
|
||||
// Supplementary Service associated with the MMI code.
|
||||
let serviceCode = "(\\d{2,3})";
|
||||
|
||||
// Supplementary Information SIA, SIB and SIC. SIA may comprise e.g. a PIN
|
||||
// code or Directory Number, SIB may be used to specify the tele or bearer
|
||||
// service and SIC to specify the value of the "No Reply Condition Timer".
|
||||
// Where a particular service request does not require any SI, "*SI" is
|
||||
// not entered. The use of SIA, SIB and SIC is optional and shall be
|
||||
// entered in any of the following formats:
|
||||
// - *SIA*SIB*SIC#
|
||||
// - *SIA*SIB#
|
||||
// - *SIA**SIC#
|
||||
// - *SIA#
|
||||
// - **SIB*SIC#
|
||||
// - ***SIC#
|
||||
//
|
||||
// Also catch the additional NEW_PASSWORD for the case of a password
|
||||
// registration procedure. Ex:
|
||||
// - * 03 * ZZ * OLD_PASSWORD * NEW_PASSWORD * NEW_PASSWORD #
|
||||
// - ** 03 * ZZ * OLD_PASSWORD * NEW_PASSWORD * NEW_PASSWORD #
|
||||
// - * 03 ** OLD_PASSWORD * NEW_PASSWORD * NEW_PASSWORD #
|
||||
// - ** 03 ** OLD_PASSWORD * NEW_PASSWORD * NEW_PASSWORD #
|
||||
let si = "\\*([^*#]*)";
|
||||
let allSi = "";
|
||||
for (let i = 0; i < 4; ++i) {
|
||||
allSi = "(?:" + si + allSi + ")?";
|
||||
}
|
||||
|
||||
let fullmmi = "(" + procedure + serviceCode + allSi + "#)";
|
||||
|
||||
// Dial string after the #.
|
||||
let optionalDialString = "([^#]+)?";
|
||||
|
||||
return new RegExp("^" + fullmmi + optionalDialString + "$");
|
||||
},
|
||||
|
||||
/**
|
||||
* Provide the regex to parse MMI string.
|
||||
*/
|
||||
_getMMIRegExp: function() {
|
||||
if (!this._mmiRegExp) {
|
||||
this._mmiRegExp = this._buildMMIRegExp();
|
||||
}
|
||||
|
||||
return this._mmiRegExp;
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper to parse # string. TS.22.030 Figure 3.5.3.2.
|
||||
*/
|
||||
_isPoundString: function(aMmiString) {
|
||||
return (aMmiString.charAt(aMmiString.length - 1) === "#");
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper to parse short string. TS.22.030 Figure 3.5.3.2.
|
||||
*/
|
||||
_isShortString: function(aMmiString) {
|
||||
if (aMmiString.length > 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Input string is
|
||||
// - emergency number or
|
||||
// - 2 digits starting with a "1"
|
||||
if (this._isEmergencyNumber(aMmiString) ||
|
||||
(aMmiString.length == 2) && (aMmiString.charAt(0) === '1')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper to parse MMI/USSD string. TS.22.030 Figure 3.5.3.2.
|
||||
*/
|
||||
_parseMMI: function(aMmiString) {
|
||||
if (!aMmiString) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let matches = this._getMMIRegExp().exec(aMmiString);
|
||||
if (matches) {
|
||||
return {
|
||||
fullMMI: matches[MMI_MATCH_GROUP_FULL_MMI],
|
||||
procedure: matches[MMI_MATCH_GROUP_PROCEDURE],
|
||||
serviceCode: matches[MMI_MATCH_GROUP_SERVICE_CODE],
|
||||
sia: matches[MMI_MATCH_GROUP_SIA],
|
||||
sib: matches[MMI_MATCH_GROUP_SIB],
|
||||
sic: matches[MMI_MATCH_GROUP_SIC],
|
||||
pwd: matches[MMI_MATCH_GROUP_PWD_CONFIRM],
|
||||
dialNumber: matches[MMI_MATCH_GROUP_DIALING_NUMBER]
|
||||
};
|
||||
}
|
||||
|
||||
if (this._isPoundString(aMmiString) || this._isShortString(aMmiString)) {
|
||||
return {
|
||||
fullMMI: aMmiString
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
_serviceCodeToKeyString: function(aServiceCode) {
|
||||
switch (aServiceCode) {
|
||||
case RIL.MMI_SC_CFU:
|
||||
@ -1178,7 +1018,7 @@ TelephonyService.prototype = {
|
||||
|
||||
aCall.clientId = aClientId;
|
||||
aCall.state = nsITelephonyService.CALL_STATE_DISCONNECTED;
|
||||
aCall.isEmergency = this._isEmergencyNumber(aCall.number);
|
||||
aCall.isEmergency = gDialNumberUtils.isEmergency(aCall.number);
|
||||
let duration = ("started" in aCall && typeof aCall.started == "number") ?
|
||||
new Date().getTime() - aCall.started : 0;
|
||||
|
||||
@ -1273,12 +1113,12 @@ TelephonyService.prototype = {
|
||||
call.state = aCall.state;
|
||||
call.number = aCall.number;
|
||||
call.isConference = aCall.isConference;
|
||||
call.isEmergency = this._isEmergencyNumber(aCall.number);
|
||||
call.isEmergency = gDialNumberUtils.isEmergency(aCall.number);
|
||||
call.isSwitchable = pick(aCall.isSwitchable, call.isSwitchable);
|
||||
call.isMergeable = pick(aCall.isMergeable, call.isMergeable);
|
||||
} else {
|
||||
call = aCall;
|
||||
call.isEmergency = pick(aCall.isEmergency, this._isEmergencyNumber(aCall.number));
|
||||
call.isEmergency = pick(aCall.isEmergency, gDialNumberUtils.isEmergency(aCall.number));
|
||||
call.isSwitchable = pick(aCall.isSwitchable, true);
|
||||
call.isMergeable = pick(aCall.isMergeable, true);
|
||||
call.name = pick(aCall.name, "");
|
||||
|
@ -66,6 +66,9 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_B2G_RIL']:
|
||||
'gonk/TelephonyService.js',
|
||||
'gonk/TelephonyService.manifest',
|
||||
]
|
||||
EXTRA_JS_MODULES += [
|
||||
'gonk/DialNumberUtils.jsm'
|
||||
]
|
||||
|
||||
FAIL_ON_WARNINGS = True
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
@ -4,15 +4,14 @@
|
||||
subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
|
||||
|
||||
let NS = {};
|
||||
subscriptLoader.loadSubScript("resource://gre/components/TelephonyService.js",
|
||||
NS);
|
||||
subscriptLoader.loadSubScript("resource://gre/modules/DialNumberUtils.jsm", NS);
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function parseMMI(mmiString) {
|
||||
return NS.TelephonyService.prototype._parseMMI(mmiString);
|
||||
return NS.DialNumberUtils.parseMMI(mmiString);
|
||||
}
|
||||
|
||||
add_test(function test_parseMMI_empty() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user