/* 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(); } /** * Test error message returned in onerror for readICCContacts. */ add_test(function test_error_message_read_icc_contact () { let worker = newUint8Worker(); let context = worker.ContextPool._contexts[0]; let ril = context.RIL; function do_test(options, expectedErrorMsg) { ril.sendChromeMessage = function(message) { equal(message.errorMsg, expectedErrorMsg); } ril.readICCContacts(options); } // Error 1, didn't specify correct contactType. do_test({}, CONTACT_ERR_REQUEST_NOT_SUPPORTED); // Error 2, specifying a non-supported contactType. ril.appType = CARD_APPTYPE_USIM; do_test({contactType: "foo"}, CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED); // Error 3, suppose we update the supported PBR fields in USIM_PBR_FIELDS, // but forget to add implemenetations for it. USIM_PBR_FIELDS.push("pbc"); do_test({contactType: GECKO_CARDCONTACT_TYPE_ADN}, CONTACT_ERR_FIELD_NOT_SUPPORTED); run_next_test(); }); /** * Test error message returned in onerror for updateICCContact. */ add_test(function test_error_message_update_icc_contact() { let worker = newUint8Worker(); let context = worker.ContextPool._contexts[0]; let ril = context.RIL; const ICCID = "123456789"; ril.iccInfo.iccid = ICCID; function do_test(options, expectedErrorMsg) { ril.sendChromeMessage = function(message) { equal(message.errorMsg, expectedErrorMsg); } ril.updateICCContact(options); } // Error 1, didn't specify correct contactType. do_test({}, CONTACT_ERR_REQUEST_NOT_SUPPORTED); // Error 2, specifying a correct contactType, but without providing 'contact'. do_test({contactType: GECKO_CARDCONTACT_TYPE_ADN}, CONTACT_ERR_REQUEST_NOT_SUPPORTED); // Error 3, specifying a non-supported contactType. ril.appType = CARD_APPTYPE_USIM; do_test({contactType: GECKO_CARDCONTACT_TYPE_SDN, contact: {}}, CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED); // Error 4, without supplying pin2. do_test({contactType: GECKO_CARDCONTACT_TYPE_FDN, contact: {contactId: ICCID + "1"}}, GECKO_ERROR_SIM_PIN2); // Error 5, No free record found in EF_ADN. let record = context.ICCRecordHelper; record.readPBR = function(onsuccess, onerror) { onsuccess([{adn: {fileId: 0x4f3a}}]); }; let io = context.ICCIOHelper; io.loadLinearFixedEF = function(options) { options.totalRecords = 1; options.p1 = 1; options.callback(options); }; do_test({contactType: GECKO_CARDCONTACT_TYPE_ADN, contact: {}}, CONTACT_ERR_NO_FREE_RECORD_FOUND); // Error 6, ICC IO Error. io.loadLinearFixedEF = function(options) { ril[REQUEST_SIM_IO](0, { errorMsg: GECKO_ERROR_GENERIC_FAILURE }); }; do_test({contactType: GECKO_CARDCONTACT_TYPE_ADN, contact: {contactId: ICCID + "1"}}, GECKO_ERROR_GENERIC_FAILURE); // Error 7, suppose we update the supported PBR fields in USIM_PBR_FIELDS, // but forget to add implemenetations for it. USIM_PBR_FIELDS.push("pbc"); do_test({contactType: GECKO_CARDCONTACT_TYPE_ADN, contact: {contactId: ICCID + "1"}}, CONTACT_ERR_FIELD_NOT_SUPPORTED); // Error 8, EF_PBR doesn't exist. record.readPBR = function(onsuccess, onerror) { onsuccess([]); }; do_test({contactType: GECKO_CARDCONTACT_TYPE_ADN, contact: {contactId: ICCID + "1"}}, CONTACT_ERR_CANNOT_ACCESS_PHONEBOOK); run_next_test(); }); /** * Verify ICCContactHelper.readICCContacts */ add_test(function test_read_icc_contacts() { let worker = newUint8Worker(); let context = worker.ContextPool._contexts[0]; let record = context.ICCRecordHelper; let contactHelper = context.ICCContactHelper; let ril = context.RIL; let test_data = [ //Record 1. { comment: "Test read SIM adn contact", rawData: { simType: CARD_APPTYPE_SIM, contactType: GECKO_CARDCONTACT_TYPE_ADN, adnLike: [{recordId: 1, alphaId: "name", number: "111111"}], }, expectedContact: [{ recordId: 1, alphaId: "name", number: "111111" }], }, //Record 2. { comment: "Test read SIM fdn contact", rawData: { simType: CARD_APPTYPE_SIM, contactType: GECKO_CARDCONTACT_TYPE_FDN, adnLike: [{recordId: 1, alphaId: "name", number: "111111"}], }, expectedContact: [{ recordId: 1, alphaId: "name", number: "111111" }], }, //Record 3. { comment: "Test read USIM adn contact", rawData: { simType: CARD_APPTYPE_USIM, contactType: GECKO_CARDCONTACT_TYPE_ADN, pbrs: [{adn:{fileId: 0x6f3a}, email: {}, anr0: {}}], adnLike: [{recordId: 1, alphaId: "name", number: "111111"}], email: "hello@mail.com", anr: "123456", }, expectedContact: [{ pbrIndex: 0, recordId: 1, alphaId: "name", number: "111111", email: "hello@mail.com", anr: ["123456"] }], }, //Record 4. { comment: "Test read USIM adn contacts", rawData: { simType: CARD_APPTYPE_USIM, contactType: GECKO_CARDCONTACT_TYPE_ADN, pbrs: [{adn:{fileId: 0x6f3a}, email: {}, anr0: {}}, {adn:{fileId: 0x6f3b}, email: {}, anr0: {}}], adnLike: [{recordId: 1, alphaId: "name1", number: "111111"}, {recordId: 2, alphaId: "name2", number: "222222"}], email: "hello@mail.com", anr: "123456", }, expectedContact: [ { pbrIndex: 0, recordId: 1, alphaId: "name1", number: "111111", email: "hello@mail.com", anr: ["123456"] }, { pbrIndex: 0, recordId: 2, alphaId: "name2", number: "222222", email: "hello@mail.com", anr: ["123456"] }, { pbrIndex: 1, recordId: 1, alphaId: "name1", number: "111111", email: "hello@mail.com", anr: ["123456"] }, { pbrIndex: 1, recordId: 2, alphaId: "name2", number: "222222", email: "hello@mail.com", anr: ["123456"] } ], }, //Record 5. { comment: "Test read USIM fdn contact", rawData: { simType: CARD_APPTYPE_USIM, contactType: GECKO_CARDCONTACT_TYPE_FDN, adnLike: [{recordId: 1, alphaId: "name", number: "111111"}], }, expectedContact: [{ recordId: 1, alphaId: "name", number: "111111" }], }, //Record 6. { comment: "Test read RUIM adn contact", rawData: { simType: CARD_APPTYPE_RUIM, contactType: GECKO_CARDCONTACT_TYPE_ADN, adnLike: [{recordId: 1, alphaId: "name", number: "111111"}], }, expectedContact: [{ recordId: 1, alphaId: "name", number: "111111" }], }, //Record 7. { comment: "Test read RUIM fdn contact", rawData: { simType: CARD_APPTYPE_RUIM, contactType: GECKO_CARDCONTACT_TYPE_FDN, adnLike: [{recordId: 1, alphaId: "name", number: "111111"}], }, expectedContact: [{ recordId: 1, alphaId: "name", number: "111111" }], }, //Record 8. { comment: "Test read RUIM adn contact with enhanced phone book", rawData: { simType: CARD_APPTYPE_RUIM, contactType: GECKO_CARDCONTACT_TYPE_ADN, pbrs: [{adn:{fileId: 0x6f3a}, email: {}, anr0: {}}], adnLike: [{recordId: 1, alphaId: "name", number: "111111"}], email: "hello@mail.com", anr: "123456", enhancedPhoneBook: true, }, expectedContact: [{ pbrIndex: 0, recordId: 1, alphaId: "name", number: "111111", email: "hello@mail.com", anr: ["123456"] }], }, //Record 9. { comment: "Test read RUIM adn contacts with enhanced phone book", rawData: { simType: CARD_APPTYPE_RUIM, contactType: GECKO_CARDCONTACT_TYPE_ADN, pbrs: [{adn:{fileId: 0x6f3a}, email: {}, anr0: {}}, {adn:{fileId: 0x6f3b}, email: {}, anr0: {}}], adnLike: [{recordId: 1, alphaId: "name1", number: "111111"}, {recordId: 2, alphaId: "name2", number: "222222"}], email: "hello@mail.com", anr: "123456", enhancedPhoneBook: true, }, expectedContact: [ { pbrIndex: 0, recordId: 1, alphaId: "name1", number: "111111", email: "hello@mail.com", anr: ["123456"] }, { pbrIndex: 0, recordId: 2, alphaId: "name2", number: "222222", email: "hello@mail.com", anr: ["123456"] }, { pbrIndex: 1, recordId: 1, alphaId: "name1", number: "111111", email: "hello@mail.com", anr: ["123456"] }, { pbrIndex: 1, recordId: 2, alphaId: "name2", number: "222222", email: "hello@mail.com", anr: ["123456"] } ], }, ]; function do_test(aTestData, aExpectedContact) { ril.appType = aTestData.simType; ril._isCdma = (aTestData.simType === CARD_APPTYPE_RUIM); ril.iccInfoPrivate.cst = (aTestData.enhancedPhoneBook) ? [0x20, 0x0C, 0x0, 0x0, 0x0]: [0x20, 0x00, 0x0, 0x0, 0x0]; ril.iccInfoPrivate.sst = (aTestData.simType === CARD_APPTYPE_SIM)? [0x20, 0x0, 0x0, 0x0, 0x0]: [0x2, 0x0, 0x0, 0x0, 0x0]; // Override some functions to test. contactHelper.getContactFieldRecordId = function(pbr, contact, field, onsuccess, onerror) { onsuccess(1); }; record.readPBR = function readPBR(onsuccess, onerror) { onsuccess(JSON.parse(JSON.stringify(aTestData.pbrs))); }; record.readADNLike = function readADNLike(fileId, extFileId, onsuccess, onerror) { onsuccess(JSON.parse(JSON.stringify(aTestData.adnLike))); }; record.readEmail = function readEmail(fileId, fileType, recordNumber, onsuccess, onerror) { onsuccess(aTestData.email); }; record.readANR = function readANR(fileId, fileType, recordNumber, onsuccess, onerror) { onsuccess(aTestData.anr); }; let onsuccess = function onsuccess(contacts) { for (let i = 0; i < contacts.length; i++) { do_print("check contacts[" + i + "]:" + JSON.stringify(contacts[i])); deepEqual(contacts[i], aExpectedContact[i]); } }; let onerror = function onerror(errorMsg) { do_print("readICCContacts failed: " + errorMsg); ok(false); }; contactHelper.readICCContacts(aTestData.simType, aTestData.contactType, onsuccess, onerror); } for (let i = 0; i < test_data.length; i++) { do_print(test_data[i].comment); do_test(test_data[i].rawData, test_data[i].expectedContact); } run_next_test(); }); /** * Verify ICCContactHelper.updateICCContact with appType is CARD_APPTYPE_USIM. */ add_test(function test_update_icc_contact() { 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; const EXT_RECORD_ID = 0x01; 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, aFileType, aHaveIapIndex, aEnhancedPhoneBook) { ril.appType = aSimType; ril._isCdma = (aSimType === CARD_APPTYPE_RUIM); ril.iccInfoPrivate.cst = (aEnhancedPhoneBook) ? [0x20, 0x0C, 0x28, 0x0, 0x20] : [0x20, 0x0, 0x28, 0x0, 0x20]; ril.iccInfoPrivate.sst = (aSimType === CARD_APPTYPE_SIM)? [0x20, 0x0, 0x28, 0x0, 0x20]: [0x16, 0x0, 0x0, 0x0, 0x0]; recordHelper.readPBR = function(onsuccess, onerror) { if (aFileType === ICC_USIM_TYPE1_TAG) { onsuccess([{ adn: {fileId: ICC_EF_ADN}, email: {fileId: EMAIL_FILE_ID, fileType: ICC_USIM_TYPE1_TAG}, anr0: {fileId: ANR0_FILE_ID, fileType: ICC_USIM_TYPE1_TAG}, ext1: {fileId: ICC_EF_EXT1} }]); } else if (aFileType === ICC_USIM_TYPE2_TAG) { 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}, ext1: {fileId: ICC_EF_EXT1} }]); } }; 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); onsuccess((aHaveIapIndex) ? [EMAIL_RECORD_ID, ANR0_RECORD_ID] : [0xff, 0xff]); }; recordHelper.updateIAP = function(fileId, recordNumber, iap, onsuccess, onerror) { equal(fileId, IAP_FILE_ID); equal(recordNumber, ADN_RECORD_ID); onsuccess(); }; recordHelper.updateEmail = function(pbr, recordNumber, email, adnRecordId, onsuccess, onerror) { equal(pbr.email.fileId, EMAIL_FILE_ID); if (pbr.email.fileType === ICC_USIM_TYPE1_TAG) { equal(recordNumber, ADN_RECORD_ID); } else if (pbr.email.fileType === ICC_USIM_TYPE2_TAG) { equal(recordNumber, EMAIL_RECORD_ID); } equal(email, aContact.email); onsuccess(email); }; recordHelper.updateANR = function(pbr, recordNumber, number, adnRecordId, onsuccess, onerror) { equal(pbr.anr0.fileId, ANR0_FILE_ID); if (pbr.anr0.fileType === ICC_USIM_TYPE1_TAG) { equal(recordNumber, ADN_RECORD_ID); } else if (pbr.anr0.fileType === ICC_USIM_TYPE2_TAG) { equal(recordNumber, ANR0_RECORD_ID); } if (Array.isArray(aContact.anr)) { equal(number, aContact.anr[0]); } onsuccess(number); }; recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) { let recordId = 0; if (fileId === EMAIL_FILE_ID) { recordId = EMAIL_RECORD_ID; } else if (fileId === ANR0_FILE_ID) { recordId = ANR0_RECORD_ID; } onsuccess(recordId); }; let isSuccess = false; 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; }; let onerror = function onerror(errorMsg) { do_print("updateICCContact failed: " + errorMsg); }; contactHelper.updateICCContact(aSimType, aContactType, aContact, aPin2, onsuccess, onerror); ok(isSuccess); } let contacts = [ { pbrIndex: 0, recordId: ADN_RECORD_ID, alphaId: "test", number: "123456", email: "test@mail.com", anr: ["+654321"] }, // a contact without email and anr. { pbrIndex: 0, recordId: ADN_RECORD_ID, alphaId: "test2", number: "123456", }, // a contact with email but no anr. { pbrIndex: 0, recordId: ADN_RECORD_ID, alphaId: "test3", number: "123456", email: "test@mail.com" }, // a contact with anr but no email. { pbrIndex: 0, recordId: ADN_RECORD_ID, 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++) { let contact = contacts[i]; // SIM do_print("Test update SIM adn contacts"); do_test(CARD_APPTYPE_SIM, GECKO_CARDCONTACT_TYPE_ADN, contact); do_print("Test update SIM fdn contacts"); do_test(CARD_APPTYPE_SIM, GECKO_CARDCONTACT_TYPE_FDN, contact, "1234"); // USIM do_print("Test update USIM adn contacts"); do_test(CARD_APPTYPE_USIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null, ICC_USIM_TYPE1_TAG); do_test(CARD_APPTYPE_USIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null, ICC_USIM_TYPE2_TAG, true); do_test(CARD_APPTYPE_USIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null, ICC_USIM_TYPE2_TAG, false); do_print("Test update USIM fdn contacts"); do_test(CARD_APPTYPE_USIM, GECKO_CARDCONTACT_TYPE_FDN, contact, "1234"); // RUIM do_print("Test update RUIM adn contacts"); do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_ADN, contact); do_print("Test update RUIM fdn contacts"); do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_FDN, contact, "1234"); // RUIM with enhanced phone book do_print("Test update RUIM adn contacts with enhanced phone book"); do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null, ICC_USIM_TYPE1_TAG, null,true); do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null, ICC_USIM_TYPE2_TAG, true, true); do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null, ICC_USIM_TYPE2_TAG, false, true); do_print("Test update RUIM fdn contacts with enhanced phone book"); do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_FDN, contact, "1234", null, true); } 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. */ add_test(function test_update_icc_contact_with_remove_type1_attr() { const ADN_RECORD_ID = 100; 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; recordHelper.updateADNLike = function(fileId, extRecordNumber, contact, pin2, onsuccess, onerror) { onsuccess({alphaId: contact.alphaId, number: contact.number}); }; let contact = { pbrIndex: 0, recordId: ADN_RECORD_ID, alphaId: "test2", number: "123456", }; recordHelper.readIAP = function(fileId, recordNumber, onsuccess, onerror) { onsuccess([EMAIL_RECORD_ID, ANR0_RECORD_ID]); }; recordHelper.updateEmail = function(pbr, recordNumber, email, adnRecordId, onsuccess, onerror) { ok(email == null); onsuccess(email); }; recordHelper.updateANR = function(pbr, recordNumber, number, adnRecordId, onsuccess, onerror) { ok(number == null); onsuccess(number); }; function do_test(type) { recordHelper.readPBR = function(onsuccess, onerror) { if (type == ICC_USIM_TYPE1_TAG) { onsuccess([{ adn: {fileId: ICC_EF_ADN}, email: {fileId: EMAIL_FILE_ID, fileType: ICC_USIM_TYPE1_TAG}, anr0: {fileId: ANR0_FILE_ID, fileType: ICC_USIM_TYPE1_TAG}}]); } else { onsuccess([{ adn: {fileId: ICC_EF_ADN}, 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}}]); } }; let successCb = function(updatedContact) { equal(updatedContact.email, null); equal(updatedContact.anr, null); ok(true); }; let errorCb = function(errorMsg) { do_print(errorMsg); ok(false); }; contactHelper.updateICCContact(CARD_APPTYPE_USIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null, successCb, errorCb); } do_test(ICC_USIM_TYPE1_TAG); do_test(ICC_USIM_TYPE2_TAG); run_next_test(); }); /** * Verify ICCContactHelper.findFreeICCContact in SIM */ add_test(function test_find_free_icc_contact_sim() { let worker = newUint8Worker(); let context = worker.ContextPool._contexts[0]; let recordHelper = context.ICCRecordHelper; let contactHelper = context.ICCContactHelper; // Correct record Id starts with 1, so put a null element at index 0. let records = [null]; const MAX_RECORDS = 3; const PBR_INDEX = 0; recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) { if (records.length > MAX_RECORDS) { onerror("No free record found."); return; } onsuccess(records.length); }; let successCb = function(pbrIndex, recordId) { equal(pbrIndex, PBR_INDEX); records[recordId] = {}; }; let errorCb = function(errorMsg) { do_print(errorMsg); ok(false); }; for (let i = 0; i < MAX_RECORDS; i++) { contactHelper.findFreeICCContact(CARD_APPTYPE_SIM, GECKO_CARDCONTACT_TYPE_ADN, successCb, errorCb); } // The 1st element, records[0], is null. equal(records.length - 1, MAX_RECORDS); // Now the EF is full, so finding a free one should result failure. successCb = function(pbrIndex, recordId) { ok(false); }; errorCb = function(errorMsg) { ok(errorMsg === "No free record found."); }; contactHelper.findFreeICCContact(CARD_APPTYPE_SIM, GECKO_CARDCONTACT_TYPE_ADN, successCb, errorCb); run_next_test(); }); /** * Verify ICCContactHelper.findFreeICCContact in USIM */ add_test(function test_find_free_icc_contact_usim() { let worker = newUint8Worker(); let context = worker.ContextPool._contexts[0]; let recordHelper = context.ICCRecordHelper; let contactHelper = context.ICCContactHelper; const ADN1_FILE_ID = 0x6f3a; const ADN2_FILE_ID = 0x6f3b; const MAX_RECORDS = 3; // The adn in the first phonebook set has already two records, which means // only 1 free record remained. let pbrs = [{adn: {fileId: ADN1_FILE_ID, records: [null, {}, {}]}}, {adn: {fileId: ADN2_FILE_ID, records: [null]}}]; recordHelper.readPBR = function readPBR(onsuccess, onerror) { onsuccess(pbrs); }; recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) { let pbr = (fileId == ADN1_FILE_ID ? pbrs[0]: pbrs[1]); if (pbr.adn.records.length > MAX_RECORDS) { onerror("No free record found."); return; } onsuccess(pbr.adn.records.length); }; let successCb = function(pbrIndex, recordId) { equal(pbrIndex, 0); pbrs[pbrIndex].adn.records[recordId] = {}; }; let errorCb = function(errorMsg) { ok(false); }; contactHelper.findFreeICCContact(CARD_APPTYPE_USIM, GECKO_CARDCONTACT_TYPE_ADN, successCb, errorCb); // Now the EF_ADN in the 1st phonebook set is full, so the next free contact // will come from the 2nd phonebook set. successCb = function(pbrIndex, recordId) { equal(pbrIndex, 1); equal(recordId, 1); } contactHelper.findFreeICCContact(CARD_APPTYPE_USIM, GECKO_CARDCONTACT_TYPE_ADN, successCb, errorCb); 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(); });