mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 13:23:07 +00:00
import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 859764 - Part 5: Changes in Test Cases. r=echen (f1a5cd4fd3) - Bug 859764 - Part 6: Changes in Payment. r=ferjm, r=smaug (2b47641375) - Bug 1010756 - Helpful errors for using nsCOMPtr on non-XPCOM types; r=froydnj (6b1521c482) - leftover (e1a24351e9) - Bug 1192102 - Remove unused file embedded/android/GeckoSmsManager.java. r=blassey (ac05ae649d) - var-let (8ddb529f96) - Bug 1181466 - Fix observe function in SmsService/MmsService. r=btseng (ca93122404) - Bug 733331 - Part 2: Update enabledGsmTableTuples when MCC changes in SmsService.js and fix segmentChars in SmsSegmentHelper.jsm. r=btseng (24fa23e4be) - Bug 1173156 - Fix typo and add a Marionette test case. r=btseng (e7199eb55a) - Bug 1132774 - [B2G][SMS] Enable DEBUG Flag in SmsService if the default value of "ril.debugging.enabled" is true. r=btseng (7300d24fb7) - Bug 1169160 - [MobileConnection] Support more call barring program: all service, outgoing service and incoming service. r=hsinyi,aknow (872c2cc056) - Bug 1169225 - [MobileConnectionService] Support setting/getting call waiting on all serviceClass. r=aknow (14c546a9ca) - Bug 1110619 - Part 1: IDL Interface Changes. r=echen (beae2b4b77) - Bug 1168064 - B2G RIL: filter out cell info with unknown values. r=echen (11dfc5a7e8) - Bug 1159591 - Part 2: Move MMI logic from ril_worker to telephonyService (Call Forwarding). r=aknow (b4edb76863) - Bug 1159591 - Part 3: Move MMI logic from ril_worker to telephonyService (Icc Lock). r=aknow (3faba76808) - Bug 1138263 - Make TelephonyService.js JSHint friendly. r=hsinyi (454bd4c765) - Bug 1159591 - Part 4: Move MMI logic from ril_worker to telephonyService (IMEI). r=aknow (57f423ecdd) - Bug 1159591 - Part 5: Move MMI logic from ril_worker to telephonyService (CLIP). r=aknow (c6611dbcb8) - Bug 1159591 - Part 6: Move MMI logic from ril_worker to telephonyService (CLIR). r=aknow (8c1fc03edb) - Bug 1159591 - Part 7: Move MMI logic from ril_worker to telephonyService (Call Barring Password). r=aknow (5d8bcbf177) - Bug 1159591 - Part 8: Move MMI logic from ril_worker to telephonyService (Call Barring). r=aknow (aa0b89aea1) - Bug 1159591 - Part 9: Move MMI logic from ril_worker to telephonyService (Call Waiting). r=aknow (1d14d2b864) - Bug 1159591 - Part 10: Move MMI logic from ril_worker to telephonyService (USSD). r=aknow (c92130b5b2) - Bug 1159591 - Part 11: Move MMI consts from ril_consts to telephonyService. r=aknow (0e7b3fea9a) - Bug 1159591 - Part 12: Move radio check for MMI to a common place. r=aknow (dcdc3178ad) - Bug 1110619 - Part 2: Implementation Changes. r=echen (6d8e78d684) - Bug 1110619 - Part 3: Bluetooth Changes. r=btian (9787727be0) - Bug 1147736 - Part 1: Extend TelephonyCallInfo. r=aknow (2a426cc99f) - Bug 1147736 - Part 2: Bypass NotifyError. r=aknow (6cd6fd6867) - Bug 1147736 - Part 3: Deprecate NotifyError. r=aknow (e41c719442) - Bug 1147736 - Part 4: Deprecate NotifyError(Bluetooth). r=btian (9c8f97bb22) - Bug 1204817 - Delete the child property of a parent call only when the parent call exists. r=btseng (d35dc6b08f) - Bug 1191205 - Cancel USSD sessions only when needed. r=edgar (01a72dbacb) - Bug 1200134 - Control USSD Sessions with State-Transitions instead of Boolean. r=echen (a4e55b3d9d) - Bug 1163511 - Use defineLazyModuleGetter. r=hsinyi (8a97a4912c) - Bug 991582 - Part 2: Handle the result of RIL request in a consistent way. r=aknow (914ecc2bbb) - Bug 1164248 - Handling of session/sessionEnded for notifyUssdReceived. r=edgar (a79df75d38) - Bug 1223662 - Part 1: Check mmiServiceCode with correct constant. r=echen (abeb286050) - Bug 1174673 - Part 1: Automatically resume the held call. r=hsinyi (280543af7d) - Bug 1174673 - Part 2: Update test case. r=hsinyi (cfe19f1a52) - Bug 1185156 - Fix bug in resuming held call. r=hsinyi (b96346d319) - Bug 1162426 - Part 1: Provide TelephonyUtils. r=hsinyi (62b71e6e83) - Bug 1162426 - Part 2: Test case. r=hsniyi (13a0b3c6f5) - Bug 1171807 - Part 1: Add enums for TelephonyCall::State and TelephonyCallGroup::State (WebIDL). r=hsinyi (0b698eecc4) - Bug 1145551 - DTMF should be sent using the active SIM, the given or the default one (in that order). r=aknow (6157636493) - Bug 1171807 - Part 2: Move to enums and deprecate TelephonyCall.mCallState and TelephonyCallGroup.mCallState (DOM). r=btseng (5faef22d91) - Bug 1168515 - do not block incall MMI requests on alerting state. r=aknow (b1f85c5789) - Bug 1155072 - Part 1: Deprecate nsITelephonyListener.conferenceCallStateChanged (Telephony). r=btseng (e41d1a4bc9) - Bug 1155072 - Part 2: Deprecate nsITelephonyListener.conferenceCallStateChanged (Bluetooth). r=btian (27e69fa89b) - Bug 1166936 - JS Warning in TelephonyService.js r=aknow (3559d3ad3d) - Bug 1191237 - Part 1: Enhance |TelephonyService.js|. r=aknow (86576a6d32) - Bug 1202902 - Fix the world. (0dc256d67d) - Bug 1161438 - Part 1 - Exporting contact to SIM should also return updated contact. r=echen (505d7d7f83) - Bug 1159622 - Split test_icc_contact.js into read contact and add contact. r=echen (fec0c428df) - Bug 1122376 - Support read SIM contact dialling number exceed 20 digits. r=echen (5d0599e93c) - Bug 1161438 - Part 2 - marionette testcase. r=echen (1f0d18a479) - Bug 1114937 - Part 5: Fix Test Case to Remove Contact with Correct Contact Id. r=echen (8d746fdbd2) - Bug 1194149 - Continue importing contacts when there is no sufficient Type 2 USIM contact fields record. r=echen (e9be40dbf2) - Bug 962995 - xpcshell tests for write ICC UCS2 characters for 0x81 and 0x82 encoding. r=echen (9500afaa4d) - Bug 1161438 - Part 3 - xpcshell testcase. r=echen (01f7fb4514) - Bug 1122376 - Support write SIM contact dialling number exceed 20 digits. r=echen (91133e286d) - Bug 999300 - Part 1: Removed the Ril v5 legacy support. r=edgar (ded77fcb6f) - Bug 999300 - Part 2: Update the related testcases. r=edgar (f77a8b96cc) - Bug 1177146 - [Aries][RIL] Reply from QUERY_AVAILABLE_NETWORKS has extra strings. r=hsinyi (a6816cbbab) - Bug 1043250 - Part 1: Update ril_worker and xpcshell test. r=btseng (8b9b25b5cf) - Bug 1185406 - B2G RIL: Read 'pcscf' and expose it in nsIRilNetworkInfo. r=hsinyi (ce707ecb83) - Bug 1174998 - Part 3: Read data call's MTU from network/apn settings. r=echen (bfa08d8380) - Bug 1166320 - Make volume service safer to use off main thread. r=dhylands (b3976622ad) - Bug 1177374 - Call realpath on volume mount points so thatVolumeService::GetVolumeByPath works properly. r=achen (aea97080eb) - Bug 1195166 - AutoMounter: add ignore command to allow volumes to be ignored. r=alchen (f265d832c8) - Bug 1196724 - Refactoring of AudioManager r=alwu (e5b896b7ce) - Bug 1222564 - Save audio volume to database r=alwu (1303d01ae7) - Bug 1164049 - Fix some mode lines in embedding/. r=smaug (79ddce4871)
This commit is contained in:
@@ -538,6 +538,8 @@
|
||||
@RESPATH@/components/RILSystemMessengerHelper.manifest
|
||||
@RESPATH@/components/TelephonyAudioService.js
|
||||
@RESPATH@/components/TelephonyAudioService.manifest
|
||||
@RESPATH@/components/USSDReceivedWrapper.js
|
||||
@RESPATH@/components/USSDReceivedWrapper.manifest
|
||||
#ifndef DISABLE_MOZ_RIL_GEOLOC
|
||||
@RESPATH@/components/TelephonyService.js
|
||||
@RESPATH@/components/TelephonyService.manifest
|
||||
|
||||
@@ -165,6 +165,12 @@ MobileConnectionListener::NotifyNetworkSelectionModeChanged()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MobileConnectionListener::NotifyDeviceIdentitiesChanged()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
MobileConnectionListener::Listen(bool aStart)
|
||||
{
|
||||
@@ -203,16 +209,23 @@ TelephonyListener::HandleCallInfo(nsITelephonyCallInfo* aInfo, bool aSend)
|
||||
uint32_t callIndex;
|
||||
uint16_t callState;
|
||||
nsAutoString number;
|
||||
nsAutoString disconnectedReason;
|
||||
bool isOutgoing;
|
||||
bool isConference;
|
||||
|
||||
aInfo->GetCallIndex(&callIndex);
|
||||
aInfo->GetCallState(&callState);
|
||||
aInfo->GetNumber(number);
|
||||
aInfo->GetDisconnectedReason(disconnectedReason);
|
||||
aInfo->GetIsOutgoing(&isOutgoing);
|
||||
aInfo->GetIsConference(&isConference);
|
||||
|
||||
hfp->HandleCallStateChanged(callIndex, callState, EmptyString(), number,
|
||||
// The disconnectedReason of a disconnected call must be nonempty no matter
|
||||
// the call is disconnected for a normal reason or an error.
|
||||
MOZ_ASSERT((callState != nsITelephonyService::CALL_STATE_DISCONNECTED ||
|
||||
!disconnectedReason.IsEmpty()),
|
||||
"disconnectedReason of an disconnected call must be nonempty.");
|
||||
hfp->HandleCallStateChanged(callIndex, callState, disconnectedReason, number,
|
||||
isOutgoing, isConference, aSend);
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -233,36 +246,6 @@ TelephonyListener::EnumerateCallState(nsITelephonyCallInfo* aInfo)
|
||||
return HandleCallInfo(aInfo, false);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyListener::NotifyError(uint32_t aServiceId,
|
||||
int32_t aCallIndex,
|
||||
const nsAString& aError)
|
||||
{
|
||||
BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
|
||||
NS_ENSURE_TRUE(hfp, NS_ERROR_FAILURE);
|
||||
|
||||
if (aCallIndex > 0) {
|
||||
// In order to not miss any related call state transition.
|
||||
// It's possible that 3G network signal lost for unknown reason.
|
||||
// If a call is released abnormally, NotifyError() will be called,
|
||||
// instead of CallStateChanged(). We need to reset the call array state
|
||||
// via setting CALL_STATE_DISCONNECTED
|
||||
hfp->HandleCallStateChanged(aCallIndex,
|
||||
nsITelephonyService::CALL_STATE_DISCONNECTED,
|
||||
aError, EmptyString(), false, false, true);
|
||||
BT_WARNING("Reset the call state due to call transition ends abnormally");
|
||||
}
|
||||
|
||||
BT_WARNING(NS_ConvertUTF16toUTF8(aError).get());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyListener::ConferenceCallStateChanged(uint16_t aCallState)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyListener::EnumerateCallStateComplete()
|
||||
{
|
||||
|
||||
@@ -47,7 +47,7 @@ const CELLBROADCASTETWSINFO_CID =
|
||||
|
||||
const NS_XPCOM_SHUTDOWN_OBSERVER_ID = "xpcom-shutdown";
|
||||
|
||||
let DEBUG;
|
||||
var DEBUG;
|
||||
function debug(s) {
|
||||
dump("CellBroadcastService: " + s);
|
||||
}
|
||||
@@ -156,7 +156,7 @@ CellBroadcastService.prototype = {
|
||||
.getRadioInterface(clientId).sendWorkerMessage("setCellBroadcastSearchList",
|
||||
{ searchList: newSearchList },
|
||||
(function callback(aResponse) {
|
||||
if (DEBUG && !aResponse.success) {
|
||||
if (DEBUG && aResponse.errorMsg) {
|
||||
debug("Failed to set new search list: " + newSearchList +
|
||||
" to client id: " + clientId);
|
||||
}
|
||||
@@ -165,7 +165,7 @@ CellBroadcastService.prototype = {
|
||||
if (responses.length == numOfRilClients) {
|
||||
let successCount = 0;
|
||||
for (let i = 0; i < responses.length; i++) {
|
||||
if (responses[i].success) {
|
||||
if (!responses[i].errorMsg) {
|
||||
successCount++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,9 @@ b2g = true
|
||||
browser = false
|
||||
qemu = true
|
||||
|
||||
[test_icc_contact.js]
|
||||
[test_icc_contact_read.js]
|
||||
[test_icc_contact_add.js]
|
||||
[test_icc_contact_update.js]
|
||||
[test_icc_card_lock_get_retry_count.js]
|
||||
[test_icc_card_lock_change_pin.js]
|
||||
[test_icc_card_lock_enable_pin.js]
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_TIMEOUT = 120000;
|
||||
MARIONETTE_HEAD_JS = "head.js";
|
||||
|
||||
var TEST_ADD_DATA = [{
|
||||
// a contact without email and anr.
|
||||
name: ["add1"],
|
||||
tel: [{value: "0912345678"}],
|
||||
}, {
|
||||
// a contact over 20 digits.
|
||||
name: ["add2"],
|
||||
tel: [{value: "012345678901234567890123456789"}],
|
||||
}, {
|
||||
// a contact over 40 digits.
|
||||
name: ["add3"],
|
||||
tel: [{value: "01234567890123456789012345678901234567890123456789"}],
|
||||
}, {
|
||||
// a contact with email but without anr.
|
||||
name: ["add4"],
|
||||
tel: [{value: "01234567890123456789"}],
|
||||
email:[{value: "test@mozilla.com"}],
|
||||
}, {
|
||||
// a contact with anr but without email.
|
||||
name: ["add5"],
|
||||
tel: [{value: "01234567890123456789"}, {value: "123456"}, {value: "123"}],
|
||||
}, {
|
||||
// a contact with email and anr.
|
||||
name: ["add6"],
|
||||
tel: [{value: "01234567890123456789"}, {value: "123456"}, {value: "123"}],
|
||||
email:[{value: "test@mozilla.com"}],
|
||||
}];
|
||||
|
||||
function testAddContact(aIcc, aType, aMozContact, aPin2) {
|
||||
log("testAddContact: type=" + aType + ", pin2=" + aPin2);
|
||||
let contact = new mozContact(aMozContact);
|
||||
|
||||
return aIcc.updateContact(aType, contact, aPin2)
|
||||
.then((aResult) => {
|
||||
is(aResult.name[0], aMozContact.name[0]);
|
||||
// Maximum digits of the Dialling Number is 20, and maximum digits of Extension is 20.
|
||||
is(aResult.tel[0].value, aMozContact.tel[0].value.substring(0, 40));
|
||||
// We only support SIM in emulator, so we don't have anr and email field.
|
||||
ok(aResult.tel.length == 1);
|
||||
ok(!aResult.email);
|
||||
|
||||
// Get ICC contact for checking new contact
|
||||
return aIcc.readContacts(aType)
|
||||
.then((aResult) => {
|
||||
let contact = aResult[aResult.length - 1];
|
||||
is(contact.name[0], aMozContact.name[0]);
|
||||
// Maximum digits of the Dialling Number is 20, and maximum digits of Extension is 20.
|
||||
is(contact.tel[0].value, aMozContact.tel[0].value.substring(0, 40));
|
||||
is(contact.id.substring(0, aIcc.iccInfo.iccid.length), aIcc.iccInfo.iccid);
|
||||
|
||||
return contact.id;
|
||||
})
|
||||
.then((aContactId) => {
|
||||
// Clean up contact
|
||||
return removeContact(aIcc, aContactId, aType, aPin2);
|
||||
});
|
||||
}, (aError) => {
|
||||
if (aType === "fdn" && aPin2 === undefined) {
|
||||
ok(aError.name === "SimPin2",
|
||||
"expected error when pin2 is not provided");
|
||||
} else {
|
||||
ok(false, "Cannot add " + aType + " contact: " + aError.name);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function removeContact(aIcc, aContactId, aType, aPin2) {
|
||||
log("removeContact: contactId=" + aContactId +
|
||||
", type=" + aType + ", pin2=" + aPin2);
|
||||
|
||||
let contact = new mozContact({});
|
||||
contact.id = aContactId;
|
||||
|
||||
return aIcc.updateContact(aType, contact, aPin2);
|
||||
}
|
||||
|
||||
// Start tests
|
||||
startTestCommon(function() {
|
||||
let icc = getMozIcc();
|
||||
let promise = Promise.resolve();
|
||||
for (let i = 0; i < TEST_ADD_DATA.length; i++) {
|
||||
let test_data = TEST_ADD_DATA[i];
|
||||
// Test add adn contacts
|
||||
promise = promise.then(() => testAddContact(icc, "adn", test_data))
|
||||
// Test add fdn contacts
|
||||
.then(() => testAddContact(icc, "fdn", test_data, "0000"))
|
||||
// Test add fdn contacts without passing pin2
|
||||
.then(() => testAddContact(icc, "fdn", test_data));
|
||||
}
|
||||
return promise;
|
||||
});
|
||||
+19
-37
@@ -9,58 +9,46 @@ function testReadContacts(aIcc, aType) {
|
||||
let iccId = aIcc.iccInfo.iccid;
|
||||
return aIcc.readContacts(aType)
|
||||
.then((aResult) => {
|
||||
is(Array.isArray(aResult), true);
|
||||
|
||||
is(Array.isArray(aResult), true);
|
||||
is(aResult.length, 6, "Check contact number.");
|
||||
|
||||
// Alpha Id(Encoded with GSM 8 bit): "Mozilla", Dialling Number: 15555218201
|
||||
is(aResult[0].name[0], "Mozilla");
|
||||
is(aResult[0].tel[0].value, "15555218201");
|
||||
is(aResult[0].id, iccId + "1");
|
||||
|
||||
// Alpha Id(Encoded with UCS2 0x80: "Saßê\u9ec3", Dialling Number: 15555218202
|
||||
is(aResult[1].name[0], "Saßê黃");
|
||||
is(aResult[1].tel[0].value, "15555218202");
|
||||
is(aResult[1].id, iccId + "2");
|
||||
|
||||
// Alpha Id(Encoded with UCS2 0x81): "Fire \u706b", Dialling Number: 15555218203
|
||||
is(aResult[2].name[0], "Fire 火");
|
||||
is(aResult[2].tel[0].value, "15555218203");
|
||||
is(aResult[2].id, iccId + "3");
|
||||
|
||||
// Alpha Id(Encoded with UCS2 0x82): "Huang \u9ec3", Dialling Number: 15555218204
|
||||
is(aResult[3].name[0], "Huang 黃");
|
||||
is(aResult[3].tel[0].value, "15555218204");
|
||||
is(aResult[3].id, iccId + "4");
|
||||
|
||||
// Alpha Id(Encoded with GSM 8 bit): "Contact001",
|
||||
// Dialling Number: 9988776655443322110001234567890123456789
|
||||
is(aResult[4].name[0], "Contact001");
|
||||
is(aResult[4].tel[0].value, "9988776655443322110001234567890123456789");
|
||||
is(aResult[4].id, iccId + "5");
|
||||
|
||||
// Alpha Id(Encoded with GSM 8 bit): "Contact002",
|
||||
// Dialling Number: 0123456789012345678999887766554433221100
|
||||
is(aResult[5].name[0], "Contact002");
|
||||
is(aResult[5].tel[0].value, "0123456789012345678999887766554433221100");
|
||||
is(aResult[5].id, iccId + "6");
|
||||
}, (aError) => {
|
||||
ok(false, "Cannot get " + aType + " contacts");
|
||||
});
|
||||
}
|
||||
|
||||
function testAddContact(aIcc, aType, aPin2) {
|
||||
log("testAddContact: type=" + aType + ", pin2=" + aPin2);
|
||||
let contact = new mozContact({
|
||||
name: ["add"],
|
||||
tel: [{value: "0912345678"}],
|
||||
email:[]
|
||||
});
|
||||
|
||||
return aIcc.updateContact(aType, contact, aPin2)
|
||||
.then((aResult) => {
|
||||
// Get ICC contact for checking new contact
|
||||
return aIcc.readContacts(aType)
|
||||
.then((aResult) => {
|
||||
// There are 4 SIM contacts which are harded in emulator
|
||||
is(aResult.length, 5);
|
||||
|
||||
is(aResult[4].name[0], "add");
|
||||
is(aResult[4].tel[0].value, "0912345678");
|
||||
}, (aError) => {
|
||||
ok(false, "Cannot get " + aType + " contacts: " + aError.name);
|
||||
})
|
||||
}, (aError) => {
|
||||
if (aType === "fdn" && aPin2 === undefined) {
|
||||
ok(aError.name === "SimPin2",
|
||||
"expected error when pin2 is not provided");
|
||||
} else {
|
||||
ok(false, "Cannot add " + aType + " contact: " + aError.name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Start tests
|
||||
startTestCommon(function() {
|
||||
@@ -68,14 +56,8 @@ startTestCommon(function() {
|
||||
|
||||
// Test read adn contacts
|
||||
return testReadContacts(icc, "adn")
|
||||
// Test add adn contacts
|
||||
.then(() => testAddContact(icc, "adn"))
|
||||
// Test read fdn contact
|
||||
.then(() => testReadContacts(icc, "fdn"))
|
||||
// Test add fdn contacts
|
||||
.then(() => testAddContact(icc, "fdn", "0000"))
|
||||
// Test add fdn contacts without passing pin2
|
||||
.then(() => testAddContact(icc, "fdn"))
|
||||
// Test read sdn contacts
|
||||
.then(() => testReadContacts(icc, "sdn"));
|
||||
});
|
||||
@@ -0,0 +1,122 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_TIMEOUT = 120000;
|
||||
MARIONETTE_HEAD_JS = "head.js";
|
||||
|
||||
const TEST_UPDATE_DATA = [{
|
||||
id: 1,
|
||||
data: {
|
||||
name: ["Mozilla"],
|
||||
tel: [{value: "9876543210987654321001234"}]},
|
||||
expect: {
|
||||
number: "9876543210987654321001234"}
|
||||
}, {
|
||||
id:2,
|
||||
data: {
|
||||
name: ["Saßê黃"],
|
||||
tel: [{value: "98765432109876543210998877665544332211001234"}]},
|
||||
expect: {
|
||||
// We don't support extension chain now.
|
||||
number: "9876543210987654321099887766554433221100"}
|
||||
}, {
|
||||
id: 3,
|
||||
data: {
|
||||
name: ["Fire 火"],
|
||||
tel: [{value: ""}]},
|
||||
expect: {
|
||||
number: null}
|
||||
}, {
|
||||
id: 5,
|
||||
data: {
|
||||
name: ["Contact001"],
|
||||
tel: [{value: "9988776655443322110098765432109876543210"}]},
|
||||
expect: {
|
||||
number: "9988776655443322110098765432109876543210"}
|
||||
}, {
|
||||
id: 6,
|
||||
data: {
|
||||
name: ["Contact002"],
|
||||
tel: [{value: "+99887766554433221100"}]},
|
||||
expect: {
|
||||
number: "+99887766554433221100"}
|
||||
}];
|
||||
|
||||
function testUpdateContact(aIcc, aType, aContactId, aMozContact, aExpect, aPin2) {
|
||||
log("testUpdateContact: type=" + aType +
|
||||
", mozContact=" + JSON.stringify(aMozContact) +
|
||||
", expect=" + aExpect.number + ", pin2=" + aPin2);
|
||||
|
||||
let contact = new mozContact(aMozContact);
|
||||
contact.id = aIcc.iccInfo.iccid + aContactId;
|
||||
|
||||
return aIcc.updateContact(aType, contact, aPin2)
|
||||
.then((aResult) => {
|
||||
// Get ICC contact for checking expect contact
|
||||
return aIcc.readContacts(aType)
|
||||
.then((aResult) => {
|
||||
let contact = aResult[aContactId - 1];
|
||||
|
||||
is(contact.name[0], aMozContact.name[0]);
|
||||
|
||||
if (aExpect.number == null) {
|
||||
is(contact.tel, null);
|
||||
} else {
|
||||
is(contact.tel[0].value, aExpect.number);
|
||||
}
|
||||
|
||||
is(contact.id, aIcc.iccInfo.iccid + aContactId);
|
||||
});
|
||||
}, (aError) => {
|
||||
if (aType === "fdn" && aPin2 === undefined) {
|
||||
ok(aError.name === "SimPin2",
|
||||
"expected error when pin2 is not provided");
|
||||
} else {
|
||||
ok(false, "Cannot update " + aType + " contact: " + aError.name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function revertContact(aIcc, aContact, aType, aPin2) {
|
||||
log("revertContact: contact:" + JSON.stringify(aContact) +
|
||||
", type=" + aType + ", pin2=" + aPin2);
|
||||
|
||||
return aIcc.updateContact(aType, aContact, aPin2);
|
||||
}
|
||||
|
||||
// Start tests
|
||||
startTestCommon(function() {
|
||||
let icc = getMozIcc();
|
||||
let adnContacts;
|
||||
let fdnContacts;
|
||||
|
||||
return icc.readContacts("adn")
|
||||
.then((aResult) => {
|
||||
adnContacts = aResult;
|
||||
})
|
||||
.then(() => icc.readContacts("fdn"))
|
||||
.then((aResult) => {
|
||||
fdnContacts = aResult;
|
||||
})
|
||||
.then(() => {
|
||||
let promise = Promise.resolve();
|
||||
for (let i = 0; i < TEST_UPDATE_DATA.length; i++) {
|
||||
let test_data = TEST_UPDATE_DATA[i];
|
||||
let adnContact = adnContacts[test_data.id - 1];
|
||||
let fdnContact = fdnContacts[test_data.id - 1];
|
||||
|
||||
// Test update adn contacts
|
||||
promise = promise.then(() => testUpdateContact(icc, "adn", test_data.id,
|
||||
test_data.data, test_data.expect))
|
||||
// Test update fdn contacts
|
||||
.then(() => testUpdateContact(icc, "fdn", test_data.id, test_data.data,
|
||||
test_data.expect))
|
||||
// Test update fdn contacts without passing pin2
|
||||
.then(() => testUpdateContact(icc, "fdn", test_data.id, test_data.data,
|
||||
test_data.expect, "0000"))
|
||||
.then(() => revertContact(icc, adnContact, "adn"))
|
||||
.then(() => revertContact(icc, fdnContact, "fdn", "0000"));
|
||||
}
|
||||
return promise;
|
||||
});
|
||||
});
|
||||
@@ -299,7 +299,7 @@ bool
|
||||
MobileConnection::IsValidCallBarringProgram(int32_t aProgram)
|
||||
{
|
||||
return aProgram >= nsIMobileConnection::CALL_BARRING_PROGRAM_ALL_OUTGOING &&
|
||||
aProgram <= nsIMobileConnection::CALL_BARRING_PROGRAM_INCOMING_ROAMING;
|
||||
aProgram <= nsIMobileConnection::CALL_BARRING_PROGRAM_INCOMING_SERVICE;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -875,7 +875,9 @@ MobileConnection::SetCallWaitingOption(bool aEnabled, ErrorResult& aRv)
|
||||
RefPtr<MobileConnectionCallback> requestCallback =
|
||||
new MobileConnectionCallback(GetOwner(), request);
|
||||
|
||||
nsresult rv = mMobileConnection->SetCallWaiting(aEnabled, requestCallback);
|
||||
nsresult rv = mMobileConnection->SetCallWaiting(aEnabled,
|
||||
nsIMobileConnection::ICC_SERVICE_CLASS_VOICE,
|
||||
requestCallback);
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
return nullptr;
|
||||
@@ -1125,6 +1127,13 @@ MobileConnection::NotifyNetworkSelectionModeChanged()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MobileConnection::NotifyDeviceIdentitiesChanged()
|
||||
{
|
||||
// To be supported when bug 1222870 is required in m-c.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIIccListener
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
||||
@@ -191,6 +191,14 @@ MobileConnectionCallback::NotifyGetCallBarringSuccess(uint16_t aProgram,
|
||||
return NotifySuccess(jsResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MobileConnectionCallback::NotifyGetCallWaitingSuccess(uint16_t aServiceClass)
|
||||
{
|
||||
return (aServiceClass & nsIMobileConnection::ICC_SERVICE_CLASS_VOICE)
|
||||
? NotifySuccess(JS::TrueHandleValue)
|
||||
: NotifySuccess(JS::FalseHandleValue);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MobileConnectionCallback::NotifyGetClirStatusSuccess(uint16_t aN, uint16_t aM)
|
||||
{
|
||||
|
||||
@@ -46,8 +46,7 @@ const NS_DATA_CALL_ERROR_TOPIC_ID = "data-call-error";
|
||||
|
||||
const kPrefRilDebuggingEnabled = "ril.debugging.enabled";
|
||||
|
||||
const INT32_MAX = 2147483647;
|
||||
const UNKNOWN_RSSI = 99;
|
||||
const UNKNOWN_VALUE = Ci.nsICellInfo.UNKNOWN_VALUE;
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "gMobileConnectionMessenger",
|
||||
"@mozilla.org/ril/system-messenger-helper;1",
|
||||
@@ -77,7 +76,7 @@ XPCOMUtils.defineLazyGetter(this, "gRadioInterfaceLayer", function() {
|
||||
return ril;
|
||||
});
|
||||
|
||||
let DEBUG = RIL.DEBUG_RIL;
|
||||
var DEBUG = RIL.DEBUG_RIL;
|
||||
function debug(s) {
|
||||
dump("MobileConnectionService: " + s + "\n");
|
||||
}
|
||||
@@ -163,7 +162,26 @@ MobileCallForwardingOptions.prototype = {
|
||||
serviceClass: Ci.nsIMobileConnection.ICC_SERVICE_CLASS_NONE
|
||||
}
|
||||
|
||||
function NeighboringCellInfo() {}
|
||||
function NeighboringCellInfo(aOptions) {
|
||||
this.networkType = aOptions.networkType;
|
||||
this.gsmLocationAreaCode = (aOptions.gsmLocationAreaCode !== undefined &&
|
||||
aOptions.gsmLocationAreaCode >= 0 &&
|
||||
aOptions.gsmLocationAreaCode <= 65535) ?
|
||||
aOptions.gsmLocationAreaCode : UNKNOWN_VALUE;
|
||||
this.gsmCellId = (aOptions.gsmCellId !== undefined &&
|
||||
aOptions.gsmCellId >= 0 &&
|
||||
aOptions.gsmCellId <= 65535) ?
|
||||
aOptions.gsmCellId : UNKNOWN_VALUE;
|
||||
this.wcdmaPsc = (aOptions.wcdmaPsc !== undefined && aOptions.wcdmaPsc >= 0 &&
|
||||
aOptions.wcdmaPsc <= 511) ?
|
||||
aOptions.wcdmaPsc : UNKNOWN_VALUE;
|
||||
this.signalStrength = (aOptions.signalStrength !== undefined &&
|
||||
((aOptions.signalStrength >= 0 &&
|
||||
aOptions.signalStrength <= 31) ||
|
||||
(aOptions.signalStrength >= -120 &&
|
||||
aOptions.signalStrength <= -25))) ?
|
||||
aOptions.signalStrength : UNKNOWN_VALUE;
|
||||
}
|
||||
NeighboringCellInfo.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsINeighboringCellInfo]),
|
||||
classID: NEIGHBORINGCELLINFO_CID,
|
||||
@@ -173,16 +191,28 @@ NeighboringCellInfo.prototype = {
|
||||
interfaces: [Ci.nsINeighboringCellInfo]
|
||||
}),
|
||||
|
||||
isValid: function() {
|
||||
return !(this.gsmLocationAreaCode == UNKNOWN_VALUE &&
|
||||
this.gsmCellId == UNKNOWN_VALUE &&
|
||||
this.wcdmaPsc == UNKNOWN_VALUE &&
|
||||
this.signalStrength == UNKNOWN_VALUE);
|
||||
},
|
||||
|
||||
// nsINeighboringCellInfo
|
||||
|
||||
networkType: null,
|
||||
gsmLocationAreaCode: -1,
|
||||
gsmCellId: -1,
|
||||
wcdmaPsc: -1,
|
||||
signalStrength: UNKNOWN_RSSI
|
||||
gsmLocationAreaCode: UNKNOWN_VALUE,
|
||||
gsmCellId: UNKNOWN_VALUE,
|
||||
wcdmaPsc: UNKNOWN_VALUE,
|
||||
signalStrength: UNKNOWN_VALUE
|
||||
};
|
||||
|
||||
function CellInfo() {}
|
||||
function CellInfo(aOptions) {
|
||||
this.type = aOptions.type;
|
||||
this.registered = aOptions.registered;
|
||||
this.timestampType = aOptions.timestampType;
|
||||
this.timestamp = aOptions.timestamp;
|
||||
}
|
||||
CellInfo.prototype = {
|
||||
|
||||
// nsICellInfo
|
||||
@@ -193,7 +223,28 @@ CellInfo.prototype = {
|
||||
timestamp: 0
|
||||
};
|
||||
|
||||
function GsmCellInfo() {}
|
||||
function GsmCellInfo(aOptions) {
|
||||
CellInfo.call(this, aOptions);
|
||||
|
||||
// Cell Identity
|
||||
this.mcc = (aOptions.mcc !== undefined && aOptions.mcc >= 0 &&
|
||||
aOptions.mcc <= 999) ? aOptions.mcc : UNKNOWN_VALUE;
|
||||
this.mnc = (aOptions.mnc !== undefined && aOptions.mnc >= 0 &&
|
||||
aOptions.mnc <= 999) ? aOptions.mnc : UNKNOWN_VALUE;
|
||||
this.lac = (aOptions.lac !== undefined && aOptions.lac >= 0 &&
|
||||
aOptions.lac <= 65535) ? aOptions.lac : UNKNOWN_VALUE;
|
||||
this.cid = (aOptions.cid !== undefined && aOptions.cid >= 0 &&
|
||||
aOptions.cid <= 65535) ? aOptions.cid : UNKNOWN_VALUE;
|
||||
|
||||
// Signal Strength
|
||||
this.signalStrength = (aOptions.signalStrength !== undefined &&
|
||||
aOptions.signalStrength >= 0 &&
|
||||
aOptions.signalStrength <= 31) ?
|
||||
aOptions.signalStrength : UNKNOWN_VALUE;
|
||||
this.bitErrorRate = (aOptions.bitErrorRate !== undefined &&
|
||||
aOptions.bitErrorRate >= 0 && aOptions.bitErrorRate <= 7)
|
||||
? aOptions.bitErrorRate : UNKNOWN_VALUE;
|
||||
}
|
||||
GsmCellInfo.prototype = {
|
||||
__proto__: CellInfo.prototype,
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsICellInfo,
|
||||
@@ -205,17 +256,47 @@ GsmCellInfo.prototype = {
|
||||
interfaces: [Ci.nsIGsmCellInfo]
|
||||
}),
|
||||
|
||||
isValid: function() {
|
||||
return !(this.mcc == UNKNOWN_VALUE && this.mnc == UNKNOWN_VALUE &&
|
||||
this.lac == UNKNOWN_VALUE && this.cid == UNKNOWN_VALUE &&
|
||||
this.signalStrength == UNKNOWN_VALUE &&
|
||||
this.bitErrorRate == UNKNOWN_VALUE);
|
||||
},
|
||||
|
||||
// nsIGsmCellInfo
|
||||
|
||||
mcc: INT32_MAX,
|
||||
mnc: INT32_MAX,
|
||||
lac: INT32_MAX,
|
||||
cid: INT32_MAX,
|
||||
signalStrength: UNKNOWN_RSSI,
|
||||
bitErrorRate: UNKNOWN_RSSI
|
||||
mcc: UNKNOWN_VALUE,
|
||||
mnc: UNKNOWN_VALUE,
|
||||
lac: UNKNOWN_VALUE,
|
||||
cid: UNKNOWN_VALUE,
|
||||
signalStrength: UNKNOWN_VALUE,
|
||||
bitErrorRate: UNKNOWN_VALUE
|
||||
};
|
||||
|
||||
function WcdmaCellInfo() {}
|
||||
function WcdmaCellInfo(aOptions) {
|
||||
CellInfo.call(this, aOptions);
|
||||
|
||||
// Cell Identity
|
||||
this.mcc = (aOptions.mcc !== undefined && aOptions.mcc >= 0 &&
|
||||
aOptions.mcc <= 999) ? aOptions.mcc : UNKNOWN_VALUE;
|
||||
this.mnc = (aOptions.mnc !== undefined && aOptions.mnc >= 0 &&
|
||||
aOptions.mnc <= 999) ? aOptions.mnc : UNKNOWN_VALUE;
|
||||
this.lac = (aOptions.lac !== undefined && aOptions.lac >= 0 &&
|
||||
aOptions.lac <= 65535) ? aOptions.lac : UNKNOWN_VALUE;
|
||||
this.cid = (aOptions.cid !== undefined && aOptions.cid >= 0 &&
|
||||
aOptions.cid <= 268435455) ? aOptions.cid : UNKNOWN_VALUE;
|
||||
this.psc = (aOptions.psc !== undefined && aOptions.psc >= 0 &&
|
||||
aOptions.psc <= 511) ? aOptions.psc : UNKNOWN_VALUE;
|
||||
|
||||
// Signal Strength
|
||||
this.signalStrength = (aOptions.signalStrength !== undefined &&
|
||||
aOptions.signalStrength >= 0 &&
|
||||
aOptions.signalStrength <= 31) ?
|
||||
aOptions.signalStrength : UNKNOWN_VALUE;
|
||||
this.bitErrorRate = (aOptions.bitErrorRate !== undefined &&
|
||||
aOptions.bitErrorRate >= 0 && aOptions.bitErrorRate <= 7)
|
||||
? aOptions.bitErrorRate : UNKNOWN_VALUE;
|
||||
}
|
||||
WcdmaCellInfo.prototype = {
|
||||
__proto__: CellInfo.prototype,
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsICellInfo,
|
||||
@@ -227,18 +308,57 @@ WcdmaCellInfo.prototype = {
|
||||
interfaces: [Ci.nsIWcdmaCellInfo]
|
||||
}),
|
||||
|
||||
isValid: function() {
|
||||
return !(this.mcc == UNKNOWN_VALUE && this.mnc == UNKNOWN_VALUE &&
|
||||
this.lac == UNKNOWN_VALUE && this.cid == UNKNOWN_VALUE &&
|
||||
this.psc == UNKNOWN_VALUE && this.signalStrength == UNKNOWN_VALUE &&
|
||||
this.bitErrorRate == UNKNOWN_VALUE);
|
||||
},
|
||||
|
||||
// nsIWcdmaCellInfo
|
||||
|
||||
mcc: INT32_MAX,
|
||||
mnc: INT32_MAX,
|
||||
lac: INT32_MAX,
|
||||
cid: INT32_MAX,
|
||||
psc: INT32_MAX,
|
||||
signalStrength: UNKNOWN_RSSI,
|
||||
bitErrorRate: UNKNOWN_RSSI
|
||||
mcc: UNKNOWN_VALUE,
|
||||
mnc: UNKNOWN_VALUE,
|
||||
lac: UNKNOWN_VALUE,
|
||||
cid: UNKNOWN_VALUE,
|
||||
psc: UNKNOWN_VALUE,
|
||||
signalStrength: UNKNOWN_VALUE,
|
||||
bitErrorRate: UNKNOWN_VALUE
|
||||
};
|
||||
|
||||
function LteCellInfo() {}
|
||||
function LteCellInfo(aOptions) {
|
||||
CellInfo.call(this, aOptions);
|
||||
|
||||
// Cell Identity
|
||||
this.mcc = (aOptions.mcc !== undefined && aOptions.mcc >= 0 &&
|
||||
aOptions.mcc <= 999) ? aOptions.mcc : UNKNOWN_VALUE;
|
||||
this.mnc = (aOptions.mnc !== undefined && aOptions.mnc >= 0 &&
|
||||
aOptions.mnc <= 999) ? aOptions.mnc : UNKNOWN_VALUE;
|
||||
this.cid = (aOptions.cid !== undefined && aOptions.cid >= 0 &&
|
||||
aOptions.cid <= 268435455) ? aOptions.cid : UNKNOWN_VALUE;
|
||||
this.pcid = (aOptions.pcid !== undefined && aOptions.pcid >= 0 &&
|
||||
aOptions.pcid <= 503) ? aOptions.pcid : UNKNOWN_VALUE;
|
||||
this.tac = (aOptions.tac !== undefined && aOptions.tac >= 0 &&
|
||||
aOptions.tac <= 65535) ? aOptions.tac : UNKNOWN_VALUE;
|
||||
|
||||
// Signal Strength
|
||||
this.signalStrength = (aOptions.signalStrength !== undefined &&
|
||||
aOptions.signalStrength >= 0 &&
|
||||
aOptions.signalStrength <= 31) ?
|
||||
aOptions.signalStrength : UNKNOWN_VALUE;
|
||||
this.rsrp = (aOptions.rsrp !== undefined && aOptions.rsrp >= 44 &&
|
||||
aOptions.rsrp <= 140) ? aOptions.rsrp : UNKNOWN_VALUE;
|
||||
this.rsrq = (aOptions.rsrq !== undefined && aOptions.rsrq >= 3 &&
|
||||
aOptions.rsrq <= 20) ? aOptions.rsrq : UNKNOWN_VALUE;
|
||||
this.rssnr = (aOptions.rssnr !== undefined && aOptions.rssnr >= -200 &&
|
||||
aOptions.rssnr <= 300) ? aOptions.rssnr : UNKNOWN_VALUE;
|
||||
this.cqi = (aOptions.cqi !== undefined && aOptions.cqi >= 0 &&
|
||||
aOptions.cqi <= 15) ? aOptions.cqi : UNKNOWN_VALUE;
|
||||
this.timingAdvance = (aOptions.timingAdvance !== undefined &&
|
||||
aOptions.timingAdvance >= 0 &&
|
||||
aOptions.timingAdvance <= 2147483646) ?
|
||||
aOptions.timingAdvance : UNKNOWN_VALUE;
|
||||
}
|
||||
LteCellInfo.prototype = {
|
||||
__proto__: CellInfo.prototype,
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsICellInfo,
|
||||
@@ -250,22 +370,64 @@ LteCellInfo.prototype = {
|
||||
interfaces: [Ci.nsILteCellInfo]
|
||||
}),
|
||||
|
||||
isValid: function() {
|
||||
return !(this.mcc == UNKNOWN_VALUE && this.mnc == UNKNOWN_VALUE &&
|
||||
this.cid == UNKNOWN_VALUE && this.pcid == UNKNOWN_VALUE &&
|
||||
this.tac == UNKNOWN_VALUE && this.signalStrength == UNKNOWN_VALUE &&
|
||||
this.rsrp == UNKNOWN_VALUE && this.rsrq == UNKNOWN_VALUE &&
|
||||
this.rssnr == UNKNOWN_VALUE && this.cqi == UNKNOWN_VALUE &&
|
||||
this.timingAdvance == UNKNOWN_VALUE);
|
||||
},
|
||||
|
||||
// nsILteCellInfo
|
||||
|
||||
mcc: INT32_MAX,
|
||||
mnc: INT32_MAX,
|
||||
cid: INT32_MAX,
|
||||
pcid: INT32_MAX,
|
||||
tac: INT32_MAX,
|
||||
signalStrength: UNKNOWN_RSSI,
|
||||
rsrp: INT32_MAX,
|
||||
rsrq: INT32_MAX,
|
||||
rssnr: INT32_MAX,
|
||||
cqi: INT32_MAX,
|
||||
timingAdvance: INT32_MAX
|
||||
mcc: UNKNOWN_VALUE,
|
||||
mnc: UNKNOWN_VALUE,
|
||||
cid: UNKNOWN_VALUE,
|
||||
pcid: UNKNOWN_VALUE,
|
||||
tac: UNKNOWN_VALUE,
|
||||
signalStrength: UNKNOWN_VALUE,
|
||||
rsrp: UNKNOWN_VALUE,
|
||||
rsrq: UNKNOWN_VALUE,
|
||||
rssnr: UNKNOWN_VALUE,
|
||||
cqi: UNKNOWN_VALUE,
|
||||
timingAdvance: UNKNOWN_VALUE
|
||||
};
|
||||
|
||||
function CdmaCellInfo() {}
|
||||
function CdmaCellInfo(aOptions) {
|
||||
CellInfo.call(this, aOptions);
|
||||
|
||||
// Cell Identity
|
||||
this.networkId = (aOptions.networkId !== undefined &&
|
||||
aOptions.networkId >= 0 && aOptions.networkId <= 65535) ?
|
||||
aOptions.networkId : UNKNOWN_VALUE;
|
||||
this.systemId = (aOptions.systemId !== undefined && aOptions.systemId >= 0 &&
|
||||
aOptions.systemId <= 32767) ?
|
||||
aOptions.systemId : UNKNOWN_VALUE;
|
||||
this.baseStationId = (aOptions.baseStationId !== undefined &&
|
||||
aOptions.baseStationId >= 0 &&
|
||||
aOptions.baseStationId <= 65535) ?
|
||||
aOptions.baseStationId : UNKNOWN_VALUE;
|
||||
this.longitude = (aOptions.longitude !== undefined &&
|
||||
aOptions.longitude >= -2592000 &&
|
||||
aOptions.longitude <= 2592000) ?
|
||||
aOptions.longitude : UNKNOWN_VALUE;
|
||||
this.latitude = (aOptions.latitude !== undefined &&
|
||||
aOptions.latitude >= -1296000 &&
|
||||
aOptions.latitude <= 1296000) ?
|
||||
aOptions.latitude : UNKNOWN_VALUE;
|
||||
|
||||
// Signal Strength
|
||||
this.cdmaEcio = (aOptions.cdmaEcio !== undefined &&
|
||||
aOptions.cdmaEcio >= 0) ? aOptions.cdmaEcio : UNKNOWN_VALUE;
|
||||
this.evdoDbm = (aOptions.evdoDbm !== undefined &&
|
||||
aOptions.evdoDbm >= 0) ? aOptions.evdoDbm : UNKNOWN_VALUE;
|
||||
this.evdoEcio = (aOptions.evdoEcio !== undefined &&
|
||||
aOptions.evdoEcio >= 0) ? aOptions.evdoEcio : UNKNOWN_VALUE;
|
||||
this.evdoSnr = (aOptions.evdoSnr !== undefined &&
|
||||
aOptions.evdoSnr >= 0 && aOptions.evdoSnr <= 8) ?
|
||||
aOptions.evdoSnr : UNKNOWN_VALUE;
|
||||
}
|
||||
CdmaCellInfo.prototype = {
|
||||
__proto__: CellInfo.prototype,
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsICellInfo,
|
||||
@@ -277,18 +439,43 @@ CdmaCellInfo.prototype = {
|
||||
interfaces: [Ci.nsICdmaCellInfo]
|
||||
}),
|
||||
|
||||
isValid: function() {
|
||||
return !(this.networkId == UNKNOWN_VALUE && this.systemId == UNKNOWN_VALUE &&
|
||||
this.baseStationId == UNKNOWN_VALUE &&
|
||||
this.longitude == UNKNOWN_VALUE &&
|
||||
this.latitude == UNKNOWN_VALUE && this.cdmaDbm == UNKNOWN_VALUE &&
|
||||
this.cdmaEcio == UNKNOWN_VALUE && this.evdoDbm == UNKNOWN_VALUE &&
|
||||
this.evdoEcio == UNKNOWN_VALUE && this.evdoSnr == UNKNOWN_VALUE);
|
||||
},
|
||||
|
||||
// nsICdmaCellInfo
|
||||
|
||||
networkId: INT32_MAX,
|
||||
systemId: INT32_MAX,
|
||||
baseStationId: INT32_MAX,
|
||||
longitude: INT32_MAX,
|
||||
latitude: INT32_MAX,
|
||||
cdmaDbm: INT32_MAX,
|
||||
cdmaEcio: INT32_MAX,
|
||||
evdoDbm: INT32_MAX,
|
||||
evdoEcio: INT32_MAX,
|
||||
evdoSnr: INT32_MAX
|
||||
networkId: UNKNOWN_VALUE,
|
||||
systemId: UNKNOWN_VALUE,
|
||||
baseStationId: UNKNOWN_VALUE,
|
||||
longitude: UNKNOWN_VALUE,
|
||||
latitude: UNKNOWN_VALUE,
|
||||
cdmaDbm: UNKNOWN_VALUE,
|
||||
cdmaEcio: UNKNOWN_VALUE,
|
||||
evdoDbm: UNKNOWN_VALUE,
|
||||
evdoEcio: UNKNOWN_VALUE,
|
||||
evdoSnr: UNKNOWN_VALUE
|
||||
};
|
||||
|
||||
function MobileDeviceIdentities(aImei, aImeisv, aEsn, aMeid) {
|
||||
this.imei = aImei;
|
||||
this.imeisv = aImeisv;
|
||||
this.esn = aEsn;
|
||||
this.meid = aMeid;
|
||||
}
|
||||
MobileDeviceIdentities.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIMobileDeviceIdentities]),
|
||||
|
||||
// nsIMobileDeviceIdentities
|
||||
imei: null,
|
||||
imeisv: null,
|
||||
esn: null,
|
||||
meid: null
|
||||
};
|
||||
|
||||
function MobileConnectionProvider(aClientId, aRadioInterface) {
|
||||
@@ -330,6 +517,7 @@ MobileConnectionProvider.prototype = {
|
||||
lastKnownNetwork: null,
|
||||
lastKnownHomeNetwork: null,
|
||||
supportedNetworkTypes: null,
|
||||
deviceIdentities: null,
|
||||
|
||||
/**
|
||||
* A utility function to dump debug message.
|
||||
@@ -790,6 +978,17 @@ MobileConnectionProvider.prototype = {
|
||||
aServiceClass]);
|
||||
},
|
||||
|
||||
notifyDeviceIdentitiesChanged: function(aImei, aImeisv, aEsn, aMeid) {
|
||||
if (this.deviceIdentities) {
|
||||
if (DEBUG) this._debug("deviceIdentities shall not be changed once being updated.");
|
||||
return;
|
||||
}
|
||||
|
||||
this.deviceIdentities =
|
||||
new MobileDeviceIdentities(aImei, aImeisv, aEsn, aMeid);
|
||||
this.deliverListenerEvent("notifyDeviceIdentitiesChanged");
|
||||
},
|
||||
|
||||
getSupportedNetworkTypes: function(aTypes) {
|
||||
aTypes.value = this.supportedNetworkTypes.slice();
|
||||
return aTypes.value.length;
|
||||
@@ -1054,9 +1253,13 @@ MobileConnectionProvider.prototype = {
|
||||
}).bind(this));
|
||||
},
|
||||
|
||||
setCallWaiting: function(aEnabled, aCallback) {
|
||||
this._radioInterface.sendWorkerMessage("setCallWaiting",
|
||||
{enabled: aEnabled},
|
||||
setCallWaiting: function(aEnabled, aServiceClass, aCallback) {
|
||||
let options = {
|
||||
enabled: aEnabled,
|
||||
serviceClass: aServiceClass
|
||||
};
|
||||
|
||||
this._radioInterface.sendWorkerMessage("setCallWaiting", options,
|
||||
(function(aResponse) {
|
||||
if (aResponse.errorMsg) {
|
||||
aCallback.notifyError(aResponse.errorMsg);
|
||||
@@ -1076,7 +1279,7 @@ MobileConnectionProvider.prototype = {
|
||||
return false;
|
||||
}
|
||||
|
||||
aCallback.notifySuccessWithBoolean(aResponse.enabled);
|
||||
aCallback.notifyGetCallWaitingSuccess(aResponse.serviceClass);
|
||||
return false;
|
||||
}).bind(this));
|
||||
},
|
||||
@@ -1176,26 +1379,26 @@ MobileConnectionProvider.prototype = {
|
||||
let cellInfo;
|
||||
switch (srcCellInfo.type) {
|
||||
case RIL.CELL_INFO_TYPE_GSM:
|
||||
cellInfo = new GsmCellInfo();
|
||||
cellInfo = new GsmCellInfo(srcCellInfo);
|
||||
break;
|
||||
case RIL.CELL_INFO_TYPE_WCDMA:
|
||||
cellInfo = new WcdmaCellInfo();
|
||||
cellInfo = new WcdmaCellInfo(srcCellInfo);
|
||||
break;
|
||||
case RIL.CELL_INFO_TYPE_LTE:
|
||||
cellInfo = new LteCellInfo();
|
||||
cellInfo = new LteCellInfo(srcCellInfo);
|
||||
break;
|
||||
case RIL.CELL_INFO_TYPE_CDMA:
|
||||
cellInfo = new CdmaCellInfo();
|
||||
cellInfo = new CdmaCellInfo(srcCellInfo);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!cellInfo) {
|
||||
if (!cellInfo || !cellInfo.isValid()) {
|
||||
continue;
|
||||
}
|
||||
this._updateInfo(cellInfo, srcCellInfo);
|
||||
|
||||
cellInfoList.push(cellInfo);
|
||||
}
|
||||
aCallback.notifyGetCellInfoList(count, cellInfoList);
|
||||
aCallback.notifyGetCellInfoList(cellInfoList.length, cellInfoList);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
@@ -1212,11 +1415,13 @@ MobileConnectionProvider.prototype = {
|
||||
let count = aResponse.result.length;
|
||||
for (let i = 0; i < count; i++) {
|
||||
let srcCellInfo = aResponse.result[i];
|
||||
let cellInfo = new NeighboringCellInfo();
|
||||
this._updateInfo(cellInfo, srcCellInfo);
|
||||
neighboringCellIds.push(cellInfo);
|
||||
let cellInfo = new NeighboringCellInfo(srcCellInfo);
|
||||
if (cellInfo && cellInfo.isValid()) {
|
||||
neighboringCellIds.push(cellInfo);
|
||||
}
|
||||
}
|
||||
aCallback.notifyGetNeighboringCellIds(count, neighboringCellIds);
|
||||
aCallback.notifyGetNeighboringCellIds(neighboringCellIds.length,
|
||||
neighboringCellIds);
|
||||
|
||||
}.bind(this));
|
||||
},
|
||||
@@ -1516,6 +1721,12 @@ MobileConnectionService.prototype = {
|
||||
.notifyCdmaInfoRecAudioControl(aClientId, aUpLink, aDownLink);
|
||||
},
|
||||
|
||||
notifyDeviceIdentitiesChanged: function(aClientId, aImei, aImeisv,
|
||||
aEsn, aMeid) {
|
||||
this.getItemByServiceId(aClientId)
|
||||
.notifyDeviceIdentitiesChanged(aImei, aImeisv, aEsn, aMeid);
|
||||
},
|
||||
|
||||
/**
|
||||
* nsIObserver interface.
|
||||
*/
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"@mozilla.org/mobileconnection/gonkmobileconnectionservice;1"
|
||||
%}
|
||||
|
||||
[scriptable, uuid(3a7b8d47-d1c6-44c3-a312-df73fda1161e)]
|
||||
[scriptable, uuid(3c306f88-86bf-11e5-91af-3b2233acec65)]
|
||||
interface nsIGonkMobileConnectionService : nsIMobileConnectionService
|
||||
{
|
||||
void notifyNetworkInfoChanged(in unsigned long clientId, in jsval networkInfo);
|
||||
@@ -248,4 +248,27 @@ interface nsIGonkMobileConnectionService : nsIMobileConnectionService
|
||||
void notifyCdmaInfoRecAudioControl(in unsigned long clientId,
|
||||
in short upLink,
|
||||
in short downLink);
|
||||
|
||||
/**
|
||||
* Notify Device Identities.
|
||||
*
|
||||
* @param aClientId
|
||||
* The ID of radioInterface where this info is notified from.
|
||||
* @param aImei
|
||||
* Device IMEI, valid if GSM subscription is available.
|
||||
* @param aImeisv
|
||||
* Device IMEISV, valid if GSM subscription is available.
|
||||
* @param aEsn
|
||||
* Device ESN, valid if CDMA subscription is available.
|
||||
* @param aMeid
|
||||
* Device MEID, valid if CDMA subscription is available.
|
||||
*
|
||||
* Note: The value might be dummy like "000..." from modem
|
||||
* if the corresponding subscription is not available.
|
||||
*/
|
||||
void notifyDeviceIdentitiesChanged(in unsigned long aClientId,
|
||||
in DOMString aImei,
|
||||
in DOMString aImeisv,
|
||||
in DOMString aEsn,
|
||||
in DOMString aMeid);
|
||||
};
|
||||
|
||||
@@ -22,20 +22,22 @@ interface nsICellInfoListCallback : nsISupports
|
||||
void notifyGetCellInfoListFailed(in DOMString error);
|
||||
};
|
||||
|
||||
[scriptable, uuid(86667898-c9ab-44ee-8a9a-026916b3183e)]
|
||||
[scriptable, uuid(a9a34341-5a33-4e0a-98e1-13e7ea4228be)]
|
||||
interface nsICellInfo : nsISupports
|
||||
{
|
||||
const long CELL_INFO_TYPE_GSM = 1;
|
||||
const long CELL_INFO_TYPE_CDMA = 2;
|
||||
const long CELL_INFO_TYPE_LTE = 3;
|
||||
const long CELL_INFO_TYPE_GSM = 1;
|
||||
const long CELL_INFO_TYPE_CDMA = 2;
|
||||
const long CELL_INFO_TYPE_LTE = 3;
|
||||
const long CELL_INFO_TYPE_WCDMA = 4;
|
||||
|
||||
const long TIMESTAMP_TYPE_UNKNOWN = 0;
|
||||
const long TIMESTAMP_TYPE_ANTENNA = 1;
|
||||
const long TIMESTAMP_TYPE_MODEM = 2;
|
||||
const long TIMESTAMP_TYPE_OEM_RIL = 3;
|
||||
const long TIMESTAMP_TYPE_UNKNOWN = 0;
|
||||
const long TIMESTAMP_TYPE_ANTENNA = 1;
|
||||
const long TIMESTAMP_TYPE_MODEM = 2;
|
||||
const long TIMESTAMP_TYPE_OEM_RIL = 3;
|
||||
const long TIMESTAMP_TYPE_JAVA_RIL = 4;
|
||||
|
||||
const long UNKNOWN_VALUE = 0x7FFFFFFF;
|
||||
|
||||
/**
|
||||
* Network type. One of the CELL_INFO_TYPE_* constants.
|
||||
*/
|
||||
@@ -57,204 +59,207 @@ interface nsICellInfo : nsISupports
|
||||
readonly attribute long long timestamp;
|
||||
};
|
||||
|
||||
[scriptable, uuid(6345967c-61fc-45a1-8362-39e9261df052)]
|
||||
[scriptable, uuid(cc476ded-350f-4c25-9a57-6a876e32f092)]
|
||||
interface nsIGsmCellInfo : nsICellInfo
|
||||
{
|
||||
/**
|
||||
* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown.
|
||||
* 3-digit Mobile Country Code, 0..999, UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long mcc;
|
||||
|
||||
/**
|
||||
* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown.
|
||||
* 2 or 3-digit Mobile Network Code, 0..999, UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long mnc;
|
||||
|
||||
/**
|
||||
* 16-bit Location Area Code, 0..65535, INT_MAX if unknown.
|
||||
* 16-bit Location Area Code, 0..65535, UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long lac;
|
||||
|
||||
/**
|
||||
* 16-bit GSM Cell Identity described in TS 27.007, 0..65535, INT_MAX if unknown.
|
||||
* 16-bit GSM Cell Identity described in TS 27.007, 0..65535,
|
||||
* UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long cid;
|
||||
|
||||
/**
|
||||
* Valid values are 0-31 as defined in TS 27.007 8.5, 99 if unknown.
|
||||
* Valid values are 0-31 as defined in TS 27.007 8.5, UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long signalStrength;
|
||||
|
||||
/**
|
||||
* Bit error rate 0-7 as defined in TS 27.007 8.5, 99 if unknown.
|
||||
* Bit error rate 0-7 as defined in TS 27.007 8.5, UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long bitErrorRate;
|
||||
};
|
||||
|
||||
[scriptable, uuid(19693f98-943d-45e7-a3e8-25373228ce6b)]
|
||||
[scriptable, uuid(aa52647b-38dd-487c-be36-b46ed2e99554)]
|
||||
interface nsIWcdmaCellInfo : nsICellInfo
|
||||
{
|
||||
/**
|
||||
* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown.
|
||||
* 2 or 3-digit Mobile Network Code, 0..999, UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long mcc;
|
||||
|
||||
/**
|
||||
* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown.
|
||||
* 2 or 3-digit Mobile Network Code, 0..999, UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long mnc;
|
||||
|
||||
/**
|
||||
* 16-bit Location Area Code, 0..65535, INT_MAX if unknown.
|
||||
* 16-bit Location Area Code, 0..65535, UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long lac;
|
||||
|
||||
/**
|
||||
* 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455,
|
||||
* INT_MAX if unknown.
|
||||
* UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long cid;
|
||||
|
||||
/**
|
||||
* 9-bit UMTS Primary Scrambling Code described in TS 25.331, 0..511,
|
||||
* INT_MAX if unknown.
|
||||
* UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long psc;
|
||||
|
||||
/**
|
||||
* Valid values are 0-31 as defined in TS 27.007 8.5, 99 if unknown.
|
||||
* Valid values are 0-31 as defined in TS 27.007 8.5, UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long signalStrength;
|
||||
|
||||
/**
|
||||
* Bit error rate 0-7 as defined in TS 27.007 8.5, 99 if unknown.
|
||||
* Bit error rate 0-7 as defined in TS 27.007 8.5, UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long bitErrorRate;
|
||||
};
|
||||
|
||||
[scriptable, uuid(76b4a35d-7e45-42bc-a2e0-bc07a6434db3)]
|
||||
[scriptable, uuid(60a38ca7-ca62-4384-aa07-eac7d4893786)]
|
||||
interface nsICdmaCellInfo : nsICellInfo
|
||||
{
|
||||
/**
|
||||
* Network Id, 0..65535, INT_MAX if unknown.
|
||||
* Network Id, 0..65535, UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long networkId;
|
||||
|
||||
/**
|
||||
* CDMA System Id, 0..32767, INT_MAX if unknown.
|
||||
* CDMA System Id, 0..32767, UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long systemId;
|
||||
|
||||
/**
|
||||
* Base Station Id, 0..65535, INT_MAX if unknown.
|
||||
* Base Station Id, 0..65535, UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long baseStationId;
|
||||
|
||||
/**
|
||||
* Longitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0.
|
||||
* It is represented in units of 0.25 seconds and ranges from -2592000 to
|
||||
* 2592000, INT_MAX if unknown.
|
||||
* 2592000, UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long longitude;
|
||||
|
||||
/**
|
||||
* Latitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0.
|
||||
* It is represented in units of 0.25 seconds and ranges from -1296000 to
|
||||
* 1296000, INT_MAX if unknown.
|
||||
* 1296000, UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long latitude;
|
||||
|
||||
/**
|
||||
* Valid values are positive integers, INT_MAX if unknown. This value is the
|
||||
* actual RSSI value multiplied by -1.
|
||||
* Valid values are positive integers, UNKNOWN_VALUE if unknown. This value is
|
||||
* the actual RSSI value multiplied by -1.
|
||||
*/
|
||||
readonly attribute long cdmaDbm;
|
||||
|
||||
/**
|
||||
* Valid values are positive integers, INT_MAX if unknown. This value is the
|
||||
* actual Ec/Io multiplied by -10. -1 if unknown.
|
||||
* Valid values are positive integers, UNKNOWN_VALUE if unknown. This value is
|
||||
* the actual Ec/Io multiplied by -10.
|
||||
*/
|
||||
readonly attribute long cdmaEcio;
|
||||
|
||||
/**
|
||||
* Valid values are positive integers, INT_MAX if unknown. This value is the
|
||||
* actual Evdo RSSI value multiplied by -1.
|
||||
* Valid values are positive integers, UNKNOWN_VALUE if unknown. This value is
|
||||
* the actual Evdo RSSI value multiplied by -1.
|
||||
*/
|
||||
readonly attribute long evdoDbm;
|
||||
|
||||
/**
|
||||
* Valid values are positive integers, INT_MAX if unknown. This value is the
|
||||
* actual Evdo Ec/Io multiplied by -10.
|
||||
* Valid values are positive integers, UNKNOWN_VALUE if unknown. This value is
|
||||
* the actual Evdo Ec/Io multiplied by -10.
|
||||
*/
|
||||
readonly attribute long evdoEcio;
|
||||
|
||||
/**
|
||||
* Valid values are 0-8, INT_MAX if unknown. 8 is the highest signal to noise
|
||||
* ratio.
|
||||
* Valid values are 0-8, UNKNOWN_VALUE if unknown. 8 is the highest signal to
|
||||
* noise ratio.
|
||||
*/
|
||||
readonly attribute long evdoSnr;
|
||||
};
|
||||
|
||||
[scriptable, uuid(122937d9-1ee5-45e0-a360-5959d578bc31)]
|
||||
[scriptable, uuid(e7b3e826-bb85-49b2-a2f1-70af46c47733)]
|
||||
interface nsILteCellInfo : nsICellInfo
|
||||
{
|
||||
/**
|
||||
* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown.
|
||||
* 3-digit Mobile Country Code, 0..999, UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long mcc;
|
||||
|
||||
/**
|
||||
* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown.
|
||||
* 2 or 3-digit Mobile Network Code, 0..999, UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long mnc;
|
||||
|
||||
/**
|
||||
* 28-bit Cell Identity, 0..268435455, INT_MAX if unknown.
|
||||
* 28-bit Cell Identity, 0..268435455, UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long cid;
|
||||
|
||||
/**
|
||||
* Physical cell id, 0..503, INT_MAX if unknown.
|
||||
* Physical cell id, 0..503, UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long pcid;
|
||||
|
||||
/**
|
||||
* 16-bit tracking area code, 0..65535, INT_MAX if unknown.
|
||||
* 16-bit tracking area code, 0..65535, UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long tac;
|
||||
|
||||
/**
|
||||
* Valid values are 0-31 as defined in TS 27.007 8.5, 99 if unknown.
|
||||
* Valid values are 0-31 as defined in TS 27.007 8.5, UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long signalStrength;
|
||||
|
||||
/**
|
||||
* The current Reference Signal Receive Power in dBm multipled by -1.
|
||||
* Range: 44 to 140 dBm, INT_MAX if unknown.
|
||||
* Range: 44 to 140 dBm, UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long rsrp;
|
||||
|
||||
/**
|
||||
* The current Reference Signal Receive Quality in dB multiplied by -1.
|
||||
* Range: 3 to 20 dB, INT_MAX if unknown.
|
||||
* Range: 3 to 20 dB, UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long rsrq;
|
||||
|
||||
/**
|
||||
* The current reference signal signal-to-noise ratio in 0.1 dB units.
|
||||
* Range: -200 to +300 (-200 = -20.0 dB, +300 = 30dB), INT_MAX if unknown.
|
||||
* Range: -200 to +300 (-200 = -20.0 dB, +300 = 30dB), UNKNOWN_VALUE if
|
||||
* unknown.
|
||||
*/
|
||||
readonly attribute long rssnr;
|
||||
|
||||
/**
|
||||
* The current Channel Quality Indicator. Range: 0 to 15, INT_MAX if unknown.
|
||||
* The current Channel Quality Indicator. Range: 0 to 15, UNKNOWN_VALUE if
|
||||
* unknown.
|
||||
*/
|
||||
readonly attribute long cqi;
|
||||
|
||||
/**
|
||||
* Timing advance in micro seconds for a one way trip from cell to device.
|
||||
* Approximate distance can be calculated using 300m/us * timingAdvance.
|
||||
* Range: 0 to 0x7FFFFFFE, INT_MAX if unknown.
|
||||
* Range: 0 to 0x7FFFFFFE, UNKNOWN_VALUE if unknown.
|
||||
*/
|
||||
readonly attribute long timingAdvance;
|
||||
};
|
||||
@@ -8,11 +8,12 @@ interface nsICellInfoListCallback;
|
||||
interface nsIMobileCallForwardingOptions;
|
||||
interface nsIMobileConnection;
|
||||
interface nsIMobileConnectionInfo;
|
||||
interface nsIMobileDeviceIdentities;
|
||||
interface nsIMobileNetworkInfo;
|
||||
interface nsINeighboringCellIdsCallback;
|
||||
interface nsIVariant;
|
||||
|
||||
[scriptable, uuid(d6827b51-61a7-4b7c-8454-42d0cffc1829)]
|
||||
[scriptable, uuid(8884b326-891c-11e5-a434-67def07c4a41)]
|
||||
interface nsIMobileConnectionListener : nsISupports
|
||||
{
|
||||
/**
|
||||
@@ -102,13 +103,18 @@ interface nsIMobileConnectionListener : nsISupports
|
||||
* Notify when network selection mode is changed.
|
||||
*/
|
||||
void notifyNetworkSelectionModeChanged();
|
||||
|
||||
/**
|
||||
* Notify when device identities are changed.
|
||||
*/
|
||||
void notifyDeviceIdentitiesChanged();
|
||||
};
|
||||
|
||||
%{C++
|
||||
#define NO_ADDITIONAL_INFORMATION 0
|
||||
%}
|
||||
|
||||
[scriptable, uuid(14d66926-8434-11e4-8c3f-f724194bb5f1)]
|
||||
[scriptable, uuid(ef5e02a6-adff-4425-8634-ec49ced1f14f)]
|
||||
interface nsIMobileConnectionCallback : nsISupports
|
||||
{
|
||||
/**
|
||||
@@ -128,6 +134,8 @@ interface nsIMobileConnectionCallback : nsISupports
|
||||
in boolean enabled,
|
||||
in unsigned short serviceClass);
|
||||
|
||||
void notifyGetCallWaitingSuccess(in unsigned short serviceClass);
|
||||
|
||||
void notifyGetClirStatusSuccess(in unsigned short n, in unsigned short m);
|
||||
|
||||
void notifyGetPreferredNetworkTypeSuccess(in long type);
|
||||
@@ -163,7 +171,7 @@ already_AddRefed<nsIMobileConnectionService>
|
||||
NS_CreateMobileConnectionService();
|
||||
%}
|
||||
|
||||
[scriptable, uuid(b9845f09-7cbb-46d0-b713-773d80844e0d)]
|
||||
[scriptable, uuid(7a557116-8753-11e5-9f9b-6794b577c0a1)]
|
||||
interface nsIMobileConnection : nsISupports
|
||||
{
|
||||
/*
|
||||
@@ -214,6 +222,9 @@ interface nsIMobileConnection : nsISupports
|
||||
const long CALL_BARRING_PROGRAM_OUTGOING_INTERNATIONAL_EXCEPT_HOME = 2;
|
||||
const long CALL_BARRING_PROGRAM_ALL_INCOMING = 3;
|
||||
const long CALL_BARRING_PROGRAM_INCOMING_ROAMING = 4;
|
||||
const long CALL_BARRING_PROGRAM_ALL_SERVICE = 5;
|
||||
const long CALL_BARRING_PROGRAM_OUTGOING_SERVICE = 6;
|
||||
const long CALL_BARRING_PROGRAM_INCOMING_SERVICE = 7;
|
||||
|
||||
/**
|
||||
* Calling line identification restriction constants.
|
||||
@@ -315,6 +326,11 @@ interface nsIMobileConnection : nsISupports
|
||||
*/
|
||||
readonly attribute long radioState;
|
||||
|
||||
/**
|
||||
* Device Identities, including IMEI, IMEISV, ESN and MEID.
|
||||
*/
|
||||
readonly attribute nsIMobileDeviceIdentities deviceIdentities;
|
||||
|
||||
/**
|
||||
* The network types supported by this radio.
|
||||
*
|
||||
@@ -598,6 +614,8 @@ interface nsIMobileConnection : nsISupports
|
||||
*
|
||||
* @param enabled
|
||||
* Boolean indicates the desired call waiting status.
|
||||
* @param serviceClass
|
||||
* One of the nsIMobileConnection.ICC_SERVICE_CLASS_* values.
|
||||
* @param requestCallback
|
||||
* Called when request is finished.
|
||||
*
|
||||
@@ -608,6 +626,7 @@ interface nsIMobileConnection : nsISupports
|
||||
* 'GenericFailure'.
|
||||
*/
|
||||
void setCallWaiting(in bool enabled,
|
||||
in unsigned short serviceClass,
|
||||
in nsIMobileConnectionCallback requestCallback);
|
||||
|
||||
/**
|
||||
@@ -616,8 +635,12 @@ interface nsIMobileConnection : nsISupports
|
||||
* @param requestCallback
|
||||
* Called when request is finished.
|
||||
*
|
||||
* If successful, the notifySuccessWithBoolean() will be called. And the result
|
||||
* will be a boolean indicating the call waiting status.
|
||||
* If successful, the notifyGetCallWaitingSuccess() will be called. And the
|
||||
* result will be a service class bit vector of services for which call
|
||||
* waiting is enabled. e.g. 3 means call waiting is enabled for data
|
||||
* and voice and disabled for everything else. 0 means call waiting is
|
||||
* disabled for all service.
|
||||
* @see nsIMobileConnection.ICC_SERVICE_CLASS_*.
|
||||
*
|
||||
* Otherwise, the notifyError() will be called, and the error will be either
|
||||
* 'RadioNotAvailable', 'RequestNotSupported', 'IllegalSIMorME', or
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/* 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 "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(3fc79ece-8399-11e5-beff-6b8209cb93f6)]
|
||||
interface nsIMobileDeviceIdentities : nsISupports
|
||||
{
|
||||
/**
|
||||
* Device IMEI, including check digit.
|
||||
*
|
||||
* Valid if GSM subscription is available.
|
||||
*
|
||||
* Note: The value might be dummy like "000..." from modem if invalid.
|
||||
*/
|
||||
readonly attribute DOMString imei;
|
||||
|
||||
/**
|
||||
* Device IMEISV.
|
||||
*
|
||||
* Valid if GSM subscription is available.
|
||||
*
|
||||
* Note: IMEISV is presented in 2-decimal digits.
|
||||
* The value might be dummy like "00" from modem if invalid.
|
||||
*/
|
||||
readonly attribute DOMString imeisv;
|
||||
|
||||
/**
|
||||
* Device ESN.
|
||||
*
|
||||
* Valid if CDMA subscription is available.
|
||||
*
|
||||
* Note: The value might be dummy like "000..." from modem if invalid.
|
||||
*/
|
||||
readonly attribute DOMString esn;
|
||||
|
||||
/**
|
||||
* Device MEID.
|
||||
*
|
||||
* Valid if CDMA subscription is available.
|
||||
*
|
||||
* Note: The value might be dummy like "000..." from modem if invalid.
|
||||
*/
|
||||
readonly attribute DOMString meid;
|
||||
};
|
||||
@@ -36,15 +36,15 @@ interface nsINeighboringCellInfo: nsISupports
|
||||
* Mobile Location Area Code (LAC) for GSM networks.
|
||||
*
|
||||
* Possible ranges from 0x0000 to 0xffff.
|
||||
* -1 if the LAC is unknown.
|
||||
* nsICellInfo.UNKNOWN_VALUE if the LAC is unknown.
|
||||
*/
|
||||
readonly attribute long gsmLocationAreaCode;
|
||||
|
||||
/**
|
||||
* Mobile Cell ID for GSM networks.
|
||||
*
|
||||
* Possible ranges from 0x00000000 to 0xffffffff.
|
||||
* -1 if the cell id is unknown.
|
||||
* Possible ranges from 0x0000 to 0xffff.
|
||||
* nsICellInfo.UNKNOWN_VALUE if the cell id is unknown.
|
||||
*/
|
||||
readonly attribute long long gsmCellId;
|
||||
|
||||
@@ -52,7 +52,7 @@ interface nsINeighboringCellInfo: nsISupports
|
||||
* Primary Scrambling Code (PSC) for WCDMA networks.
|
||||
*
|
||||
* Possible ranges from 0x0000 to 0x01ff.
|
||||
* -1 if the psc is unknown.
|
||||
* nsICellInfo.UNKNOWN_VALUE if the psc is unknown.
|
||||
*/
|
||||
readonly attribute long wcdmaPsc;
|
||||
|
||||
@@ -61,7 +61,7 @@ interface nsINeighboringCellInfo: nsISupports
|
||||
* For WCDMA networks, signalStrength is the CPICH Received Signal Code Power,
|
||||
* ranging from -120 to -25.
|
||||
*
|
||||
* 99 if signalStrength is unknown.
|
||||
* nsICellInfo.UNKNOWN_VALUE if signalStrength is unknown.
|
||||
*/
|
||||
readonly attribute long signalStrength;
|
||||
};
|
||||
@@ -107,6 +107,12 @@ MobileConnectionChild::GetRadioState(int32_t* aRadioState)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MobileConnectionChild::GetDeviceIdentities(nsIMobileDeviceIdentities** aIdentities)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MobileConnectionChild::GetSupportedNetworkTypes(int32_t** aTypes,
|
||||
uint32_t* aLength)
|
||||
@@ -276,9 +282,10 @@ MobileConnectionChild::ChangeCallBarringPassword(const nsAString& aPin,
|
||||
|
||||
NS_IMETHODIMP
|
||||
MobileConnectionChild::SetCallWaiting(bool aEnabled,
|
||||
uint16_t aServiceClass,
|
||||
nsIMobileConnectionCallback* aCallback)
|
||||
{
|
||||
return SendRequest(SetCallWaitingRequest(aEnabled), aCallback)
|
||||
return SendRequest(SetCallWaitingRequest(aEnabled, aServiceClass), aCallback)
|
||||
? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@@ -550,6 +557,12 @@ MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccessCallBarr
|
||||
aReply.serviceClass()));
|
||||
}
|
||||
|
||||
bool
|
||||
MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccessCallWaiting& aReply)
|
||||
{
|
||||
return NS_SUCCEEDED(mRequestCallback->NotifyGetCallWaitingSuccess(aReply.serviceClass()));
|
||||
}
|
||||
|
||||
bool
|
||||
MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccessClirStatus& aReply)
|
||||
{
|
||||
@@ -591,6 +604,8 @@ MobileConnectionRequestChild::Recv__delete__(const MobileConnectionReply& aReply
|
||||
return DoReply(aReply.get_MobileConnectionReplySuccessCallForwarding());
|
||||
case MobileConnectionReply::TMobileConnectionReplySuccessCallBarring:
|
||||
return DoReply(aReply.get_MobileConnectionReplySuccessCallBarring());
|
||||
case MobileConnectionReply::TMobileConnectionReplySuccessCallWaiting:
|
||||
return DoReply(aReply.get_MobileConnectionReplySuccessCallWaiting());
|
||||
case MobileConnectionReply::TMobileConnectionReplySuccessClirStatus:
|
||||
return DoReply(aReply.get_MobileConnectionReplySuccessClirStatus());
|
||||
case MobileConnectionReply::TMobileConnectionReplySuccessPreferredNetworkType:
|
||||
|
||||
@@ -148,6 +148,9 @@ public:
|
||||
bool
|
||||
DoReply(const MobileConnectionReplySuccessCallBarring& aReply);
|
||||
|
||||
bool
|
||||
DoReply(const MobileConnectionReplySuccessCallWaiting& aReply);
|
||||
|
||||
bool
|
||||
DoReply(const MobileConnectionReplySuccessClirStatus& aReply);
|
||||
|
||||
|
||||
@@ -288,6 +288,13 @@ MobileConnectionParent::NotifyNetworkSelectionModeChanged()
|
||||
return SendNotifyNetworkSelectionModeChanged(mode) ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MobileConnectionParent::NotifyDeviceIdentitiesChanged()
|
||||
{
|
||||
// To be supported when bug 1222870 is required in m-c.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* PMobileConnectionRequestParent
|
||||
******************************************************************************/
|
||||
@@ -434,7 +441,9 @@ MobileConnectionRequestParent::DoRequest(const SetCallWaitingRequest& aRequest)
|
||||
{
|
||||
NS_ENSURE_TRUE(mMobileConnection, false);
|
||||
|
||||
return NS_SUCCEEDED(mMobileConnection->SetCallWaiting(aRequest.enabled(), this));
|
||||
return NS_SUCCEEDED(mMobileConnection->SetCallWaiting(aRequest.enabled(),
|
||||
aRequest.serviceClass(),
|
||||
this));
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -536,6 +545,12 @@ MobileConnectionRequestParent::NotifyGetCallBarringSuccess(uint16_t aProgram,
|
||||
aServiceClass));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MobileConnectionRequestParent::NotifyGetCallWaitingSuccess(uint16_t aServiceClass)
|
||||
{
|
||||
return SendReply(MobileConnectionReplySuccessCallWaiting(aServiceClass));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MobileConnectionRequestParent::NotifyGetClirStatusSuccess(uint16_t aN,
|
||||
uint16_t aM)
|
||||
|
||||
@@ -133,6 +133,7 @@ struct ChangeCallBarringPasswordRequest
|
||||
struct SetCallWaitingRequest
|
||||
{
|
||||
bool enabled;
|
||||
uint16_t serviceClass;
|
||||
};
|
||||
|
||||
struct GetCallWaitingRequest
|
||||
|
||||
@@ -52,6 +52,11 @@ struct MobileConnectionReplySuccessCallBarring
|
||||
uint16_t serviceClass;
|
||||
};
|
||||
|
||||
struct MobileConnectionReplySuccessCallWaiting
|
||||
{
|
||||
uint16_t serviceClass;
|
||||
};
|
||||
|
||||
struct MobileConnectionReplySuccessClirStatus
|
||||
{
|
||||
uint16_t n;
|
||||
@@ -82,6 +87,7 @@ union MobileConnectionReply
|
||||
MobileConnectionReplySuccessNetworks;
|
||||
MobileConnectionReplySuccessCallForwarding;
|
||||
MobileConnectionReplySuccessCallBarring;
|
||||
MobileConnectionReplySuccessCallWaiting;
|
||||
MobileConnectionReplySuccessClirStatus;
|
||||
MobileConnectionReplySuccessPreferredNetworkType;
|
||||
MobileConnectionReplySuccessRoamingPreference;
|
||||
|
||||
@@ -27,6 +27,7 @@ XPIDL_SOURCES += [
|
||||
'interfaces/nsIMobileCellInfo.idl',
|
||||
'interfaces/nsIMobileConnectionInfo.idl',
|
||||
'interfaces/nsIMobileConnectionService.idl',
|
||||
'interfaces/nsIMobileDeviceIdentities.idl',
|
||||
'interfaces/nsIMobileNetworkInfo.idl',
|
||||
'interfaces/nsINeighboringCellInfo.idl',
|
||||
]
|
||||
|
||||
@@ -640,6 +640,37 @@ function selectNetworkAutomaticallyAndWait() {
|
||||
return request.then(null, () => { throw request.error });
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures call waiting options.
|
||||
*
|
||||
* Fulfill params: (none)
|
||||
* Reject params:
|
||||
* 'RadioNotAvailable', 'RequestNotSupported', 'InvalidParameter' or
|
||||
* 'GenericFailure'.
|
||||
*
|
||||
* @return A deferred promise.
|
||||
*/
|
||||
function setCallWaitingOption(aEnabled) {
|
||||
let request = mobileConnection.setCallWaitingOption(aEnabled);
|
||||
return request.then(null, () => { throw request.error });
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries current call waiting status.
|
||||
*
|
||||
* Fulfill params:
|
||||
* A boolean indicating the call waiting status.
|
||||
* Reject params:
|
||||
* 'RadioNotAvailable', 'RequestNotSupported', 'InvalidParameter' or
|
||||
* 'GenericFailure'.
|
||||
*
|
||||
* @return A deferred promise.
|
||||
*/
|
||||
function getCallWaitingOption() {
|
||||
let request = mobileConnection.getCallWaitingOption();
|
||||
return request.then(() => request.result, () => { throw request.error });
|
||||
}
|
||||
|
||||
/**
|
||||
* Set data connection enabling state and wait for "datachange" event.
|
||||
*
|
||||
|
||||
@@ -15,9 +15,10 @@ qemu = true
|
||||
[test_mobile_data_location.js]
|
||||
[test_mobile_data_state.js]
|
||||
[test_mobile_roaming_preference.js]
|
||||
[test_call_barring_get_option.js]
|
||||
[test_call_barring_get_error.js]
|
||||
[test_call_barring_set_error.js]
|
||||
[test_call_barring_change_password.js]
|
||||
[test_call_waiting.js]
|
||||
[test_mobile_set_radio.js]
|
||||
[test_mobile_last_known_network.js]
|
||||
[test_mobile_icc_change.js]
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_TIMEOUT = 60000;
|
||||
MARIONETTE_HEAD_JS = "head.js";
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_TIMEOUT = 60000;
|
||||
MARIONETTE_HEAD_JS = "head.js";
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_TIMEOUT = 60000;
|
||||
MARIONETTE_HEAD_JS = "head.js";
|
||||
|
||||
// Start tests
|
||||
startTestCommon(function() {
|
||||
return Promise.resolve()
|
||||
// TODO: Bug 1090811 - [B2G] support SET_CALL_WAITING and QUERY_CALL_WAITING
|
||||
// Currently emulator doesn't support RIL_REQUEST_QUERY_CALL_WAITING and
|
||||
// RIL_REQUEST_SET_CALL_WAITING, so we expect to get a 'RequestNotSupported'
|
||||
// error here.
|
||||
.then(() => setCallWaitingOption(true))
|
||||
.then(() => {
|
||||
ok(false, "setCallWaitingOption should not success");
|
||||
}, aError => {
|
||||
is(aError.name, "RequestNotSupported",
|
||||
"failed to setCallWaitingOption");
|
||||
})
|
||||
|
||||
.then(() => getCallWaitingOption())
|
||||
.then(() => {
|
||||
ok(false, "getCallWaitingOption should not success");
|
||||
}, aError => {
|
||||
is(aError.name, "RequestNotSupported",
|
||||
"failed to getCallWaitingOption");
|
||||
});
|
||||
});
|
||||
@@ -6,14 +6,14 @@
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
|
||||
let WSP = {};
|
||||
var WSP = {};
|
||||
Cu.import("resource://gre/modules/WspPduHelper.jsm", WSP);
|
||||
|
||||
Cu.import("resource://gre/modules/mms_consts.js");
|
||||
|
||||
Cu.import("resource://gre/modules/PhoneNumberUtils.jsm");
|
||||
|
||||
let DEBUG; // set to true to see debug messages
|
||||
var DEBUG; // set to true to see debug messages
|
||||
|
||||
this.MMS_VERSION = (function() {
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
@@ -1660,7 +1660,7 @@ const MMS_WELL_KNOWN_PARAMS = (function() {
|
||||
return params;
|
||||
})();
|
||||
|
||||
let debug;
|
||||
var debug;
|
||||
if (DEBUG) {
|
||||
debug = function(s) {
|
||||
dump("-$- MmsPduHelper: " + s + "\n");
|
||||
|
||||
@@ -17,7 +17,7 @@ Cu.import("resource://gre/modules/Promise.jsm");
|
||||
const GONK_MMSSERVICE_CONTRACTID = "@mozilla.org/mms/gonkmmsservice;1";
|
||||
const GONK_MMSSERVICE_CID = Components.ID("{9b069b8c-8697-11e4-a406-474f5190272b}");
|
||||
|
||||
let DEBUG = false;
|
||||
var DEBUG = false;
|
||||
function debug(s) {
|
||||
dump("-@- MmsService: " + s + "\n");
|
||||
};
|
||||
@@ -1072,8 +1072,9 @@ CancellableTransaction.prototype = {
|
||||
break;
|
||||
}
|
||||
case kSmsDeletedObserverTopic: {
|
||||
if (subject && subject.deletedMessageIds &&
|
||||
subject.deletedMessageIds.indexOf(this.cancellableId) >= 0) {
|
||||
let deletedInfo = subject.QueryInterface(Ci.nsIDeletedMessageInfo);
|
||||
if (deletedInfo && deletedInfo.deletedMessageIds &&
|
||||
deletedInfo.deletedMessageIds.indexOf(this.cancellableId) >= 0) {
|
||||
this.cancelRunning(_MMS_ERROR_MESSAGE_DELETED);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -9,7 +9,7 @@ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
let MMDB = {};
|
||||
var MMDB = {};
|
||||
Cu.import("resource://gre/modules/MobileMessageDB.jsm", MMDB);
|
||||
|
||||
const GONK_MOBILEMESSAGEDATABASESERVICE_CONTRACTID =
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
|
||||
let RIL = {};
|
||||
var RIL = {};
|
||||
Cu.import("resource://gre/modules/ril_consts.js", RIL);
|
||||
|
||||
/**
|
||||
@@ -122,10 +122,9 @@ this.SmsSegmentHelper = {
|
||||
*
|
||||
* |enabledGsmTableTuples|:
|
||||
* List of tuples of national language identifier pairs.
|
||||
* TODO: Support static/runtime settings, see bug 733331.
|
||||
* |segmentRef16Bit|:
|
||||
* Use 16-bit reference number for concatenated outgoint messages.
|
||||
* TODO: Support static/runtime settings, see bug 733331.
|
||||
* TODO: Support static/runtime settings, see bug 1019443.
|
||||
*/
|
||||
enabledGsmTableTuples: [
|
||||
[RIL.PDU_NL_IDENTIFIER_DEFAULT, RIL.PDU_NL_IDENTIFIER_DEFAULT],
|
||||
@@ -162,8 +161,8 @@ this.SmsSegmentHelper = {
|
||||
if ((bodySeptets + headerSeptets) > segmentSeptets) {
|
||||
headerLen += this.segmentRef16Bit ? 6 : 5;
|
||||
headerSeptets = Math.ceil((headerLen + 1) * 8 / 7);
|
||||
segmentSeptets -= headerSeptets;
|
||||
}
|
||||
segmentSeptets -= headerSeptets;
|
||||
|
||||
let segments = Math.ceil(bodySeptets / segmentSeptets);
|
||||
let userDataSeptets = bodySeptets + headerSeptets * segments;
|
||||
@@ -423,4 +422,4 @@ this.SmsSegmentHelper = {
|
||||
}
|
||||
};
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ 'SmsSegmentHelper' ];
|
||||
this.EXPORTED_SYMBOLS = [ 'SmsSegmentHelper' ];
|
||||
|
||||
@@ -21,6 +21,7 @@ const NS_PREFBRANCH_PREFCHANGE_TOPIC_ID = "nsPref:changed";
|
||||
const kPrefDefaultServiceId = "dom.sms.defaultServiceId";
|
||||
const kPrefRilDebuggingEnabled = "ril.debugging.enabled";
|
||||
const kPrefRilNumRadioInterfaces = "ril.numRadioInterfaces";
|
||||
const kPrefLastKnownSimMcc = "ril.lastKnownSimMcc";
|
||||
|
||||
const kDiskSpaceWatcherObserverTopic = "disk-space-watcher";
|
||||
|
||||
@@ -56,6 +57,10 @@ XPCOMUtils.defineLazyGetter(this, "gRadioInterfaces", function() {
|
||||
XPCOMUtils.defineLazyGetter(this, "gSmsSegmentHelper", function() {
|
||||
let ns = {};
|
||||
Cu.import("resource://gre/modules/SmsSegmentHelper.jsm", ns);
|
||||
|
||||
// Initialize enabledGsmTableTuples from current MCC.
|
||||
ns.SmsSegmentHelper.enabledGsmTableTuples = getEnabledGsmTableTuplesFromMcc();
|
||||
|
||||
return ns.SmsSegmentHelper;
|
||||
});
|
||||
|
||||
@@ -71,17 +76,17 @@ XPCOMUtils.defineLazyGetter(this, "gWAP", function() {
|
||||
return ns;
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gSmsSendingSchedulars", function() {
|
||||
XPCOMUtils.defineLazyGetter(this, "gSmsSendingSchedulers", function() {
|
||||
return {
|
||||
_schedulars: [],
|
||||
getSchedularByServiceId: function(aServiceId) {
|
||||
let schedular = this._schedulars[aServiceId];
|
||||
if (!schedular) {
|
||||
schedular = this._schedulars[aServiceId] =
|
||||
new SmsSendingSchedular(aServiceId);
|
||||
_schedulers: [],
|
||||
getSchedulerByServiceId: function(aServiceId) {
|
||||
let scheduler = this._schedulers[aServiceId];
|
||||
if (!scheduler) {
|
||||
scheduler = this._schedulers[aServiceId] =
|
||||
new SmsSendingScheduler(aServiceId);
|
||||
}
|
||||
|
||||
return schedular;
|
||||
return scheduler;
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -120,6 +125,7 @@ function debug(s) {
|
||||
}
|
||||
|
||||
function SmsService() {
|
||||
this._updateDebugFlag();
|
||||
this._silentNumbers = [];
|
||||
this.smsDefaultServiceId = this._getDefaultServiceId();
|
||||
|
||||
@@ -131,6 +137,7 @@ function SmsService() {
|
||||
|
||||
Services.prefs.addObserver(kPrefRilDebuggingEnabled, this, false);
|
||||
Services.prefs.addObserver(kPrefDefaultServiceId, this, false);
|
||||
Services.prefs.addObserver(kPrefLastKnownSimMcc, this, false);
|
||||
Services.obs.addObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
|
||||
Services.obs.addObserver(this, kDiskSpaceWatcherObserverTopic, false);
|
||||
}
|
||||
@@ -331,11 +338,14 @@ SmsService.prototype = {
|
||||
* Schedule the sending request.
|
||||
*/
|
||||
_scheduleSending: function(aServiceId, aDomMessage, aSilent, aOptions, aRequest) {
|
||||
gSmsSendingSchedulars.getSchedularByServiceId(aServiceId)
|
||||
gSmsSendingSchedulers.getSchedulerByServiceId(aServiceId)
|
||||
.schedule({
|
||||
messageId: aDomMessage.id,
|
||||
onSend: () => {
|
||||
if (DEBUG) debug("onSend: " + aDomMessage.id);
|
||||
if (DEBUG) {
|
||||
debug("onSend: messageId=" + aDomMessage.id +
|
||||
", serviceId=" + aServiceId);
|
||||
}
|
||||
this._sendToTheAir(aServiceId,
|
||||
aDomMessage,
|
||||
aSilent,
|
||||
@@ -1187,6 +1197,10 @@ SmsService.prototype = {
|
||||
else if (aData === kPrefDefaultServiceId) {
|
||||
this.smsDefaultServiceId = this._getDefaultServiceId();
|
||||
}
|
||||
else if ( aData === kPrefLastKnownSimMcc) {
|
||||
gSmsSegmentHelper.enabledGsmTableTuples =
|
||||
getEnabledGsmTableTuplesFromMcc();
|
||||
}
|
||||
break;
|
||||
case kDiskSpaceWatcherObserverTopic:
|
||||
if (DEBUG) {
|
||||
@@ -1206,14 +1220,36 @@ SmsService.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
function SmsSendingSchedular(aServiceId) {
|
||||
/**
|
||||
* Get enabled GSM national language locking shift / single shift table pairs
|
||||
* for current SIM MCC.
|
||||
*
|
||||
* @return a list of pairs of national language identifiers for locking shift
|
||||
* table and single shfit table, respectively.
|
||||
*/
|
||||
function getEnabledGsmTableTuplesFromMcc() {
|
||||
let mcc;
|
||||
try {
|
||||
mcc = Services.prefs.getCharPref(kPrefLastKnownSimMcc);
|
||||
} catch (e) {}
|
||||
let tuples = [[RIL.PDU_NL_IDENTIFIER_DEFAULT,
|
||||
RIL.PDU_NL_IDENTIFIER_DEFAULT]];
|
||||
let extraTuples = RIL.PDU_MCC_NL_TABLE_TUPLES_MAPPING[mcc];
|
||||
if (extraTuples) {
|
||||
tuples = tuples.concat(extraTuples);
|
||||
}
|
||||
|
||||
return tuples;
|
||||
};
|
||||
|
||||
function SmsSendingScheduler(aServiceId) {
|
||||
this._serviceId = aServiceId;
|
||||
this._queue = [];
|
||||
|
||||
Services.obs.addObserver(this, kSmsDeletedObserverTopic, false);
|
||||
Services.obs.addObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
|
||||
}
|
||||
SmsSendingSchedular.prototype = {
|
||||
SmsSendingScheduler.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIMobileConnectionListener]),
|
||||
|
||||
_serviceId: 0,
|
||||
@@ -1263,6 +1299,10 @@ SmsSendingSchedular.prototype = {
|
||||
*/
|
||||
schedule: function(aSendingRequest) {
|
||||
if (aSendingRequest) {
|
||||
if (DEBUG) {
|
||||
debug("scheduling message: messageId=" + aSendingRequest.messageId +
|
||||
", serviceId=" + this._serviceId);
|
||||
}
|
||||
this._ensureMoboConnObserverRegistration();
|
||||
this._queue.push(aSendingRequest)
|
||||
|
||||
@@ -1281,7 +1321,7 @@ SmsSendingSchedular.prototype = {
|
||||
*/
|
||||
send: function() {
|
||||
let connection =
|
||||
gMobileConnectionService.getItemByServiceId(this._servicdeId);
|
||||
gMobileConnectionService.getItemByServiceId(this._serviceId);
|
||||
|
||||
// If the voice connection is temporarily unavailable, pend the request.
|
||||
let voiceInfo = connection && connection.voice;
|
||||
@@ -1313,19 +1353,19 @@ SmsSendingSchedular.prototype = {
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
switch (aTopic) {
|
||||
case kSmsDeletedObserverTopic:
|
||||
let deletedInfo = aSubject.QueryInterface(Ci.nsIDeletedMessageInfo);
|
||||
if (DEBUG) {
|
||||
debug("Observe " + kSmsDeletedObserverTopic + ": " +
|
||||
JSON.stringify(aSubject));
|
||||
JSON.stringify(deletedInfo));
|
||||
}
|
||||
|
||||
if (aSubject && aSubject.deletedMessageIds) {
|
||||
for (let id of aSubject.deletedMessageIds) {
|
||||
for (let i = 0; i < this._queue.length; i++) {
|
||||
if (this._queue[i].messageId === id) {
|
||||
if (DEBUG) debug("Deleting message with id=" + id);
|
||||
this._queue.splice(i, 1)[0].onCancel(
|
||||
Ci.nsIMobileMessageCallback.NOT_FOUND_ERROR);
|
||||
}
|
||||
if (deletedInfo && deletedInfo.deletedMessageIds) {
|
||||
for (let i = 0; i < this._queue.length; i++) {
|
||||
let id = this._queue[i].messageId;
|
||||
if (deletedInfo.deletedMessageIds.includes(id)) {
|
||||
if (DEBUG) debug("Deleting message with id=" + id);
|
||||
this._queue.splice(i, 1)[0].onCancel(
|
||||
Ci.nsIMobileMessageCallback.NOT_FOUND_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1370,7 +1410,9 @@ SmsSendingSchedular.prototype = {
|
||||
notifyClirModeChanged: function(mode) {},
|
||||
notifyLastKnownNetworkChanged: function() {},
|
||||
notifyLastKnownHomeNetworkChanged: function() {},
|
||||
notifyNetworkSelectionModeChanged: function() {}
|
||||
notifyNetworkSelectionModeChanged: function() {},
|
||||
notifyDeviceIdentitiesChanged: function() {}
|
||||
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SmsService]);
|
||||
|
||||
@@ -9,7 +9,7 @@ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
Cu.importGlobalProperties(['Blob']);
|
||||
Cu.import("resource://gre/modules/wap_consts.js", this);
|
||||
|
||||
let DEBUG; // set to true to see debug messages
|
||||
var DEBUG; // set to true to see debug messages
|
||||
|
||||
// Special ASCII characters
|
||||
const NUL = 0;
|
||||
@@ -2834,7 +2834,7 @@ this.OMNA_PUSH_APPLICATION_IDS = (function() {
|
||||
return ids;
|
||||
})();
|
||||
|
||||
let debug;
|
||||
var debug;
|
||||
if (DEBUG) {
|
||||
debug = function(s) {
|
||||
dump("-@- WspPduHelper: " + s + "\n");
|
||||
|
||||
@@ -10,7 +10,7 @@ interface nsIMobileMessageCallback : nsISupports
|
||||
/**
|
||||
* All SMS related errors.
|
||||
* Make sure to keep this list in sync with the list in:
|
||||
* embedding/android/GeckoSmsManager.java
|
||||
* mobile/android/base/GeckoSmsManager.java
|
||||
*/
|
||||
const unsigned short SUCCESS_NO_ERROR = 0;
|
||||
const unsigned short NO_SIGNAL_ERROR = 1;
|
||||
|
||||
@@ -200,7 +200,6 @@ SmsRequestChild::Recv__delete__(const MessageReply& aReply)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mReplyRequest);
|
||||
nsCOMPtr<SmsMessage> message;
|
||||
switch(aReply.type()) {
|
||||
case MessageReply::TReplyMessageSend: {
|
||||
const MobileMessageData& data =
|
||||
|
||||
@@ -227,7 +227,7 @@ function sendMmsWithFailure(aMmsParameters, aSendParameters) {
|
||||
/**
|
||||
* Retrieve message by message id.
|
||||
*
|
||||
* Fulfill params: MozSmsMessage
|
||||
* Fulfill params: SmsMessage
|
||||
* Reject params:
|
||||
* event -- a DOMEvent
|
||||
*
|
||||
@@ -476,7 +476,7 @@ function sendTextSmsToEmulator(aFrom, aText) {
|
||||
/**
|
||||
* Send simple text SMS to emulator and wait for a received event.
|
||||
*
|
||||
* Fulfill params: MozSmsMessage
|
||||
* Fulfill params: SmsMessage
|
||||
* Reject params: (none)
|
||||
*
|
||||
* @param aFrom
|
||||
|
||||
@@ -53,7 +53,7 @@ function saveMmsNotification() {
|
||||
.saveReceivedMessage(notification, function(aRv, aDomMessage) {
|
||||
log("saveReceivedMessage(): " + aRv);
|
||||
if (Components.isSuccessCode(aRv)) {
|
||||
deferred.resolve(aDomMessage);
|
||||
deferred.resolve(aDomMessage.QueryInterface(Ci.nsIMmsMessage));
|
||||
} else {
|
||||
deferred.reject();
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ const LONG_BODY = new Array(17).join(SHORT_BODY);
|
||||
ok(LONG_BODY.length > 160, "LONG_BODY.length");
|
||||
|
||||
function checkMessage(aMessage, aBody) {
|
||||
ok(aMessage instanceof MozSmsMessage, "Message is instanceof MozSmsMessage");
|
||||
ok(aMessage instanceof SmsMessage, "Message is instanceof SmsMessage");
|
||||
|
||||
is(aMessage.type, "sms", "message.type");
|
||||
ok(aMessage.id, "message.id");
|
||||
|
||||
@@ -34,7 +34,7 @@ function sendSmsPduToEmulator(pdu) {
|
||||
}
|
||||
|
||||
function checkMessage(message, id, threadId, messageClass) {
|
||||
ok(message instanceof MozSmsMessage,
|
||||
ok(message instanceof SmsMessage,
|
||||
"message is instanceof " + message.constructor);
|
||||
if (id == null) {
|
||||
ok(message.id > 0, "message.id");
|
||||
|
||||
@@ -24,7 +24,7 @@ const LONG_BODY = "Let me not to the marriage of true minds\n"
|
||||
|
||||
function checkMessage(message, delivery, body) {
|
||||
ok(message, "message is valid");
|
||||
ok(message instanceof MozSmsMessage,
|
||||
ok(message instanceof SmsMessage,
|
||||
"message is instanceof " + message.constructor);
|
||||
|
||||
is(message.type, "sms", "message.type");
|
||||
|
||||
@@ -15,13 +15,14 @@
|
||||
|
||||
/** Test for WebSMS **/
|
||||
|
||||
// idl interfaces exposed to every page.
|
||||
// TODO Bug 859764
|
||||
const IDL_IFACE_WITH_PREFIX = ["SmsMessage", "MmsMessage", "MobileMessageThread"];
|
||||
|
||||
// webidl interfaces guarded by [AvailableIn=CertifiedApps].
|
||||
const WEBIDL_IFACE_WITH_PREFIX = ["SmsEvent", "MmsEvent", "MessageDeletedEvent"];
|
||||
const WEBIDL_IFACE = ["DOMMobileMessageError"];
|
||||
const WEBIDL_IFACE = [
|
||||
"DOMMobileMessageError",
|
||||
"MmsMessage",
|
||||
"MobileMessageThread",
|
||||
"SmsMessage",
|
||||
];
|
||||
|
||||
function checkSmsDisabled() {
|
||||
ok(!('mozMobileMessage' in frames[0].navigator), "navigator.mozMobileMessage should not exist");
|
||||
@@ -42,14 +43,6 @@ function checkSmsEnabled() {
|
||||
"navigator.mozMobileMessage is an MobileMessageManager object");
|
||||
}
|
||||
|
||||
function checkIdlInterfaceInWindow() {
|
||||
for (let i = 0; i < IDL_IFACE_WITH_PREFIX.length; i++) {
|
||||
let iface = IDL_IFACE_WITH_PREFIX[i];
|
||||
ok(!(iface in window), iface + " should be prefixed");
|
||||
ok(("Moz" + iface) in window, iface + " should be prefixed");
|
||||
}
|
||||
}
|
||||
|
||||
function checkWebidlInterfaceInWindow() {
|
||||
for (let i = 0; i < WEBIDL_IFACE_WITH_PREFIX.length; i++) {
|
||||
let iface = WEBIDL_IFACE_WITH_PREFIX[i];
|
||||
@@ -77,7 +70,6 @@ function checkWebidlInterfaceNotInWindow() {
|
||||
}
|
||||
|
||||
function test() {
|
||||
checkIdlInterfaceInWindow();
|
||||
checkWebidlInterfaceNotInWindow();
|
||||
|
||||
// If sms is disabled and permission is removed, sms is disabled.
|
||||
|
||||
@@ -34,7 +34,7 @@ function run_test() {
|
||||
add_test(function test_interface() {
|
||||
let sms = newMessage(null, null, ICC_ID, "sent", "success", null, null, null,
|
||||
"normal", Date.now(), Date.now(), Date.now(), true);
|
||||
do_check_true(sms instanceof Ci.nsIDOMMozSmsMessage);
|
||||
do_check_true(sms instanceof Ci.nsISmsMessage);
|
||||
do_check_eq(sms.id, 0);
|
||||
do_check_eq(sms.threadId, 0);
|
||||
do_check_eq(sms.iccId, ICC_ID);
|
||||
@@ -54,7 +54,7 @@ add_test(function test_interface() {
|
||||
add_test(function test_icc_id_not_available() {
|
||||
let sms = newMessage(null, null, null, "sent", "success", null, null, null,
|
||||
"normal", Date.now(), Date.now(), Date.now(), true);
|
||||
do_check_true(sms instanceof Ci.nsIDOMMozSmsMessage);
|
||||
do_check_true(sms instanceof Ci.nsISmsMessage);
|
||||
do_check_eq(sms.id, 0);
|
||||
do_check_eq(sms.threadId, 0);
|
||||
do_check_eq(sms.iccId, null);
|
||||
|
||||
@@ -231,9 +231,16 @@ PaymentProvider.prototype.removeSilentSmsObserver = function(aNumber, aCallback)
|
||||
};
|
||||
|
||||
PaymentProvider.prototype._onSilentSms = function(aSubject, aTopic, aData) {
|
||||
_debug && DEBUG("Got silent message! " + aSubject.sender + " - " + aSubject.body);
|
||||
if (!aSubject || !(aSubject instanceof Ci.nsISmsMessage)) {
|
||||
_debug && DEBUG("Invalid subject when receiving silent message!");
|
||||
return;
|
||||
}
|
||||
|
||||
let number = aSubject.sender;
|
||||
let message = aSubject.QueryInterface(Ci.nsISmsMessage);
|
||||
|
||||
_debug && DEBUG("Got silent message! " + message.sender + " - " + message.body);
|
||||
|
||||
let number = message.sender;
|
||||
if (!number || this._silentNumbers.indexOf(number) == -1) {
|
||||
_debug && DEBUG("No observers for " + number);
|
||||
return;
|
||||
@@ -246,7 +253,7 @@ PaymentProvider.prototype._onSilentSms = function(aSubject, aTopic, aData) {
|
||||
if (this._strategy.paymentServiceId === null) {
|
||||
let i = 0;
|
||||
while(i < gRil.numRadioInterfaces) {
|
||||
if (this.iccInfo[i].iccId === aSubject.iccId) {
|
||||
if (this.iccInfo[i].iccId === message.iccId) {
|
||||
this._strategy.paymentServiceId = i;
|
||||
break;
|
||||
}
|
||||
@@ -255,7 +262,13 @@ PaymentProvider.prototype._onSilentSms = function(aSubject, aTopic, aData) {
|
||||
}
|
||||
|
||||
this._silentSmsObservers[number].forEach(function(callback) {
|
||||
callback(aSubject);
|
||||
callback({
|
||||
iccId: message.iccId,
|
||||
sender: message.sender,
|
||||
body: message.body,
|
||||
timestamp: message.timestamp,
|
||||
sentTimestamp: message.sentTimestamp
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
+748
-506
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,9 @@
|
||||
|
||||
#include "mozilla/HalTypes.h"
|
||||
#include "mozilla/Observer.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsIAudioManager.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "android_audio/AudioSystem.h"
|
||||
@@ -53,32 +55,7 @@ enum AudioOutputProfiles {
|
||||
DEVICE_TOTAL_NUMBER = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
* We have five sound volume settings from UX spec,
|
||||
* You can see more informations in Bug1068219.
|
||||
* (1) Media : music, video, FM ...
|
||||
* (2) Notification : ringer, notification ...
|
||||
* (3) Alarm : alarm
|
||||
* (4) Telephony : GSM call, WebRTC call
|
||||
* (5) Bluetooth SCO : SCO call
|
||||
**/
|
||||
enum AudioVolumeCategories {
|
||||
VOLUME_MEDIA = 0,
|
||||
VOLUME_NOTIFICATION = 1,
|
||||
VOLUME_ALARM = 2,
|
||||
VOLUME_TELEPHONY = 3,
|
||||
VOLUME_BLUETOOTH_SCO = 4,
|
||||
VOLUME_TOTAL_NUMBER = 5,
|
||||
};
|
||||
|
||||
struct VolumeData {
|
||||
const char* mChannelName;
|
||||
uint32_t mCategory;
|
||||
};
|
||||
|
||||
class RecoverTask;
|
||||
class VolumeInitCallback;
|
||||
class AudioProfileData;
|
||||
|
||||
class AudioManager final : public nsIAudioManager
|
||||
, public nsIObserver
|
||||
@@ -90,27 +67,66 @@ public:
|
||||
NS_DECL_NSIAUDIOMANAGER
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
// When audio backend is dead, recovery task needs to read all volume
|
||||
// settings then set back into audio backend.
|
||||
friend class RecoverTask;
|
||||
friend class VolumeInitCallback;
|
||||
|
||||
// Open or close the specific profile
|
||||
void SwitchProfileData(AudioOutputProfiles aProfile, bool aActive);
|
||||
|
||||
// Validate whether the volume index is within the range
|
||||
nsresult ValidateVolumeIndex(uint32_t aCategory, uint32_t aIndex) const;
|
||||
nsresult ValidateVolumeIndex(int32_t aStream, uint32_t aIndex) const;
|
||||
|
||||
// Called when android AudioFlinger in mediaserver is died
|
||||
void HandleAudioFlingerDied();
|
||||
|
||||
void HandleHeadphoneSwitchEvent(const hal::SwitchEvent& aEvent);
|
||||
|
||||
class VolumeStreamState {
|
||||
public:
|
||||
explicit VolumeStreamState(AudioManager& aManager, int32_t aStreamType);
|
||||
int32_t GetStreamType()
|
||||
{
|
||||
return mStreamType;
|
||||
}
|
||||
bool IsDevicesChanged(bool aFromCache = true);
|
||||
void ClearDevicesChanged();
|
||||
uint32_t GetLastDevices()
|
||||
{
|
||||
return mLastDevices;
|
||||
}
|
||||
bool IsVolumeIndexesChanged();
|
||||
void ClearVolumeIndexesChanged();
|
||||
void InitStreamVolume();
|
||||
uint32_t GetMaxIndex();
|
||||
uint32_t GetDefaultIndex();
|
||||
uint32_t GetVolumeIndex();
|
||||
uint32_t GetVolumeIndex(uint32_t aDevice);
|
||||
void ClearCurrentVolumeUpdated();
|
||||
// Set volume index to all active devices.
|
||||
// Active devices are chosen by android AudioPolicyManager.
|
||||
nsresult SetVolumeIndexToActiveDevices(uint32_t aIndex);
|
||||
// Set volume index to all alias streams. Alias streams have same volume.
|
||||
// It is used to update volume based on audio output profile data.
|
||||
nsresult SetVolumeIndexToAliasStreams(uint32_t aIndex, uint32_t aDevice);
|
||||
// Set volume index to all alias devices in audio output profile.
|
||||
// Alias devices have same volume.
|
||||
nsresult SetVolumeIndexToAliasDevices(uint32_t aIndex, uint32_t aDevice);
|
||||
nsresult SetVolumeIndex(uint32_t aIndex, uint32_t aDevice, bool aUpdateCache = true);
|
||||
// Restore volume index to all devices. Called when AudioFlinger is restarted.
|
||||
void RestoreVolumeIndexToAllDevices();
|
||||
private:
|
||||
AudioManager& mManager;
|
||||
const int32_t mStreamType;
|
||||
uint32_t mLastDevices;
|
||||
bool mIsDevicesChanged;
|
||||
bool mIsVolumeIndexesChanged;
|
||||
nsDataHashtable<nsUint32HashKey, uint32_t> mVolumeIndexes;
|
||||
};
|
||||
|
||||
protected:
|
||||
int32_t mPhoneState;
|
||||
|
||||
// A bitwise variable for recording what kind of headset/headphone is attached.
|
||||
int32_t mHeadsetState;
|
||||
bool mIsVolumeInited;
|
||||
|
||||
// A bitwise variable for volume update of audio output profiles
|
||||
uint32_t mAudioOutProfileUpdated;
|
||||
|
||||
// Connected devices that are controlled by setDeviceConnectionState()
|
||||
nsDataHashtable<nsUint32HashKey, nsCString> mConnectedDevices;
|
||||
|
||||
bool mSwitchDone;
|
||||
|
||||
@@ -120,11 +136,23 @@ protected:
|
||||
#ifdef MOZ_B2G_BT
|
||||
bool mA2dpSwitchDone;
|
||||
#endif
|
||||
uint32_t mCurrentStreamVolumeTbl[AUDIO_STREAM_CNT];
|
||||
nsTArray<UniquePtr<VolumeStreamState> > mStreamStates;
|
||||
uint32_t mLastChannelVolume[AUDIO_STREAM_CNT];
|
||||
|
||||
bool IsFmOutConnected();
|
||||
|
||||
nsresult SetStreamVolumeForProfile(AudioOutputProfiles aProfile,
|
||||
int32_t aStream,
|
||||
uint32_t aIndex);
|
||||
nsresult SetStreamVolumeIndex(int32_t aStream, uint32_t aIndex);
|
||||
nsresult GetStreamVolumeIndex(int32_t aStream, uint32_t *aIndex);
|
||||
|
||||
void UpdateCachedActiveDevicesForStreams();
|
||||
uint32_t GetDevicesForStream(int32_t aStream, bool aFromCache = true);
|
||||
uint32_t GetDeviceForStream(int32_t aStream);
|
||||
// Choose one device as representative of active devices.
|
||||
static uint32_t SelectDeviceFromDevices(uint32_t aOutDevices);
|
||||
|
||||
private:
|
||||
nsAutoPtr<mozilla::hal::SwitchObserver> mObserver;
|
||||
#ifdef MOZ_B2G_RIL
|
||||
@@ -132,57 +160,41 @@ private:
|
||||
// mIsMicMuted is only used for toggling mute call to RIL.
|
||||
bool mIsMicMuted;
|
||||
#endif
|
||||
nsTArray<nsAutoPtr<AudioProfileData>> mAudioProfiles;
|
||||
AudioOutputProfiles mPresentProfile;
|
||||
|
||||
void HandleBluetoothStatusChanged(nsISupports* aSubject,
|
||||
const char* aTopic,
|
||||
const nsCString aAddress);
|
||||
void HandleAudioChannelProcessChanged();
|
||||
|
||||
void CreateAudioProfilesData();
|
||||
// Initialize volume index for audio output profile
|
||||
void InitVolumeForProfile(AudioOutputProfiles aProfile,
|
||||
int32_t aStreamType,
|
||||
uint32_t aIndex);
|
||||
|
||||
// Init the volume setting from the init setting callback
|
||||
void InitProfileVolume(AudioOutputProfiles aProfile,
|
||||
uint32_t aCatogory, uint32_t aIndex);
|
||||
|
||||
// Update volume data of profiles
|
||||
void UpdateVolumeToProfile(AudioProfileData* aProfileData);
|
||||
|
||||
// Apply the volume data to device
|
||||
void UpdateVolumeFromProfile(AudioProfileData* aProfileData);
|
||||
|
||||
// Send the volume changing event to Gaia
|
||||
void SendVolumeChangeNotification(AudioProfileData* aProfileData);
|
||||
|
||||
// Update the mPresentProfile and profiles active status
|
||||
void UpdateProfileState(AudioOutputProfiles aProfile, bool aActive);
|
||||
|
||||
// Volume control functions
|
||||
nsresult SetVolumeByCategory(uint32_t aCategory, uint32_t aIndex);
|
||||
uint32_t GetVolumeByCategory(uint32_t aCategory) const;
|
||||
uint32_t GetMaxVolumeByCategory(uint32_t aCategory) const;
|
||||
|
||||
AudioProfileData* FindAudioProfileData(AudioOutputProfiles aProfile);
|
||||
|
||||
// Append the profile to the volume setting string.
|
||||
// Append the audio output profile to the volume setting string.
|
||||
nsAutoCString AppendProfileToVolumeSetting(const char* aName,
|
||||
AudioOutputProfiles aProfile);
|
||||
|
||||
// We store the volume setting in the database, these are related functions.
|
||||
void InitVolumeFromDatabase();
|
||||
void UpdateVolumeSettingToDatabase(nsISettingsServiceLock* aLock,
|
||||
const char* aTopic,
|
||||
uint32_t aVolIndex);
|
||||
void MaybeUpdateVolumeSettingToDatabase(bool aForce = false);
|
||||
|
||||
// Promise functions.
|
||||
void InitProfileVolumeSucceeded();
|
||||
void InitProfileVolumeFailed(const char* aError);
|
||||
|
||||
void AudioOutProfileUpdated(AudioOutputProfiles aProfile);
|
||||
|
||||
void UpdateHeadsetConnectionState(hal::SwitchState aState);
|
||||
void UpdateDeviceConnectionState(bool aIsConnected, uint32_t aDevice, const nsCString& aDeviceName);
|
||||
void SetAllDeviceConnectionStates();
|
||||
|
||||
AudioManager();
|
||||
~AudioManager();
|
||||
|
||||
friend class VolumeInitCallback;
|
||||
friend class VolumeStreamState;
|
||||
friend class GonkAudioPortCallback;
|
||||
};
|
||||
|
||||
} /* namespace gonk */
|
||||
|
||||
@@ -71,7 +71,9 @@ DataCall.prototype = {
|
||||
ifname: null,
|
||||
addreses: null,
|
||||
dnses: null,
|
||||
gateways: null
|
||||
gateways: null,
|
||||
pcscf: null,
|
||||
mtu: -1
|
||||
};
|
||||
|
||||
function DataCallInterfaceService() {
|
||||
|
||||
@@ -941,7 +941,9 @@ DataCallHandler.prototype = {
|
||||
|
||||
notifyLastKnownHomeNetworkChanged: function() {},
|
||||
|
||||
notifyNetworkSelectionModeChanged: function() {}
|
||||
notifyNetworkSelectionModeChanged: function() {},
|
||||
|
||||
notifyDeviceIdentitiesChanged: function() {}
|
||||
};
|
||||
|
||||
function DataCall(aClientId, aApnSetting, aDataCallHandler) {
|
||||
@@ -960,7 +962,9 @@ function DataCall(aClientId, aApnSetting, aDataCallHandler) {
|
||||
ifname: null,
|
||||
addresses: [],
|
||||
dnses: [],
|
||||
gateways: []
|
||||
gateways: [],
|
||||
pcscf: [],
|
||||
mtu: null
|
||||
};
|
||||
this.state = NETWORK_STATE_UNKNOWN;
|
||||
this.requestedNetworkIfaces = [];
|
||||
@@ -1026,6 +1030,10 @@ DataCall.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
if (aCurrentDataCall.mtu != aUpdatedDataCall.mtu) {
|
||||
return "changed";
|
||||
}
|
||||
|
||||
return "identical";
|
||||
},
|
||||
|
||||
@@ -1091,6 +1099,8 @@ DataCall.prototype = {
|
||||
this.linkInfo.addresses = aDataCall.addresses ? aDataCall.addresses.split(" ") : [];
|
||||
this.linkInfo.gateways = aDataCall.gateways ? aDataCall.gateways.split(" ") : [];
|
||||
this.linkInfo.dnses = aDataCall.dnses ? aDataCall.dnses.split(" ") : [];
|
||||
this.linkInfo.pcscf = aDataCall.pcscf ? aDataCall.pcscf.split(" ") : [];
|
||||
this.linkInfo.mtu = aDataCall.mtu > 0 ? aDataCall.mtu : 0;
|
||||
this.state = this._getGeckoDataCallState(aDataCall);
|
||||
|
||||
// Notify DataCallHandler about data call connected.
|
||||
@@ -1143,7 +1153,9 @@ DataCall.prototype = {
|
||||
ifname: aUpdatedDataCall.ifname,
|
||||
addresses: aUpdatedDataCall.addresses ? aUpdatedDataCall.addresses.split(" ") : [],
|
||||
dnses: aUpdatedDataCall.dnses ? aUpdatedDataCall.dnses.split(" ") : [],
|
||||
gateways: aUpdatedDataCall.gateways ? aUpdatedDataCall.gateways.split(" ") : []
|
||||
gateways: aUpdatedDataCall.gateways ? aUpdatedDataCall.gateways.split(" ") : [],
|
||||
pcscf: aUpdatedDataCall.pcscf ? aUpdatedDataCall.pcscf.split(" ") : [],
|
||||
mtu: aUpdatedDataCall.mtu > 0 ? aUpdatedDataCall.mtu : 0
|
||||
};
|
||||
|
||||
switch (dataCallState) {
|
||||
@@ -1169,6 +1181,8 @@ DataCall.prototype = {
|
||||
this.linkInfo.addresses = newLinkInfo.addresses.slice();
|
||||
this.linkInfo.gateways = newLinkInfo.gateways.slice();
|
||||
this.linkInfo.dnses = newLinkInfo.dnses.slice();
|
||||
this.linkInfo.pcscf = newLinkInfo.pcscf.slice();
|
||||
this.linkInfo.mtu = newLinkInfo.mtu;
|
||||
}
|
||||
break;
|
||||
case NETWORK_STATE_DISCONNECTED:
|
||||
@@ -1267,6 +1281,8 @@ DataCall.prototype = {
|
||||
this.linkInfo.addresses = [];
|
||||
this.linkInfo.dnses = [];
|
||||
this.linkInfo.gateways = [];
|
||||
this.linkInfo.pcscf = [];
|
||||
this.linkInfo.mtu = null;
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
@@ -1604,6 +1620,20 @@ RILNetworkInfo.prototype = {
|
||||
// See http://www.iana.org/assignments/port-numbers
|
||||
return this.getApnSetting().mmsport || -1;
|
||||
},
|
||||
|
||||
getPcscf: function(aCount) {
|
||||
if (this.type != NETWORK_TYPE_MOBILE_IMS) {
|
||||
if (DEBUG) this.debug("Error! Only IMS network can get pcscf.");
|
||||
throw Cr.NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
let linkInfo = this.getDataCall().linkInfo;
|
||||
|
||||
if (aCount) {
|
||||
aCount.value = linkInfo.pcscf.length;
|
||||
}
|
||||
return linkInfo.pcscf.slice();
|
||||
},
|
||||
};
|
||||
|
||||
function RILNetworkInterface(aDataCallHandler, aType, aApnSetting, aDataCall) {
|
||||
@@ -1647,6 +1677,11 @@ RILNetworkInterface.prototype = {
|
||||
return this.apnSetting.port || "";
|
||||
},
|
||||
|
||||
get mtu() {
|
||||
// Value provided by network has higher priority than apn settings.
|
||||
return this.dataCall.linkInfo.mtu || this.apnSetting.mtu || -1;
|
||||
},
|
||||
|
||||
// Helpers
|
||||
|
||||
debug: function(aMsg) {
|
||||
|
||||
@@ -30,26 +30,11 @@ XPCOMUtils.defineLazyGetter(this, "RIL", function () {
|
||||
return obj;
|
||||
});
|
||||
|
||||
// Ril quirk to attach data registration on demand.
|
||||
let RILQUIRKS_DATA_REGISTRATION_ON_DEMAND =
|
||||
libcutils.property_get("ro.moz.ril.data_reg_on_demand", "false") == "true";
|
||||
|
||||
// Ril quirk to control the uicc/data subscription.
|
||||
let RILQUIRKS_SUBSCRIPTION_CONTROL =
|
||||
libcutils.property_get("ro.moz.ril.subscription_control", "false") == "true";
|
||||
|
||||
// Ril quirk to always turn the radio off for the client without SIM card
|
||||
// except hw default client.
|
||||
var RILQUIRKS_RADIO_OFF_WO_CARD =
|
||||
libcutils.property_get("ro.moz.ril.radio_off_wo_card", "false") == "true";
|
||||
|
||||
// Ril quirk to enable IPv6 protocol/roaming protocol in APN settings.
|
||||
let RILQUIRKS_HAVE_IPV6 =
|
||||
libcutils.property_get("ro.moz.ril.ipv6", "false") == "true";
|
||||
|
||||
let RILQUIRKS_SIGNAL_EXTRA_INT32 =
|
||||
libcutils.property_get("ro.moz.ril.signal_extra_int", "false") == "true";
|
||||
|
||||
const RADIOINTERFACELAYER_CID =
|
||||
Components.ID("{2d831c8d-6017-435b-a80c-e5d422810cea}");
|
||||
const RADIOINTERFACE_CID =
|
||||
@@ -407,7 +392,9 @@ DataCall.prototype = {
|
||||
ifname: null,
|
||||
addreses: null,
|
||||
dnses: null,
|
||||
gateways: null
|
||||
gateways: null,
|
||||
pcscf: null,
|
||||
mtu: -1
|
||||
};
|
||||
|
||||
function RadioInterfaceLayer() {
|
||||
@@ -522,23 +509,26 @@ WorkerMessenger.prototype = {
|
||||
quirks: {
|
||||
callstateExtraUint32:
|
||||
libcutils.property_get("ro.moz.ril.callstate_extra_int", "false") === "true",
|
||||
v5Legacy:
|
||||
libcutils.property_get("ro.moz.ril.v5_legacy", "true") === "true",
|
||||
requestUseDialEmergencyCall:
|
||||
libcutils.property_get("ro.moz.ril.dial_emergency_call", "false") === "true",
|
||||
simAppStateExtraFields:
|
||||
libcutils.property_get("ro.moz.ril.simstate_extra_field", "false") === "true",
|
||||
extraUint2ndCall:
|
||||
libcutils.property_get("ro.moz.ril.extra_int_2nd_call", "false") == "true",
|
||||
libcutils.property_get("ro.moz.ril.extra_int_2nd_call", "false") === "true",
|
||||
haveQueryIccLockRetryCount:
|
||||
libcutils.property_get("ro.moz.ril.query_icc_count", "false") == "true",
|
||||
libcutils.property_get("ro.moz.ril.query_icc_count", "false") === "true",
|
||||
sendStkProfileDownload:
|
||||
libcutils.property_get("ro.moz.ril.send_stk_profile_dl", "false") == "true",
|
||||
libcutils.property_get("ro.moz.ril.send_stk_profile_dl", "false") === "true",
|
||||
smscAddressFormat:
|
||||
libcutils.property_get("ro.moz.ril.smsc_address_format", "text"),
|
||||
dataRegistrationOnDemand: RILQUIRKS_DATA_REGISTRATION_ON_DEMAND,
|
||||
subscriptionControl: RILQUIRKS_SUBSCRIPTION_CONTROL,
|
||||
signalExtraInt: RILQUIRKS_SIGNAL_EXTRA_INT32
|
||||
dataRegistrationOnDemand:
|
||||
libcutils.property_get("ro.moz.ril.data_reg_on_demand", "false") === "true",
|
||||
subscriptionControl:
|
||||
libcutils.property_get("ro.moz.ril.subscription_control", "false") === "true",
|
||||
signalExtraInt:
|
||||
libcutils.property_get("ro.moz.ril.signal_extra_int", "false") === "true",
|
||||
availableNetworkExtraStr:
|
||||
libcutils.property_get("ro.moz.ril.avlbl_nw_extra_str", "false") === "true",
|
||||
}
|
||||
};
|
||||
|
||||
@@ -778,6 +768,13 @@ RadioInterface.prototype = {
|
||||
case "otastatuschange":
|
||||
gMobileConnectionService.notifyOtaStatusChanged(this.clientId, message.status);
|
||||
break;
|
||||
case "deviceidentitieschange":
|
||||
gMobileConnectionService.notifyDeviceIdentitiesChanged(this.clientId,
|
||||
message.deviceIdentities.imei,
|
||||
message.deviceIdentities.imeisv,
|
||||
message.deviceIdentities.esn,
|
||||
message.deviceIdentities.meid);
|
||||
break;
|
||||
case "radiostatechange":
|
||||
// gRadioEnabledController should know the radio state for each client,
|
||||
// so notify gRadioEnabledController here.
|
||||
|
||||
@@ -112,11 +112,33 @@ Volume::Dump(const char* aLabel) const
|
||||
: (IsUnmounting() ? "y" : "n"));
|
||||
}
|
||||
|
||||
void
|
||||
Volume::ResolveAndSetMountPoint(const nsCSubstring& aMountPoint)
|
||||
{
|
||||
nsCString mountPoint(aMountPoint);
|
||||
char realPathBuf[PATH_MAX];
|
||||
|
||||
// Call realpath so that we wind up with a path which is compatible with
|
||||
// functions like nsVolumeService::GetVolumeByPath.
|
||||
|
||||
if (realpath(mountPoint.get(), realPathBuf) < 0) {
|
||||
// The path we were handed doesn't exist. Warn about it, but use it
|
||||
// anyways assuming that the user knows what they're doing.
|
||||
|
||||
ERR("ResolveAndSetMountPoint: realpath on '%s' failed: %d",
|
||||
mountPoint.get(), errno);
|
||||
mMountPoint = mountPoint;
|
||||
} else {
|
||||
mMountPoint = realPathBuf;
|
||||
}
|
||||
DBG("Volume %s: Setting mountpoint to '%s'", NameStr(), mMountPoint.get());
|
||||
}
|
||||
|
||||
void Volume::SetFakeVolume(const nsACString& aMountPoint)
|
||||
{
|
||||
this->mMountLocked = false;
|
||||
this->mCanBeShared = false;
|
||||
this->mMountPoint = aMountPoint;
|
||||
ResolveAndSetMountPoint(aMountPoint);
|
||||
SetState(nsIVolume::STATE_MOUNTED);
|
||||
}
|
||||
|
||||
@@ -386,8 +408,7 @@ Volume::SetMountPoint(const nsCSubstring& aMountPoint)
|
||||
if (mMountPoint.Equals(aMountPoint)) {
|
||||
return;
|
||||
}
|
||||
mMountPoint = aMountPoint;
|
||||
DBG("Volume %s: Setting mountpoint to '%s'", NameStr(), mMountPoint.get());
|
||||
ResolveAndSetMountPoint(aMountPoint);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -119,6 +119,8 @@ private:
|
||||
void SetMountPoint(const nsCSubstring& aMountPoint);
|
||||
void StartCommand(VolumeCommand* aCommand);
|
||||
|
||||
void ResolveAndSetMountPoint(const nsCSubstring& aMountPoint);
|
||||
|
||||
bool BoolConfigValue(const nsCString& aConfigValue, bool& aBoolValue);
|
||||
void SetConfig(const nsCString& aConfigName, const nsCString& aConfigValue);
|
||||
|
||||
|
||||
@@ -156,6 +156,27 @@ VolumeManager::FindAddVolumeByName(const nsCSubstring& aName)
|
||||
return vol.forget();
|
||||
}
|
||||
|
||||
//static
|
||||
bool
|
||||
VolumeManager::RemoveVolumeByName(const nsCSubstring& aName)
|
||||
{
|
||||
if (!sVolumeManager) {
|
||||
return false;
|
||||
}
|
||||
VolumeArray::size_type numVolumes = NumVolumes();
|
||||
VolumeArray::index_type volIndex;
|
||||
for (volIndex = 0; volIndex < numVolumes; volIndex++) {
|
||||
RefPtr<Volume> vol = GetVolume(volIndex);
|
||||
if (vol->Name().Equals(aName)) {
|
||||
sVolumeManager->mVolumeArray.RemoveElementAt(volIndex);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// No volume found. Return false to indicate this.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//static
|
||||
void VolumeManager::InitConfig()
|
||||
{
|
||||
@@ -236,6 +257,17 @@ void VolumeManager::InitConfig()
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (command.EqualsLiteral("ignore")) {
|
||||
// This command is useful to remove volumes which are being tracked by
|
||||
// vold, but for which we have no interest.
|
||||
if (!tokenizer.hasMoreTokens()) {
|
||||
ERR("No vol_name in %s line %d", filename, n);
|
||||
continue;
|
||||
}
|
||||
nsCString volName(tokenizer.nextToken());
|
||||
RemoveVolumeByName(volName);
|
||||
continue;
|
||||
}
|
||||
ERR("Unrecognized command: '%s'", command.get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,6 +128,7 @@ public:
|
||||
static already_AddRefed<Volume> GetVolume(VolumeArray::index_type aIndex);
|
||||
static already_AddRefed<Volume> FindVolumeByName(const nsCSubstring& aName);
|
||||
static already_AddRefed<Volume> FindAddVolumeByName(const nsCSubstring& aName);
|
||||
static bool RemoveVolumeByName(const nsCSubstring& aName);
|
||||
static void InitConfig();
|
||||
|
||||
static void PostCommand(VolumeCommand* aCommand);
|
||||
|
||||
@@ -969,6 +969,9 @@ public:
|
||||
static status_t getStreamVolumeIndex(audio_stream_type_t stream, int *index);
|
||||
|
||||
static uint32_t getStrategyForStream(stream_type stream);
|
||||
#if ANDROID_VERSION >= 17
|
||||
static audio_devices_t getDevicesForStream(audio_stream_type_t stream);
|
||||
#endif
|
||||
|
||||
static audio_io_handle_t getOutputForEffect(effect_descriptor_t *desc);
|
||||
static status_t registerEffect(effect_descriptor_t *desc,
|
||||
@@ -995,6 +998,23 @@ public:
|
||||
static bool isLinearPCM(uint32_t format);
|
||||
static bool isModeInCall();
|
||||
|
||||
#if ANDROID_VERSION >= 21
|
||||
class AudioPortCallback : public RefBase
|
||||
{
|
||||
public:
|
||||
|
||||
AudioPortCallback() {}
|
||||
virtual ~AudioPortCallback() {}
|
||||
|
||||
virtual void onAudioPortListUpdate() = 0;
|
||||
virtual void onAudioPatchListUpdate() = 0;
|
||||
virtual void onServiceDied() = 0;
|
||||
|
||||
};
|
||||
|
||||
static void setAudioPortCallback(sp<AudioPortCallback> callBack);
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
class AudioFlingerClient: public IBinder::DeathRecipient, public BnAudioFlingerClient
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(d27ce247-9c7c-4582-826b-125e8275e9c2)]
|
||||
[scriptable, uuid(6b66446a-7000-438f-8e1b-b56b4cbf4fa9)]
|
||||
interface nsIDataCall : nsISupports
|
||||
{
|
||||
/**
|
||||
@@ -55,6 +55,17 @@ interface nsIDataCall : nsISupports
|
||||
* A space-delimited list of default gateway addresses.
|
||||
*/
|
||||
readonly attribute DOMString gateways;
|
||||
|
||||
/**
|
||||
* A space-delimited list of Proxy Call State Control Function addresses for
|
||||
* IMS client.
|
||||
*/
|
||||
readonly attribute DOMString pcscf;
|
||||
|
||||
/**
|
||||
* MTU received from network, -1 if not set or invalid.
|
||||
*/
|
||||
readonly attribute long mtu;
|
||||
};
|
||||
|
||||
[scriptable, uuid(e119c54b-9354-4ad6-a1ee-18608bde9320)]
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "nsISupports.idl"
|
||||
#include "nsINetworkInterface.idl"
|
||||
|
||||
[scriptable, uuid(501b7041-0754-4ddb-9174-946e2c2ebd83)]
|
||||
[scriptable, uuid(b8bcd6aa-5b06-4362-a68c-317878429e51)]
|
||||
interface nsIRilNetworkInfo : nsINetworkInfo
|
||||
{
|
||||
readonly attribute unsigned long serviceId;
|
||||
@@ -15,6 +15,17 @@ interface nsIRilNetworkInfo : nsINetworkInfo
|
||||
readonly attribute DOMString mmsc; // Empty string if not set.
|
||||
readonly attribute DOMString mmsProxy; // Empty string if not set.
|
||||
readonly attribute long mmsPort; // -1 if not set.
|
||||
|
||||
/**
|
||||
* Get the list of pcscf addresses, could be IPv4 or IPv6.
|
||||
*
|
||||
* @param count
|
||||
* The length of the list of pcscf addresses.
|
||||
*
|
||||
* @returns the list of pcscf addresses.
|
||||
*/
|
||||
void getPcscf([optional] out unsigned long count,
|
||||
[array, size_is(count), retval] out wstring pcscf);
|
||||
};
|
||||
|
||||
[scriptable, function, uuid(cb2f0f5b-67f4-4c14-93e8-01e66b630464)]
|
||||
|
||||
@@ -66,6 +66,22 @@ nsVolume::nsVolume(const Volume* aVolume)
|
||||
{
|
||||
}
|
||||
|
||||
nsVolume::nsVolume(const nsVolume* aVolume)
|
||||
: mName(aVolume->mName),
|
||||
mMountPoint(aVolume->mMountPoint),
|
||||
mState(aVolume->mState),
|
||||
mMountGeneration(aVolume->mMountGeneration),
|
||||
mMountLocked(aVolume->mMountLocked),
|
||||
mIsFake(aVolume->mIsFake),
|
||||
mIsMediaPresent(aVolume->mIsMediaPresent),
|
||||
mIsSharing(aVolume->mIsSharing),
|
||||
mIsFormatting(aVolume->mIsFormatting),
|
||||
mIsUnmounting(aVolume->mIsUnmounting),
|
||||
mIsRemovable(aVolume->mIsRemovable),
|
||||
mIsHotSwappable(aVolume->mIsHotSwappable)
|
||||
{
|
||||
}
|
||||
|
||||
void nsVolume::Dump(const char* aLabel) const
|
||||
{
|
||||
LOG("%s: Volume: %s is %s and %s @ %s gen %d locked %d",
|
||||
@@ -333,40 +349,28 @@ nsVolume::LogState() const
|
||||
LOG("nsVolume: %s state %s", NameStr().get(), StateStr());
|
||||
}
|
||||
|
||||
void nsVolume::Set(nsIVolume* aVolume)
|
||||
void nsVolume::UpdateMountLock(nsVolume* aOldVolume)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
aVolume->GetName(mName);
|
||||
aVolume->GetMountPoint(mMountPoint);
|
||||
aVolume->GetState(&mState);
|
||||
aVolume->GetIsFake(&mIsFake);
|
||||
aVolume->GetIsMediaPresent(&mIsMediaPresent);
|
||||
aVolume->GetIsSharing(&mIsSharing);
|
||||
aVolume->GetIsFormatting(&mIsFormatting);
|
||||
aVolume->GetIsUnmounting(&mIsUnmounting);
|
||||
aVolume->GetIsRemovable(&mIsRemovable);
|
||||
aVolume->GetIsHotSwappable(&mIsHotSwappable);
|
||||
|
||||
int32_t volMountGeneration;
|
||||
aVolume->GetMountGeneration(&volMountGeneration);
|
||||
|
||||
bool oldMountLocked = aOldVolume ? aOldVolume->mMountLocked : false;
|
||||
if (mState != nsIVolume::STATE_MOUNTED) {
|
||||
// Since we're not in the mounted state, we need to
|
||||
// forgot whatever mount generation we may have had.
|
||||
mMountGeneration = -1;
|
||||
return;
|
||||
}
|
||||
if (mMountGeneration == volMountGeneration) {
|
||||
// No change in mount generation, nothing else to do
|
||||
mMountLocked = oldMountLocked;
|
||||
return;
|
||||
}
|
||||
|
||||
mMountGeneration = volMountGeneration;
|
||||
int32_t oldMountGeneration = aOldVolume ? aOldVolume->mMountGeneration : -1;
|
||||
if (mMountGeneration == oldMountGeneration) {
|
||||
// No change in mount generation, nothing else to do
|
||||
mMountLocked = oldMountLocked;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!XRE_IsParentProcess()) {
|
||||
// Child processes just track the state, not maintain it.
|
||||
aVolume->GetIsMountLocked(&mMountLocked);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,9 @@ public:
|
||||
// This constructor is used by the UpdateVolumeRunnable constructor
|
||||
nsVolume(const Volume* aVolume);
|
||||
|
||||
// This constructor is used by nsVolumeService::SetFakeVolumeState
|
||||
nsVolume(const nsVolume* aVolume);
|
||||
|
||||
// This constructor is used by ContentChild::RecvFileSystemUpdate which is
|
||||
// used to update the volume cache maintained in the child process.
|
||||
nsVolume(const nsAString& aName, const nsAString& aMountPoint,
|
||||
@@ -47,25 +50,8 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
// This constructor is used by nsVolumeService::FindAddVolumeByName, and
|
||||
// will be followed shortly by a Set call.
|
||||
nsVolume(const nsAString& aName)
|
||||
: mName(aName),
|
||||
mState(STATE_INIT),
|
||||
mMountGeneration(-1),
|
||||
mMountLocked(true), // Needs to agree with Volume::Volume
|
||||
mIsFake(false),
|
||||
mIsMediaPresent(false),
|
||||
mIsSharing(false),
|
||||
mIsFormatting(false),
|
||||
mIsUnmounting(false),
|
||||
mIsRemovable(false),
|
||||
mIsHotSwappable(false)
|
||||
{
|
||||
}
|
||||
|
||||
bool Equals(nsIVolume* aVolume);
|
||||
void Set(nsIVolume* aVolume);
|
||||
void UpdateMountLock(nsVolume* aOldVolume);
|
||||
|
||||
void LogState() const;
|
||||
|
||||
|
||||
@@ -368,7 +368,7 @@ nsVolumeService::FindVolumeByMountLockName(const nsAString& aMountLockName)
|
||||
}
|
||||
|
||||
already_AddRefed<nsVolume>
|
||||
nsVolumeService::FindVolumeByName(const nsAString& aName)
|
||||
nsVolumeService::FindVolumeByName(const nsAString& aName, nsVolume::Array::index_type* aIndex)
|
||||
{
|
||||
mArrayMonitor.AssertCurrentThreadOwns();
|
||||
|
||||
@@ -377,52 +377,35 @@ nsVolumeService::FindVolumeByName(const nsAString& aName)
|
||||
for (volIndex = 0; volIndex < numVolumes; volIndex++) {
|
||||
RefPtr<nsVolume> vol = mVolumeArray[volIndex];
|
||||
if (vol->Name().Equals(aName)) {
|
||||
if (aIndex) {
|
||||
*aIndex = volIndex;
|
||||
}
|
||||
return vol.forget();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//static
|
||||
already_AddRefed<nsVolume>
|
||||
nsVolumeService::CreateOrFindVolumeByName(const nsAString& aName, bool aIsFake /*= false*/)
|
||||
{
|
||||
MonitorAutoLock autoLock(mArrayMonitor);
|
||||
|
||||
RefPtr<nsVolume> vol;
|
||||
vol = FindVolumeByName(aName);
|
||||
if (vol) {
|
||||
return vol.forget();
|
||||
}
|
||||
// Volume not found - add a new one
|
||||
vol = new nsVolume(aName);
|
||||
vol->SetIsFake(aIsFake);
|
||||
mVolumeArray.AppendElement(vol);
|
||||
return vol.forget();
|
||||
}
|
||||
|
||||
void
|
||||
nsVolumeService::UpdateVolume(nsIVolume* aVolume, bool aNotifyObservers)
|
||||
nsVolumeService::UpdateVolume(nsVolume* aVolume, bool aNotifyObservers)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsString volName;
|
||||
aVolume->GetName(volName);
|
||||
bool aIsFake;
|
||||
aVolume->GetIsFake(&aIsFake);
|
||||
RefPtr<nsVolume> vol = CreateOrFindVolumeByName(volName, aIsFake);
|
||||
if (vol->Equals(aVolume)) {
|
||||
// Nothing has really changed. Don't bother telling anybody.
|
||||
return;
|
||||
{
|
||||
MonitorAutoLock autoLock(mArrayMonitor);
|
||||
nsVolume::Array::index_type volIndex;
|
||||
RefPtr<nsVolume> vol = FindVolumeByName(aVolume->Name(), &volIndex);
|
||||
if (!vol) {
|
||||
mVolumeArray.AppendElement(aVolume);
|
||||
} else if (vol->Equals(aVolume) || (!vol->IsFake() && aVolume->IsFake())) {
|
||||
// Ignore if nothing changed or if a fake tries to override a real volume.
|
||||
return;
|
||||
} else {
|
||||
mVolumeArray.ReplaceElementAt(volIndex, aVolume);
|
||||
}
|
||||
aVolume->UpdateMountLock(vol);
|
||||
}
|
||||
|
||||
if (!vol->IsFake() && aIsFake) {
|
||||
// Prevent an incoming fake volume from overriding an existing real volume.
|
||||
return;
|
||||
}
|
||||
|
||||
vol->Set(aVolume);
|
||||
|
||||
if (!aNotifyObservers) {
|
||||
return;
|
||||
}
|
||||
@@ -431,8 +414,8 @@ nsVolumeService::UpdateVolume(nsIVolume* aVolume, bool aNotifyObservers)
|
||||
if (!obs) {
|
||||
return;
|
||||
}
|
||||
NS_ConvertUTF8toUTF16 stateStr(vol->StateStr());
|
||||
obs->NotifyObservers(vol, NS_VOLUME_STATE_CHANGED, stateStr.get());
|
||||
NS_ConvertUTF8toUTF16 stateStr(aVolume->StateStr());
|
||||
obs->NotifyObservers(aVolume, NS_VOLUME_STATE_CHANGED, stateStr.get());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@@ -471,11 +454,8 @@ nsVolumeService::SetFakeVolumeState(const nsAString& name, int32_t state)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
// UpdateVolume expects the volume passed in to NOT be the
|
||||
// same pointer as what CreateOrFindVolumeByName would return,
|
||||
// which is why we allocate a temporary volume here.
|
||||
RefPtr<nsVolume> volume = new nsVolume(name);
|
||||
volume->Set(vol);
|
||||
// Clone the existing volume so we can replace it
|
||||
RefPtr<nsVolume> volume = new nsVolume(vol);
|
||||
volume->SetState(state);
|
||||
volume->LogState();
|
||||
UpdateVolume(volume.get());
|
||||
@@ -502,15 +482,15 @@ nsVolumeService::RemoveFakeVolume(const nsAString& name)
|
||||
void
|
||||
nsVolumeService::RemoveVolumeByName(const nsAString& aName)
|
||||
{
|
||||
RefPtr<nsVolume> vol;
|
||||
{
|
||||
MonitorAutoLock autoLock(mArrayMonitor);
|
||||
vol = FindVolumeByName(aName);
|
||||
nsVolume::Array::index_type volIndex;
|
||||
RefPtr<nsVolume> vol = FindVolumeByName(aName, &volIndex);
|
||||
if (!vol) {
|
||||
return;
|
||||
}
|
||||
mVolumeArray.RemoveElementAt(volIndex);
|
||||
}
|
||||
if (!vol) {
|
||||
return;
|
||||
}
|
||||
mVolumeArray.RemoveElement(vol);
|
||||
|
||||
if (XRE_IsParentProcess()) {
|
||||
nsCOMPtr<nsIObserverService> obs = GetObserverService();
|
||||
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
void DumpNoLock(const char* aLabel);
|
||||
|
||||
// To use this function, you have to create a new volume and pass it in.
|
||||
void UpdateVolume(nsIVolume* aVolume, bool aNotifyObservers = true);
|
||||
void UpdateVolume(nsVolume* aVolume, bool aNotifyObservers = true);
|
||||
void UpdateVolumeIOThread(const Volume* aVolume);
|
||||
|
||||
void RecvVolumesFromParent(const nsTArray<dom::VolumeInfo>& aVolumes);
|
||||
@@ -61,8 +61,9 @@ private:
|
||||
void CheckMountLock(const nsAString& aMountLockName,
|
||||
const nsAString& aMountLockState);
|
||||
already_AddRefed<nsVolume> FindVolumeByMountLockName(const nsAString& aMountLockName);
|
||||
already_AddRefed<nsVolume> FindVolumeByName(const nsAString& aName);
|
||||
already_AddRefed<nsVolume> CreateOrFindVolumeByName(const nsAString& aName, bool aIsFake = false);
|
||||
|
||||
already_AddRefed<nsVolume> FindVolumeByName(const nsAString& aName,
|
||||
nsVolume::Array::index_type* aIndex = nullptr);
|
||||
|
||||
Monitor mArrayMonitor;
|
||||
nsVolume::Array mVolumeArray;
|
||||
|
||||
+24
-158
@@ -278,17 +278,7 @@ this.SMS_RETRY_MAX = 3;
|
||||
|
||||
this.RADIO_STATE_OFF = 0;
|
||||
this.RADIO_STATE_UNAVAILABLE = 1;
|
||||
this.RADIO_STATE_ON = 10; // RIL v7
|
||||
|
||||
// RIL v5 legacy constants:
|
||||
this.RADIO_STATE_SIM_NOT_READY = 2;
|
||||
this.RADIO_STATE_SIM_LOCKED_OR_ABSENT = 3;
|
||||
this.RADIO_STATE_SIM_READY = 4;
|
||||
this.RADIO_STATE_RUIM_NOT_READY = 5;
|
||||
this.RADIO_STATE_RUIM_READY = 6;
|
||||
this.RADIO_STATE_RUIM_LOCKED_OR_ABSENT = 7;
|
||||
this.RADIO_STATE_NV_NOT_READY = 8;
|
||||
this.RADIO_STATE_NV_READY = 9;
|
||||
this.RADIO_STATE_ON = 10; // since RIL v7
|
||||
|
||||
this.CARD_STATE_ABSENT = 0;
|
||||
this.CARD_STATE_PRESENT = 1;
|
||||
@@ -582,6 +572,12 @@ this.ADN_MAX_BCD_NUMBER_BYTES = 11;
|
||||
// Maximum digits of the Dialling Number in ADN.
|
||||
// See TS 151.011 clause 10.5.1 EF_ADN, 'Dialling Number'.
|
||||
this.ADN_MAX_NUMBER_DIGITS = 20;
|
||||
// Maximum size of BCD numbers in EXT.
|
||||
// See TS 151.011 clause 10.5.10 EF_EXT1, 'Extension data'.
|
||||
this.EXT_MAX_BCD_NUMBER_BYTES = 10;
|
||||
// Maximum digits of the Dialling Number in EXT.
|
||||
// See TS 151.011 clause 10.5.10 EF_EXT1, 'Extension data'.
|
||||
this.EXT_MAX_NUMBER_DIGITS = 20;
|
||||
|
||||
// READ_RECORD mode, TS 102.221
|
||||
this.READ_RECORD_ABSOLUTE_MODE = 4;
|
||||
@@ -1270,10 +1266,13 @@ this.GECKO_ICC_SERVICES = {
|
||||
FDN: 3,
|
||||
PLMNSEL: 7,
|
||||
MSISDN: 9,
|
||||
EXT1: 10,
|
||||
EXT2: 11,
|
||||
CBMI: 14,
|
||||
GID1: 15,
|
||||
SPN: 17,
|
||||
SDN: 18,
|
||||
EXT3: 19,
|
||||
DATA_DOWNLOAD_SMS_CB: 25,
|
||||
DATA_DOWNLOAD_SMS_PP: 26,
|
||||
CBMIR: 30,
|
||||
@@ -1288,7 +1287,9 @@ this.GECKO_ICC_SERVICES = {
|
||||
// @see 3GPP TS 31.102 4.2.8 (USIM).
|
||||
usim: {
|
||||
FDN: 2,
|
||||
EXT2: 3,
|
||||
SDN: 4,
|
||||
EXT3: 5,
|
||||
BDN: 6,
|
||||
CBMI: 15,
|
||||
CBMIR: 16,
|
||||
@@ -1308,8 +1309,11 @@ this.GECKO_ICC_SERVICES = {
|
||||
ruim: {
|
||||
FDN: 3,
|
||||
ENHANCED_PHONEBOOK: 6,
|
||||
EXT1: 10,
|
||||
EXT2: 11,
|
||||
SPN: 17,
|
||||
SDN: 18
|
||||
SDN: 18,
|
||||
EXT3: 19,
|
||||
},
|
||||
// @see B.3.1.1 CPHS Information in CPHS Phase 2:
|
||||
// Indicates which of the CPHS 'optional' data-fields are present in the SIM card:
|
||||
@@ -1419,7 +1423,8 @@ this.CALLED_PARTY_BCD_NPI_PRIVATE = 9;
|
||||
|
||||
/**
|
||||
* Array of number plan identification values which can be used to map an
|
||||
* enumeration to the corresponding value.
|
||||
* enumeration to the corresponding value. The indices should be consistent
|
||||
* with nsISmsService::NUMBER_PLAN_IDENTIFICATION_* constants.
|
||||
*/
|
||||
this.CALLED_PARTY_BCD_NPI = [
|
||||
CALLED_PARTY_BCD_NPI_UNKNOWN,
|
||||
@@ -2970,6 +2975,9 @@ this.CALL_BARRING_PROGRAM_OUTGOING_INTERNATIONAL = 1;
|
||||
this.CALL_BARRING_PROGRAM_OUTGOING_INTERNATIONAL_EXCEPT_HOME = 2;
|
||||
this.CALL_BARRING_PROGRAM_ALL_INCOMING = 3;
|
||||
this.CALL_BARRING_PROGRAM_INCOMING_ROAMING = 4;
|
||||
this.CALL_BARRING_PROGRAM_ALL_SERVICE = 5;
|
||||
this.CALL_BARRING_PROGRAM_OUTGOING_SERVICE = 6;
|
||||
this.CALL_BARRING_PROGRAM_INCOMING_SERVICE = 7;
|
||||
|
||||
this.CALL_BARRING_PROGRAM_TO_FACILITY = {};
|
||||
CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_ALL_OUTGOING] = ICC_CB_FACILITY_BAOC;
|
||||
@@ -2977,152 +2985,10 @@ CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_OUTGOING_INTERNATIONAL] =
|
||||
CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_OUTGOING_INTERNATIONAL_EXCEPT_HOME] = ICC_CB_FACILITY_BAOICxH;
|
||||
CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_ALL_INCOMING] = ICC_CB_FACILITY_BAIC;
|
||||
CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_INCOMING_ROAMING] = ICC_CB_FACILITY_BAICr;
|
||||
CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_ALL_SERVICE] = ICC_CB_FACILITY_BA_ALL;
|
||||
CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_OUTGOING_SERVICE] = ICC_CB_FACILITY_BA_MO;
|
||||
CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_INCOMING_SERVICE] = ICC_CB_FACILITY_BA_MT;
|
||||
|
||||
// CLIR constants. Must be in sync with nsIMobileConnectionService interface
|
||||
this.CLIR_DEFAULT = 0;
|
||||
this.CLIR_INVOCATION = 1;
|
||||
this.CLIR_SUPPRESSION = 2;
|
||||
|
||||
// MMI procedure as defined in TS.22.030 6.5.2
|
||||
this.MMI_PROCEDURE_ACTIVATION = "*";
|
||||
this.MMI_PROCEDURE_DEACTIVATION = "#";
|
||||
this.MMI_PROCEDURE_INTERROGATION = "*#";
|
||||
this.MMI_PROCEDURE_REGISTRATION = "**";
|
||||
this.MMI_PROCEDURE_ERASURE = "##";
|
||||
|
||||
this.MMI_PROC_TO_CF_ACTION = {};
|
||||
MMI_PROC_TO_CF_ACTION[MMI_PROCEDURE_ACTIVATION] = CALL_FORWARD_ACTION_ENABLE;
|
||||
MMI_PROC_TO_CF_ACTION[MMI_PROCEDURE_DEACTIVATION] = CALL_FORWARD_ACTION_DISABLE;
|
||||
MMI_PROC_TO_CF_ACTION[MMI_PROCEDURE_INTERROGATION] = CALL_FORWARD_ACTION_QUERY_STATUS;
|
||||
MMI_PROC_TO_CF_ACTION[MMI_PROCEDURE_REGISTRATION] = CALL_FORWARD_ACTION_REGISTRATION;
|
||||
MMI_PROC_TO_CF_ACTION[MMI_PROCEDURE_ERASURE] = CALL_FORWARD_ACTION_ERASURE;
|
||||
|
||||
// MMI call forwarding service codes as defined in TS.22.030 Annex B
|
||||
this.MMI_SC_CFU = "21";
|
||||
this.MMI_SC_CF_BUSY = "67";
|
||||
this.MMI_SC_CF_NO_REPLY = "61";
|
||||
this.MMI_SC_CF_NOT_REACHABLE = "62";
|
||||
this.MMI_SC_CF_ALL = "002";
|
||||
this.MMI_SC_CF_ALL_CONDITIONAL = "004";
|
||||
|
||||
this.MMI_SC_TO_CF_REASON = {};
|
||||
MMI_SC_TO_CF_REASON[MMI_SC_CFU] = CALL_FORWARD_REASON_UNCONDITIONAL;
|
||||
MMI_SC_TO_CF_REASON[MMI_SC_CF_BUSY] = CALL_FORWARD_REASON_MOBILE_BUSY;
|
||||
MMI_SC_TO_CF_REASON[MMI_SC_CF_NO_REPLY] = CALL_FORWARD_REASON_NO_REPLY;
|
||||
MMI_SC_TO_CF_REASON[MMI_SC_CF_NOT_REACHABLE] = CALL_FORWARD_REASON_NOT_REACHABLE;
|
||||
MMI_SC_TO_CF_REASON[MMI_SC_CF_ALL] = CALL_FORWARD_REASON_ALL_CALL_FORWARDING;
|
||||
MMI_SC_TO_CF_REASON[MMI_SC_CF_ALL_CONDITIONAL] = CALL_FORWARD_REASON_ALL_CONDITIONAL_CALL_FORWARDING;
|
||||
|
||||
// MMI service codes for PIN/PIN2/PUK/PUK2 management as defined in TS.22.030
|
||||
// sec 6.6
|
||||
this.MMI_SC_PIN = "04";
|
||||
this.MMI_SC_PIN2 = "042";
|
||||
this.MMI_SC_PUK = "05";
|
||||
this.MMI_SC_PUK2 = "052";
|
||||
|
||||
// MMI service code for IMEI presentation as defined in TS.22.030 sec 6.7
|
||||
this.MMI_SC_IMEI = "06";
|
||||
|
||||
// MMI called line presentation service codes
|
||||
this.MMI_SC_CLIP = "30";
|
||||
this.MMI_SC_CLIR = "31";
|
||||
|
||||
// MMI call waiting service code
|
||||
this.MMI_SC_CALL_WAITING = "43";
|
||||
|
||||
// MMI service code for registration new password as defined in TS 22.030 6.5.4
|
||||
this.MMI_SC_CHANGE_PASSWORD = "03";
|
||||
this.MMI_ZZ_BARRING_SERVICE = "330";
|
||||
|
||||
// MMI call barring service codes
|
||||
this.MMI_SC_BAOC = "33";
|
||||
this.MMI_SC_BAOIC = "331";
|
||||
this.MMI_SC_BAOICxH = "332";
|
||||
this.MMI_SC_BAIC = "35";
|
||||
this.MMI_SC_BAICr = "351";
|
||||
this.MMI_SC_BA_ALL = "330";
|
||||
this.MMI_SC_BA_MO = "333";
|
||||
this.MMI_SC_BA_MT = "353";
|
||||
|
||||
this.MMI_SC_TO_CB_FACILITY = {};
|
||||
|
||||
MMI_SC_TO_CB_FACILITY[MMI_SC_BAOC] = ICC_CB_FACILITY_BAOC;
|
||||
MMI_SC_TO_CB_FACILITY[MMI_SC_BAOIC] = ICC_CB_FACILITY_BAOIC;
|
||||
MMI_SC_TO_CB_FACILITY[MMI_SC_BAOICxH] = ICC_CB_FACILITY_BAOICxH;
|
||||
MMI_SC_TO_CB_FACILITY[MMI_SC_BAIC] = ICC_CB_FACILITY_BAIC;
|
||||
MMI_SC_TO_CB_FACILITY[MMI_SC_BAICr] = ICC_CB_FACILITY_BAICr;
|
||||
MMI_SC_TO_CB_FACILITY[MMI_SC_BA_ALL] = ICC_CB_FACILITY_BA_ALL;
|
||||
MMI_SC_TO_CB_FACILITY[MMI_SC_BA_MO] = ICC_CB_FACILITY_BA_MO;
|
||||
MMI_SC_TO_CB_FACILITY[MMI_SC_BA_MT] = ICC_CB_FACILITY_BA_MT;
|
||||
|
||||
// MMI service code key strings.
|
||||
this.MMI_KS_SC_CALL_BARRING = "scCallBarring";
|
||||
this.MMI_KS_SC_CALL_FORWARDING = "scCallForwarding";
|
||||
this.MMI_KS_SC_CLIP = "scClip";
|
||||
this.MMI_KS_SC_CLIR = "scClir";
|
||||
this.MMI_KS_SC_PWD = "scPwd";
|
||||
this.MMI_KS_SC_CALL_WAITING = "scCallWaiting";
|
||||
this.MMI_KS_SC_PIN = "scPin";
|
||||
this.MMI_KS_SC_PIN2 = "scPin2";
|
||||
this.MMI_KS_SC_PUK = "scPuk";
|
||||
this.MMI_KS_SC_PUK2 = "scPuk2";
|
||||
this.MMI_KS_SC_CHANGE_PASSWORD = "scChangePassword";
|
||||
this.MMI_KS_SC_IMEI = "scImei";
|
||||
this.MMI_KS_SC_USSD = "scUssd";
|
||||
this.MMI_KS_SC_CALL = "scCall";
|
||||
|
||||
// MMI error messages key strings.
|
||||
this.MMI_ERROR_KS_ERROR = "emMmiError";
|
||||
this.MMI_ERROR_KS_NOT_SUPPORTED = "emMmiErrorNotSupported";
|
||||
this.MMI_ERROR_KS_INVALID_ACTION = "emMmiErrorInvalidAction";
|
||||
this.MMI_ERROR_KS_MISMATCH_PIN = "emMmiErrorMismatchPin";
|
||||
this.MMI_ERROR_KS_MISMATCH_PASSWORD = "emMmiErrorMismatchPassword";
|
||||
this.MMI_ERROR_KS_BAD_PIN = "emMmiErrorBadPin";
|
||||
this.MMI_ERROR_KS_BAD_PUK = "emMmiErrorBadPuk";
|
||||
this.MMI_ERROR_KS_INVALID_PIN = "emMmiErrorInvalidPin";
|
||||
this.MMI_ERROR_KS_INVALID_PASSWORD = "emMmiErrorInvalidPassword";
|
||||
this.MMI_ERROR_KS_NEEDS_PUK = "emMmiErrorNeedsPuk";
|
||||
this.MMI_ERROR_KS_SIM_BLOCKED = "emMmiErrorSimBlocked";
|
||||
|
||||
// MMI status message.
|
||||
this.MMI_SM_KS_PASSWORD_CHANGED = "smPasswordChanged";
|
||||
this.MMI_SM_KS_PIN_CHANGED = "smPinChanged";
|
||||
this.MMI_SM_KS_PIN2_CHANGED = "smPin2Changed";
|
||||
this.MMI_SM_KS_PIN_UNBLOCKED = "smPinUnblocked";
|
||||
this.MMI_SM_KS_PIN2_UNBLOCKED = "smPin2Unblocked";
|
||||
this.MMI_SM_KS_SERVICE_ENABLED = "smServiceEnabled";
|
||||
this.MMI_SM_KS_SERVICE_ENABLED_FOR = "smServiceEnabledFor";
|
||||
this.MMI_SM_KS_SERVICE_DISABLED = "smServiceDisabled";
|
||||
this.MMI_SM_KS_SERVICE_REGISTERED = "smServiceRegistered";
|
||||
this.MMI_SM_KS_SERVICE_ERASED = "smServiceErased";
|
||||
this.MMI_SM_KS_SERVICE_INTERROGATED = "smServiceInterrogated";
|
||||
this.MMI_SM_KS_SERVICE_NOT_PROVISIONED = "smServiceNotProvisioned";
|
||||
this.MMI_SM_KS_CLIR_PERMANENT = "smClirPermanent";
|
||||
this.MMI_SM_KS_CLIR_DEFAULT_ON_NEXT_CALL_ON = "smClirDefaultOnNextCallOn";
|
||||
this.MMI_SM_KS_CLIR_DEFAULT_ON_NEXT_CALL_OFF = "smClirDefaultOnNextCallOff";
|
||||
this.MMI_SM_KS_CLIR_DEFAULT_OFF_NEXT_CALL_ON = "smClirDefaultOffNextCallOn";
|
||||
this.MMI_SM_KS_CLIR_DEFAULT_OFF_NEXT_CALL_OFF = "smClirDefaultOffNextCallOff";
|
||||
this.MMI_SM_KS_CALL_CONTROL = "smCallControl";
|
||||
|
||||
// MMI Service class
|
||||
this.MMI_KS_SERVICE_CLASS_VOICE = "serviceClassVoice";
|
||||
this.MMI_KS_SERVICE_CLASS_DATA = "serviceClassData";
|
||||
this.MMI_KS_SERVICE_CLASS_FAX = "serviceClassFax";
|
||||
this.MMI_KS_SERVICE_CLASS_SMS = "serviceClassSms";
|
||||
this.MMI_KS_SERVICE_CLASS_DATA_SYNC = "serviceClassDataSync";
|
||||
this.MMI_KS_SERVICE_CLASS_DATA_ASYNC = "serviceClassDataAsync";
|
||||
this.MMI_KS_SERVICE_CLASS_PACKET = "serviceClassPacket";
|
||||
this.MMI_KS_SERVICE_CLASS_PAD = "serviceClassPad";
|
||||
|
||||
this.MMI_KS_SERVICE_CLASS_MAPPING = {};
|
||||
MMI_KS_SERVICE_CLASS_MAPPING[ICC_SERVICE_CLASS_VOICE] = MMI_KS_SERVICE_CLASS_VOICE;
|
||||
MMI_KS_SERVICE_CLASS_MAPPING[ICC_SERVICE_CLASS_DATA] = MMI_KS_SERVICE_CLASS_DATA;
|
||||
MMI_KS_SERVICE_CLASS_MAPPING[ICC_SERVICE_CLASS_FAX] = MMI_KS_SERVICE_CLASS_FAX;
|
||||
MMI_KS_SERVICE_CLASS_MAPPING[ICC_SERVICE_CLASS_SMS] = MMI_KS_SERVICE_CLASS_SMS;
|
||||
MMI_KS_SERVICE_CLASS_MAPPING[ICC_SERVICE_CLASS_DATA_SYNC] = MMI_KS_SERVICE_CLASS_DATA_SYNC;
|
||||
MMI_KS_SERVICE_CLASS_MAPPING[ICC_SERVICE_CLASS_DATA_ASYNC] = MMI_KS_SERVICE_CLASS_DATA_ASYNC;
|
||||
MMI_KS_SERVICE_CLASS_MAPPING[ICC_SERVICE_CLASS_PACKET] = MMI_KS_SERVICE_CLASS_PACKET;
|
||||
MMI_KS_SERVICE_CLASS_MAPPING[ICC_SERVICE_CLASS_PAD] = MMI_KS_SERVICE_CLASS_PAD;
|
||||
/**
|
||||
* CDMA PDU constants
|
||||
*/
|
||||
|
||||
+671
-1035
File diff suppressed because it is too large
Load Diff
@@ -156,7 +156,7 @@ add_test(function test_ril_worker_cellbroadcast_set_search_list() {
|
||||
context.RIL.setCellBroadcastSearchList(options);
|
||||
// Enforce the MMI result to string for comparison.
|
||||
equal("" + context.RIL.cellBroadcastConfigs.MMI, aExpected);
|
||||
equal(options.success, true);
|
||||
do_check_eq(options.errorMsg, undefined);
|
||||
}
|
||||
|
||||
let searchListStr = "1,2,3,4";
|
||||
|
||||
@@ -71,8 +71,7 @@ add_test(function test_setCallForward_unconditional() {
|
||||
|
||||
let postedMessage = workerHelper.postedMessage;
|
||||
|
||||
equal(postedMessage.errorMsg, GECKO_ERROR_SUCCESS);
|
||||
ok(postedMessage.success);
|
||||
equal(postedMessage.errorMsg, undefined);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
@@ -116,8 +115,7 @@ add_test(function test_queryCallForwardStatus_unconditional() {
|
||||
|
||||
let postedMessage = workerHelper.postedMessage;
|
||||
|
||||
equal(postedMessage.errorMsg, GECKO_ERROR_SUCCESS);
|
||||
ok(postedMessage.success);
|
||||
equal(postedMessage.errorMsg, undefined);
|
||||
ok(Array.isArray(postedMessage.rules));
|
||||
do_print(postedMessage.rules.length);
|
||||
equal(postedMessage.rules.length, 1);
|
||||
|
||||
@@ -29,7 +29,6 @@ add_test(function test_queryCLIP_provisioned() {
|
||||
let postedMessage = workerHelper.postedMessage;
|
||||
|
||||
equal(postedMessage.errorMsg, undefined);
|
||||
ok(postedMessage.success);
|
||||
equal(postedMessage.provisioned, 1);
|
||||
run_next_test();
|
||||
});
|
||||
@@ -55,7 +54,6 @@ add_test(function test_getCLIP_error_generic_failure_invalid_length() {
|
||||
|
||||
let postedMessage = workerHelper.postedMessage;
|
||||
|
||||
equal(postedMessage.errorMsg, "GenericFailure");
|
||||
ok(!postedMessage.success);
|
||||
equal(postedMessage.errorMsg, GECKO_ERROR_GENERIC_FAILURE);
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
@@ -34,7 +34,6 @@ add_test(function test_setCLIR_success() {
|
||||
let postedMessage = workerHelper.postedMessage;
|
||||
|
||||
equal(postedMessage.errorMsg, undefined);
|
||||
ok(postedMessage.success);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
@@ -57,8 +56,7 @@ add_test(function test_setCLIR_generic_failure() {
|
||||
|
||||
let postedMessage = workerHelper.postedMessage;
|
||||
|
||||
equal(postedMessage.errorMsg, "GenericFailure");
|
||||
ok(!postedMessage.success);
|
||||
equal(postedMessage.errorMsg, GECKO_ERROR_GENERIC_FAILURE);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
@@ -89,7 +87,6 @@ add_test(function test_getCLIR_n0_m1() {
|
||||
let postedMessage = workerHelper.postedMessage;
|
||||
|
||||
equal(postedMessage.errorMsg, undefined);
|
||||
ok(postedMessage.success);
|
||||
equal(postedMessage.n, 0);
|
||||
equal(postedMessage.m, 1);
|
||||
run_next_test();
|
||||
@@ -120,7 +117,6 @@ add_test(function test_getCLIR_error_generic_failure_invalid_length() {
|
||||
|
||||
let postedMessage = workerHelper.postedMessage;
|
||||
|
||||
equal(postedMessage.errorMsg, "GenericFailure");
|
||||
ok(!postedMessage.success);
|
||||
equal(postedMessage.errorMsg, GECKO_ERROR_GENERIC_FAILURE);
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
@@ -23,7 +23,6 @@ add_test(function test_setCallWaiting_success() {
|
||||
let postedMessage = workerHelper.postedMessage;
|
||||
|
||||
equal(postedMessage.errorMsg, undefined);
|
||||
ok(postedMessage.success);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
@@ -45,8 +44,7 @@ add_test(function test_setCallWaiting_generic_failure() {
|
||||
|
||||
let postedMessage = workerHelper.postedMessage;
|
||||
|
||||
equal(postedMessage.errorMsg, "GenericFailure");
|
||||
ok(!postedMessage.success);
|
||||
equal(postedMessage.errorMsg, GECKO_ERROR_GENERIC_FAILURE);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
@@ -64,7 +62,7 @@ add_test(function test_queryCallWaiting_success_enabled_true() {
|
||||
context.Buf.int32Array = [
|
||||
1, // serviceClass
|
||||
1, // enabled
|
||||
1 // length
|
||||
2 // length
|
||||
];
|
||||
context.RIL[REQUEST_QUERY_CALL_WAITING](1, {});
|
||||
};
|
||||
@@ -74,9 +72,7 @@ add_test(function test_queryCallWaiting_success_enabled_true() {
|
||||
let postedMessage = workerHelper.postedMessage;
|
||||
|
||||
equal(postedMessage.errorMsg, undefined);
|
||||
ok(postedMessage.success);
|
||||
equal(postedMessage.length, 1);
|
||||
ok(postedMessage.enabled);
|
||||
equal(postedMessage.serviceClass, 1);
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
@@ -93,7 +89,7 @@ add_test(function test_queryCallWaiting_success_enabled_false() {
|
||||
context.Buf.int32Array = [
|
||||
1, // serviceClass
|
||||
0, // enabled
|
||||
1 // length
|
||||
2 // length
|
||||
];
|
||||
context.RIL[REQUEST_QUERY_CALL_WAITING](1, {});
|
||||
};
|
||||
@@ -103,8 +99,6 @@ add_test(function test_queryCallWaiting_success_enabled_false() {
|
||||
let postedMessage = workerHelper.postedMessage;
|
||||
|
||||
equal(postedMessage.errorMsg, undefined);
|
||||
ok(postedMessage.success);
|
||||
equal(postedMessage.length, 1);
|
||||
ok(!postedMessage.enabled);
|
||||
equal(postedMessage.serviceClass, ICC_SERVICE_CLASS_NONE);
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
@@ -16,7 +16,6 @@ add_test(function test_icc_get_card_lock_enabled() {
|
||||
let buf = context.Buf;
|
||||
let ril = context.RIL;
|
||||
ril.aid = "123456789";
|
||||
ril.v5Legacy = false;
|
||||
|
||||
function do_test(aLock) {
|
||||
const serviceClass = ICC_SERVICE_CLASS_VOICE |
|
||||
@@ -32,13 +31,11 @@ add_test(function test_icc_get_card_lock_enabled() {
|
||||
|
||||
// Data
|
||||
let parcel = this.readStringList();
|
||||
equal(parcel.length, ril.v5Legacy ? 3 : 4);
|
||||
equal(parcel.length, 4);
|
||||
equal(parcel[0], GECKO_CARDLOCK_TO_FACILITY[aLock]);
|
||||
equal(parcel[1], "");
|
||||
equal(parcel[2], serviceClass.toString());
|
||||
if (!ril.v5Legacy) {
|
||||
equal(parcel[3], ril.aid);
|
||||
}
|
||||
equal(parcel[3], ril.aid);
|
||||
};
|
||||
|
||||
ril.iccGetCardLockEnabled({lockType: aLock});
|
||||
@@ -87,7 +84,6 @@ add_test(function test_icc_set_card_lock_enabled() {
|
||||
let buf = context.Buf;
|
||||
let ril = context.RIL;
|
||||
ril.aid = "123456789";
|
||||
ril.v5Legacy = false;
|
||||
|
||||
function do_test(aLock, aPassword, aEnabled) {
|
||||
const serviceClass = ICC_SERVICE_CLASS_VOICE |
|
||||
@@ -103,14 +99,12 @@ add_test(function test_icc_set_card_lock_enabled() {
|
||||
|
||||
// Data
|
||||
let parcel = this.readStringList();
|
||||
equal(parcel.length, ril.v5Legacy ? 4 : 5);
|
||||
equal(parcel.length, 5);
|
||||
equal(parcel[0], GECKO_CARDLOCK_TO_FACILITY[aLock]);
|
||||
equal(parcel[1], aEnabled ? "1" : "0");
|
||||
equal(parcel[2], aPassword);
|
||||
equal(parcel[3], serviceClass.toString());
|
||||
if (!ril.v5Legacy) {
|
||||
equal(parcel[4], ril.aid);
|
||||
}
|
||||
equal(parcel[4], ril.aid);
|
||||
};
|
||||
|
||||
ril.iccSetCardLockEnabled({
|
||||
@@ -151,12 +145,10 @@ add_test(function test_icc_change_card_lock_password() {
|
||||
|
||||
// Data
|
||||
let parcel = this.readStringList();
|
||||
equal(parcel.length, ril.v5Legacy ? 2 : 3);
|
||||
equal(parcel.length, 3);
|
||||
equal(parcel[0], aPassword);
|
||||
equal(parcel[1], aNewPassword);
|
||||
if (!ril.v5Legacy) {
|
||||
equal(parcel[2], ril.aid);
|
||||
}
|
||||
equal(parcel[2], ril.aid);
|
||||
};
|
||||
|
||||
ril.iccChangeCardLockPassword({
|
||||
@@ -180,7 +172,6 @@ add_test(function test_icc_unlock_card_lock_pin() {
|
||||
let ril = context.RIL;
|
||||
let buf = context.Buf;
|
||||
ril.aid = "123456789";
|
||||
ril.v5Legacy = false;
|
||||
|
||||
function do_test(aLock, aPassword) {
|
||||
let GECKO_CARDLOCK_TO_REQUEST = {};
|
||||
@@ -196,11 +187,9 @@ add_test(function test_icc_unlock_card_lock_pin() {
|
||||
|
||||
// Data
|
||||
let parcel = this.readStringList();
|
||||
equal(parcel.length, ril.v5Legacy ? 1 : 2);
|
||||
equal(parcel.length, 2);
|
||||
equal(parcel[0], aPassword);
|
||||
if (!ril.v5Legacy) {
|
||||
equal(parcel[1], ril.aid);
|
||||
}
|
||||
equal(parcel[1], ril.aid);
|
||||
};
|
||||
|
||||
ril.iccUnlockCardLock({
|
||||
@@ -224,7 +213,6 @@ add_test(function test_icc_unlock_card_lock_puk() {
|
||||
let ril = context.RIL;
|
||||
let buf = context.Buf;
|
||||
ril.aid = "123456789";
|
||||
ril.v5Legacy = false;
|
||||
|
||||
function do_test(aLock, aPassword, aNewPin) {
|
||||
let GECKO_CARDLOCK_TO_REQUEST = {};
|
||||
@@ -240,12 +228,10 @@ add_test(function test_icc_unlock_card_lock_puk() {
|
||||
|
||||
// Data
|
||||
let parcel = this.readStringList();
|
||||
equal(parcel.length, ril.v5Legacy ? 2 : 3);
|
||||
equal(parcel.length, 3);
|
||||
equal(parcel[0], aPassword);
|
||||
equal(parcel[1], aNewPin);
|
||||
if (!ril.v5Legacy) {
|
||||
equal(parcel[2], ril.aid);
|
||||
}
|
||||
equal(parcel[2], ril.aid);
|
||||
};
|
||||
|
||||
ril.iccUnlockCardLock({
|
||||
|
||||
@@ -352,7 +352,7 @@ add_test(function test_read_icc_contacts() {
|
||||
onsuccess(JSON.parse(JSON.stringify(aTestData.pbrs)));
|
||||
};
|
||||
|
||||
record.readADNLike = function readADNLike(fileId, onsuccess, onerror) {
|
||||
record.readADNLike = function readADNLike(fileId, extFileId, onsuccess, onerror) {
|
||||
onsuccess(JSON.parse(JSON.stringify(aTestData.adnLike)));
|
||||
};
|
||||
|
||||
@@ -398,6 +398,7 @@ add_test(function test_update_icc_contact() {
|
||||
const EMAIL_RECORD_ID = 20;
|
||||
const ANR0_FILE_ID = 0x4f11;
|
||||
const ANR0_RECORD_ID = 30;
|
||||
const EXT_RECORD_ID = 0x01;
|
||||
|
||||
let worker = newUint8Worker();
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
@@ -408,11 +409,11 @@ add_test(function test_update_icc_contact() {
|
||||
function do_test(aSimType, aContactType, aContact, aPin2, aFileType, aHaveIapIndex, aEnhancedPhoneBook) {
|
||||
ril.appType = aSimType;
|
||||
ril._isCdma = (aSimType === CARD_APPTYPE_RUIM);
|
||||
ril.iccInfoPrivate.cst = (aEnhancedPhoneBook) ? [0x20, 0x0C, 0x0, 0x0, 0x0]
|
||||
: [0x20, 0x00, 0x0, 0x0, 0x0];
|
||||
ril.iccInfoPrivate.cst = (aEnhancedPhoneBook) ? [0x20, 0x0C, 0x28, 0x0, 0x20]
|
||||
: [0x20, 0x0, 0x28, 0x0, 0x20];
|
||||
ril.iccInfoPrivate.sst = (aSimType === CARD_APPTYPE_SIM)?
|
||||
[0x20, 0x0, 0x0, 0x0, 0x0]:
|
||||
[0x2, 0x0, 0x0, 0x0, 0x0];
|
||||
[0x20, 0x0, 0x28, 0x0, 0x20]:
|
||||
[0x16, 0x0, 0x0, 0x0, 0x0];
|
||||
|
||||
recordHelper.readPBR = function(onsuccess, onerror) {
|
||||
if (aFileType === ICC_USIM_TYPE1_TAG) {
|
||||
@@ -421,7 +422,9 @@ add_test(function test_update_icc_contact() {
|
||||
email: {fileId: EMAIL_FILE_ID,
|
||||
fileType: ICC_USIM_TYPE1_TAG},
|
||||
anr0: {fileId: ANR0_FILE_ID,
|
||||
fileType: ICC_USIM_TYPE1_TAG}
|
||||
fileType: ICC_USIM_TYPE1_TAG},
|
||||
ext1: {fileId: ICC_EF_EXT1}
|
||||
|
||||
}]);
|
||||
} else if (aFileType === ICC_USIM_TYPE2_TAG) {
|
||||
onsuccess([{
|
||||
@@ -433,23 +436,48 @@ add_test(function test_update_icc_contact() {
|
||||
indexInIAP: 0},
|
||||
anr0: {fileId: ANR0_FILE_ID,
|
||||
fileType: ICC_USIM_TYPE2_TAG,
|
||||
indexInIAP: 1}
|
||||
indexInIAP: 1},
|
||||
ext1: {fileId: ICC_EF_EXT1}
|
||||
}]);
|
||||
}
|
||||
};
|
||||
|
||||
recordHelper.updateADNLike = function(fileId, contact, pin2, onsuccess, onerror) {
|
||||
recordHelper.updateADNLike = function(fileId, extRecordNumber, contact, pin2, onsuccess, onerror) {
|
||||
if (aContactType === GECKO_CARDCONTACT_TYPE_FDN) {
|
||||
equal(fileId, ICC_EF_FDN);
|
||||
} else if (aContactType === GECKO_CARDCONTACT_TYPE_ADN) {
|
||||
equal(fileId, ICC_EF_ADN);
|
||||
}
|
||||
|
||||
if (aContact.number.length > ADN_MAX_NUMBER_DIGITS) {
|
||||
equal(extRecordNumber, EXT_RECORD_ID);
|
||||
} else {
|
||||
equal(extRecordNumber, 0xff);
|
||||
}
|
||||
|
||||
equal(pin2, aPin2);
|
||||
equal(contact.alphaId, aContact.alphaId);
|
||||
equal(contact.number, aContact.number);
|
||||
onsuccess({alphaId: contact.alphaId,
|
||||
number: contact.number.substring(0, ADN_MAX_NUMBER_DIGITS)});
|
||||
};
|
||||
|
||||
recordHelper.getADNLikeExtensionRecordNumber = function(fileId, recordNumber, onsuccess, onerror) {
|
||||
onsuccess(EXT_RECORD_ID);
|
||||
};
|
||||
|
||||
recordHelper.updateExtension = function(fileId, recordNumber, number, onsuccess, onerror) {
|
||||
onsuccess();
|
||||
};
|
||||
|
||||
recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) {
|
||||
onsuccess(EXT_RECORD_ID);
|
||||
};
|
||||
|
||||
recordHelper.cleanEFRecord = function(fileId, recordNumber, onsuccess, onerror) {
|
||||
onsuccess();
|
||||
}
|
||||
|
||||
recordHelper.readIAP = function(fileId, recordNumber, onsuccess, onerror) {
|
||||
equal(fileId, IAP_FILE_ID);
|
||||
equal(recordNumber, ADN_RECORD_ID);
|
||||
@@ -471,7 +499,7 @@ add_test(function test_update_icc_contact() {
|
||||
equal(recordNumber, EMAIL_RECORD_ID);
|
||||
}
|
||||
equal(email, aContact.email);
|
||||
onsuccess();
|
||||
onsuccess(email);
|
||||
};
|
||||
|
||||
recordHelper.updateANR = function(pbr, recordNumber, number, adnRecordId, onsuccess, onerror) {
|
||||
@@ -484,7 +512,7 @@ add_test(function test_update_icc_contact() {
|
||||
if (Array.isArray(aContact.anr)) {
|
||||
equal(number, aContact.anr[0]);
|
||||
}
|
||||
onsuccess();
|
||||
onsuccess(number);
|
||||
};
|
||||
|
||||
recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) {
|
||||
@@ -498,7 +526,25 @@ add_test(function test_update_icc_contact() {
|
||||
};
|
||||
|
||||
let isSuccess = false;
|
||||
let onsuccess = function onsuccess() {
|
||||
let onsuccess = function onsuccess(updatedContact) {
|
||||
equal(ADN_RECORD_ID, updatedContact.recordId);
|
||||
equal(aContact.alphaId, updatedContact.alphaId);
|
||||
equal(aContact.number.substring(0, ADN_MAX_NUMBER_DIGITS + EXT_MAX_NUMBER_DIGITS),
|
||||
updatedContact.number);
|
||||
if ((aSimType == CARD_APPTYPE_USIM || aSimType == CARD_APPTYPE_RUIM) &&
|
||||
(aFileType == ICC_USIM_TYPE1_TAG || aFileType == ICC_USIM_TYPE2_TAG)) {
|
||||
if (aContact.hasOwnProperty('email')) {
|
||||
equal(aContact.email, updatedContact.email);
|
||||
}
|
||||
|
||||
if (aContact.hasOwnProperty('anr')) {
|
||||
equal(aContact.anr[0], updatedContact.anr[0]);
|
||||
}
|
||||
} else {
|
||||
equal(updatedContact.email, null);
|
||||
equal(updatedContact.anr, null);
|
||||
}
|
||||
|
||||
do_print("updateICCContact success");
|
||||
isSuccess = true;
|
||||
};
|
||||
@@ -542,6 +588,22 @@ add_test(function test_update_icc_contact() {
|
||||
alphaId: "test4",
|
||||
number: "123456",
|
||||
anr: ["+654321"]
|
||||
},
|
||||
// a contact number over 20 digits.
|
||||
{
|
||||
pbrIndex: 0,
|
||||
recordId: ADN_RECORD_ID,
|
||||
alphaId: "test4",
|
||||
number: "0123456789012345678901234567890123456789",
|
||||
anr: ["+654321"]
|
||||
},
|
||||
// a contact number over 40 digits.
|
||||
{
|
||||
pbrIndex: 0,
|
||||
recordId: ADN_RECORD_ID,
|
||||
alphaId: "test5",
|
||||
number: "01234567890123456789012345678901234567890123456789",
|
||||
anr: ["+654321"]
|
||||
}];
|
||||
|
||||
for (let i = 0; i < contacts.length; i++) {
|
||||
@@ -589,6 +651,111 @@ add_test(function test_update_icc_contact() {
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify ICCContactHelper.updateICCContact with appType is CARD_APPTYPE_USIM and
|
||||
* insufficient space to store Type 2 USIM contact fields.
|
||||
*/
|
||||
add_test(function test_update_icc_contact_full_email_and_anr_field() {
|
||||
const ADN_RECORD_ID = 100;
|
||||
const ADN_SFI = 1;
|
||||
const IAP_FILE_ID = 0x4f17;
|
||||
const EMAIL_FILE_ID = 0x4f50;
|
||||
const EMAIL_RECORD_ID = 20;
|
||||
const ANR0_FILE_ID = 0x4f11;
|
||||
const ANR0_RECORD_ID = 30;
|
||||
|
||||
let worker = newUint8Worker();
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
let recordHelper = context.ICCRecordHelper;
|
||||
let contactHelper = context.ICCContactHelper;
|
||||
let ril = context.RIL;
|
||||
|
||||
function do_test(aSimType, aContactType, aContact, aPin2) {
|
||||
ril.appType = CARD_APPTYPE_USIM;
|
||||
ril.iccInfoPrivate.sst = [0x2, 0x0, 0x0, 0x0, 0x0];
|
||||
|
||||
recordHelper.readPBR = function(onsuccess, onerror) {
|
||||
onsuccess([{
|
||||
adn: {fileId: ICC_EF_ADN,
|
||||
sfi: ADN_SFI},
|
||||
iap: {fileId: IAP_FILE_ID},
|
||||
email: {fileId: EMAIL_FILE_ID,
|
||||
fileType: ICC_USIM_TYPE2_TAG,
|
||||
indexInIAP: 0},
|
||||
anr0: {fileId: ANR0_FILE_ID,
|
||||
fileType: ICC_USIM_TYPE2_TAG,
|
||||
indexInIAP: 1}
|
||||
}]);
|
||||
};
|
||||
|
||||
recordHelper.updateADNLike = function(fileId, extRecordNumber, contact, pin2, onsuccess, onerror) {
|
||||
if (aContactType === GECKO_CARDCONTACT_TYPE_ADN) {
|
||||
equal(fileId, ICC_EF_ADN);
|
||||
}
|
||||
equal(pin2, aPin2);
|
||||
equal(contact.alphaId, aContact.alphaId);
|
||||
equal(contact.number, aContact.number);
|
||||
onsuccess({alphaId: contact.alphaId,
|
||||
number: contact.number});
|
||||
};
|
||||
|
||||
recordHelper.readIAP = function(fileId, recordNumber, onsuccess, onerror) {
|
||||
equal(fileId, IAP_FILE_ID);
|
||||
equal(recordNumber, ADN_RECORD_ID);
|
||||
onsuccess([0xff, 0xff]);
|
||||
};
|
||||
|
||||
recordHelper.updateIAP = function(fileId, recordNumber, iap, onsuccess, onerror) {
|
||||
equal(fileId, IAP_FILE_ID);
|
||||
equal(recordNumber, ADN_RECORD_ID);
|
||||
onsuccess();
|
||||
};
|
||||
|
||||
recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) {
|
||||
let recordId = 0;
|
||||
// emulate email and anr don't have free record.
|
||||
if (fileId === EMAIL_FILE_ID || fileId === ANR0_FILE_ID) {
|
||||
onerror(CONTACT_ERR_NO_FREE_RECORD_FOUND);
|
||||
} else {
|
||||
onsuccess(recordId);
|
||||
}
|
||||
};
|
||||
|
||||
let isSuccess = false;
|
||||
let onsuccess = function onsuccess(updatedContact) {
|
||||
equal(ADN_RECORD_ID, updatedContact.recordId);
|
||||
equal(aContact.alphaId, updatedContact.alphaId);
|
||||
equal(updatedContact.email, null);
|
||||
equal(updatedContact.anr, null);
|
||||
|
||||
do_print("updateICCContact success");
|
||||
isSuccess = true;
|
||||
};
|
||||
|
||||
let onerror = function onerror(errorMsg) {
|
||||
do_print("updateICCContact failed: " + errorMsg);
|
||||
};
|
||||
|
||||
contactHelper.updateICCContact(aSimType, aContactType, aContact, aPin2, onsuccess, onerror);
|
||||
ok(isSuccess);
|
||||
}
|
||||
|
||||
let contact = {
|
||||
pbrIndex: 0,
|
||||
recordId: ADN_RECORD_ID,
|
||||
alphaId: "test",
|
||||
number: "123456",
|
||||
email: "test@mail.com",
|
||||
anr: ["+654321"]
|
||||
};
|
||||
|
||||
// USIM
|
||||
do_print("Test update USIM adn contacts");
|
||||
do_test(CARD_APPTYPE_USIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify updateICCContact with removal of anr and email with File Type 1.
|
||||
*/
|
||||
@@ -605,8 +772,9 @@ add_test(function test_update_icc_contact_with_remove_type1_attr() {
|
||||
let recordHelper = context.ICCRecordHelper;
|
||||
let contactHelper = context.ICCContactHelper;
|
||||
|
||||
recordHelper.updateADNLike = function(fileId, contact, pin2, onsuccess, onerror) {
|
||||
onsuccess();
|
||||
recordHelper.updateADNLike = function(fileId, extRecordNumber, contact, pin2, onsuccess, onerror) {
|
||||
onsuccess({alphaId: contact.alphaId,
|
||||
number: contact.number});
|
||||
};
|
||||
|
||||
let contact = {
|
||||
@@ -622,12 +790,12 @@ add_test(function test_update_icc_contact_with_remove_type1_attr() {
|
||||
|
||||
recordHelper.updateEmail = function(pbr, recordNumber, email, adnRecordId, onsuccess, onerror) {
|
||||
ok(email == null);
|
||||
onsuccess();
|
||||
onsuccess(email);
|
||||
};
|
||||
|
||||
recordHelper.updateANR = function(pbr, recordNumber, number, adnRecordId, onsuccess, onerror) {
|
||||
ok(number == null);
|
||||
onsuccess();
|
||||
onsuccess(number);
|
||||
};
|
||||
|
||||
function do_test(type) {
|
||||
@@ -652,7 +820,9 @@ add_test(function test_update_icc_contact_with_remove_type1_attr() {
|
||||
}
|
||||
};
|
||||
|
||||
let successCb = function() {
|
||||
let successCb = function(updatedContact) {
|
||||
equal(updatedContact.email, null);
|
||||
equal(updatedContact.anr, null);
|
||||
ok(true);
|
||||
};
|
||||
|
||||
@@ -782,3 +952,91 @@ add_test(function test_find_free_icc_contact_usim() {
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify ICCContactHelper.updateADNLikeWithExtension
|
||||
*/
|
||||
add_test(function test_update_adn_like_with_extension() {
|
||||
let worker = newUint8Worker();
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
let ril = context.RIL;
|
||||
let record = context.ICCRecordHelper;
|
||||
let contactHelper = context.ICCContactHelper;
|
||||
ril.appType = CARD_APPTYPE_SIM;
|
||||
// Correct record Id starts from 1, so put a null element at index 0.
|
||||
// ext_records contains data at index 1, and it only has 1 free record at index 2.
|
||||
let notFree = 0x01;
|
||||
let ext_records = [null, notFree, null];
|
||||
|
||||
function do_test(contact, extRecordNumber, expectedExtRecordNumber, expectedNumber, expectedCleanEFRecord) {
|
||||
// Override some functions to test.
|
||||
record.getADNLikeExtensionRecordNumber = function(fileId, recordNumber, onsuccess, onerror) {
|
||||
onsuccess(extRecordNumber);
|
||||
}
|
||||
|
||||
record.updateADNLike = function(fileId, extRecordNumber, contact, pin2, onsuccess, onerror) {
|
||||
equal(extRecordNumber, expectedExtRecordNumber);
|
||||
onsuccess({alphaId: contact.alphaId,
|
||||
number: contact.number.substring(0, ADN_MAX_NUMBER_DIGITS)});
|
||||
}
|
||||
|
||||
record.updateExtension = function(fileId, recordNumber, number, onsuccess, onerror) {
|
||||
if (recordNumber > ext_records.length) {
|
||||
onerror("updateExtension failed.");
|
||||
return;
|
||||
}
|
||||
ext_records[recordNumber] = number;
|
||||
onsuccess();
|
||||
}
|
||||
|
||||
record.findFreeRecordId = function(fileId, onsuccess, onerror) {
|
||||
for (let i = 1; i < ext_records.length; i++) {
|
||||
if (!ext_records[i]) {
|
||||
onsuccess(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
onerror("No free record found.");
|
||||
}
|
||||
|
||||
let isCleanEFRecord = false;
|
||||
record.cleanEFRecord = function(fileId, recordNumber, onsuccess, onerror) {
|
||||
if (recordNumber > ext_records.length) {
|
||||
onerror("cleanEFRecord failed.");
|
||||
return;
|
||||
}
|
||||
ext_records[recordNumber] = null;
|
||||
isCleanEFRecord = true;
|
||||
onsuccess();
|
||||
}
|
||||
|
||||
let successCb = function successCb(updatedContact) {
|
||||
equal(updatedContact.number, expectedNumber);
|
||||
};
|
||||
|
||||
let errorCb = function errorCb(errorMsg) {
|
||||
do_print("updateADNLikeWithExtension failed, msg = " + errorMsg);
|
||||
ok(false);
|
||||
};
|
||||
|
||||
contactHelper.updateADNLikeWithExtension(ICC_EF_ADN, ICC_EF_EXT1, contact, null, successCb, errorCb);
|
||||
|
||||
if (expectedCleanEFRecord) {
|
||||
ok(isCleanEFRecord);
|
||||
}
|
||||
}
|
||||
|
||||
// Update extension record with previous extension record number.
|
||||
do_test({recordId: 1, alphaId: "test", number: "001122334455667788991234"}, 0x01, 0x01, "001122334455667788991234");
|
||||
// Update extension record and find a free record.
|
||||
do_test({recordId: 1, alphaId: "test", number: "001122334455667788995678"}, 0xff, 0x02, "001122334455667788995678");
|
||||
// Update extension record with no free extension record.
|
||||
do_test({recordId: 1, alphaId: "test", number: "001122334455667788994321"}, 0xff, 0xff, "00112233445566778899");
|
||||
// Update extension record with clean previous extension record.
|
||||
do_test({recordId: 1, alphaId: "test", number: "00112233445566778899"}, 0x01, 0xff, "00112233445566778899", true);
|
||||
// Update extension record with no extension record and previous extension record.
|
||||
do_test({recordId: 1, alphaId: "test", number: "00112233445566778899"}, 0xff, 0xff, "00112233445566778899");
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
@@ -47,6 +47,84 @@ add_test(function test_read_icc_ucs2_string() {
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify ICCPDUHelper#writeICCUCS2String()
|
||||
*/
|
||||
add_test(function test_write_icc_ucs2_string() {
|
||||
let worker = newUint8Worker();
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
let helper = context.GsmPDUHelper;
|
||||
let iccHelper = context.ICCPDUHelper;
|
||||
let alphaLen = 18;
|
||||
let test_data = [
|
||||
{
|
||||
encode: 0x80,
|
||||
// string only contain one character.
|
||||
data: "\u82b3"
|
||||
}, {
|
||||
encode: 0x80,
|
||||
// 2 UCS2 character not located in the same half-page.
|
||||
data: "Fire \u82b3\u8233"
|
||||
}, {
|
||||
encode: 0x80,
|
||||
// 2 UCS2 character not located in the same half-page.
|
||||
data: "\u694a\u704a"
|
||||
}, {
|
||||
encode: 0x81,
|
||||
// 2 UCS2 character within same half-page.
|
||||
data: "Fire \u6901\u697f"
|
||||
}, {
|
||||
encode: 0x81,
|
||||
// 2 UCS2 character within same half-page.
|
||||
data: "Fire \u6980\u69ff"
|
||||
}, {
|
||||
encode: 0x82,
|
||||
// 2 UCS2 character within same half-page, but bit 8 is different.
|
||||
data: "Fire \u0514\u0593"
|
||||
}, {
|
||||
encode: 0x82,
|
||||
// 2 UCS2 character over 0x81 can encode range.
|
||||
data: "Fire \u8000\u8001"
|
||||
}, {
|
||||
encode: 0x82,
|
||||
// 2 UCS2 character over 0x81 can encode range.
|
||||
data: "Fire \ufffd\ufffe"
|
||||
}];
|
||||
|
||||
for (let i = 0; i < test_data.length; i++) {
|
||||
let test = test_data[i];
|
||||
let writtenStr = iccHelper.writeICCUCS2String(alphaLen, test.data);
|
||||
equal(writtenStr, test.data);
|
||||
equal(helper.readHexOctet(), test.encode);
|
||||
equal(iccHelper.readICCUCS2String(test.encode, alphaLen - 1), test.data);
|
||||
}
|
||||
|
||||
// This string use 0x80 encoded and the maximum capacity is 17 octets.
|
||||
// Each alphabet takes 2 octets, thus the first 8 alphabets can be written.
|
||||
let str = "Mozilla \u82b3\u8233 On Fire";
|
||||
let writtenStr = iccHelper.writeICCUCS2String(alphaLen, str);
|
||||
equal(writtenStr, str.substring(0, 8));
|
||||
equal(helper.readHexOctet(), 0x80);
|
||||
equal(iccHelper.readICCUCS2String(0x80, alphaLen - 1), str.substring(0, 8));
|
||||
|
||||
// This string use 0x81 encoded and the maximum capacity is 15 octets.
|
||||
// Each alphabet takes 1 octets, thus the first 15 alphabets can be written.
|
||||
str = "Mozilla \u6901\u697f On Fire";
|
||||
writtenStr = iccHelper.writeICCUCS2String(alphaLen, str);
|
||||
equal(writtenStr, str.substring(0, 15));
|
||||
equal(helper.readHexOctet(), 0x81);
|
||||
equal(iccHelper.readICCUCS2String(0x81, alphaLen - 1), str.substring(0, 15));
|
||||
|
||||
// This string use 0x82 encoded and the maximum capacity is 14 octets.
|
||||
// Each alphabet takes 1 octets, thus the first 14 alphabets can be written.
|
||||
str = "Mozilla \u0514\u0593 On Fire";
|
||||
writtenStr = iccHelper.writeICCUCS2String(alphaLen, str);
|
||||
equal(writtenStr, str.substring(0, 14));
|
||||
equal(helper.readHexOctet(), 0x82);
|
||||
equal(iccHelper.readICCUCS2String(0x82, alphaLen - 1), str.substring(0, 14));
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
/**
|
||||
* Verify ICCPDUHelper#readDiallingNumber
|
||||
*/
|
||||
@@ -154,7 +232,8 @@ add_test(function test_write_string_to_8bit_unpacked() {
|
||||
let str;
|
||||
|
||||
// Test 1, write GSM alphabets.
|
||||
iccHelper.writeStringTo8BitUnpacked(langTable.length + ffLen, langTable);
|
||||
let writtenStr = iccHelper.writeStringTo8BitUnpacked(langTable.length + ffLen, langTable);
|
||||
equal(writtenStr, langTable);
|
||||
|
||||
for (let i = 0; i < langTable.length; i++) {
|
||||
equal(helper.readHexOctet(), i);
|
||||
@@ -166,8 +245,8 @@ add_test(function test_write_string_to_8bit_unpacked() {
|
||||
|
||||
// Test 2, write GSM extended alphabets.
|
||||
str = "\u000c\u20ac";
|
||||
iccHelper.writeStringTo8BitUnpacked(4, str);
|
||||
|
||||
writtenStr = iccHelper.writeStringTo8BitUnpacked(4, str);
|
||||
equal(writtenStr, str);
|
||||
equal(iccHelper.read8BitUnpackedToString(4), str);
|
||||
|
||||
// Test 3, write GSM and GSM extended alphabets.
|
||||
@@ -179,8 +258,8 @@ add_test(function test_write_string_to_8bit_unpacked() {
|
||||
// 1 octet for 1 gsm alphabet,
|
||||
// 2 octes for trailing 0xff.
|
||||
// "Totally 7 octets are to be written."
|
||||
iccHelper.writeStringTo8BitUnpacked(7, str);
|
||||
|
||||
writtenStr = iccHelper.writeStringTo8BitUnpacked(7, str);
|
||||
equal(writtenStr, str);
|
||||
equal(iccHelper.read8BitUnpackedToString(7), str);
|
||||
|
||||
run_next_test();
|
||||
@@ -199,7 +278,8 @@ add_test(function test_write_string_to_8bit_unpacked_with_max_octets_written() {
|
||||
|
||||
// The maximum of the number of octets that can be written is 3.
|
||||
// Only 3 characters shall be written even the length of the string is 4.
|
||||
iccHelper.writeStringTo8BitUnpacked(3, langTable.substring(0, 4));
|
||||
let writtenStr = iccHelper.writeStringTo8BitUnpacked(3, langTable.substring(0, 4));
|
||||
equal(writtenStr, langTable.substring(0, 3));
|
||||
helper.writeHexOctet(0xff); // dummy octet.
|
||||
for (let i = 0; i < 3; i++) {
|
||||
equal(helper.readHexOctet(), i);
|
||||
@@ -209,18 +289,21 @@ add_test(function test_write_string_to_8bit_unpacked_with_max_octets_written() {
|
||||
// \u000c is GSM extended alphabet, 2 octets.
|
||||
// \u00a3 is GSM alphabet, 1 octet.
|
||||
let str = "\u000c\u00a3";
|
||||
iccHelper.writeStringTo8BitUnpacked(3, str);
|
||||
writtenStr = iccHelper.writeStringTo8BitUnpacked(3, str);
|
||||
equal(writtenStr, str.substring(0, 2));
|
||||
equal(iccHelper.read8BitUnpackedToString(3), str);
|
||||
|
||||
str = "\u00a3\u000c";
|
||||
iccHelper.writeStringTo8BitUnpacked(3, str);
|
||||
writtenStr = iccHelper.writeStringTo8BitUnpacked(3, str);
|
||||
equal(writtenStr, str.substring(0, 2));
|
||||
equal(iccHelper.read8BitUnpackedToString(3), str);
|
||||
|
||||
// 2 GSM extended alphabets cost 4 octets, but maximum is 3, so only the 1st
|
||||
// alphabet can be written.
|
||||
str = "\u000c\u000c";
|
||||
iccHelper.writeStringTo8BitUnpacked(3, str);
|
||||
writtenStr = iccHelper.writeStringTo8BitUnpacked(3, str);
|
||||
helper.writeHexOctet(0xff); // dummy octet.
|
||||
equal(writtenStr, str.substring(0, 1));
|
||||
equal(iccHelper.read8BitUnpackedToString(4), str.substring(0, 1));
|
||||
|
||||
run_next_test();
|
||||
@@ -283,36 +366,42 @@ add_test(function test_write_alpha_identifier() {
|
||||
let ffLen = 2;
|
||||
|
||||
// Removal
|
||||
iccHelper.writeAlphaIdentifier(10, null);
|
||||
let writenAlphaId = iccHelper.writeAlphaIdentifier(10, null);
|
||||
equal(writenAlphaId, null);
|
||||
equal(iccHelper.readAlphaIdentifier(10), "");
|
||||
|
||||
// GSM 8 bit
|
||||
let str = "Mozilla";
|
||||
iccHelper.writeAlphaIdentifier(str.length + ffLen, str);
|
||||
writenAlphaId = iccHelper.writeAlphaIdentifier(str.length + ffLen, str);
|
||||
equal(writenAlphaId , str);
|
||||
equal(iccHelper.readAlphaIdentifier(str.length + ffLen), str);
|
||||
|
||||
// UCS2
|
||||
str = "Mozilla\u694a";
|
||||
iccHelper.writeAlphaIdentifier(str.length * 2 + ffLen, str);
|
||||
str = "Mozilla\u8000";
|
||||
writenAlphaId = iccHelper.writeAlphaIdentifier(str.length * 2 + ffLen, str);
|
||||
equal(writenAlphaId , str);
|
||||
// * 2 for each character will be encoded to UCS2 alphabets.
|
||||
equal(iccHelper.readAlphaIdentifier(str.length * 2 + ffLen), str);
|
||||
|
||||
// Test with maximum octets written.
|
||||
// 1 coding scheme (0x80) and 1 UCS2 character, total 3 octets.
|
||||
str = "\u694a";
|
||||
iccHelper.writeAlphaIdentifier(3, str);
|
||||
writenAlphaId = iccHelper.writeAlphaIdentifier(3, str);
|
||||
equal(writenAlphaId , str);
|
||||
equal(iccHelper.readAlphaIdentifier(3), str);
|
||||
|
||||
// 1 coding scheme (0x80) and 2 UCS2 characters, total 5 octets.
|
||||
// numOctets is limited to 4, so only 1 UCS2 character can be written.
|
||||
str = "\u694a\u694a";
|
||||
iccHelper.writeAlphaIdentifier(4, str);
|
||||
str = "\u694a\u69ca";
|
||||
writenAlphaId = iccHelper.writeAlphaIdentifier(4, str);
|
||||
helper.writeHexOctet(0xff); // dummy octet.
|
||||
equal(writenAlphaId , str.substring(0, 1));
|
||||
equal(iccHelper.readAlphaIdentifier(5), str.substring(0, 1));
|
||||
|
||||
// Write 0 octet.
|
||||
iccHelper.writeAlphaIdentifier(0, "1");
|
||||
writenAlphaId = iccHelper.writeAlphaIdentifier(0, "1");
|
||||
helper.writeHexOctet(0xff); // dummy octet.
|
||||
equal(writenAlphaId, null);
|
||||
equal(iccHelper.readAlphaIdentifier(1), "");
|
||||
|
||||
run_next_test();
|
||||
@@ -373,28 +462,36 @@ add_test(function test_write_alpha_id_dialling_number() {
|
||||
alphaId: "Mozilla",
|
||||
number: "1234567890"
|
||||
};
|
||||
helper.writeAlphaIdDiallingNumber(recordSize, contactW.alphaId,
|
||||
contactW.number);
|
||||
|
||||
let writtenContact = helper.writeAlphaIdDiallingNumber(recordSize,
|
||||
contactW.alphaId,
|
||||
contactW.number, 0xff);
|
||||
|
||||
let contactR = helper.readAlphaIdDiallingNumber(recordSize);
|
||||
equal(contactW.alphaId, contactR.alphaId);
|
||||
equal(contactW.number, contactR.number);
|
||||
equal(writtenContact.alphaId, contactR.alphaId);
|
||||
equal(writtenContact.number, contactR.number);
|
||||
equal(0xff, contactR.extRecordNumber);
|
||||
|
||||
// Write a contact with alphaId encoded in UCS2 and number has '+'.
|
||||
let contactUCS2 = {
|
||||
alphaId: "火狐",
|
||||
number: "+1234567890"
|
||||
};
|
||||
helper.writeAlphaIdDiallingNumber(recordSize, contactUCS2.alphaId,
|
||||
contactUCS2.number);
|
||||
|
||||
writtenContact = helper.writeAlphaIdDiallingNumber(recordSize,
|
||||
contactUCS2.alphaId,
|
||||
contactUCS2.number, 0xff);
|
||||
contactR = helper.readAlphaIdDiallingNumber(recordSize);
|
||||
equal(contactUCS2.alphaId, contactR.alphaId);
|
||||
equal(contactUCS2.number, contactR.number);
|
||||
equal(writtenContact.alphaId, contactR.alphaId);
|
||||
equal(writtenContact.number, contactR.number);
|
||||
equal(0xff, contactR.extRecordNumber);
|
||||
|
||||
// Write a null contact (Removal).
|
||||
helper.writeAlphaIdDiallingNumber(recordSize);
|
||||
writtenContact = helper.writeAlphaIdDiallingNumber(recordSize);
|
||||
contactR = helper.readAlphaIdDiallingNumber(recordSize);
|
||||
equal(contactR, null);
|
||||
equal(writtenContact.alphaId, null);
|
||||
equal(writtenContact.number, null);
|
||||
|
||||
// Write a longer alphaId/dialling number
|
||||
// Dialling Number : Maximum 20 digits(10 octets).
|
||||
@@ -405,19 +502,24 @@ add_test(function test_write_alpha_id_dialling_number() {
|
||||
alphaId: "AAAAAAAAABBBBBBBBBCCCCCCCCC",
|
||||
number: "123456789012345678901234567890",
|
||||
};
|
||||
helper.writeAlphaIdDiallingNumber(recordSize, longContact.alphaId,
|
||||
longContact.number);
|
||||
|
||||
writtenContact = helper.writeAlphaIdDiallingNumber(recordSize,
|
||||
longContact.alphaId,
|
||||
longContact.number, 0xff);
|
||||
contactR = helper.readAlphaIdDiallingNumber(recordSize);
|
||||
equal(contactR.alphaId, "AAAAAAAAABBBBBBBBB");
|
||||
equal(contactR.number, "12345678901234567890");
|
||||
equal(writtenContact.alphaId, contactR.alphaId);
|
||||
equal(writtenContact.number, contactR.number);
|
||||
equal(0xff, contactR.extRecordNumber);
|
||||
|
||||
// Add '+' to number and test again.
|
||||
longContact.number = "+123456789012345678901234567890";
|
||||
helper.writeAlphaIdDiallingNumber(recordSize, longContact.alphaId,
|
||||
longContact.number);
|
||||
writtenContact = helper.writeAlphaIdDiallingNumber(recordSize,
|
||||
longContact.alphaId,
|
||||
longContact.number, 0xff);
|
||||
contactR = helper.readAlphaIdDiallingNumber(recordSize);
|
||||
equal(contactR.alphaId, "AAAAAAAAABBBBBBBBB");
|
||||
equal(contactR.number, "+12345678901234567890");
|
||||
equal(writtenContact.alphaId, contactR.alphaId);
|
||||
equal(writtenContact.number, contactR.number);
|
||||
equal(0xff, contactR.extRecordNumber);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
@@ -511,7 +613,8 @@ add_test(function test_write_number_with_length() {
|
||||
|
||||
function test(number, expectedNumber) {
|
||||
expectedNumber = expectedNumber || number;
|
||||
iccHelper.writeNumberWithLength(number);
|
||||
let writeNumber = iccHelper.writeNumberWithLength(number);
|
||||
equal(writeNumber, expectedNumber);
|
||||
let numLen = helper.readHexOctet();
|
||||
equal(expectedNumber, iccHelper.readDiallingNumber(numLen));
|
||||
for (let i = 0; i < (ADN_MAX_BCD_NUMBER_BYTES - numLen); i++) {
|
||||
@@ -536,6 +639,9 @@ add_test(function test_write_number_with_length() {
|
||||
|
||||
test("++(01)2*3-4#5,6+7(8)9*0#1,", "+012*34#5,6789*0#1,");
|
||||
|
||||
// over maximum 20 digits should be truncated.
|
||||
test("012345678901234567890123456789", "01234567890123456789");
|
||||
|
||||
// null
|
||||
iccHelper.writeNumberWithLength(null);
|
||||
for (let i = 0; i < (ADN_MAX_BCD_NUMBER_BYTES + 1); i++) {
|
||||
|
||||
@@ -204,10 +204,8 @@ add_test(function test_update_email() {
|
||||
// pin2.
|
||||
equal(this.readString(), null);
|
||||
|
||||
if (!ril.v5Legacy) {
|
||||
// AID. Ignore because it's from modem.
|
||||
this.readInt32();
|
||||
}
|
||||
// AID. Ignore because it's from modem.
|
||||
this.readInt32();
|
||||
|
||||
if (count == NUM_TESTS) {
|
||||
run_next_test();
|
||||
@@ -350,10 +348,8 @@ add_test(function test_update_anr() {
|
||||
// pin2.
|
||||
equal(this.readString(), null);
|
||||
|
||||
if (!ril.v5Legacy) {
|
||||
// AID. Ignore because it's from modem.
|
||||
this.readInt32();
|
||||
}
|
||||
// AID. Ignore because it's from modem.
|
||||
this.readInt32();
|
||||
|
||||
if (count == NUM_TESTS) {
|
||||
run_next_test();
|
||||
@@ -487,10 +483,8 @@ add_test(function test_update_iap() {
|
||||
// pin2.
|
||||
equal(this.readString(), null);
|
||||
|
||||
if (!ril.v5Legacy) {
|
||||
// AID. Ignore because it's from modem.
|
||||
this.readInt32();
|
||||
}
|
||||
// AID. Ignore because it's from modem.
|
||||
this.readInt32();
|
||||
|
||||
run_next_test();
|
||||
};
|
||||
@@ -500,6 +494,74 @@ add_test(function test_update_iap() {
|
||||
do_test([1, 2]);
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify ICCRecordHelper.readADNLike.
|
||||
*/
|
||||
add_test(function test_read_adn_like() {
|
||||
const RECORD_SIZE = 0x20;
|
||||
|
||||
let worker = newUint8Worker();
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
let helper = context.GsmPDUHelper;
|
||||
let record = context.ICCRecordHelper;
|
||||
let buf = context.Buf;
|
||||
let io = context.ICCIOHelper;
|
||||
let ril = context.RIL;
|
||||
|
||||
function do_test(extFileId, rawEF, expectedExtRecordNumber, expectedNumber) {
|
||||
io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
|
||||
// Write data size
|
||||
buf.writeInt32(rawEF.length * 2);
|
||||
|
||||
// Write adn
|
||||
for (let i = 0; i < rawEF.length; i += 2) {
|
||||
helper.writeHexOctet(parseInt(rawEF.substr(i, 2), 16));
|
||||
}
|
||||
|
||||
// Write string delimiter
|
||||
buf.writeStringDelimiter(rawEF.length * 2);
|
||||
|
||||
options.p1 = 1;
|
||||
options.recordSize = RECORD_SIZE;
|
||||
options.totalRecords = 1;
|
||||
if (options.callback) {
|
||||
options.callback(options);
|
||||
}
|
||||
};
|
||||
|
||||
record.readExtension = function(fileId, recordNumber, onsuccess, onerror) {
|
||||
onsuccess("1234");
|
||||
}
|
||||
|
||||
let successCb = function successCb(contacts) {
|
||||
ok(contacts[0].number == expectedNumber);
|
||||
};
|
||||
|
||||
let errorCb = function errorCb(errorMsg) {
|
||||
do_print("Reading ADNLike failed, msg = " + errorMsg);
|
||||
ok(false);
|
||||
};
|
||||
|
||||
record.readADNLike(ICC_EF_ADN, extFileId, successCb, errorCb);
|
||||
}
|
||||
|
||||
ril.appType = CARD_APPTYPE_SIM;
|
||||
// Valid extension
|
||||
do_test(ICC_EF_EXT1,"436f6e74616374303031ffffffffffffffff0b8199887766554433221100ff01",
|
||||
0x01,"998877665544332211001234");
|
||||
// Empty extension
|
||||
do_test(ICC_EF_EXT1,"436f6e74616374303031ffffffffffffffff0b8199887766554433221100ffff",
|
||||
0xff, "99887766554433221100");
|
||||
// Unsupport extension
|
||||
do_test(null,"436f6e74616374303031ffffffffffffffff0b8199887766554433221100ffff",
|
||||
0xff, "99887766554433221100");
|
||||
// Empty dialling number contact
|
||||
do_test(null,"436f6e74616374303031ffffffffffffffffffffffffffffffffffffffffffff",
|
||||
0xff, "");
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify ICCRecordHelper.updateADNLike.
|
||||
*/
|
||||
@@ -555,6 +617,7 @@ add_test(function test_update_adn_like() {
|
||||
let contact = pdu.readAlphaIdDiallingNumber(0x20);
|
||||
equal(contact.alphaId, "test");
|
||||
equal(contact.number, "123456");
|
||||
equal(contact.extRecordNumber, "0xff");
|
||||
|
||||
// pin2.
|
||||
if (fileId == ICC_EF_ADN) {
|
||||
@@ -563,10 +626,8 @@ add_test(function test_update_adn_like() {
|
||||
equal(this.readString(), "1111");
|
||||
}
|
||||
|
||||
if (!ril.v5Legacy) {
|
||||
// AID. Ignore because it's from modem.
|
||||
this.readInt32();
|
||||
}
|
||||
// AID. Ignore because it's from modem.
|
||||
this.readInt32();
|
||||
|
||||
if (fileId == ICC_EF_FDN) {
|
||||
run_next_test();
|
||||
@@ -574,11 +635,11 @@ add_test(function test_update_adn_like() {
|
||||
};
|
||||
|
||||
fileId = ICC_EF_ADN;
|
||||
record.updateADNLike(fileId,
|
||||
record.updateADNLike(fileId, 0xff,
|
||||
{recordId: 1, alphaId: "test", number: "123456"});
|
||||
|
||||
fileId = ICC_EF_FDN;
|
||||
record.updateADNLike(fileId,
|
||||
record.updateADNLike(fileId, 0xff,
|
||||
{recordId: 1, alphaId: "test", number: "123456"},
|
||||
"1111");
|
||||
});
|
||||
@@ -729,3 +790,291 @@ add_test(function test_handling_iccid() {
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify ICCRecordHelper.readExtension
|
||||
*/
|
||||
add_test(function test_read_extension() {
|
||||
let worker = newUint8Worker();
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
let helper = context.GsmPDUHelper;
|
||||
let record = context.ICCRecordHelper;
|
||||
let buf = context.Buf;
|
||||
let io = context.ICCIOHelper;
|
||||
|
||||
function do_test(rawExtension, expectedExtensionNumber) {
|
||||
io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
|
||||
// Write data size
|
||||
buf.writeInt32(rawExtension.length * 2);
|
||||
|
||||
// Write ext
|
||||
for (let i = 0; i < rawExtension.length; i += 2) {
|
||||
helper.writeHexOctet(parseInt(rawExtension.substr(i, 2), 16));
|
||||
}
|
||||
|
||||
// Write string delimiter
|
||||
buf.writeStringDelimiter(rawExtension.length);
|
||||
|
||||
if (options.callback) {
|
||||
options.callback(options);
|
||||
}
|
||||
};
|
||||
|
||||
let successCb = function successCb(number) {
|
||||
do_print("extension number:" + number);
|
||||
equal(number, expectedExtensionNumber);
|
||||
};
|
||||
|
||||
let errorCb = function errorCb() {
|
||||
ok(expectedExtensionNumber == null);
|
||||
};
|
||||
|
||||
record.readExtension(0x6f4a, 1, successCb, errorCb);
|
||||
}
|
||||
|
||||
// Test unsupported record type 0x01
|
||||
do_test("010a10325476981032547698ff", "");
|
||||
// Test invalid length 0xc1
|
||||
do_test("020c10325476981032547698ff", null);
|
||||
// Test extension chain which we don't support
|
||||
do_test("020a1032547698103254769802", "01234567890123456789");
|
||||
// Test valid Extension
|
||||
do_test("020a10325476981032547698ff", "01234567890123456789");
|
||||
// Test valid Extension
|
||||
do_test("0209103254769810325476ffff", "012345678901234567");
|
||||
// Test empty Extension
|
||||
do_test("02ffffffffffffffffffffffff", "");
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify ICCRecordHelper.updateExtension
|
||||
*/
|
||||
add_test(function test_update_extension() {
|
||||
const RECORD_SIZE = 13;
|
||||
const RECORD_NUMBER = 1;
|
||||
|
||||
let worker = newUint8Worker();
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
let pduHelper = context.GsmPDUHelper;
|
||||
let ril = context.RIL;
|
||||
let recordHelper = context.ICCRecordHelper;
|
||||
let buf = context.Buf;
|
||||
let ioHelper = context.ICCIOHelper;
|
||||
|
||||
// Override.
|
||||
ioHelper.updateLinearFixedEF = function(options) {
|
||||
options.pathId = context.ICCFileHelper.getEFPath(options.fileId);
|
||||
options.command = ICC_COMMAND_UPDATE_RECORD;
|
||||
options.p1 = options.recordNumber;
|
||||
options.p2 = READ_RECORD_ABSOLUTE_MODE;
|
||||
options.p3 = RECORD_SIZE;
|
||||
ril.iccIO(options);
|
||||
};
|
||||
|
||||
function do_test(fileId, number, expectedNumber) {
|
||||
buf.sendParcel = function() {
|
||||
// Request Type.
|
||||
equal(this.readInt32(), REQUEST_SIM_IO);
|
||||
|
||||
// Token : we don't care
|
||||
this.readInt32();
|
||||
|
||||
// command.
|
||||
equal(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
|
||||
|
||||
// fileId.
|
||||
equal(this.readInt32(), fileId);
|
||||
|
||||
// pathId.
|
||||
if (ril.appType == CARD_APPTYPE_SIM || ril.appType == CARD_APPTYPE_RUIM) {
|
||||
equal(this.readString(),
|
||||
EF_PATH_MF_SIM + EF_PATH_DF_TELECOM);
|
||||
} else{
|
||||
equal(this.readString(),
|
||||
EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK);
|
||||
}
|
||||
|
||||
// p1.
|
||||
equal(this.readInt32(), RECORD_NUMBER);
|
||||
|
||||
// p2.
|
||||
equal(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
|
||||
|
||||
// p3.
|
||||
equal(this.readInt32(), RECORD_SIZE);
|
||||
|
||||
// data.
|
||||
let strLen = this.readInt32();
|
||||
// Extension record
|
||||
let recordType = pduHelper.readHexOctet();
|
||||
|
||||
equal(recordType, 0x02);
|
||||
equal(pduHelper.readHexOctet(), 10);
|
||||
equal(
|
||||
pduHelper.readSwappedNibbleExtendedBcdString(EXT_MAX_NUMBER_DIGITS - 1),
|
||||
expectedNumber);
|
||||
|
||||
this.readStringDelimiter(strLen);
|
||||
|
||||
// pin2.
|
||||
equal(this.readString(), null);
|
||||
|
||||
// AID. Ignore because it's from modem.
|
||||
this.readInt32();
|
||||
};
|
||||
|
||||
recordHelper.updateExtension(fileId, RECORD_NUMBER, number);
|
||||
}
|
||||
|
||||
ril.appType = CARD_APPTYPE_SIM;
|
||||
do_test(ICC_EF_EXT1, "01234567890123456789", "01234567890123456789");
|
||||
// We don't support extension chain.
|
||||
do_test(ICC_EF_EXT1, "012345678901234567891234", "01234567890123456789");
|
||||
|
||||
ril.appType = CARD_APPTYPE_USIM;
|
||||
do_test(ICC_EF_EXT1, "01234567890123456789", "01234567890123456789");
|
||||
|
||||
ril.appType = CARD_APPTYPE_RUIM;
|
||||
do_test(ICC_EF_EXT1, "01234567890123456789", "01234567890123456789");
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify ICCRecordHelper.cleanEFRecord
|
||||
*/
|
||||
add_test(function test_clean_ef_record() {
|
||||
const RECORD_SIZE = 13;
|
||||
const RECORD_NUMBER = 1;
|
||||
|
||||
let worker = newUint8Worker();
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
let pduHelper = context.GsmPDUHelper;
|
||||
let ril = context.RIL;
|
||||
let recordHelper = context.ICCRecordHelper;
|
||||
let buf = context.Buf;
|
||||
let ioHelper = context.ICCIOHelper;
|
||||
|
||||
// Override.
|
||||
ioHelper.updateLinearFixedEF = function(options) {
|
||||
options.pathId = context.ICCFileHelper.getEFPath(options.fileId);
|
||||
options.command = ICC_COMMAND_UPDATE_RECORD;
|
||||
options.p1 = options.recordNumber;
|
||||
options.p2 = READ_RECORD_ABSOLUTE_MODE;
|
||||
options.p3 = RECORD_SIZE;
|
||||
ril.iccIO(options);
|
||||
};
|
||||
|
||||
function do_test(fileId) {
|
||||
buf.sendParcel = function() {
|
||||
// Request Type.
|
||||
equal(this.readInt32(), REQUEST_SIM_IO);
|
||||
|
||||
// Token : we don't care
|
||||
this.readInt32();
|
||||
|
||||
// command.
|
||||
equal(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
|
||||
|
||||
// fileId.
|
||||
equal(this.readInt32(), fileId);
|
||||
|
||||
// pathId.
|
||||
if (ril.appType == CARD_APPTYPE_SIM || ril.appType == CARD_APPTYPE_RUIM) {
|
||||
equal(this.readString(),
|
||||
EF_PATH_MF_SIM + EF_PATH_DF_TELECOM);
|
||||
} else{
|
||||
equal(this.readString(),
|
||||
EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK);
|
||||
}
|
||||
|
||||
// p1.
|
||||
equal(this.readInt32(), RECORD_NUMBER);
|
||||
|
||||
// p2.
|
||||
equal(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
|
||||
|
||||
// p3.
|
||||
equal(this.readInt32(), RECORD_SIZE);
|
||||
|
||||
// data.
|
||||
let strLen = this.readInt32();
|
||||
// Extension record
|
||||
for (let i = 0; i < RECORD_SIZE; i++) {
|
||||
equal(pduHelper.readHexOctet(), 0xff);
|
||||
}
|
||||
|
||||
this.readStringDelimiter(strLen);
|
||||
|
||||
// pin2.
|
||||
equal(this.readString(), null);
|
||||
|
||||
// AID. Ignore because it's from modem.
|
||||
this.readInt32();
|
||||
};
|
||||
|
||||
recordHelper.cleanEFRecord(fileId, RECORD_NUMBER);
|
||||
}
|
||||
|
||||
ril.appType = CARD_APPTYPE_SIM;
|
||||
do_test(ICC_EF_EXT1);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify ICCRecordHelper.getADNLikeExtensionRecordNumber
|
||||
*/
|
||||
add_test(function test_get_adn_like_extension_record_number() {
|
||||
const RECORD_SIZE = 0x20;
|
||||
|
||||
let worker = newUint8Worker();
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
let helper = context.GsmPDUHelper;
|
||||
let record = context.ICCRecordHelper;
|
||||
let buf = context.Buf;
|
||||
let io = context.ICCIOHelper;
|
||||
|
||||
function do_test(rawEF, expectedRecordNumber) {
|
||||
io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
|
||||
// Write data size
|
||||
buf.writeInt32(rawEF.length * 2);
|
||||
|
||||
// Write ext
|
||||
for (let i = 0; i < rawEF.length; i += 2) {
|
||||
helper.writeHexOctet(parseInt(rawEF.substr(i, 2), 16));
|
||||
}
|
||||
|
||||
// Write string delimiter
|
||||
buf.writeStringDelimiter(rawEF.length);
|
||||
options.recordSize = RECORD_SIZE;
|
||||
if (options.callback) {
|
||||
options.callback(options);
|
||||
}
|
||||
};
|
||||
|
||||
let isSuccess = false;
|
||||
let successCb = function successCb(number) {
|
||||
equal(number, expectedRecordNumber);
|
||||
isSuccess = true;
|
||||
};
|
||||
|
||||
let errorCb = function errorCb(errorMsg) {
|
||||
do_print("Reading ADNLike failed, msg = " + errorMsg);
|
||||
ok(false);
|
||||
};
|
||||
|
||||
record.getADNLikeExtensionRecordNumber(ICC_EF_ADN, 1, successCb, errorCb);
|
||||
ok(isSuccess);
|
||||
}
|
||||
|
||||
// Valid Extension, Alpha Id(Encoded with GSM 8 bit): "Contact001",
|
||||
// Dialling Number: 99887766554433221100, Ext1: 0x01
|
||||
do_test("436f6e74616374303031ffffffffffffffff0b8199887766554433221100ff01", 0x01);
|
||||
// Empty Extension, Alpha Id(Encoded with GSM 8 bit): "Contact001", Ext1: 0xff
|
||||
do_test("436f6e74616374303031ffffffffffffffffffffffffffffffffffffffffffff", 0xff);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
@@ -355,10 +355,8 @@ add_test(function test_update_mwis() {
|
||||
// pin2.
|
||||
equal(this.readString(), null);
|
||||
|
||||
if (!ril.v5Legacy) {
|
||||
// AID. Ignore because it's from modem.
|
||||
this.readInt32();
|
||||
}
|
||||
// AID. Ignore because it's from modem.
|
||||
this.readInt32();
|
||||
};
|
||||
|
||||
ok(!isUpdated);
|
||||
|
||||
@@ -1,525 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function createMMIOptions(procedure, serviceCode, sia, sib, sic) {
|
||||
let mmi = {
|
||||
fullMMI: Array.slice(arguments).join("*") + "#",
|
||||
procedure: procedure,
|
||||
serviceCode: serviceCode,
|
||||
sia: sia,
|
||||
sib: sib,
|
||||
sic: sic
|
||||
};
|
||||
|
||||
return mmi;
|
||||
}
|
||||
|
||||
function testSendMMI(mmi, error) {
|
||||
let workerhelper = newInterceptWorker();
|
||||
let worker = workerhelper.worker;
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
|
||||
do_print("worker.postMessage " + worker.postMessage);
|
||||
|
||||
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
|
||||
context.RIL.sendMMI({rilMessageType: "sendMMI", mmi: mmi});
|
||||
|
||||
let postedMessage = workerhelper.postedMessage;
|
||||
|
||||
equal(postedMessage.rilMessageType, "sendMMI");
|
||||
equal(postedMessage.errorMsg, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* sendMMI tests.
|
||||
*/
|
||||
|
||||
add_test(function test_sendMMI_null() {
|
||||
testSendMMI(null, MMI_ERROR_KS_ERROR);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_short_code() {
|
||||
let workerhelper = newInterceptWorker();
|
||||
let worker = workerhelper.worker;
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
|
||||
let ussdOptions;
|
||||
|
||||
context.RIL.sendUSSD = function fakeSendUSSD(options){
|
||||
ussdOptions = options;
|
||||
context.RIL[REQUEST_SEND_USSD](0, {});
|
||||
};
|
||||
|
||||
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
|
||||
context.RIL.sendMMI({mmi: {fullMMI: "**"}});
|
||||
|
||||
let postedMessage = workerhelper.postedMessage;
|
||||
equal(ussdOptions.ussd, "**");
|
||||
equal (postedMessage.errorMsg, GECKO_ERROR_SUCCESS);
|
||||
ok(postedMessage.success);
|
||||
ok(context.RIL._ussdSession);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_change_PIN() {
|
||||
let workerhelper = newInterceptWorker();
|
||||
let worker = workerhelper.worker;
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
|
||||
context.RIL.changeICCPIN = function fakeChangeICCPIN(options) {
|
||||
context.RIL[REQUEST_ENTER_SIM_PIN](0, {});
|
||||
};
|
||||
|
||||
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
|
||||
context.RIL.sendMMI({mmi: createMMIOptions("**", "04", "1234", "4567",
|
||||
"4567")});
|
||||
|
||||
let postedMessage = workerhelper.postedMessage;
|
||||
|
||||
equal (postedMessage.errorMsg, GECKO_ERROR_SUCCESS);
|
||||
ok(postedMessage.success);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_change_PIN_no_new_PIN() {
|
||||
testSendMMI(createMMIOptions("**", "04", "1234", "", "4567"),
|
||||
MMI_ERROR_KS_ERROR);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_change_PIN_no_old_PIN() {
|
||||
testSendMMI(createMMIOptions("**", "04", "", "1234", "4567"),
|
||||
MMI_ERROR_KS_ERROR);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_change_PIN_wrong_procedure() {
|
||||
testSendMMI(createMMIOptions("*", "04", "1234", "4567", "4567"),
|
||||
MMI_ERROR_KS_INVALID_ACTION);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_change_PIN_new_PIN_mismatch() {
|
||||
testSendMMI(createMMIOptions("**", "04", "4567", "1234", "4567"),
|
||||
MMI_ERROR_KS_MISMATCH_PIN);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_change_PIN2() {
|
||||
let workerhelper = newInterceptWorker();
|
||||
let worker = workerhelper.worker;
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
|
||||
context.RIL.changeICCPIN2 = function fakeChangeICCPIN2(options) {
|
||||
context.RIL[REQUEST_ENTER_SIM_PIN2](0, {});
|
||||
};
|
||||
|
||||
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
|
||||
context.RIL.sendMMI({mmi: createMMIOptions("**", "042", "1234", "4567",
|
||||
"4567")});
|
||||
|
||||
let postedMessage = workerhelper.postedMessage;
|
||||
|
||||
equal (postedMessage.errorMsg, GECKO_ERROR_SUCCESS);
|
||||
ok(postedMessage.success);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_change_PIN2_no_new_PIN2() {
|
||||
testSendMMI(createMMIOptions("**", "042", "1234", "", "4567"),
|
||||
MMI_ERROR_KS_ERROR);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_change_PIN2_no_old_PIN2() {
|
||||
testSendMMI(createMMIOptions("**", "042", "", "1234", "4567"),
|
||||
MMI_ERROR_KS_ERROR);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_change_PIN2_wrong_procedure() {
|
||||
testSendMMI(createMMIOptions("*", "042", "1234", "4567", "4567"),
|
||||
MMI_ERROR_KS_INVALID_ACTION);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_change_PIN2_new_PIN2_mismatch() {
|
||||
testSendMMI(createMMIOptions("**", "042", "4567", "1234", "4567"),
|
||||
MMI_ERROR_KS_MISMATCH_PIN);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_unblock_PIN() {
|
||||
let workerhelper = newInterceptWorker();
|
||||
let worker = workerhelper.worker;
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
|
||||
context.RIL.enterICCPUK = function fakeEnterICCPUK(options) {
|
||||
context.RIL[REQUEST_ENTER_SIM_PUK](0, {});
|
||||
};
|
||||
|
||||
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
|
||||
context.RIL.sendMMI({mmi: createMMIOptions("**", "05", "1234", "4567",
|
||||
"4567")});
|
||||
|
||||
let postedMessage = workerhelper.postedMessage;
|
||||
|
||||
equal (postedMessage.errorMsg, GECKO_ERROR_SUCCESS);
|
||||
ok(postedMessage.success);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_unblock_PIN_no_new_PIN() {
|
||||
testSendMMI(createMMIOptions("**", "05", "1234", "", "4567"),
|
||||
MMI_ERROR_KS_ERROR);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_unblock_PIN_no_PUK() {
|
||||
testSendMMI(createMMIOptions("**", "05", "", "1234", "4567"),
|
||||
MMI_ERROR_KS_ERROR);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_unblock_PIN_wrong_procedure() {
|
||||
testSendMMI(createMMIOptions("*", "05", "1234", "4567", "4567"),
|
||||
MMI_ERROR_KS_INVALID_ACTION);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_unblock_PIN_new_PIN_mismatch() {
|
||||
testSendMMI(createMMIOptions("**", "05", "4567", "1234", "4567"),
|
||||
MMI_ERROR_KS_MISMATCH_PIN);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_unblock_PIN2() {
|
||||
let workerhelper = newInterceptWorker();
|
||||
let worker = workerhelper.worker;
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
|
||||
context.RIL.enterICCPUK2 = function fakeEnterICCPUK2(options) {
|
||||
context.RIL[REQUEST_ENTER_SIM_PUK2](0, {});
|
||||
};
|
||||
|
||||
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
|
||||
context.RIL.sendMMI({mmi: createMMIOptions("**", "052", "1234", "4567",
|
||||
"4567")});
|
||||
|
||||
let postedMessage = workerhelper.postedMessage;
|
||||
|
||||
equal (postedMessage.errorMsg, GECKO_ERROR_SUCCESS);
|
||||
ok(postedMessage.success);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_unblock_PIN2_no_new_PIN2() {
|
||||
testSendMMI(createMMIOptions("**", "052", "1234", "", "4567"),
|
||||
MMI_ERROR_KS_ERROR);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_unblock_PIN2_no_PUK2() {
|
||||
testSendMMI(createMMIOptions("**", "052", "", "1234", "4567"),
|
||||
MMI_ERROR_KS_ERROR);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_unblock_PIN2_wrong_procedure() {
|
||||
testSendMMI(createMMIOptions("*", "052", "1234", "4567", "4567"),
|
||||
MMI_ERROR_KS_INVALID_ACTION);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_unblock_PIN2_new_PIN_mismatch() {
|
||||
testSendMMI(createMMIOptions("**", "052", "4567", "1234", "4567"),
|
||||
MMI_ERROR_KS_MISMATCH_PIN);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_get_IMEI() {
|
||||
let workerhelper = newInterceptWorker();
|
||||
let worker = workerhelper.worker;
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
let mmiOptions;
|
||||
|
||||
context.RIL.getIMEI = function getIMEI(options) {
|
||||
mmiOptions = options;
|
||||
context.RIL[REQUEST_SEND_USSD](0, {});
|
||||
};
|
||||
|
||||
context.RIL.sendMMI({mmi: createMMIOptions("*#", "06")});
|
||||
|
||||
let postedMessage = workerhelper.postedMessage;
|
||||
|
||||
notEqual(mmiOptions.mmi, null);
|
||||
equal (postedMessage.errorMsg, GECKO_ERROR_SUCCESS);
|
||||
ok(postedMessage.success);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_get_IMEI_error() {
|
||||
let workerhelper = newInterceptWorker();
|
||||
let worker = workerhelper.worker;
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
let mmiOptions;
|
||||
|
||||
context.RIL.getIMEI = function getIMEI(options){
|
||||
mmiOptions = options;
|
||||
context.RIL[REQUEST_SEND_USSD](0, {
|
||||
errorMsg: GECKO_ERROR_RADIO_NOT_AVAILABLE
|
||||
});
|
||||
};
|
||||
|
||||
context.RIL.sendMMI({mmi: createMMIOptions("*#", "06")});
|
||||
|
||||
let postedMessage = workerhelper.postedMessage;
|
||||
|
||||
notEqual(mmiOptions.mmi, null);
|
||||
equal (postedMessage.errorMsg, GECKO_ERROR_RADIO_NOT_AVAILABLE);
|
||||
ok(!postedMessage.success);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_call_barring_BAIC_interrogation_voice() {
|
||||
let workerhelper = newInterceptWorker();
|
||||
let worker = workerhelper.worker;
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
|
||||
context.Buf.readInt32List = function fakeReadUint32List() {
|
||||
return [1];
|
||||
};
|
||||
|
||||
context.RIL.queryICCFacilityLock =
|
||||
function fakeQueryICCFacilityLock(options) {
|
||||
context.RIL[REQUEST_QUERY_FACILITY_LOCK](1, {
|
||||
rilMessageType: "sendMMI"
|
||||
});
|
||||
};
|
||||
|
||||
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
|
||||
context.RIL.sendMMI({mmi: createMMIOptions("*#", "33")});
|
||||
|
||||
let postedMessage = workerhelper.postedMessage;
|
||||
|
||||
ok(postedMessage.success);
|
||||
ok(postedMessage.enabled);
|
||||
equal(postedMessage.statusMessage, MMI_SM_KS_SERVICE_ENABLED_FOR);
|
||||
ok(Array.isArray(postedMessage.additionalInformation));
|
||||
equal(postedMessage.additionalInformation[0], "serviceClassVoice");
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_call_barring_BAIC_activation() {
|
||||
let workerhelper = newInterceptWorker();
|
||||
let worker = workerhelper.worker;
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
let mmiOptions;
|
||||
|
||||
context.RIL.setICCFacilityLock =
|
||||
function fakeSetICCFacilityLock(options) {
|
||||
mmiOptions = options;
|
||||
context.RIL[REQUEST_SET_FACILITY_LOCK](0, {
|
||||
rilMessageType: "sendMMI",
|
||||
procedure: MMI_PROCEDURE_ACTIVATION
|
||||
});
|
||||
};
|
||||
|
||||
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
|
||||
context.RIL.sendMMI({mmi: createMMIOptions("*", "33")});
|
||||
|
||||
let postedMessage = workerhelper.postedMessage;
|
||||
|
||||
equal(mmiOptions.procedure, MMI_PROCEDURE_ACTIVATION);
|
||||
ok(postedMessage.success);
|
||||
equal(postedMessage.statusMessage, MMI_SM_KS_SERVICE_ENABLED);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_call_barring_BAIC_deactivation() {
|
||||
let workerhelper = newInterceptWorker();
|
||||
let worker = workerhelper.worker;
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
let mmiOptions;
|
||||
|
||||
context.RIL.setICCFacilityLock =
|
||||
function fakeSetICCFacilityLock(options) {
|
||||
mmiOptions = options;
|
||||
context.RIL[REQUEST_SET_FACILITY_LOCK](0, {
|
||||
rilMessageType: "sendMMI",
|
||||
procedure: MMI_PROCEDURE_DEACTIVATION
|
||||
});
|
||||
};
|
||||
|
||||
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
|
||||
context.RIL.sendMMI({mmi: createMMIOptions("#", "33")});
|
||||
|
||||
let postedMessage = workerhelper.postedMessage;
|
||||
|
||||
equal(mmiOptions.procedure, MMI_PROCEDURE_DEACTIVATION);
|
||||
ok(postedMessage.success);
|
||||
equal(postedMessage.statusMessage, MMI_SM_KS_SERVICE_DISABLED);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_call_barring_BAIC_procedure_not_supported() {
|
||||
testSendMMI(createMMIOptions("**", "33", "0000"), MMI_ERROR_KS_NOT_SUPPORTED);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_USSD() {
|
||||
let workerhelper = newInterceptWorker();
|
||||
let worker = workerhelper.worker;
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
let ussdOptions;
|
||||
|
||||
context.RIL.sendUSSD = function fakeSendUSSD(options) {
|
||||
ussdOptions = options;
|
||||
context.RIL[REQUEST_SEND_USSD](0, {});
|
||||
};
|
||||
|
||||
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
|
||||
context.RIL.sendMMI({mmi: createMMIOptions("*", "123")});
|
||||
|
||||
let postedMessage = workerhelper.postedMessage;
|
||||
|
||||
equal(ussdOptions.ussd, "**123#");
|
||||
equal (postedMessage.errorMsg, GECKO_ERROR_SUCCESS);
|
||||
ok(postedMessage.success);
|
||||
ok(context.RIL._ussdSession);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_USSD_error() {
|
||||
let workerhelper = newInterceptWorker();
|
||||
let worker = workerhelper.worker;
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
let ussdOptions;
|
||||
|
||||
context.RIL.sendUSSD = function fakeSendUSSD(options){
|
||||
ussdOptions = options;
|
||||
context.RIL[REQUEST_SEND_USSD](0, {
|
||||
errorMsg: GECKO_ERROR_GENERIC_FAILURE
|
||||
});
|
||||
};
|
||||
|
||||
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
|
||||
context.RIL.sendMMI({mmi: createMMIOptions("*", "123")});
|
||||
|
||||
let postedMessage = workerhelper.postedMessage;
|
||||
|
||||
equal(ussdOptions.ussd, "**123#");
|
||||
equal (postedMessage.errorMsg, GECKO_ERROR_GENERIC_FAILURE);
|
||||
ok(!postedMessage.success);
|
||||
ok(!context.RIL._ussdSession);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
function setCallWaitingSuccess(mmi) {
|
||||
let workerhelper = newInterceptWorker();
|
||||
let worker = workerhelper.worker;
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
|
||||
context.RIL.setCallWaiting = function fakeSetCallWaiting(options) {
|
||||
context.RIL[REQUEST_SET_CALL_WAITING](0, {});
|
||||
};
|
||||
|
||||
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
|
||||
context.RIL.sendMMI({mmi: mmi});
|
||||
|
||||
let postedMessage = workerhelper.postedMessage;
|
||||
|
||||
equal(postedMessage.errorMsg, GECKO_ERROR_SUCCESS);
|
||||
ok(postedMessage.success);
|
||||
}
|
||||
|
||||
add_test(function test_sendMMI_call_waiting_activation() {
|
||||
setCallWaitingSuccess(createMMIOptions("*", "43", "10"));
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_call_waiting_deactivation() {
|
||||
setCallWaitingSuccess(createMMIOptions("#", "43"));
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_call_waiting_registration() {
|
||||
testSendMMI(createMMIOptions("**", "43"), MMI_ERROR_KS_NOT_SUPPORTED);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_call_waiting_erasure() {
|
||||
testSendMMI(createMMIOptions("##", "43"), MMI_ERROR_KS_NOT_SUPPORTED);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_sendMMI_call_waiting_interrogation() {
|
||||
let workerhelper = newInterceptWorker();
|
||||
let worker = workerhelper.worker;
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
|
||||
context.Buf.readInt32 = function fakeReadUint32() {
|
||||
return context.Buf.int32Array.pop();
|
||||
};
|
||||
|
||||
context.RIL.queryCallWaiting = function fakeQueryCallWaiting(options) {
|
||||
context.Buf.int32Array = [
|
||||
7, // serviceClass
|
||||
1, // enabled
|
||||
2 // length
|
||||
];
|
||||
context.RIL[REQUEST_QUERY_CALL_WAITING](1, {});
|
||||
};
|
||||
|
||||
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
|
||||
context.RIL.sendMMI({mmi: createMMIOptions("*#", "43")});
|
||||
|
||||
let postedMessage = workerhelper.postedMessage;
|
||||
|
||||
equal(postedMessage.errorMsg, GECKO_ERROR_SUCCESS);
|
||||
ok(postedMessage.success);
|
||||
equal(postedMessage.length, 2);
|
||||
ok(postedMessage.enabled);
|
||||
run_next_test();
|
||||
});
|
||||
@@ -36,7 +36,6 @@ function setCallForwardSuccess(procedure, serviceCode, sia, sib, sic) {
|
||||
let postedMessage = workerhelper.postedMessage;
|
||||
|
||||
equal(postedMessage.errorMsg, undefined);
|
||||
ok(postedMessage.success);
|
||||
}
|
||||
|
||||
add_test(function test_sendMMI_call_forwarding_activation() {
|
||||
@@ -82,7 +81,6 @@ add_test(function test_sendMMI_call_forwarding_interrogation() {
|
||||
let postedMessage = workerhelper.postedMessage;
|
||||
|
||||
equal(postedMessage.errorMsg, undefined);
|
||||
ok(postedMessage.success);
|
||||
ok(Array.isArray(postedMessage.rules));
|
||||
equal(postedMessage.rules.length, 1);
|
||||
ok(postedMessage.rules[0].active);
|
||||
@@ -110,7 +108,6 @@ add_test(function test_sendMMI_call_forwarding_interrogation_no_rules() {
|
||||
let postedMessage = workerhelper.postedMessage;
|
||||
|
||||
equal(postedMessage.errorMsg, GECKO_ERROR_GENERIC_FAILURE);
|
||||
ok(!postedMessage.success);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
@@ -6,20 +6,26 @@ subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
|
||||
const SMSC_ATT = '+13123149810';
|
||||
const SMSC_ATT_TYPO = '+++1312@@@314$$$9,8,1,0';
|
||||
const SMSC_ATT_TEXT = '"+13123149810",145';
|
||||
const SMSC_ATT_TEXT_INCORRECT_TOA = '"+13123149810",129';
|
||||
const SMSC_ATT_PDU = '07913121139418F0';
|
||||
const SMSC_O2 = '+447802000332';
|
||||
const SMSC_O2_TEXT = '"+447802000332",145';
|
||||
const SMSC_O2_PDU = '0791448720003023';
|
||||
const SMSC_EMPTY = '';
|
||||
const SMSC_TON_UNKNOWN = '0407485455'
|
||||
const SMSC_TON_UNKNOWN_TEXT = '"0407485455",129';
|
||||
const SMSC_TON_UNKNOWN_TEXT_NO_TOA = '"0407485455"';
|
||||
const SMSC_TON_UNKNOWN_TEXT_INVALID_TOA = '"0407485455",abc';
|
||||
const SMSC_TON_UNKNOWN_PDU = '06814070844555';
|
||||
const SMSC_EMPTY_PDU = 'FFFFFFFFFFFFFFFFFFFFFFFF';
|
||||
const SMSC_EMPTY_TEXT = '';
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function setSmsc(context, smsc, ton, npi, expected) {
|
||||
context.Buf.sendParcel = function() {
|
||||
context.Buf.postRILMessage = function() {
|
||||
equal(this.readString(), expected);
|
||||
};
|
||||
|
||||
@@ -30,6 +36,17 @@ function setSmsc(context, smsc, ton, npi, expected) {
|
||||
});
|
||||
}
|
||||
|
||||
function getSmsc(worker, context, raw, smsc, ton, npi) {
|
||||
worker.postMessage = function(message) {
|
||||
equal(message.smscAddress, smsc);
|
||||
equal(message.typeOfNumber, ton);
|
||||
equal(message.numberPlanIdentification, npi);
|
||||
}
|
||||
|
||||
context.Buf.writeString(raw);
|
||||
context.RIL[REQUEST_GET_SMSC_ADDRESS](0, { rilMessageType: "getSmscAddress"});
|
||||
}
|
||||
|
||||
add_test(function test_setSmscAddress() {
|
||||
let worker = newUint8Worker();
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
@@ -69,3 +86,27 @@ add_test(function test_setSmscAddress() {
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_getSmscAddress() {
|
||||
let worker = newUint8Worker();
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
|
||||
// Test text mode.
|
||||
worker.RILQUIRKS_SMSC_ADDRESS_FORMAT = "text";
|
||||
getSmsc(worker, context, SMSC_ATT_TEXT, SMSC_ATT, 1, 1);
|
||||
getSmsc(worker, context, SMSC_ATT_TEXT_INCORRECT_TOA, SMSC_ATT, 1, 1);
|
||||
getSmsc(worker, context, SMSC_O2_TEXT, SMSC_O2, 1, 1);
|
||||
getSmsc(worker, context, SMSC_TON_UNKNOWN_TEXT, SMSC_TON_UNKNOWN, 0, 1);
|
||||
getSmsc(worker, context, SMSC_TON_UNKNOWN_TEXT_NO_TOA, SMSC_TON_UNKNOWN, 0, 1);
|
||||
getSmsc(worker, context, SMSC_TON_UNKNOWN_TEXT_INVALID_TOA, SMSC_TON_UNKNOWN,
|
||||
0, 1);
|
||||
getSmsc(worker, context, SMSC_EMPTY_TEXT, SMSC_EMPTY, 0, 1);
|
||||
|
||||
// Test pdu mode.
|
||||
worker.RILQUIRKS_SMSC_ADDRESS_FORMAT = "pdu";
|
||||
getSmsc(worker, context, SMSC_ATT_PDU, SMSC_ATT, 1, 1);
|
||||
getSmsc(worker, context, SMSC_O2_PDU, SMSC_O2, 1, 1);
|
||||
getSmsc(worker, context, SMSC_TON_UNKNOWN_PDU, SMSC_TON_UNKNOWN, 0, 1);
|
||||
getSmsc(worker, context, SMSC_EMPTY_PDU, SMSC_EMPTY, 0, 1);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
@@ -23,8 +23,6 @@ skip-if = true
|
||||
[test_ril_worker_sms_gsmpduhelper.js]
|
||||
[test_ril_worker_sms_segment_info.js]
|
||||
[test_ril_worker_smsc_address.js]
|
||||
[test_ril_worker_mmi.js]
|
||||
[test_ril_worker_mmi_cf.js]
|
||||
[test_ril_worker_cf.js]
|
||||
[test_ril_worker_cellbroadcast_config.js]
|
||||
[test_ril_worker_cellbroadcast.js]
|
||||
|
||||
+90
-127
@@ -165,38 +165,27 @@ Telephony::IsValidServiceId(uint32_t aServiceId)
|
||||
return aServiceId < GetNumServices();
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
Telephony::IsActiveState(uint16_t aCallState) {
|
||||
return aCallState == nsITelephonyService::CALL_STATE_DIALING ||
|
||||
aCallState == nsITelephonyService::CALL_STATE_ALERTING ||
|
||||
aCallState == nsITelephonyService::CALL_STATE_CONNECTED;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Telephony::ProvidedOrDefaultServiceId(const Optional<uint32_t>& aServiceId)
|
||||
Telephony::GetServiceId(const Optional<uint32_t>& aServiceId,
|
||||
bool aGetIfActiveCall)
|
||||
{
|
||||
if (aServiceId.WasPassed()) {
|
||||
return aServiceId.Value();
|
||||
} else {
|
||||
uint32_t serviceId = 0;
|
||||
mService->GetDefaultServiceId(&serviceId);
|
||||
return serviceId;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Telephony::HasDialingCall()
|
||||
{
|
||||
for (uint32_t i = 0; i < mCalls.Length(); i++) {
|
||||
const RefPtr<TelephonyCall>& call = mCalls[i];
|
||||
if (call->CallState() > nsITelephonyService::CALL_STATE_UNKNOWN &&
|
||||
call->CallState() < nsITelephonyService::CALL_STATE_CONNECTED) {
|
||||
return true;
|
||||
} else if (aGetIfActiveCall) {
|
||||
nsTArray<RefPtr<TelephonyCall> > &calls = mCalls;
|
||||
if (mGroup->IsActive()) {
|
||||
calls = mGroup->CallsArray();
|
||||
}
|
||||
for (uint32_t i = 0; i < calls.Length(); i++) {
|
||||
if (calls[i]->IsActive()) {
|
||||
return calls[i]->mServiceId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
uint32_t serviceId = 0;
|
||||
mService->GetDefaultServiceId(&serviceId);
|
||||
return serviceId;
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
@@ -218,12 +207,6 @@ Telephony::DialInternal(uint32_t aServiceId, const nsAString& aNumber,
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
// We only support one outgoing call at a time.
|
||||
if (HasDialingCall()) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsITelephonyDialCallback> callback =
|
||||
new TelephonyDialCallback(GetOwner(), this, promise);
|
||||
|
||||
@@ -265,17 +248,17 @@ Telephony::CreateCallId(const nsAString& aNumber, uint16_t aNumberPresentation,
|
||||
|
||||
already_AddRefed<TelephonyCall>
|
||||
Telephony::CreateCall(TelephonyCallId* aId, uint32_t aServiceId,
|
||||
uint32_t aCallIndex, uint16_t aCallState,
|
||||
uint32_t aCallIndex, TelephonyCallState aState,
|
||||
bool aEmergency, bool aConference,
|
||||
bool aSwitchable, bool aMergeable)
|
||||
{
|
||||
// We don't have to create an already ended call.
|
||||
if (aCallState == nsITelephonyService::CALL_STATE_DISCONNECTED) {
|
||||
if (aState == TelephonyCallState::Disconnected) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<TelephonyCall> call =
|
||||
TelephonyCall::Create(this, aId, aServiceId, aCallIndex, aCallState,
|
||||
TelephonyCall::Create(this, aId, aServiceId, aCallIndex, aState,
|
||||
aEmergency, aConference, aSwitchable, aMergeable);
|
||||
|
||||
NS_ASSERTION(call, "This should never fail!");
|
||||
@@ -346,57 +329,66 @@ Telephony::HandleCallInfo(nsITelephonyCallInfo* aInfo)
|
||||
aInfo->GetIsSwitchable(&isSwitchable);
|
||||
aInfo->GetIsMergeable(&isMergeable);
|
||||
|
||||
RefPtr<TelephonyCall> call = GetCallFromEverywhere(serviceId, callIndex);
|
||||
TelephonyCallState state = TelephonyCall::ConvertToTelephonyCallState(callState);
|
||||
|
||||
RefPtr<TelephonyCall> call = GetCallFromEverywhere(serviceId, callIndex);
|
||||
// Handle a newly created call.
|
||||
if (!call) {
|
||||
RefPtr<TelephonyCallId> id = CreateCallId(aInfo);
|
||||
call = CreateCall(id, serviceId, callIndex, callState, isEmergency,
|
||||
call = CreateCall(id, serviceId, callIndex, state, isEmergency,
|
||||
isConference, isSwitchable, isMergeable);
|
||||
|
||||
if (call && callState == nsITelephonyService::CALL_STATE_INCOMING) {
|
||||
// The newly created call is an incoming call.
|
||||
if (call &&
|
||||
state == TelephonyCallState::Incoming) {
|
||||
nsresult rv = DispatchCallEvent(NS_LITERAL_STRING("incoming"), call);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
} else {
|
||||
call->UpdateEmergency(isEmergency);
|
||||
call->UpdateSwitchable(isSwitchable);
|
||||
call->UpdateMergeable(isMergeable);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoString number;
|
||||
aInfo->GetNumber(number);
|
||||
RefPtr<TelephonyCallId> id = call->Id();
|
||||
id->UpdateNumber(number);
|
||||
// Update an existing call
|
||||
call->UpdateEmergency(isEmergency);
|
||||
call->UpdateSwitchable(isSwitchable);
|
||||
call->UpdateMergeable(isMergeable);
|
||||
|
||||
// State changed.
|
||||
if (call->CallState() != callState) {
|
||||
if (callState == nsITelephonyService::CALL_STATE_DISCONNECTED) {
|
||||
call->ChangeStateInternal(callState, true);
|
||||
return NS_OK;
|
||||
}
|
||||
nsAutoString number;
|
||||
aInfo->GetNumber(number);
|
||||
RefPtr<TelephonyCallId> id = call->Id();
|
||||
id->UpdateNumber(number);
|
||||
|
||||
// We don't fire the statechange event on a call in conference here.
|
||||
// Instead, the event will be fired later in
|
||||
// TelephonyCallGroup::ChangeState(). Thus the sequence of firing the
|
||||
// statechange events is guaranteed: first on TelephonyCallGroup then on
|
||||
// individual TelephonyCall objects.
|
||||
bool fireEvent = !isConference;
|
||||
call->ChangeStateInternal(callState, fireEvent);
|
||||
nsAutoString disconnectedReason;
|
||||
aInfo->GetDisconnectedReason(disconnectedReason);
|
||||
|
||||
// State changed.
|
||||
if (call->State() != state) {
|
||||
if (state == TelephonyCallState::Disconnected) {
|
||||
call->UpdateDisconnectedReason(disconnectedReason);
|
||||
call->ChangeState(TelephonyCallState::Disconnected);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Group changed.
|
||||
RefPtr<TelephonyCallGroup> group = call->GetGroup();
|
||||
// We don't fire the statechange event on a call in conference here.
|
||||
// Instead, the event will be fired later in
|
||||
// TelephonyCallGroup::ChangeState(). Thus the sequence of firing the
|
||||
// statechange events is guaranteed: first on TelephonyCallGroup then on
|
||||
// individual TelephonyCall objects.
|
||||
bool fireEvent = !isConference;
|
||||
call->ChangeStateInternal(state, fireEvent);
|
||||
}
|
||||
|
||||
if (!group && isConference) {
|
||||
// Add to conference.
|
||||
NS_ASSERTION(mCalls.Contains(call), "Should in mCalls");
|
||||
mGroup->AddCall(call);
|
||||
RemoveCall(call);
|
||||
} else if (group && !isConference) {
|
||||
// Remove from conference.
|
||||
NS_ASSERTION(mGroup->CallsArray().Contains(call), "Should in mGroup");
|
||||
mGroup->RemoveCall(call);
|
||||
AddCall(call);
|
||||
}
|
||||
// Group changed.
|
||||
RefPtr<TelephonyCallGroup> group = call->GetGroup();
|
||||
|
||||
if (!group && isConference) {
|
||||
// Add to conference.
|
||||
NS_ASSERTION(mCalls.Contains(call), "Should in mCalls");
|
||||
mGroup->AddCall(call);
|
||||
RemoveCall(call);
|
||||
} else if (group && !isConference) {
|
||||
// Remove from conference.
|
||||
NS_ASSERTION(mGroup->CallsArray().Contains(call), "Should in mGroup");
|
||||
mGroup->RemoveCall(call);
|
||||
AddCall(call);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@@ -437,7 +429,7 @@ already_AddRefed<Promise>
|
||||
Telephony::Dial(const nsAString& aNumber, const Optional<uint32_t>& aServiceId,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
uint32_t serviceId = ProvidedOrDefaultServiceId(aServiceId);
|
||||
uint32_t serviceId = GetServiceId(aServiceId);
|
||||
RefPtr<Promise> promise = DialInternal(serviceId, aNumber, false, aRv);
|
||||
return promise.forget();
|
||||
}
|
||||
@@ -447,7 +439,7 @@ Telephony::DialEmergency(const nsAString& aNumber,
|
||||
const Optional<uint32_t>& aServiceId,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
uint32_t serviceId = ProvidedOrDefaultServiceId(aServiceId);
|
||||
uint32_t serviceId = GetServiceId(aServiceId);
|
||||
RefPtr<Promise> promise = DialInternal(serviceId, aNumber, true, aRv);
|
||||
return promise.forget();
|
||||
}
|
||||
@@ -459,7 +451,8 @@ Telephony::SendTones(const nsAString& aDTMFChars,
|
||||
const Optional<uint32_t>& aServiceId,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
uint32_t serviceId = ProvidedOrDefaultServiceId(aServiceId);
|
||||
uint32_t serviceId = GetServiceId(aServiceId,
|
||||
true /* aGetIfActiveCall */);
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
|
||||
if (!global) {
|
||||
@@ -496,7 +489,8 @@ Telephony::StartTone(const nsAString& aDTMFChar,
|
||||
const Optional<uint32_t>& aServiceId,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
uint32_t serviceId = ProvidedOrDefaultServiceId(aServiceId);
|
||||
uint32_t serviceId = GetServiceId(aServiceId,
|
||||
true /* aGetIfActiveCall */);
|
||||
|
||||
if (aDTMFChar.IsEmpty()) {
|
||||
NS_WARNING("Empty tone string will be ignored");
|
||||
@@ -514,7 +508,8 @@ Telephony::StartTone(const nsAString& aDTMFChar,
|
||||
void
|
||||
Telephony::StopTone(const Optional<uint32_t>& aServiceId, ErrorResult& aRv)
|
||||
{
|
||||
uint32_t serviceId = ProvidedOrDefaultServiceId(aServiceId);
|
||||
uint32_t serviceId = GetServiceId(aServiceId,
|
||||
true /* aGetIfActiveCall */);
|
||||
|
||||
if (!IsValidServiceId(serviceId)) {
|
||||
aRv.Throw(NS_ERROR_INVALID_ARG);
|
||||
@@ -625,18 +620,21 @@ Telephony::SetSpeakerEnabled(bool aEnabled, ErrorResult& aRv)
|
||||
void
|
||||
Telephony::GetActive(Nullable<OwningTelephonyCallOrTelephonyCallGroup>& aValue)
|
||||
{
|
||||
if (mGroup->CallState() == nsITelephonyService::CALL_STATE_CONNECTED) {
|
||||
if (mGroup->IsActive()) {
|
||||
aValue.SetValue().SetAsTelephonyCallGroup() = mGroup;
|
||||
} else {
|
||||
// Search the first active call.
|
||||
for (uint32_t i = 0; i < mCalls.Length(); i++) {
|
||||
if (IsActiveState(mCalls[i]->CallState())) {
|
||||
aValue.SetValue().SetAsTelephonyCall() = mCalls[i];
|
||||
return;
|
||||
}
|
||||
}
|
||||
aValue.SetNull();
|
||||
return;
|
||||
}
|
||||
|
||||
// Search for the active call.
|
||||
for (uint32_t i = 0; i < mCalls.Length(); i++) {
|
||||
if (mCalls[i]->IsActive()) {
|
||||
aValue.SetValue().SetAsTelephonyCall() = mCalls[i];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing active found.
|
||||
aValue.SetNull();
|
||||
}
|
||||
|
||||
already_AddRefed<CallsList>
|
||||
@@ -725,6 +723,7 @@ Telephony::WindowAudioCaptureChanged()
|
||||
NS_IMETHODIMP
|
||||
Telephony::CallStateChanged(uint32_t aLength, nsITelephonyCallInfo** aAllInfo)
|
||||
{
|
||||
// Update call state
|
||||
nsresult rv;
|
||||
for (uint32_t i = 0; i < aLength; ++i) {
|
||||
rv = HandleCallInfo(aAllInfo[i]);
|
||||
@@ -733,6 +732,9 @@ Telephony::CallStateChanged(uint32_t aLength, nsITelephonyCallInfo** aAllInfo)
|
||||
}
|
||||
}
|
||||
|
||||
// Update conference state
|
||||
mGroup->ChangeState();
|
||||
|
||||
rv = HandleAudioAgentState();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
@@ -746,30 +748,11 @@ Telephony::EnumerateCallState(nsITelephonyCallInfo* aInfo)
|
||||
return HandleCallInfo(aInfo);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Telephony::ConferenceCallStateChanged(uint16_t aCallState)
|
||||
{
|
||||
mGroup->ChangeState(aCallState);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Telephony::EnumerateCallStateComplete()
|
||||
{
|
||||
// Set conference state.
|
||||
if (mGroup->CallsArray().Length() >= 2) {
|
||||
const nsTArray<RefPtr<TelephonyCall> > &calls = mGroup->CallsArray();
|
||||
|
||||
uint16_t callState = calls[0]->CallState();
|
||||
for (uint32_t i = 1; i < calls.Length(); i++) {
|
||||
if (calls[i]->CallState() != callState) {
|
||||
callState = nsITelephonyService::CALL_STATE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mGroup->ChangeState(callState);
|
||||
}
|
||||
mGroup->ChangeState();
|
||||
|
||||
HandleAudioAgentState();
|
||||
if (mReadyPromise) {
|
||||
@@ -809,26 +792,6 @@ Telephony::SupplementaryServiceNotification(uint32_t aServiceId,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Telephony::NotifyError(uint32_t aServiceId,
|
||||
int32_t aCallIndex,
|
||||
const nsAString& aError)
|
||||
{
|
||||
RefPtr<TelephonyCall> callToNotify =
|
||||
GetCallFromEverywhere(aServiceId, aCallIndex);
|
||||
if (!callToNotify) {
|
||||
NS_ERROR("Don't call me with a bad call index!");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
// Set the call state to 'disconnected' and remove it from the calls list.
|
||||
callToNotify->UpdateDisconnectedReason(aError);
|
||||
callToNotify->NotifyError(aError);
|
||||
callToNotify->ChangeState(nsITelephonyService::CALL_STATE_DISCONNECTED);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Telephony::NotifyCdmaCallWaiting(uint32_t aServiceId, const nsAString& aNumber,
|
||||
uint16_t aNumberPresentation,
|
||||
|
||||
@@ -189,14 +189,9 @@ private:
|
||||
static bool
|
||||
IsValidServiceId(uint32_t aServiceId);
|
||||
|
||||
static bool
|
||||
IsActiveState(uint16_t aCallState);
|
||||
|
||||
uint32_t
|
||||
ProvidedOrDefaultServiceId(const Optional<uint32_t>& aServiceId);
|
||||
|
||||
bool
|
||||
HasDialingCall();
|
||||
GetServiceId(const Optional<uint32_t>& aServiceId,
|
||||
bool aGetIfActiveCall = false);
|
||||
|
||||
already_AddRefed<Promise>
|
||||
DialInternal(uint32_t aServiceId, const nsAString& aNumber, bool aEmergency,
|
||||
@@ -213,9 +208,13 @@ private:
|
||||
|
||||
already_AddRefed<TelephonyCall>
|
||||
CreateCall(TelephonyCallId* aId,
|
||||
uint32_t aServiceId, uint32_t aCallIndex, uint16_t aCallState,
|
||||
bool aEmergency = false, bool aConference = false,
|
||||
bool aSwitchable = true, bool aMergeable = true);
|
||||
uint32_t aServiceId,
|
||||
uint32_t aCallIndex,
|
||||
TelephonyCallState aState,
|
||||
bool aEmergency = false,
|
||||
bool aConference = false,
|
||||
bool aSwitchable = true,
|
||||
bool aMergeable = true);
|
||||
|
||||
nsresult
|
||||
NotifyEvent(const nsAString& aType);
|
||||
|
||||
+123
-82
@@ -34,16 +34,51 @@
|
||||
} \
|
||||
}
|
||||
|
||||
#ifdef TELEPHONY_CALL_STATE
|
||||
#undef TELEPHONY_CALL_STATE
|
||||
#endif
|
||||
|
||||
#define TELEPHONY_CALL_STATE(_state) \
|
||||
(TelephonyCallStateValues::strings[static_cast<int32_t>(_state)].value)
|
||||
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::dom::telephony;
|
||||
using mozilla::ErrorResult;
|
||||
|
||||
// static
|
||||
TelephonyCallState
|
||||
TelephonyCall::ConvertToTelephonyCallState(uint32_t aCallState)
|
||||
{
|
||||
switch (aCallState) {
|
||||
case nsITelephonyService::CALL_STATE_DIALING:
|
||||
return TelephonyCallState::Dialing;
|
||||
case nsITelephonyService::CALL_STATE_ALERTING:
|
||||
return TelephonyCallState::Alerting;
|
||||
case nsITelephonyService::CALL_STATE_CONNECTED:
|
||||
return TelephonyCallState::Connected;
|
||||
case nsITelephonyService::CALL_STATE_HELD:
|
||||
return TelephonyCallState::Held;
|
||||
case nsITelephonyService::CALL_STATE_DISCONNECTED:
|
||||
return TelephonyCallState::Disconnected;
|
||||
case nsITelephonyService::CALL_STATE_INCOMING:
|
||||
return TelephonyCallState::Incoming;
|
||||
}
|
||||
|
||||
NS_NOTREACHED("Unknown state!");
|
||||
return TelephonyCallState::Disconnected;
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<TelephonyCall>
|
||||
TelephonyCall::Create(Telephony* aTelephony, TelephonyCallId* aId,
|
||||
uint32_t aServiceId, uint32_t aCallIndex,
|
||||
uint16_t aCallState, bool aEmergency, bool aConference,
|
||||
bool aSwitchable, bool aMergeable)
|
||||
TelephonyCall::Create(Telephony* aTelephony,
|
||||
TelephonyCallId* aId,
|
||||
uint32_t aServiceId,
|
||||
uint32_t aCallIndex,
|
||||
TelephonyCallState aState,
|
||||
bool aEmergency,
|
||||
bool aConference,
|
||||
bool aSwitchable,
|
||||
bool aMergeable)
|
||||
{
|
||||
NS_ASSERTION(aTelephony, "Null aTelephony pointer!");
|
||||
NS_ASSERTION(aId, "Null aId pointer!");
|
||||
@@ -61,8 +96,7 @@ TelephonyCall::Create(Telephony* aTelephony, TelephonyCallId* aId,
|
||||
call->mMergeable = aMergeable;
|
||||
call->mError = nullptr;
|
||||
|
||||
call->ChangeStateInternal(aCallState, false);
|
||||
|
||||
call->ChangeStateInternal(aState, false);
|
||||
return call.forget();
|
||||
}
|
||||
|
||||
@@ -83,35 +117,15 @@ TelephonyCall::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
}
|
||||
|
||||
void
|
||||
TelephonyCall::ChangeStateInternal(uint16_t aCallState, bool aFireEvents)
|
||||
TelephonyCall::ChangeStateInternal(TelephonyCallState aState, bool aFireEvents)
|
||||
{
|
||||
RefPtr<TelephonyCall> kungFuDeathGrip(this);
|
||||
|
||||
mCallState = aCallState;
|
||||
switch (aCallState) {
|
||||
case nsITelephonyService::CALL_STATE_DIALING:
|
||||
mState.AssignLiteral("dialing");
|
||||
break;
|
||||
case nsITelephonyService::CALL_STATE_ALERTING:
|
||||
mState.AssignLiteral("alerting");
|
||||
break;
|
||||
case nsITelephonyService::CALL_STATE_CONNECTED:
|
||||
mState.AssignLiteral("connected");
|
||||
break;
|
||||
case nsITelephonyService::CALL_STATE_HELD:
|
||||
mState.AssignLiteral("held");
|
||||
break;
|
||||
case nsITelephonyService::CALL_STATE_DISCONNECTED:
|
||||
mState.AssignLiteral("disconnected");
|
||||
break;
|
||||
case nsITelephonyService::CALL_STATE_INCOMING:
|
||||
mState.AssignLiteral("incoming");
|
||||
break;
|
||||
default:
|
||||
NS_NOTREACHED("Unknown state!");
|
||||
}
|
||||
// Update current state
|
||||
mState = aState;
|
||||
|
||||
if (aCallState == nsITelephonyService::CALL_STATE_DISCONNECTED) {
|
||||
// Handle disconnected calls
|
||||
if (mState == TelephonyCallState::Disconnected) {
|
||||
NS_ASSERTION(mLive, "Should be live!");
|
||||
mLive = false;
|
||||
if (mGroup) {
|
||||
@@ -119,8 +133,7 @@ TelephonyCall::ChangeStateInternal(uint16_t aCallState, bool aFireEvents)
|
||||
} else {
|
||||
mTelephony->RemoveCall(this);
|
||||
}
|
||||
UpdateDisconnectedReason(NS_LITERAL_STRING("NormalCallClearingError"));
|
||||
} else if (!mLive) {
|
||||
} else if (!mLive) { // Handle newly added calls
|
||||
mLive = true;
|
||||
if (mGroup) {
|
||||
mGroup->AddCall(this);
|
||||
@@ -129,23 +142,39 @@ TelephonyCall::ChangeStateInternal(uint16_t aCallState, bool aFireEvents)
|
||||
}
|
||||
}
|
||||
|
||||
// Dispatch call state changed and call state event
|
||||
if (aFireEvents) {
|
||||
nsresult rv = DispatchCallEvent(NS_LITERAL_STRING("statechange"), this);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to dispatch specific event!");
|
||||
}
|
||||
|
||||
// This can change if the statechange handler called back here... Need to
|
||||
// figure out something smarter.
|
||||
if (mCallState == aCallState) {
|
||||
rv = DispatchCallEvent(mState, this);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to dispatch specific event!");
|
||||
}
|
||||
}
|
||||
NotifyStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
TelephonyCall::NotifyStateChanged()
|
||||
{
|
||||
// Since |mState| can be changed after statechange handler called back here,
|
||||
// we must save current state. Maybe we should figure out something smarter.
|
||||
TelephonyCallState prevState = mState;
|
||||
|
||||
nsresult res = DispatchCallEvent(NS_LITERAL_STRING("statechange"), this);
|
||||
if (NS_FAILED(res)) {
|
||||
NS_WARNING("Failed to dispatch specific event!");
|
||||
}
|
||||
|
||||
// Check whether |mState| remains the same after the statechange handler.
|
||||
if (mState != prevState) {
|
||||
NS_WARNING("Call State has changed by statechange handler!");
|
||||
return res;
|
||||
}
|
||||
|
||||
res = DispatchCallEvent(NS_ConvertASCIItoUTF16(TELEPHONY_CALL_STATE(mState)),
|
||||
this);
|
||||
if (NS_FAILED(res)) {
|
||||
NS_WARNING("Failed to dispatch a specific event!");
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
nsresult
|
||||
TelephonyCall::DispatchCallEvent(const nsAString& aType,
|
||||
TelephonyCall* aCall)
|
||||
@@ -196,16 +225,23 @@ TelephonyCall::NotifyError(const nsAString& aError)
|
||||
void
|
||||
TelephonyCall::UpdateDisconnectedReason(const nsAString& aDisconnectedReason)
|
||||
{
|
||||
NS_ASSERTION(Substring(aDisconnectedReason, aDisconnectedReason.Length() - 5).EqualsLiteral("Error"),
|
||||
NS_ASSERTION(Substring(aDisconnectedReason,
|
||||
aDisconnectedReason.Length() - 5).EqualsLiteral("Error"),
|
||||
"Disconnected reason should end with 'Error'");
|
||||
|
||||
if (mDisconnectedReason.IsNull()) {
|
||||
// There is no 'Error' suffix in the corresponding enum. We should skip
|
||||
// that part for comparison.
|
||||
CONVERT_STRING_TO_NULLABLE_ENUM(
|
||||
Substring(aDisconnectedReason, 0, aDisconnectedReason.Length() - 5),
|
||||
TelephonyCallDisconnectedReason,
|
||||
mDisconnectedReason);
|
||||
if (!mDisconnectedReason.IsNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// There is no 'Error' suffix in the corresponding enum. We should skip
|
||||
// that part for comparison.
|
||||
CONVERT_STRING_TO_NULLABLE_ENUM(
|
||||
Substring(aDisconnectedReason, 0, aDisconnectedReason.Length() - 5),
|
||||
TelephonyCallDisconnectedReason,
|
||||
mDisconnectedReason);
|
||||
|
||||
if (!aDisconnectedReason.EqualsLiteral("NormalCallClearingError")) {
|
||||
NotifyError(aDisconnectedReason);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,9 +308,10 @@ TelephonyCall::Answer(ErrorResult& aRv)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (mCallState != nsITelephonyService::CALL_STATE_INCOMING) {
|
||||
if (mState != TelephonyCallState::Incoming) {
|
||||
NS_WARNING(nsPrintfCString("Answer on non-incoming call is rejected!"
|
||||
" (State: %u)", mCallState).get());
|
||||
" (State: %s)",
|
||||
TELEPHONY_CALL_STATE(mState)).get());
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
@@ -294,15 +331,16 @@ TelephonyCall::HangUp(ErrorResult& aRv)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (mCallState == nsITelephonyService::CALL_STATE_DISCONNECTED) {
|
||||
NS_WARNING(nsPrintfCString("HangUp on previously disconnected call"
|
||||
" is rejected! (State: %u)", mCallState).get());
|
||||
if (mState == TelephonyCallState::Disconnected) {
|
||||
NS_WARNING(nsPrintfCString("HangUp on a disconnected call is rejected!"
|
||||
" (State: %s)",
|
||||
TELEPHONY_CALL_STATE(mState)).get());
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsITelephonyCallback> callback = new TelephonyCallback(promise);
|
||||
aRv = mCallState == nsITelephonyService::CALL_STATE_INCOMING ?
|
||||
aRv = mState == TelephonyCallState::Incoming ?
|
||||
mTelephony->Service()->RejectCall(mServiceId, mCallIndex, callback) :
|
||||
mTelephony->Service()->HangUpCall(mServiceId, mCallIndex, callback);
|
||||
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
|
||||
@@ -328,30 +366,13 @@ TelephonyCall::Hold(ErrorResult& aRv)
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
TelephonyCall::Resume(ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<Promise> promise = CreatePromise(aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsITelephonyCallback> callback = new TelephonyCallback(promise);
|
||||
aRv = Resume(callback);
|
||||
if (NS_WARN_IF(aRv.Failed() &&
|
||||
!aRv.ErrorCodeIs(NS_ERROR_DOM_INVALID_STATE_ERR))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
TelephonyCall::Hold(nsITelephonyCallback* aCallback)
|
||||
{
|
||||
if (mCallState != nsITelephonyService::CALL_STATE_CONNECTED) {
|
||||
if (mState != TelephonyCallState::Connected) {
|
||||
NS_WARNING(nsPrintfCString("Hold non-connected call is rejected!"
|
||||
" (State: %u)", mCallState).get());
|
||||
" (State: %s)",
|
||||
TELEPHONY_CALL_STATE(mState)).get());
|
||||
aCallback->NotifyError(NS_LITERAL_STRING("InvalidStateError"));
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
}
|
||||
@@ -383,11 +404,31 @@ TelephonyCall::Hold(nsITelephonyCallback* aCallback)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
TelephonyCall::Resume(ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<Promise> promise = CreatePromise(aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsITelephonyCallback> callback = new TelephonyCallback(promise);
|
||||
aRv = Resume(callback);
|
||||
if (NS_WARN_IF(aRv.Failed() &&
|
||||
!aRv.ErrorCodeIs(NS_ERROR_DOM_INVALID_STATE_ERR))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
TelephonyCall::Resume(nsITelephonyCallback* aCallback)
|
||||
{
|
||||
if (mCallState != nsITelephonyService::CALL_STATE_HELD) {
|
||||
NS_WARNING("Resume non-held call is rejected!");
|
||||
if (mState != TelephonyCallState::Held) {
|
||||
NS_WARNING(nsPrintfCString("Resume non-held call is rejected!"
|
||||
" (State: %s)",
|
||||
TELEPHONY_CALL_STATE(mState)).get());
|
||||
aCallback->NotifyError(NS_LITERAL_STRING("InvalidStateError"));
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ class TelephonyCall final : public DOMEventTargetHelper
|
||||
RefPtr<TelephonyCallId> mSecondId;
|
||||
|
||||
uint32_t mServiceId;
|
||||
nsString mState;
|
||||
TelephonyCallState mState;
|
||||
bool mEmergency;
|
||||
RefPtr<DOMError> mError;
|
||||
Nullable<TelephonyCallDisconnectedReason> mDisconnectedReason;
|
||||
@@ -38,7 +38,6 @@ class TelephonyCall final : public DOMEventTargetHelper
|
||||
bool mMergeable;
|
||||
|
||||
uint32_t mCallIndex;
|
||||
uint16_t mCallState;
|
||||
bool mLive;
|
||||
|
||||
public:
|
||||
@@ -65,10 +64,10 @@ public:
|
||||
already_AddRefed<TelephonyCallId>
|
||||
GetSecondId() const;
|
||||
|
||||
void
|
||||
GetState(nsString& aState) const
|
||||
TelephonyCallState
|
||||
State() const
|
||||
{
|
||||
aState.Assign(mState);
|
||||
return mState;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -89,6 +88,14 @@ public:
|
||||
return mMergeable;
|
||||
}
|
||||
|
||||
bool
|
||||
IsActive() const
|
||||
{
|
||||
return mState == TelephonyCallState::Dialing ||
|
||||
mState == TelephonyCallState::Alerting ||
|
||||
mState == TelephonyCallState::Connected;
|
||||
}
|
||||
|
||||
already_AddRefed<DOMError>
|
||||
GetError() const;
|
||||
|
||||
@@ -122,18 +129,24 @@ public:
|
||||
IMPL_EVENT_HANDLER(error)
|
||||
IMPL_EVENT_HANDLER(groupchange)
|
||||
|
||||
static TelephonyCallState
|
||||
ConvertToTelephonyCallState(uint32_t aCallState);
|
||||
|
||||
static already_AddRefed<TelephonyCall>
|
||||
Create(Telephony* aTelephony, TelephonyCallId* aId,
|
||||
uint32_t aServiceId, uint32_t aCallIndex, uint16_t aCallState,
|
||||
uint32_t aServiceId, uint32_t aCallIndex, TelephonyCallState aState,
|
||||
bool aEmergency = false, bool aConference = false,
|
||||
bool aSwitchable = true, bool aMergeable = true);
|
||||
|
||||
void
|
||||
ChangeState(uint16_t aCallState)
|
||||
ChangeState(TelephonyCallState aState)
|
||||
{
|
||||
ChangeStateInternal(aCallState, true);
|
||||
ChangeStateInternal(aState, true);
|
||||
}
|
||||
|
||||
nsresult
|
||||
NotifyStateChanged();
|
||||
|
||||
uint32_t
|
||||
ServiceId() const
|
||||
{
|
||||
@@ -146,12 +159,6 @@ public:
|
||||
return mCallIndex;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
CallState() const
|
||||
{
|
||||
return mCallState;
|
||||
}
|
||||
|
||||
void
|
||||
UpdateEmergency(bool aEmergency)
|
||||
{
|
||||
@@ -194,7 +201,7 @@ private:
|
||||
Resume(nsITelephonyCallback* aCallback);
|
||||
|
||||
void
|
||||
ChangeStateInternal(uint16_t aCallState, bool aFireEvents);
|
||||
ChangeStateInternal(TelephonyCallState aState, bool aFireEvents);
|
||||
|
||||
nsresult
|
||||
DispatchCallEvent(const nsAString& aType,
|
||||
|
||||
@@ -10,16 +10,23 @@
|
||||
#include "Telephony.h"
|
||||
#include "mozilla/dom/CallEvent.h"
|
||||
#include "mozilla/dom/CallGroupErrorEvent.h"
|
||||
#include "mozilla/dom/TelephonyCallGroupBinding.h"
|
||||
#include "mozilla/dom/telephony/TelephonyCallback.h"
|
||||
|
||||
#include "nsPrintfCString.h"
|
||||
|
||||
#ifdef TELEPHONY_GROUP_STATE
|
||||
#undef TELEPHONY_GROUP_STATE
|
||||
#endif
|
||||
|
||||
#define TELEPHONY_GROUP_STATE(_state) \
|
||||
(TelephonyCallGroupStateValues::strings[static_cast<int32_t>(_state)].value)
|
||||
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::dom::telephony;
|
||||
using mozilla::ErrorResult;
|
||||
|
||||
TelephonyCallGroup::TelephonyCallGroup(nsPIDOMWindow* aOwner)
|
||||
: DOMEventTargetHelper(aOwner)
|
||||
, mCallState(nsITelephonyService::CALL_STATE_UNKNOWN)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -37,6 +44,7 @@ TelephonyCallGroup::Create(Telephony* aTelephony)
|
||||
new TelephonyCallGroup(aTelephony->GetOwner());
|
||||
|
||||
group->mTelephony = aTelephony;
|
||||
group->mState = TelephonyCallGroupState::_empty;
|
||||
group->mCallsList = new CallsList(aTelephony, group);
|
||||
|
||||
return group.forget();
|
||||
@@ -82,48 +90,84 @@ TelephonyCallGroup::NotifyError(const nsAString& aName, const nsAString& aMessag
|
||||
}
|
||||
|
||||
void
|
||||
TelephonyCallGroup::ChangeState(uint16_t aCallState)
|
||||
TelephonyCallGroup::ChangeState()
|
||||
{
|
||||
if (mCallState == aCallState) {
|
||||
MOZ_ASSERT(mCalls.Length() != 1);
|
||||
if (mCalls.Length() == 0) {
|
||||
ChangeStateInternal(TelephonyCallGroupState::_empty);
|
||||
return;
|
||||
}
|
||||
|
||||
mCallState = aCallState;
|
||||
switch (aCallState) {
|
||||
case nsITelephonyService::CALL_STATE_UNKNOWN:
|
||||
mState.AssignLiteral("");
|
||||
break;
|
||||
case nsITelephonyService::CALL_STATE_CONNECTED:
|
||||
mState.AssignLiteral("connected");
|
||||
break;
|
||||
case nsITelephonyService::CALL_STATE_HELD:
|
||||
mState.AssignLiteral("held");
|
||||
break;
|
||||
default:
|
||||
NS_NOTREACHED("Unknown state!");
|
||||
}
|
||||
|
||||
nsresult rv = DispatchCallEvent(NS_LITERAL_STRING("statechange"), nullptr);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to dispatch specific event!");
|
||||
}
|
||||
if (!mState.IsEmpty()) {
|
||||
// This can change if the statechange handler called back here... Need to
|
||||
// figure out something smarter.
|
||||
if (mCallState == aCallState) {
|
||||
rv = DispatchCallEvent(mState, nullptr);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to dispatch specific event!");
|
||||
}
|
||||
TelephonyCallState state = mCalls[0]->State();
|
||||
for (uint32_t i = 1; i < mCalls.Length(); i++) {
|
||||
if (mCalls[i]->State() != state) {
|
||||
MOZ_ASSERT(false, "Various call states are found in a call group!");
|
||||
ChangeStateInternal(TelephonyCallGroupState::_empty);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t index = 0; index < mCalls.Length(); index++) {
|
||||
RefPtr<TelephonyCall> call = mCalls[index];
|
||||
call->ChangeState(aCallState);
|
||||
|
||||
MOZ_ASSERT(call->CallState() == aCallState);
|
||||
TelephonyCallGroupState groupState = TelephonyCallGroupState::_empty;
|
||||
switch (state) {
|
||||
case TelephonyCallState::Connected:
|
||||
groupState = TelephonyCallGroupState::Connected;
|
||||
break;
|
||||
case TelephonyCallState::Held:
|
||||
groupState = TelephonyCallGroupState::Held;
|
||||
break;
|
||||
default:
|
||||
NS_NOTREACHED(nsPrintfCString("Invavild call state for a call group(%s)!",
|
||||
TELEPHONY_CALL_STATE(state)).get());
|
||||
}
|
||||
|
||||
ChangeStateInternal(groupState);
|
||||
}
|
||||
|
||||
void
|
||||
TelephonyCallGroup::ChangeStateInternal(TelephonyCallGroupState aState)
|
||||
{
|
||||
if (mState == aState) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update Current State
|
||||
mState = aState;
|
||||
|
||||
// Dispatch related events
|
||||
NotifyStateChanged();
|
||||
}
|
||||
|
||||
nsresult
|
||||
TelephonyCallGroup::NotifyStateChanged()
|
||||
{
|
||||
// Since |mState| can be changed after statechange handler called back here,
|
||||
// we must save current state. Maybe we should figure out something smarter.
|
||||
TelephonyCallGroupState prevState = mState;
|
||||
|
||||
nsresult res = DispatchCallEvent(NS_LITERAL_STRING("statechange"), nullptr);
|
||||
if (NS_FAILED(res)) {
|
||||
NS_WARNING("Failed to dispatch specific event!");
|
||||
}
|
||||
|
||||
// Check whether |mState| remains the same after the statechange handler.
|
||||
// Besides, If there is no conference call at all, then we dont't have to
|
||||
// dispatch the state evnet.
|
||||
if (mState == prevState) {
|
||||
res = DispatchCallEvent(NS_ConvertASCIItoUTF16(TELEPHONY_GROUP_STATE(mState)),
|
||||
nullptr);
|
||||
if (NS_FAILED(res)) {
|
||||
NS_WARNING("Failed to dispatch specific event!");
|
||||
}
|
||||
}
|
||||
|
||||
// Notify each call within to dispatch call state change event
|
||||
for (uint32_t index = 0; index < mCalls.Length(); index++) {
|
||||
if (NS_FAILED(mCalls[index]->NotifyStateChanged())){
|
||||
res = NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
nsresult
|
||||
@@ -172,14 +216,13 @@ TelephonyCallGroup::CanConference(const TelephonyCall& aCall,
|
||||
|
||||
if (!aSecondCall) {
|
||||
MOZ_ASSERT(!mCalls.IsEmpty());
|
||||
|
||||
return (mCallState == nsITelephonyService::CALL_STATE_CONNECTED &&
|
||||
aCall.CallState() == nsITelephonyService::CALL_STATE_HELD) ||
|
||||
(mCallState == nsITelephonyService::CALL_STATE_HELD &&
|
||||
aCall.CallState() == nsITelephonyService::CALL_STATE_CONNECTED);
|
||||
return (mState == TelephonyCallGroupState::Connected &&
|
||||
aCall.State() == TelephonyCallState::Held) ||
|
||||
(mState == TelephonyCallGroupState::Held &&
|
||||
aCall.State() == TelephonyCallState::Connected);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mCallState == nsITelephonyService::CALL_STATE_UNKNOWN);
|
||||
MOZ_ASSERT(mState != TelephonyCallGroupState::_empty);
|
||||
|
||||
if (aCall.ServiceId() != aSecondCall->ServiceId()) {
|
||||
return false;
|
||||
@@ -189,10 +232,10 @@ TelephonyCallGroup::CanConference(const TelephonyCall& aCall,
|
||||
return false;
|
||||
}
|
||||
|
||||
return (aCall.CallState() == nsITelephonyService::CALL_STATE_CONNECTED &&
|
||||
aSecondCall->CallState() == nsITelephonyService::CALL_STATE_HELD) ||
|
||||
(aCall.CallState() == nsITelephonyService::CALL_STATE_HELD &&
|
||||
aSecondCall->CallState() == nsITelephonyService::CALL_STATE_CONNECTED);
|
||||
return (aCall.State() == TelephonyCallState::Connected &&
|
||||
aSecondCall->State() == TelephonyCallState::Held) ||
|
||||
(aCall.State() == TelephonyCallState::Held &&
|
||||
aSecondCall->State() == TelephonyCallState::Connected);
|
||||
}
|
||||
|
||||
already_AddRefed<TelephonyCall>
|
||||
@@ -297,7 +340,7 @@ TelephonyCallGroup::Remove(TelephonyCall& aCall, ErrorResult& aRv)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (mCallState != nsITelephonyService::CALL_STATE_CONNECTED) {
|
||||
if (mState != TelephonyCallGroupState::Connected) {
|
||||
NS_WARNING("Remove call from a non-connected call group. Ignore!");
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
@@ -330,6 +373,14 @@ TelephonyCallGroup::HangUp(ErrorResult& aRv)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (mState == TelephonyCallGroupState::_empty) {
|
||||
NS_WARNING(nsPrintfCString("We don't have a call group now!"
|
||||
" (State: %s)",
|
||||
TELEPHONY_GROUP_STATE(mState)).get());
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsITelephonyCallback> callback = new TelephonyCallback(promise);
|
||||
aRv = mTelephony->Service()->HangUpConference(mCalls[0]->ServiceId(),
|
||||
callback);
|
||||
@@ -357,6 +408,26 @@ TelephonyCallGroup::Hold(ErrorResult& aRv)
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
TelephonyCallGroup::Hold(nsITelephonyCallback* aCallback)
|
||||
{
|
||||
if (mState != TelephonyCallGroupState::Connected) {
|
||||
NS_WARNING(nsPrintfCString("Resume non-connected call group is rejected!"
|
||||
" (State: %s)",
|
||||
TELEPHONY_GROUP_STATE(mState)).get());
|
||||
aCallback->NotifyError(NS_LITERAL_STRING("InvalidStateError"));
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
}
|
||||
|
||||
nsresult rv = mTelephony->Service()->HoldConference(mCalls[0]->ServiceId(),
|
||||
aCallback);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
TelephonyCallGroup::Resume(ErrorResult& aRv)
|
||||
{
|
||||
@@ -377,29 +448,13 @@ TelephonyCallGroup::Resume(ErrorResult& aRv)
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
TelephonyCallGroup::Hold(nsITelephonyCallback* aCallback)
|
||||
{
|
||||
if (mCallState != nsITelephonyService::CALL_STATE_CONNECTED) {
|
||||
NS_WARNING("Holding a non-connected call is rejected!");
|
||||
aCallback->NotifyError(NS_LITERAL_STRING("InvalidStateError"));
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
}
|
||||
|
||||
nsresult rv = mTelephony->Service()->HoldConference(mCalls[0]->ServiceId(),
|
||||
aCallback);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
TelephonyCallGroup::Resume(nsITelephonyCallback* aCallback)
|
||||
{
|
||||
if (mCallState != nsITelephonyService::CALL_STATE_HELD) {
|
||||
NS_WARNING("Resuming a non-held call is rejected!");
|
||||
if (mState != TelephonyCallGroupState::Held) {
|
||||
NS_WARNING(nsPrintfCString("Resume non-held call group is rejected!"
|
||||
" (State: %s)",
|
||||
TELEPHONY_GROUP_STATE(mState)).get());
|
||||
aCallback->NotifyError(NS_LITERAL_STRING("InvalidStateError"));
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#define mozilla_dom_telephony_telephonycallgroup_h__
|
||||
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/TelephonyCallGroupBinding.h"
|
||||
#include "mozilla/dom/telephony/TelephonyCommon.h"
|
||||
|
||||
namespace mozilla {
|
||||
@@ -21,9 +22,7 @@ class TelephonyCallGroup final : public DOMEventTargetHelper
|
||||
|
||||
RefPtr<CallsList> mCallsList;
|
||||
|
||||
nsString mState;
|
||||
|
||||
uint16_t mCallState;
|
||||
TelephonyCallGroupState mState;
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
@@ -64,10 +63,15 @@ public:
|
||||
already_AddRefed<Promise>
|
||||
Resume(ErrorResult& aRv);
|
||||
|
||||
void
|
||||
GetState(nsString& aState) const
|
||||
TelephonyCallGroupState
|
||||
State() const
|
||||
{
|
||||
aState = mState;
|
||||
return mState;
|
||||
}
|
||||
|
||||
bool
|
||||
IsActive() {
|
||||
return mState == TelephonyCallGroupState::Connected;
|
||||
}
|
||||
|
||||
IMPL_EVENT_HANDLER(statechange)
|
||||
@@ -94,14 +98,9 @@ public:
|
||||
return mCalls;
|
||||
}
|
||||
|
||||
// Update its call state according to the calls wihtin itself.
|
||||
void
|
||||
ChangeState(uint16_t aCallState);
|
||||
|
||||
uint16_t
|
||||
CallState() const
|
||||
{
|
||||
return mCallState;
|
||||
}
|
||||
ChangeState();
|
||||
|
||||
nsresult
|
||||
NotifyError(const nsAString& aName, const nsAString& aMessage);
|
||||
@@ -116,9 +115,15 @@ private:
|
||||
nsresult
|
||||
Resume(nsITelephonyCallback* aCallback);
|
||||
|
||||
nsresult
|
||||
NotifyStateChanged();
|
||||
|
||||
nsresult
|
||||
NotifyCallsChanged(TelephonyCall* aCall);
|
||||
|
||||
void
|
||||
ChangeStateInternal(TelephonyCallGroupState aState);
|
||||
|
||||
nsresult
|
||||
DispatchCallEvent(const nsAString& aType,
|
||||
TelephonyCall* aCall);
|
||||
|
||||
@@ -15,10 +15,13 @@ NS_IMPL_ISUPPORTS(TelephonyCallInfo, nsITelephonyCallInfo)
|
||||
TelephonyCallInfo::TelephonyCallInfo(uint32_t aClientId,
|
||||
uint32_t aCallIndex,
|
||||
uint16_t aCallState,
|
||||
const nsAString& aDisconnectedReason,
|
||||
|
||||
const nsAString& aNumber,
|
||||
uint16_t aNumberPresentation,
|
||||
const nsAString& aName,
|
||||
uint16_t aNamePresentation,
|
||||
|
||||
bool aIsOutgoing,
|
||||
bool aIsEmergency,
|
||||
bool aIsConference,
|
||||
@@ -27,10 +30,13 @@ TelephonyCallInfo::TelephonyCallInfo(uint32_t aClientId,
|
||||
: mClientId(aClientId),
|
||||
mCallIndex(aCallIndex),
|
||||
mCallState(aCallState),
|
||||
mDisconnectedReason(aDisconnectedReason),
|
||||
|
||||
mNumber(aNumber),
|
||||
mNumberPresentation(aNumberPresentation),
|
||||
mName(aName),
|
||||
mNamePresentation(aNamePresentation),
|
||||
|
||||
mIsOutgoing(aIsOutgoing),
|
||||
mIsEmergency(aIsEmergency),
|
||||
mIsConference(aIsConference),
|
||||
@@ -60,6 +66,13 @@ TelephonyCallInfo::GetCallState(uint16_t* aCallState)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyCallInfo::GetDisconnectedReason(nsAString& aDisconnectedReason)
|
||||
{
|
||||
aDisconnectedReason = mDisconnectedReason;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyCallInfo::GetNumber(nsAString& aNumber)
|
||||
{
|
||||
|
||||
@@ -21,12 +21,21 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSITELEPHONYCALLINFO
|
||||
|
||||
TelephonyCallInfo(uint32_t aClientId, uint32_t aCallIndex,
|
||||
uint16_t aCallState, const nsAString& aNumber,
|
||||
uint16_t aNumberPresentation, const nsAString& aName,
|
||||
uint16_t aNamePresentation, bool aIsOutgoing,
|
||||
bool aIsEmergency, bool aIsConference,
|
||||
bool aIsSwitchable, bool aIsMergeable);
|
||||
TelephonyCallInfo(uint32_t aClientId,
|
||||
uint32_t aCallIndex,
|
||||
uint16_t aCallState,
|
||||
const nsAString& aDisconnectedReason,
|
||||
|
||||
const nsAString& aNumber,
|
||||
uint16_t aNumberPresentation,
|
||||
const nsAString& aName,
|
||||
uint16_t aNamePresentation,
|
||||
|
||||
bool aIsOutgoing,
|
||||
bool aIsEmergency,
|
||||
bool aIsConference,
|
||||
bool aIsSwitchable,
|
||||
bool aIsMergeable);
|
||||
|
||||
private:
|
||||
// Don't try to use the default constructor.
|
||||
@@ -37,10 +46,13 @@ private:
|
||||
uint32_t mClientId;
|
||||
uint32_t mCallIndex;
|
||||
uint16_t mCallState;
|
||||
nsString mDisconnectedReason;
|
||||
|
||||
nsString mNumber;
|
||||
uint16_t mNumberPresentation;
|
||||
nsString mName;
|
||||
uint16_t mNamePresentation;
|
||||
|
||||
bool mIsOutgoing;
|
||||
bool mIsEmergency;
|
||||
bool mIsConference;
|
||||
|
||||
@@ -59,7 +59,7 @@ TelephonyDialCallback::NotifyDialCallSuccess(uint32_t aClientId,
|
||||
RefPtr<TelephonyCallId> id = mTelephony->CreateCallId(aNumber);
|
||||
RefPtr<TelephonyCall> call =
|
||||
mTelephony->CreateCall(id, aClientId, aCallIndex,
|
||||
nsITelephonyService::CALL_STATE_DIALING);
|
||||
TelephonyCallState::Dialing);
|
||||
|
||||
mPromise->MaybeResolve(call);
|
||||
return NS_OK;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,3 @@
|
||||
component {67d26434-d063-4d28-9f48-5b3189788155} TelephonyService.js
|
||||
contract @mozilla.org/telephony/gonktelephonyservice;1 {67d26434-d063-4d28-9f48-5b3189788155}
|
||||
|
||||
component {d03684ed-ede4-4210-8206-f4f32772d9f5} TelephonyService.js
|
||||
contract @mozilla.org/dom/system-messages/wrapper/ussd-received;1 {d03684ed-ede4-4210-8206-f4f32772d9f5}
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
/* 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 = ["TelephonyUtils"];
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
|
||||
/* global TelephonyService */
|
||||
XPCOMUtils.defineLazyServiceGetter(this,
|
||||
"TelephonyService",
|
||||
"@mozilla.org/telephony/telephonyservice;1",
|
||||
"nsITelephonyService");
|
||||
|
||||
function getCurrentCalls(aFilter) {
|
||||
if (aFilter === undefined) {
|
||||
aFilter = call => true;
|
||||
}
|
||||
|
||||
let calls = [];
|
||||
|
||||
// nsITelephonyService.enumerateCalls is synchronous.
|
||||
TelephonyService.enumerateCalls({
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsITelephonyListener]),
|
||||
enumerateCallStateComplete: function() {},
|
||||
enumerateCallState: function(call) {
|
||||
if (aFilter(call)) {
|
||||
calls.push(call);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
return calls;
|
||||
}
|
||||
|
||||
this.TelephonyUtils = {
|
||||
/**
|
||||
* Check whether there are any calls.
|
||||
*
|
||||
* @param aClientId [optional] If provided, only check on aClientId
|
||||
* @return boolean
|
||||
*/
|
||||
hasAnyCalls: function(aClientId) {
|
||||
let calls = getCurrentCalls(call => {
|
||||
if (aClientId !== undefined && call.clientId !== aClientId) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
return calls.length !== 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check whether there are any connected calls.
|
||||
*
|
||||
* @param aClientId [optional] If provided, only check on aClientId
|
||||
* @return boolean
|
||||
*/
|
||||
hasConnectedCalls: function(aClientId) {
|
||||
let calls = getCurrentCalls(call => {
|
||||
if (aClientId !== undefined && call.clientId !== aClientId) {
|
||||
return false;
|
||||
}
|
||||
return call.callState === Ci.nsITelephonyService.CALL_STATE_CONNECTED;
|
||||
});
|
||||
|
||||
return calls.length !== 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return a promise which will be resolved when there are no calls.
|
||||
*
|
||||
* @param aClientId [optional] only check on aClientId if provided
|
||||
* @return Promise
|
||||
*/
|
||||
waitForNoCalls: function(aClientId) {
|
||||
if (!this.hasAnyCalls(aClientId)) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
let self = this;
|
||||
return new Promise(resolve => {
|
||||
let listener = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsITelephonyListener]),
|
||||
|
||||
enumerateCallStateComplete: function() {},
|
||||
enumerateCallState: function() {},
|
||||
callStateChanged: function() {
|
||||
if (!self.hasAnyCalls(aClientId)) {
|
||||
TelephonyService.unregisterListener(this);
|
||||
resolve();
|
||||
}
|
||||
},
|
||||
supplementaryServiceNotification: function() {},
|
||||
notifyError: function() {},
|
||||
notifyCdmaCallWaiting: function() {},
|
||||
notifyConferenceError: function() {}
|
||||
};
|
||||
|
||||
TelephonyService.registerListener(listener);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,82 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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";
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
const NS_PREFBRANCH_PREFCHANGE_TOPIC_ID = "nsPref:changed";
|
||||
const kPrefRilDebuggingEnabled = "ril.debugging.enabled";
|
||||
|
||||
let DEBUG;
|
||||
function debug(s) {
|
||||
dump("USSDReceivedWrapper: " + s + "\n");
|
||||
}
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "RIL", function () {
|
||||
let obj = {};
|
||||
Cu.import("resource://gre/modules/ril_consts.js", obj);
|
||||
return obj;
|
||||
});
|
||||
|
||||
/**
|
||||
* This implements nsISystemMessagesWrapper.wrapMessage(), which provides a
|
||||
* plugable way to wrap a "ussd-received" type system message.
|
||||
*
|
||||
* Please see SystemMessageManager.js to know how it customizes the wrapper.
|
||||
*/
|
||||
function USSDReceivedWrapper() {
|
||||
this._updateDebugFlag();
|
||||
Services.prefs.addObserver(kPrefRilDebuggingEnabled, this, false);
|
||||
if (DEBUG) debug("USSDReceivedWrapper()");
|
||||
}
|
||||
USSDReceivedWrapper.prototype = {
|
||||
_updateDebugFlag: function() {
|
||||
try {
|
||||
DEBUG = RIL.DEBUG_RIL ||
|
||||
Services.prefs.getBoolPref(kPrefRilDebuggingEnabled);
|
||||
} catch (e) {}
|
||||
},
|
||||
|
||||
/**
|
||||
* nsIObserver interface.
|
||||
*/
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
switch (aTopic) {
|
||||
case NS_PREFBRANCH_PREFCHANGE_TOPIC_ID:
|
||||
if (aData === kPrefRilDebuggingEnabled) {
|
||||
this._updateDebugFlag();
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
// nsISystemMessagesWrapper implementation.
|
||||
wrapMessage: function(aMessage, aWindow) {
|
||||
if (DEBUG) debug("wrapMessage: " + JSON.stringify(aMessage));
|
||||
|
||||
let session = aMessage.sessionEnded ? null :
|
||||
new aWindow.USSDSession(aMessage.serviceId);
|
||||
|
||||
let event = new aWindow.USSDReceivedEvent("ussdreceived", {
|
||||
serviceId: aMessage.serviceId,
|
||||
message: aMessage.message,
|
||||
session: session
|
||||
});
|
||||
|
||||
return event;
|
||||
},
|
||||
|
||||
classDescription: "USSDReceivedWrapper",
|
||||
classID: Components.ID("{d03684ed-ede4-4210-8206-f4f32772d9f5}"),
|
||||
contractID: "@mozilla.org/dom/system-messages/wrapper/ussd-received;1",
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
|
||||
Ci.nsISystemMessagesWrapper])
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([USSDReceivedWrapper]);
|
||||
@@ -0,0 +1,2 @@
|
||||
component {d03684ed-ede4-4210-8206-f4f32772d9f5} USSDReceivedWrapper.js
|
||||
contract @mozilla.org/dom/system-messages/wrapper/ussd-received;1 {d03684ed-ede4-4210-8206-f4f32772d9f5}
|
||||
@@ -125,14 +125,10 @@ sync protocol PTelephony {
|
||||
manages PTelephonyRequest;
|
||||
|
||||
child:
|
||||
NotifyCallError(uint32_t aClientId, int32_t aCallIndex, nsString aError);
|
||||
|
||||
NotifyCallStateChanged(nsTelephonyCallInfo[] aAllInfo);
|
||||
|
||||
NotifyCdmaCallWaiting(uint32_t aClientId, IPCCdmaWaitingCallData aData);
|
||||
|
||||
NotifyConferenceCallStateChanged(uint16_t aCallState);
|
||||
|
||||
NotifyConferenceError(nsString aName, nsString aMessage);
|
||||
|
||||
NotifySupplementaryService(uint32_t aClientId, int32_t aCallIndex,
|
||||
|
||||
@@ -47,17 +47,6 @@ TelephonyChild::DeallocPTelephonyRequestChild(PTelephonyRequestChild* aActor)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TelephonyChild::RecvNotifyCallError(const uint32_t& aClientId,
|
||||
const int32_t& aCallIndex,
|
||||
const nsString& aError)
|
||||
{
|
||||
MOZ_ASSERT(mService);
|
||||
|
||||
mService->NotifyError(aClientId, aCallIndex, aError);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TelephonyChild::RecvNotifyCallStateChanged(nsTArray<nsITelephonyCallInfo*>&& aAllInfo)
|
||||
{
|
||||
@@ -91,15 +80,6 @@ TelephonyChild::RecvNotifyCdmaCallWaiting(const uint32_t& aClientId,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TelephonyChild::RecvNotifyConferenceCallStateChanged(const uint16_t& aCallState)
|
||||
{
|
||||
MOZ_ASSERT(mService);
|
||||
|
||||
mService->ConferenceCallStateChanged(aCallState);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TelephonyChild::RecvNotifyConferenceError(const nsString& aName,
|
||||
const nsString& aMessage)
|
||||
|
||||
@@ -34,10 +34,6 @@ protected:
|
||||
virtual bool
|
||||
DeallocPTelephonyRequestChild(PTelephonyRequestChild* aActor) override;
|
||||
|
||||
virtual bool
|
||||
RecvNotifyCallError(const uint32_t& aClientId, const int32_t& aCallIndex,
|
||||
const nsString& aError) override;
|
||||
|
||||
virtual bool
|
||||
RecvNotifyCallStateChanged(nsTArray<nsITelephonyCallInfo*>&& aAllInfo) override;
|
||||
|
||||
@@ -45,9 +41,6 @@ protected:
|
||||
RecvNotifyCdmaCallWaiting(const uint32_t& aClientId,
|
||||
const IPCCdmaWaitingCallData& aData) override;
|
||||
|
||||
virtual bool
|
||||
RecvNotifyConferenceCallStateChanged(const uint16_t& aCallState) override;
|
||||
|
||||
virtual bool
|
||||
RecvNotifyConferenceError(const nsString& aName,
|
||||
const nsString& aMessage) override;
|
||||
|
||||
@@ -37,10 +37,13 @@ struct ParamTraits<nsITelephonyCallInfo*>
|
||||
uint32_t clientId;
|
||||
uint32_t callIndex;
|
||||
uint16_t callState;
|
||||
nsString disconnectedReason;
|
||||
|
||||
nsString number;
|
||||
uint16_t numberPresentation;
|
||||
nsString name;
|
||||
uint16_t namePresentation;
|
||||
|
||||
bool isOutgoing;
|
||||
bool isEmergency;
|
||||
bool isConference;
|
||||
@@ -50,10 +53,13 @@ struct ParamTraits<nsITelephonyCallInfo*>
|
||||
aParam->GetClientId(&clientId);
|
||||
aParam->GetCallIndex(&callIndex);
|
||||
aParam->GetCallState(&callState);
|
||||
aParam->GetDisconnectedReason(disconnectedReason);
|
||||
|
||||
aParam->GetNumber(number);
|
||||
aParam->GetNumberPresentation(&numberPresentation);
|
||||
aParam->GetName(name);
|
||||
aParam->GetNamePresentation(&namePresentation);
|
||||
|
||||
aParam->GetIsOutgoing(&isOutgoing);
|
||||
aParam->GetIsEmergency(&isEmergency);
|
||||
aParam->GetIsConference(&isConference);
|
||||
@@ -63,10 +69,13 @@ struct ParamTraits<nsITelephonyCallInfo*>
|
||||
WriteParam(aMsg, clientId);
|
||||
WriteParam(aMsg, callIndex);
|
||||
WriteParam(aMsg, callState);
|
||||
WriteParam(aMsg, disconnectedReason);
|
||||
|
||||
WriteParam(aMsg, number);
|
||||
WriteParam(aMsg, numberPresentation);
|
||||
WriteParam(aMsg, name);
|
||||
WriteParam(aMsg, namePresentation);
|
||||
|
||||
WriteParam(aMsg, isOutgoing);
|
||||
WriteParam(aMsg, isEmergency);
|
||||
WriteParam(aMsg, isConference);
|
||||
@@ -90,10 +99,13 @@ struct ParamTraits<nsITelephonyCallInfo*>
|
||||
uint32_t clientId;
|
||||
uint32_t callIndex;
|
||||
uint16_t callState;
|
||||
nsString disconnectedReason;
|
||||
|
||||
nsString number;
|
||||
uint16_t numberPresentation;
|
||||
nsString name;
|
||||
uint16_t namePresentation;
|
||||
|
||||
bool isOutgoing;
|
||||
bool isEmergency;
|
||||
bool isConference;
|
||||
@@ -104,10 +116,13 @@ struct ParamTraits<nsITelephonyCallInfo*>
|
||||
if (!(ReadParam(aMsg, aIter, &clientId) &&
|
||||
ReadParam(aMsg, aIter, &callIndex) &&
|
||||
ReadParam(aMsg, aIter, &callState) &&
|
||||
ReadParam(aMsg, aIter, &disconnectedReason) &&
|
||||
|
||||
ReadParam(aMsg, aIter, &number) &&
|
||||
ReadParam(aMsg, aIter, &numberPresentation) &&
|
||||
ReadParam(aMsg, aIter, &name) &&
|
||||
ReadParam(aMsg, aIter, &namePresentation) &&
|
||||
|
||||
ReadParam(aMsg, aIter, &isOutgoing) &&
|
||||
ReadParam(aMsg, aIter, &isEmergency) &&
|
||||
ReadParam(aMsg, aIter, &isConference) &&
|
||||
@@ -117,10 +132,21 @@ struct ParamTraits<nsITelephonyCallInfo*>
|
||||
}
|
||||
|
||||
nsCOMPtr<nsITelephonyCallInfo> info =
|
||||
new TelephonyCallInfo(clientId, callIndex, callState, number,
|
||||
numberPresentation, name, namePresentation,
|
||||
isOutgoing, isEmergency, isConference,
|
||||
isSwitchable, isMergeable);
|
||||
new TelephonyCallInfo(clientId,
|
||||
callIndex,
|
||||
callState,
|
||||
disconnectedReason,
|
||||
|
||||
number,
|
||||
numberPresentation,
|
||||
name,
|
||||
namePresentation,
|
||||
|
||||
isOutgoing,
|
||||
isEmergency,
|
||||
isConference,
|
||||
isSwitchable,
|
||||
isMergeable);
|
||||
|
||||
info.forget(aResult);
|
||||
|
||||
|
||||
@@ -376,15 +376,6 @@ TelephonyIPCService::CallStateChanged(uint32_t aLength, nsITelephonyCallInfo** a
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyIPCService::ConferenceCallStateChanged(uint16_t aCallState)
|
||||
{
|
||||
for (uint32_t i = 0; i < mListeners.Length(); i++) {
|
||||
mListeners[i]->ConferenceCallStateChanged(aCallState);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyIPCService::EnumerateCallStateComplete()
|
||||
{
|
||||
@@ -421,16 +412,6 @@ TelephonyIPCService::NotifyConferenceError(const nsAString& aName,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyIPCService::NotifyError(uint32_t aClientId, int32_t aCallIndex,
|
||||
const nsAString& aError)
|
||||
{
|
||||
for (uint32_t i = 0; i < mListeners.Length(); i++) {
|
||||
mListeners[i]->NotifyError(aClientId, aCallIndex, aError);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyIPCService::SupplementaryServiceNotification(uint32_t aClientId,
|
||||
int32_t aCallIndex,
|
||||
|
||||
@@ -286,15 +286,6 @@ TelephonyParent::CallStateChanged(uint32_t aLength, nsITelephonyCallInfo** aAllI
|
||||
return SendNotifyCallStateChanged(allInfo) ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyParent::ConferenceCallStateChanged(uint16_t aCallState)
|
||||
{
|
||||
NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE);
|
||||
|
||||
return SendNotifyConferenceCallStateChanged(aCallState) ? NS_OK
|
||||
: NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyParent::EnumerateCallStateComplete()
|
||||
{
|
||||
@@ -331,17 +322,6 @@ TelephonyParent::NotifyConferenceError(const nsAString& aName,
|
||||
: NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyParent::NotifyError(uint32_t aClientId,
|
||||
int32_t aCallIndex,
|
||||
const nsAString& aError)
|
||||
{
|
||||
NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE);
|
||||
|
||||
return SendNotifyCallError(aClientId, aCallIndex, nsString(aError))
|
||||
? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyParent::SupplementaryServiceNotification(uint32_t aClientId,
|
||||
int32_t aCallIndex,
|
||||
@@ -392,12 +372,6 @@ TelephonyRequestParent::CallStateChanged(uint32_t aLength, nsITelephonyCallInfo*
|
||||
MOZ_CRASH("Not a TelephonyParent!");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyRequestParent::ConferenceCallStateChanged(uint16_t aCallState)
|
||||
{
|
||||
MOZ_CRASH("Not a TelephonyParent!");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyRequestParent::EnumerateCallStateComplete()
|
||||
{
|
||||
@@ -431,14 +405,6 @@ TelephonyRequestParent::NotifyConferenceError(const nsAString& aName,
|
||||
MOZ_CRASH("Not a TelephonyParent!");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyRequestParent::NotifyError(uint32_t aClientId,
|
||||
int32_t aCallIndex,
|
||||
const nsAString& aError)
|
||||
{
|
||||
MOZ_CRASH("Not a TelephonyParent!");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyRequestParent::SupplementaryServiceNotification(uint32_t aClientId,
|
||||
int32_t aCallIndex,
|
||||
|
||||
@@ -63,6 +63,8 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_B2G_RIL']:
|
||||
EXTRA_COMPONENTS += [
|
||||
'gonk/TelephonyAudioService.js',
|
||||
'gonk/TelephonyAudioService.manifest',
|
||||
'gonk/USSDReceivedWrapper.js',
|
||||
'gonk/USSDReceivedWrapper.manifest',
|
||||
]
|
||||
if not CONFIG['DISABLE_MOZ_RIL_GEOLOC']:
|
||||
EXTRA_COMPONENTS += [
|
||||
@@ -70,9 +72,13 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_B2G_RIL']:
|
||||
'gonk/TelephonyService.manifest',
|
||||
]
|
||||
EXTRA_JS_MODULES += [
|
||||
'gonk/DialNumberUtils.jsm'
|
||||
'gonk/DialNumberUtils.jsm',
|
||||
'gonk/TelephonyUtils.jsm',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
if CONFIG['GNU_CXX']:
|
||||
CXXFLAGS += ['-Wshadow']
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(3ea2d155-8ea2-42be-85d7-bd8ede8afc40)]
|
||||
[scriptable, uuid(e5e1be26-a3d4-49b3-8d9f-c1df5192b364)]
|
||||
interface nsITelephonyCallInfo : nsISupports
|
||||
{
|
||||
/**
|
||||
@@ -22,6 +22,14 @@ interface nsITelephonyCallInfo : nsISupports
|
||||
*/
|
||||
readonly attribute unsigned short callState;
|
||||
|
||||
/**
|
||||
* The disconnectedReason of a call is defualt to an empty string when the
|
||||
* call is "not disconnected", but once the call becomes "disconnected" the
|
||||
* disconnectedReason should be a non-empty string no matter the call is
|
||||
* disconnected for a noraml reason or an error.
|
||||
*/
|
||||
readonly attribute DOMString disconnectedReason;
|
||||
|
||||
/**
|
||||
* Number of the other party.
|
||||
*/
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
interface nsIMobileCallForwardingOptions;
|
||||
interface nsITelephonyCallInfo;
|
||||
|
||||
[scriptable, uuid(37fb45bb-ae10-4cfd-b24e-d656a9787a0a)]
|
||||
[scriptable, uuid(baa9f5f3-5cab-40e0-81e9-ae0abd917907)]
|
||||
interface nsITelephonyListener : nsISupports
|
||||
{
|
||||
/**
|
||||
@@ -29,17 +29,6 @@ interface nsITelephonyListener : nsISupports
|
||||
void callStateChanged(in unsigned long length,
|
||||
[array, size_is(length)] in nsITelephonyCallInfo allInfo);
|
||||
|
||||
/**
|
||||
* Called when participants of a conference call have been updated, and the
|
||||
* conference call state changes.
|
||||
*
|
||||
* @param callState
|
||||
* Possible values are: nsITelephonyService::CALL_STATE_UNKNOWN,
|
||||
* nsITelephonyService::CALL_STATE_HELD,
|
||||
* nsITelephonyService::CALL_STATE_CONNECTED.
|
||||
*/
|
||||
void conferenceCallStateChanged(in unsigned short callState);
|
||||
|
||||
/**
|
||||
* Notify when RIL receives supplementary service notification.
|
||||
*
|
||||
@@ -54,20 +43,6 @@ interface nsITelephonyListener : nsISupports
|
||||
in long callIndex,
|
||||
in unsigned short notification);
|
||||
|
||||
/**
|
||||
* Called when RIL error occurs.
|
||||
*
|
||||
* @param clientId
|
||||
Indicate the RIL client, 0 ~ (number of client - 1).
|
||||
* @param callIndex
|
||||
* Call identifier assigned by the RIL. -1 if no connection
|
||||
* @param error
|
||||
* Error from RIL.
|
||||
*/
|
||||
void notifyError(in unsigned long clientId,
|
||||
in long callIndex,
|
||||
in AString error);
|
||||
|
||||
/**
|
||||
* Called when a waiting call comes in CDMA networks.
|
||||
*
|
||||
|
||||
@@ -1022,6 +1022,11 @@ let emulator = (function() {
|
||||
});
|
||||
}
|
||||
|
||||
function sendTone(tone, pause, serviceId) {
|
||||
log("Send DTMF " + tone + " serviceId " + serviceId);
|
||||
return telephony.sendTones(tone, pause, null, serviceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Config radio.
|
||||
*
|
||||
@@ -1085,6 +1090,7 @@ let emulator = (function() {
|
||||
this.gRemoveCallInConference = removeCallInConference;
|
||||
this.gHangUpCallInConference = hangUpCallInConference;
|
||||
this.gHangUpConference = hangUpConference;
|
||||
this.gSendTone = sendTone;
|
||||
this.gSetupConference = setupConference;
|
||||
this.gSetRadioEnabled = setRadioEnabled;
|
||||
}());
|
||||
|
||||
@@ -21,6 +21,7 @@ qemu = true
|
||||
[test_dsds_connection_conflict.js]
|
||||
[test_dsds_default_service_id.js]
|
||||
[test_dsds_normal_call.js]
|
||||
[test_dtmf.js]
|
||||
[test_emergency.js]
|
||||
[test_emergency_label.js]
|
||||
[test_incall_mmi_call_hold.js]
|
||||
@@ -32,7 +33,6 @@ qemu = true
|
||||
[test_incoming_answer_hangup_oncallschanged.js]
|
||||
[test_incoming_basic_operations.js]
|
||||
[test_incoming_onstatechange.js]
|
||||
[test_mmi.js]
|
||||
[test_mmi_call_barring.js]
|
||||
[test_mmi_call_forwarding.js]
|
||||
[test_mmi_call_waiting.js]
|
||||
@@ -41,6 +41,7 @@ qemu = true
|
||||
[test_mmi_change_pin2.js]
|
||||
[test_mmi_clip.js]
|
||||
[test_mmi_clir.js]
|
||||
[test_mmi_imei.js]
|
||||
[test_mmi_unlock_puk.js]
|
||||
[test_mmi_unlock_puk2.js]
|
||||
[test_mmi_ussd.js]
|
||||
@@ -58,4 +59,5 @@ qemu = true
|
||||
[test_ready.js]
|
||||
[test_redundant_operations.js]
|
||||
[test_swap_held_and_active.js]
|
||||
[test_TelephonyUtils.js]
|
||||
[test_temporary_clir.js]
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_TIMEOUT = 60000;
|
||||
MARIONETTE_CONTEXT = "chrome";
|
||||
MARIONETTE_HEAD_JS = 'head.js';
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this,
|
||||
"TelephonyService",
|
||||
"@mozilla.org/telephony/telephonyservice;1",
|
||||
"nsIGonkTelephonyService");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "TelephonyUtils",
|
||||
"resource://gre/modules/TelephonyUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "RIL", function () {
|
||||
let ns = {};
|
||||
Cu.import("resource://gre/modules/ril_consts.js", ns);
|
||||
return ns;
|
||||
});
|
||||
|
||||
const number = "0912345678";
|
||||
|
||||
function dial() {
|
||||
return new Promise(resolve => {
|
||||
TelephonyService.dial(0, number, false, {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsITelephonyDialCallback]),
|
||||
notifyDialCallSuccess: function() { resolve(); }
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function waitForStateChanged() {
|
||||
return new Promise(resolve => {
|
||||
let listener = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsITelephonyListener]),
|
||||
|
||||
callStateChanged: function(length, allInfo) {
|
||||
resolve(allInfo);
|
||||
TelephonyService.unregisterListener(listener);
|
||||
},
|
||||
conferenceCallStateChanged: function() {},
|
||||
supplementaryServiceNotification: function() {},
|
||||
notifyError: function() {},
|
||||
notifyCdmaCallWaiting: function() {},
|
||||
notifyConferenceError: function() {}
|
||||
};
|
||||
|
||||
TelephonyService.registerListener(listener);
|
||||
});
|
||||
}
|
||||
|
||||
function test_noCall() {
|
||||
log("== test_noCall ==");
|
||||
is(TelephonyUtils.hasAnyCalls(), false, "hasAnyCalls");
|
||||
is(TelephonyUtils.hasConnectedCalls(), false, "hasConnectedCalls");
|
||||
return TelephonyUtils.waitForNoCalls();
|
||||
}
|
||||
|
||||
function test_oneCall() {
|
||||
log("== test_oneCall ==");
|
||||
|
||||
return dial()
|
||||
.then(() => {
|
||||
is(TelephonyUtils.hasAnyCalls(), true, "hasAnyCalls");
|
||||
is(TelephonyUtils.hasConnectedCalls(), false, "hasConnectedCalls");
|
||||
})
|
||||
.then(() => {
|
||||
let p = waitForStateChanged();
|
||||
emulator.runCmd("gsm accept " + number);
|
||||
return p;
|
||||
})
|
||||
.then(allInfo => {
|
||||
is(allInfo[0].callState, Ci.nsITelephonyService.CALL_STATE_CONNECTED);
|
||||
is(TelephonyUtils.hasAnyCalls(), true, "hasAnyCalls");
|
||||
is(TelephonyUtils.hasConnectedCalls(), true, "hasConnectedCalls");
|
||||
})
|
||||
.then(() => {
|
||||
let p = TelephonyUtils.waitForNoCalls();
|
||||
emulator.runCmd("gsm cancel " + number);
|
||||
return p;
|
||||
});
|
||||
}
|
||||
|
||||
test_noCall()
|
||||
.then(test_oneCall)
|
||||
.catch(error => ok(false, "Promise reject: " + error))
|
||||
.then(finish);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user