summaryrefslogtreecommitdiffstats
path: root/dom/system/gonk/tests/test_ril_worker_icc_SimRecordHelper.js
diff options
context:
space:
mode:
Diffstat (limited to 'dom/system/gonk/tests/test_ril_worker_icc_SimRecordHelper.js')
-rw-r--r--dom/system/gonk/tests/test_ril_worker_icc_SimRecordHelper.js1648
1 files changed, 1648 insertions, 0 deletions
diff --git a/dom/system/gonk/tests/test_ril_worker_icc_SimRecordHelper.js b/dom/system/gonk/tests/test_ril_worker_icc_SimRecordHelper.js
new file mode 100644
index 000000000..6500cc663
--- /dev/null
+++ b/dom/system/gonk/tests/test_ril_worker_icc_SimRecordHelper.js
@@ -0,0 +1,1648 @@
+/* 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();
+}
+
+/**
+ * Verify reading EF_AD and parsing MCC/MNC
+ */
+add_test(function test_reading_ad_and_parsing_mcc_mnc() {
+ let worker = newUint8Worker();
+ let context = worker.ContextPool._contexts[0];
+ let record = context.SimRecordHelper;
+ let helper = context.GsmPDUHelper;
+ let ril = context.RIL;
+ let buf = context.Buf;
+ let io = context.ICCIOHelper;
+
+ function do_test(mncLengthInEf, imsi, expectedMcc, expectedMnc) {
+ ril.iccInfoPrivate.imsi = imsi;
+
+ io.loadTransparentEF = function fakeLoadTransparentEF(options) {
+ let ad = [0x00, 0x00, 0x00];
+ if (typeof mncLengthInEf === 'number') {
+ ad.push(mncLengthInEf);
+ }
+
+ // Write data size
+ buf.writeInt32(ad.length * 2);
+
+ // Write data
+ for (let i = 0; i < ad.length; i++) {
+ helper.writeHexOctet(ad[i]);
+ }
+
+ // Write string delimiter
+ buf.writeStringDelimiter(ad.length * 2);
+
+ if (options.callback) {
+ options.callback(options);
+ }
+ };
+
+ record.readAD();
+
+ equal(ril.iccInfo.mcc, expectedMcc);
+ equal(ril.iccInfo.mnc, expectedMnc);
+ }
+
+ do_test(undefined, "466923202422409", "466", "92" );
+ do_test(0x00, "466923202422409", "466", "92" );
+ do_test(0x01, "466923202422409", "466", "92" );
+ do_test(0x02, "466923202422409", "466", "92" );
+ do_test(0x03, "466923202422409", "466", "923");
+ do_test(0x04, "466923202422409", "466", "92" );
+ do_test(0xff, "466923202422409", "466", "92" );
+
+ do_test(undefined, "310260542718417", "310", "260");
+ do_test(0x00, "310260542718417", "310", "260");
+ do_test(0x01, "310260542718417", "310", "260");
+ do_test(0x02, "310260542718417", "310", "26" );
+ do_test(0x03, "310260542718417", "310", "260");
+ do_test(0x04, "310260542718417", "310", "260");
+ do_test(0xff, "310260542718417", "310", "260");
+
+ run_next_test();
+});
+
+add_test(function test_reading_optional_efs() {
+ let worker = newUint8Worker();
+ let context = worker.ContextPool._contexts[0];
+ let record = context.SimRecordHelper;
+ let gsmPdu = context.GsmPDUHelper;
+ let ril = context.RIL;
+ let buf = context.Buf;
+ let io = context.ICCIOHelper;
+
+ function buildSST(supportedEf) {
+ let sst = [];
+ let len = supportedEf.length;
+ for (let i = 0; i < len; i++) {
+ let index, bitmask, iccService;
+ if (ril.appType === CARD_APPTYPE_SIM) {
+ iccService = GECKO_ICC_SERVICES.sim[supportedEf[i]];
+ iccService -= 1;
+ index = Math.floor(iccService / 4);
+ bitmask = 2 << ((iccService % 4) << 1);
+ } else if (ril.appType === CARD_APPTYPE_USIM){
+ iccService = GECKO_ICC_SERVICES.usim[supportedEf[i]];
+ iccService -= 1;
+ index = Math.floor(iccService / 8);
+ bitmask = 1 << ((iccService % 8) << 0);
+ }
+
+ if (sst) {
+ sst[index] |= bitmask;
+ }
+ }
+ return sst;
+ }
+
+ ril.updateCellBroadcastConfig = function fakeUpdateCellBroadcastConfig() {
+ // Ignore updateCellBroadcastConfig after reading SST
+ };
+
+ function do_test(sst, supportedEf) {
+ // Clone supportedEf to local array for testing
+ let testEf = supportedEf.slice(0);
+
+ record.readMSISDN = function fakeReadMSISDN() {
+ testEf.splice(testEf.indexOf("MSISDN"), 1);
+ };
+
+ record.readMBDN = function fakeReadMBDN() {
+ testEf.splice(testEf.indexOf("MDN"), 1);
+ };
+
+ record.readMWIS = function fakeReadMWIS() {
+ testEf.splice(testEf.indexOf("MWIS"), 1);
+ };
+
+ io.loadTransparentEF = function fakeLoadTransparentEF(options) {
+ // Write data size
+ buf.writeInt32(sst.length * 2);
+
+ // Write data
+ for (let i = 0; i < sst.length; i++) {
+ gsmPdu.writeHexOctet(sst[i] || 0);
+ }
+
+ // Write string delimiter
+ buf.writeStringDelimiter(sst.length * 2);
+
+ if (options.callback) {
+ options.callback(options);
+ }
+
+ if (testEf.length !== 0) {
+ do_print("Un-handled EF: " + JSON.stringify(testEf));
+ ok(false);
+ }
+ };
+
+ record.readSST();
+ }
+
+ // TODO: Add all necessary optional EFs eventually
+ let supportedEf = ["MSISDN", "MDN", "MWIS"];
+ ril.appType = CARD_APPTYPE_SIM;
+ do_test(buildSST(supportedEf), supportedEf);
+ ril.appType = CARD_APPTYPE_USIM;
+ do_test(buildSST(supportedEf), supportedEf);
+
+ run_next_test();
+});
+
+/**
+ * Verify fetchSimRecords.
+ */
+add_test(function test_fetch_sim_records() {
+ let worker = newWorker();
+ let context = worker.ContextPool._contexts[0];
+ let RIL = context.RIL;
+ let iccRecord = context.ICCRecordHelper;
+ let simRecord = context.SimRecordHelper;
+
+ function testFetchSimRecordes(expectCalled, expectCphsSuccess) {
+ let ifCalled = [];
+
+ RIL.getIMSI = function() {
+ ifCalled.push("getIMSI");
+ };
+
+ simRecord.readAD = function() {
+ ifCalled.push("readAD");
+ };
+
+ simRecord.readCphsInfo = function(onsuccess, onerror) {
+ ifCalled.push("readCphsInfo");
+ if (expectCphsSuccess) {
+ onsuccess();
+ } else {
+ onerror();
+ }
+ };
+
+ simRecord.readSST = function() {
+ ifCalled.push("readSST");
+ };
+
+ simRecord.fetchSimRecords();
+
+ for (let i = 0; i < expectCalled.length; i++ ) {
+ if (ifCalled[i] != expectCalled[i]) {
+ do_print(expectCalled[i] + " is not called.");
+ ok(false);
+ }
+ }
+ }
+
+ let expectCalled = ["getIMSI", "readAD", "readCphsInfo", "readSST"];
+ testFetchSimRecordes(expectCalled, true);
+ testFetchSimRecordes(expectCalled, false);
+
+ run_next_test();
+});
+
+/**
+ * Verify SimRecordHelper.readMWIS
+ */
+add_test(function test_read_mwis() {
+ let worker = newUint8Worker();
+ let context = worker.ContextPool._contexts[0];
+ let helper = context.GsmPDUHelper;
+ let recordHelper = context.SimRecordHelper;
+ let buf = context.Buf;
+ let io = context.ICCIOHelper;
+ let mwisData;
+ let postedMessage;
+
+ worker.postMessage = function fakePostMessage(message) {
+ postedMessage = message;
+ };
+
+ io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
+ if (mwisData) {
+ // Write data size
+ buf.writeInt32(mwisData.length * 2);
+
+ // Write MWIS
+ for (let i = 0; i < mwisData.length; i++) {
+ helper.writeHexOctet(mwisData[i]);
+ }
+
+ // Write string delimiter
+ buf.writeStringDelimiter(mwisData.length * 2);
+
+ options.recordSize = mwisData.length;
+ if (options.callback) {
+ options.callback(options);
+ }
+ } else {
+ do_print("mwisData[] is not set.");
+ }
+ };
+
+ function buildMwisData(isActive, msgCount) {
+ if (msgCount < 0 || msgCount === GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN) {
+ msgCount = 0;
+ } else if (msgCount > 255) {
+ msgCount = 255;
+ }
+
+ mwisData = [ (isActive) ? 0x01 : 0x00,
+ msgCount,
+ 0xFF, 0xFF, 0xFF ];
+ }
+
+ function do_test(isActive, msgCount) {
+ buildMwisData(isActive, msgCount);
+ recordHelper.readMWIS();
+
+ equal("iccmwis", postedMessage.rilMessageType);
+ equal(isActive, postedMessage.mwi.active);
+ equal((isActive) ? msgCount : 0, postedMessage.mwi.msgCount);
+ }
+
+ do_test(true, GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN);
+ do_test(true, 1);
+ do_test(true, 255);
+
+ do_test(false, 0);
+ do_test(false, 255); // Test the corner case when mwi is disable with incorrect msgCount.
+
+ run_next_test();
+});
+
+/**
+ * Verify SimRecordHelper.updateMWIS
+ */
+add_test(function test_update_mwis() {
+ let worker = newUint8Worker();
+ let context = worker.ContextPool._contexts[0];
+ let pduHelper = context.GsmPDUHelper;
+ let ril = context.RIL;
+ ril.appType = CARD_APPTYPE_USIM;
+ ril.iccInfoPrivate.mwis = [0x00, 0x00, 0x00, 0x00, 0x00];
+ let recordHelper = context.SimRecordHelper;
+ let buf = context.Buf;
+ let ioHelper = context.ICCIOHelper;
+ let recordSize = ril.iccInfoPrivate.mwis.length;
+ let recordNum = 1;
+
+ 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 = recordSize;
+ ril.iccIO(options);
+ };
+
+ function do_test(isActive, count) {
+ let mwis = ril.iccInfoPrivate.mwis;
+ let isUpdated = false;
+
+ function buildMwisData() {
+ let result = mwis.slice(0);
+ result[0] = isActive? (mwis[0] | 0x01) : (mwis[0] & 0xFE);
+ result[1] = (count === GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN) ? 0 : count;
+
+ return result;
+ }
+
+ buf.sendParcel = function() {
+ isUpdated = true;
+
+ // 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(), ICC_EF_MWIS);
+
+ // pathId.
+ equal(this.readString(),
+ EF_PATH_MF_SIM + ((ril.appType === CARD_APPTYPE_USIM) ? EF_PATH_ADF_USIM : EF_PATH_DF_GSM));
+
+ // p1.
+ equal(this.readInt32(), recordNum);
+
+ // p2.
+ equal(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
+
+ // p3.
+ equal(this.readInt32(), recordSize);
+
+ // data.
+ let strLen = this.readInt32();
+ equal(recordSize * 2, strLen);
+ let expectedMwis = buildMwisData();
+ for (let i = 0; i < recordSize; i++) {
+ equal(expectedMwis[i], pduHelper.readHexOctet());
+ }
+ this.readStringDelimiter(strLen);
+
+ // pin2.
+ equal(this.readString(), null);
+
+ // AID. Ignore because it's from modem.
+ this.readInt32();
+ };
+
+ ok(!isUpdated);
+
+ recordHelper.updateMWIS({ active: isActive,
+ msgCount: count });
+
+ ok((ril.iccInfoPrivate.mwis) ? isUpdated : !isUpdated);
+ }
+
+ do_test(true, GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN);
+ do_test(true, 1);
+ do_test(true, 255);
+
+ do_test(false, 0);
+
+ // Test if Path ID is correct for SIM.
+ ril.appType = CARD_APPTYPE_SIM;
+ do_test(false, 0);
+
+ // Test if loadLinearFixedEF() is not invoked in updateMWIS() when
+ // EF_MWIS is not loaded/available.
+ delete ril.iccInfoPrivate.mwis;
+ do_test(false, 0);
+
+ run_next_test();
+});
+
+/**
+ * Verify the call flow of receiving Class 2 SMS stored in SIM:
+ * 1. UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM.
+ * 2. SimRecordHelper.readSMS().
+ * 3. sendChromeMessage() with rilMessageType == "sms-received".
+ */
+add_test(function test_read_new_sms_on_sim() {
+ // Instead of reusing newUint8Worker defined in this file,
+ // we define our own worker to fake the methods in WorkerBuffer dynamically.
+ function newSmsOnSimWorkerHelper() {
+ let _postedMessage;
+ let _worker = newWorker({
+ postRILMessage: function(data) {
+ },
+ postMessage: function(message) {
+ _postedMessage = message;
+ }
+ });
+
+ _worker.debug = do_print;
+
+ return {
+ get postedMessage() {
+ return _postedMessage;
+ },
+ get worker() {
+ return _worker;
+ },
+ fakeWokerBuffer: function() {
+ let context = _worker.ContextPool._contexts[0];
+ let index = 0; // index for read
+ let buf = [];
+ context.Buf.writeUint8 = function(value) {
+ buf.push(value);
+ };
+ context.Buf.readUint8 = function() {
+ return buf[index++];
+ };
+ context.Buf.seekIncoming = function(offset) {
+ index += offset;
+ };
+ context.Buf.getReadAvailable = function() {
+ return buf.length - index;
+ };
+ }
+ };
+ }
+
+ let workerHelper = newSmsOnSimWorkerHelper();
+ let worker = workerHelper.worker;
+ let context = worker.ContextPool._contexts[0];
+
+ context.ICCIOHelper.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
+ // SimStatus: Unread, SMSC:+0123456789, Sender: +9876543210, Text: How are you?
+ let SimSmsPduHex = "0306911032547698040A9189674523010000208062917314080CC8F71D14969741F977FD07"
+ // In 4.2.25 EF_SMS Short Messages of 3GPP TS 31.102:
+ // 1. Record length == 176 bytes.
+ // 2. Any bytes in the record following the TPDU shall be filled with 'FF'.
+ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF";
+
+ workerHelper.fakeWokerBuffer();
+
+ context.Buf.writeString(SimSmsPduHex);
+
+ options.recordSize = 176; // Record length is fixed to 176 bytes.
+ if (options.callback) {
+ options.callback(options);
+ }
+ };
+
+ function newSmsOnSimParcel() {
+ let data = new Uint8Array(4 + 4); // Int32List with 1 element.
+ let offset = 0;
+
+ function writeInt(value) {
+ data[offset++] = value & 0xFF;
+ data[offset++] = (value >> 8) & 0xFF;
+ data[offset++] = (value >> 16) & 0xFF;
+ data[offset++] = (value >> 24) & 0xFF;
+ }
+
+ writeInt(1); // Length of Int32List
+ writeInt(1); // RecordNum = 1.
+
+ return newIncomingParcel(-1,
+ RESPONSE_TYPE_UNSOLICITED,
+ UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM,
+ data);
+ }
+
+ function do_test() {
+ worker.onRILMessage(0, newSmsOnSimParcel());
+
+ let postedMessage = workerHelper.postedMessage;
+
+ equal("sms-received", postedMessage.rilMessageType);
+ equal("+0123456789", postedMessage.SMSC);
+ equal("+9876543210", postedMessage.sender);
+ equal("How are you?", postedMessage.body);
+ }
+
+ do_test();
+
+ run_next_test();
+});
+
+/**
+ * Verify the result of updateDisplayCondition after reading EF_SPDI | EF_SPN.
+ */
+add_test(function test_update_display_condition() {
+ let worker = newUint8Worker();
+ let context = worker.ContextPool._contexts[0];
+ let record = context.SimRecordHelper;
+ let helper = context.GsmPDUHelper;
+ let ril = context.RIL;
+ let buf = context.Buf;
+ let io = context.ICCIOHelper;
+
+ function do_test_spdi() {
+ // No EF_SPN, but having EF_SPDI.
+ // It implies "ril.iccInfoPrivate.spnDisplayCondition = undefined;".
+ io.loadTransparentEF = function fakeLoadTransparentEF(options) {
+ // PLMN lists are : 234-136 and 466-92.
+ let spdi = [0xA3, 0x0B, 0x80, 0x09, 0x32, 0x64, 0x31, 0x64, 0x26, 0x9F,
+ 0xFF, 0xFF, 0xFF];
+
+ // Write data size.
+ buf.writeInt32(spdi.length * 2);
+
+ // Write data.
+ for (let i = 0; i < spdi.length; i++) {
+ helper.writeHexOctet(spdi[i]);
+ }
+
+ // Write string delimiter.
+ buf.writeStringDelimiter(spdi.length * 2);
+
+ if (options.callback) {
+ options.callback(options);
+ }
+ };
+
+ record.readSPDI();
+
+ equal(ril.iccInfo.isDisplayNetworkNameRequired, true);
+ equal(ril.iccInfo.isDisplaySpnRequired, false);
+ }
+
+ function do_test_spn(displayCondition,
+ expectedPlmnNameDisplay,
+ expectedSpnDisplay) {
+ io.loadTransparentEF = function fakeLoadTransparentEF(options) {
+ // "Android" as Service Provider Name.
+ let spn = [0x41, 0x6E, 0x64, 0x72, 0x6F, 0x69, 0x64];
+ if (typeof displayCondition === 'number') {
+ spn.unshift(displayCondition);
+ }
+
+ // Write data size.
+ buf.writeInt32(spn.length * 2);
+
+ // Write data.
+ for (let i = 0; i < spn.length; i++) {
+ helper.writeHexOctet(spn[i]);
+ }
+
+ // Write string delimiter.
+ buf.writeStringDelimiter(spn.length * 2);
+
+ if (options.callback) {
+ options.callback(options);
+ }
+ };
+
+ record.readSPN();
+
+ equal(ril.iccInfo.isDisplayNetworkNameRequired, expectedPlmnNameDisplay);
+ equal(ril.iccInfo.isDisplaySpnRequired, expectedSpnDisplay);
+ }
+
+ // Create empty operator object.
+ ril.operator = {};
+ // Setup SIM MCC-MNC to 310-260 as home network.
+ ril.iccInfo.mcc = 310;
+ ril.iccInfo.mnc = 260;
+
+ do_test_spdi();
+
+ // No network.
+ do_test_spn(0x00, true, true);
+ do_test_spn(0x01, true, true);
+ do_test_spn(0x02, true, false);
+ do_test_spn(0x03, true, false);
+
+ // Home network.
+ ril.operator.mcc = 310;
+ ril.operator.mnc = 260;
+ do_test_spn(0x00, false, true);
+ do_test_spn(0x01, true, true);
+ do_test_spn(0x02, false, true);
+ do_test_spn(0x03, true, true);
+
+ // Not HPLMN but in PLMN list.
+ ril.iccInfoPrivate.SPDI = [{"mcc":"234","mnc":"136"},{"mcc":"466","mnc":"92"}];
+ ril.operator.mcc = 466;
+ ril.operator.mnc = 92;
+ do_test_spn(0x00, false, true);
+ do_test_spn(0x01, true, true);
+ do_test_spn(0x02, false, true);
+ do_test_spn(0x03, true, true);
+ ril.iccInfoPrivate.SPDI = null; // reset SPDI to null;
+
+ // Non-Home network.
+ ril.operator.mcc = 466;
+ ril.operator.mnc = 01;
+ do_test_spn(0x00, true, true);
+ do_test_spn(0x01, true, true);
+ do_test_spn(0x02, true, false);
+ do_test_spn(0x03, true, false);
+
+ run_next_test();
+});
+
+/**
+ * Verify reading EF_IMG and EF_IIDF with ICC_IMG_CODING_SCHEME_BASIC
+ */
+add_test(function test_reading_img_basic() {
+ let worker = newUint8Worker();
+ let context = worker.ContextPool._contexts[0];
+ let record = context.SimRecordHelper;
+ let helper = context.GsmPDUHelper;
+ let ril = context.RIL;
+ let buf = context.Buf;
+ let io = context.ICCIOHelper;
+
+ let test_data = [
+ {img: [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x06],
+ iidf: [
+ [/* Header */
+ 0x05, 0x05,
+ /* Image body */
+ 0x11, 0x33, 0x55, 0xfe]],
+ expected: [
+ {width: 0x05,
+ height: 0x05,
+ codingScheme: ICC_IMG_CODING_SCHEME_BASIC,
+ body: [0x11, 0x33, 0x55, 0xfe]}]},
+ {img: [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x06,
+ /* Padding */
+ 0xff, 0xff],
+ iidf: [
+ [/* Header */
+ 0x05, 0x05,
+ /* Image body */
+ 0x11, 0x33, 0x55, 0xfe]],
+ expected: [
+ {width: 0x05,
+ height: 0x05,
+ codingScheme: ICC_IMG_CODING_SCHEME_BASIC,
+ body: [0x11, 0x33, 0x55, 0xfe]}]},
+ {img: [0x02, 0x10, 0x01, 0x11, 0x4f, 0x04, 0x00, 0x05, 0x00, 0x04, 0x10,
+ 0x01, 0x11, 0x4f, 0x05, 0x00, 0x05, 0x00, 0x04],
+ iidf: [
+ [/* Data offset */
+ 0xff, 0xff, 0xff, 0xff, 0xff,
+ /* Header */
+ 0x10, 0x01,
+ /* Image body */
+ 0x11, 0x99,
+ /* Trailing data */
+ 0xff, 0xff, 0xff],
+ [/* Data offset */
+ 0xff, 0xff, 0xff, 0xff, 0xff,
+ /* Header */
+ 0x10, 0x01,
+ /* Image body */
+ 0x99, 0x11]],
+ expected: [
+ {width: 0x10,
+ height: 0x01,
+ codingScheme: ICC_IMG_CODING_SCHEME_BASIC,
+ body: [0x11, 0x99]},
+ {width: 0x10,
+ height: 0x01,
+ codingScheme: ICC_IMG_CODING_SCHEME_BASIC,
+ body: [0x99, 0x11]}]},
+ {img: [0x01, 0x28, 0x20, 0x11, 0x4f, 0xac, 0x00, 0x0b, 0x00, 0xa2],
+ iidf: [
+ [/* Data offset */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ /* Header */
+ 0x28, 0x20,
+ /* Image body */
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
+ 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
+ 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
+ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
+ 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
+ 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41,
+ 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c,
+ 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x00, 0x01, 0x02,
+ 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
+ 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+ 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
+ 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
+ 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f]],
+ expected: [
+ {width: 0x28,
+ height: 0x20,
+ codingScheme: ICC_IMG_CODING_SCHEME_BASIC,
+ body: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
+ 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
+ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
+ 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
+ 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
+ 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+ 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x00, 0x01, 0x02, 0x03,
+ 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
+ 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21,
+ 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
+ 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f]}]}];
+
+ function do_test(img, iidf, expected) {
+ io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
+ // Write data size
+ buf.writeInt32(img.length * 2);
+
+ // Write data
+ for (let i = 0; i < img.length; i++) {
+ helper.writeHexOctet(img[i]);
+ }
+
+ // Write string delimiter
+ buf.writeStringDelimiter(img.length * 2);
+
+ if (options.callback) {
+ options.callback(options);
+ }
+ };
+
+ let instanceIndex = 0;
+ io.loadTransparentEF = function fakeLoadTransparentEF(options) {
+ // Write data size
+ buf.writeInt32(iidf[instanceIndex].length * 2);
+
+ // Write data
+ for (let i = 0; i < iidf[instanceIndex].length; i++) {
+ helper.writeHexOctet(iidf[instanceIndex][i]);
+ }
+
+ // Write string delimiter
+ buf.writeStringDelimiter(iidf[instanceIndex].length * 2);
+
+ instanceIndex++;
+
+ if (options.callback) {
+ options.callback(options);
+ }
+ };
+
+ let onsuccess = function(icons) {
+ equal(icons.length, expected.length);
+ for (let i = 0; i < icons.length; i++) {
+ let icon = icons[i];
+ let exp = expected[i];
+ equal(icon.width, exp.width);
+ equal(icon.height, exp.height);
+ equal(icon.codingScheme, exp.codingScheme);
+
+ equal(icon.body.length, exp.body.length);
+ for (let j = 0; j < icon.body.length; j++) {
+ equal(icon.body[j], exp.body[j]);
+ }
+ }
+ };
+ record.readIMG(0, onsuccess);
+ }
+
+ for (let i = 0; i< test_data.length; i++) {
+ do_test(test_data[i].img, test_data[i].iidf, test_data[i].expected);
+ }
+ run_next_test();
+});
+
+/**
+ * Verify reading EF_IMG and EF_IIDF with the case data length is not enough
+ */
+add_test(function test_reading_img_length_error() {
+ let worker = newUint8Worker();
+ let context = worker.ContextPool._contexts[0];
+ let record = context.SimRecordHelper;
+ let helper = context.GsmPDUHelper;
+ let ril = context.RIL;
+ let buf = context.Buf;
+ let io = context.ICCIOHelper;
+
+ let test_data = [
+ {/* Offset length not enough, should be 4. */
+ img: [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x04, 0x00, 0x06],
+ iidf: [0xff, 0xff, 0xff, // Offset.
+ 0x05, 0x05, 0x11, 0x22, 0x33, 0xfe]},
+ {/* iidf data length not enough, should be 6. */
+ img: [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x06],
+ iidf: [0x05, 0x05, 0x11, 0x22, 0x33]}];
+
+ function do_test(img, iidf) {
+ io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
+ // Write data size
+ buf.writeInt32(img.length * 2);
+
+ // Write data
+ for (let i = 0; i < img.length; i++) {
+ helper.writeHexOctet(img[i]);
+ }
+
+ // Write string delimiter
+ buf.writeStringDelimiter(img.length * 2);
+
+ if (options.callback) {
+ options.callback(options);
+ }
+ };
+
+ io.loadTransparentEF = function fakeLoadTransparentEF(options) {
+ // Write data size
+ buf.writeInt32(iidf.length * 2);
+
+ // Write data
+ for (let i = 0; i < iidf.length; i++) {
+ helper.writeHexOctet(iidf[i]);
+ }
+
+ // Write string delimiter
+ buf.writeStringDelimiter(iidf.length * 2);
+
+ if (options.callback) {
+ options.callback(options);
+ }
+ };
+
+ let onsuccess = function() {
+ do_print("onsuccess shouldn't be called.");
+ ok(false);
+ };
+
+ let onerror = function() {
+ do_print("onerror called as expected.");
+ ok(true);
+ };
+
+ record.readIMG(0, onsuccess, onerror);
+ }
+
+ for (let i = 0; i < test_data.length; i++) {
+ do_test(test_data[i].img, test_data[i].iidf);
+ }
+ run_next_test();
+});
+
+/**
+ * Verify reading EF_IMG and EF_IIDF with an invalid fileId
+ */
+add_test(function test_reading_img_invalid_fileId() {
+ let worker = newUint8Worker();
+ let context = worker.ContextPool._contexts[0];
+ let record = context.SimRecordHelper;
+ let helper = context.GsmPDUHelper;
+ let ril = context.RIL;
+ let buf = context.Buf;
+ let io = context.ICCIOHelper;
+
+ // Test invalid fileId: 0x5f00.
+ let img_test = [0x01, 0x05, 0x05, 0x11, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x06];
+ let iidf_test = [0x05, 0x05, 0x11, 0x22, 0x33, 0xfe];
+
+ io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
+ // Write data size
+ buf.writeInt32(img_test.length * 2);
+
+ // Write data
+ for (let i = 0; i < img_test.length; i++) {
+ helper.writeHexOctet(img_test[i]);
+ }
+
+ // Write string delimiter
+ buf.writeStringDelimiter(img_test.length * 2);
+
+ if (options.callback) {
+ options.callback(options);
+ }
+ };
+
+ io.loadTransparentEF = function fakeLoadTransparentEF(options) {
+ // Write data size
+ buf.writeInt32(iidf_test.length * 2);
+
+ // Write data
+ for (let i = 0; i < iidf_test.length; i++) {
+ helper.writeHexOctet(iidf_test[i]);
+ }
+
+ // Write string delimiter
+ buf.writeStringDelimiter(iidf_test.length * 2);
+
+ if (options.callback) {
+ options.callback(options);
+ }
+ };
+
+ let onsuccess = function() {
+ do_print("onsuccess shouldn't be called.");
+ ok(false);
+ };
+
+ let onerror = function() {
+ do_print("onerror called as expected.");
+ ok(true);
+ };
+
+ record.readIMG(0, onsuccess, onerror);
+
+ run_next_test();
+});
+
+/**
+ * Verify reading EF_IMG with a wrong record length
+ */
+add_test(function test_reading_img_wrong_record_length() {
+ let worker = newUint8Worker();
+ let context = worker.ContextPool._contexts[0];
+ let record = context.SimRecordHelper;
+ let helper = context.GsmPDUHelper;
+ let ril = context.RIL;
+ let buf = context.Buf;
+ let io = context.ICCIOHelper;
+
+ let test_data = [
+ [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00],
+ [0x02, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x06]];
+
+ function do_test(img) {
+ io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
+ // Write data size
+ buf.writeInt32(img.length * 2);
+
+ // Write data
+ for (let i = 0; i < img.length; i++) {
+ helper.writeHexOctet(img[i]);
+ }
+
+ // Write string delimiter
+ buf.writeStringDelimiter(img.length * 2);
+
+ if (options.callback) {
+ options.callback(options);
+ }
+ };
+
+ let onsuccess = function() {
+ do_print("onsuccess shouldn't be called.");
+ ok(false);
+ };
+
+ let onerror = function() {
+ do_print("onerror called as expected.");
+ ok(true);
+ };
+
+ record.readIMG(0, onsuccess, onerror);
+ }
+
+ for (let i = 0; i < test_data.length; i++) {
+ do_test(test_data[i]);
+ }
+ run_next_test();
+});
+
+/**
+ * Verify reading EF_IMG and EF_IIDF with ICC_IMG_CODING_SCHEME_COLOR
+ */
+add_test(function test_reading_img_color() {
+ let worker = newUint8Worker();
+ let context = worker.ContextPool._contexts[0];
+ let record = context.SimRecordHelper;
+ let helper = context.GsmPDUHelper;
+ let ril = context.RIL;
+ let buf = context.Buf;
+ let io = context.ICCIOHelper;
+
+ let test_data = [
+ {img: [0x01, 0x05, 0x05, 0x21, 0x4f, 0x11, 0x00, 0x00, 0x00, 0x13],
+ iidf: [
+ [/* Header */
+ 0x05, 0x05, 0x03, 0x08, 0x00, 0x13,
+ /* Image body */
+ 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0,
+ 0xb0, 0xc0, 0xd0,
+ /* Clut entries */
+ 0x00, 0x01, 0x02,
+ 0x10, 0x11, 0x12,
+ 0x20, 0x21, 0x22,
+ 0x30, 0x31, 0x32,
+ 0x40, 0x41, 0x42,
+ 0x50, 0x51, 0x52,
+ 0x60, 0x61, 0x62,
+ 0x70, 0x71, 0x72]],
+ expected: [
+ {width: 0x05,
+ height: 0x05,
+ codingScheme: ICC_IMG_CODING_SCHEME_COLOR,
+ bitsPerImgPoint: 0x03,
+ numOfClutEntries: 0x08,
+ body: [0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, 0xb0,
+ 0xc0, 0xd0],
+ clut: [0x00, 0x01, 0x02,
+ 0x10, 0x11, 0x12,
+ 0x20, 0x21, 0x22,
+ 0x30, 0x31, 0x32,
+ 0x40, 0x41, 0x42,
+ 0x50, 0x51, 0x52,
+ 0x60, 0x61, 0x62,
+ 0x70, 0x71, 0x72]}]},
+ {img: [0x02, 0x01, 0x06, 0x21, 0x4f, 0x33, 0x00, 0x02, 0x00, 0x08, 0x01,
+ 0x06, 0x21, 0x4f, 0x44, 0x00, 0x02, 0x00, 0x08],
+ iidf: [
+ [/* Data offset */
+ 0xff, 0xff,
+ /* Header */
+ 0x01, 0x06, 0x02, 0x04, 0x00, 0x0d,
+ /* Image body */
+ 0x40, 0x50,
+ /* Clut offset */
+ 0xaa, 0xbb, 0xcc,
+ /* Clut entries */
+ 0x01, 0x03, 0x05,
+ 0x21, 0x23, 0x25,
+ 0x41, 0x43, 0x45,
+ 0x61, 0x63, 0x65],
+ [/* Data offset */
+ 0xff, 0xff,
+ /* Header */
+ 0x01, 0x06, 0x02, 0x04, 0x00, 0x0d,
+ /* Image body */
+ 0x4f, 0x5f,
+ /* Clut offset */
+ 0xaa, 0xbb, 0xcc,
+ /* Clut entries */
+ 0x11, 0x13, 0x15,
+ 0x21, 0x23, 0x25,
+ 0x41, 0x43, 0x45,
+ 0x61, 0x63, 0x65]],
+ expected: [
+ {width: 0x01,
+ height: 0x06,
+ codingScheme: ICC_IMG_CODING_SCHEME_COLOR,
+ bitsPerImgPoint: 0x02,
+ numOfClutEntries: 0x04,
+ body: [0x40, 0x50],
+ clut: [0x01, 0x03, 0x05,
+ 0x21, 0x23, 0x25,
+ 0x41, 0x43, 0x45,
+ 0x61, 0x63, 0x65]},
+ {width: 0x01,
+ height: 0x06,
+ codingScheme: ICC_IMG_CODING_SCHEME_COLOR,
+ bitsPerImgPoint: 0x02,
+ numOfClutEntries: 0x04,
+ body: [0x4f, 0x5f],
+ clut: [0x11, 0x13, 0x15,
+ 0x21, 0x23, 0x25,
+ 0x41, 0x43, 0x45,
+ 0x61, 0x63, 0x65]}]}];
+
+ function do_test(img, iidf, expected) {
+ io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
+ // Write data size
+ buf.writeInt32(img.length * 2);
+
+ // Write data
+ for (let i = 0; i < img.length; i++) {
+ helper.writeHexOctet(img[i]);
+ }
+
+ // Write string delimiter
+ buf.writeStringDelimiter(img.length * 2);
+
+ if (options.callback) {
+ options.callback(options);
+ }
+ };
+
+ let instanceIndex = 0;
+ io.loadTransparentEF = function fakeLoadTransparentEF(options) {
+ // Write data size
+ buf.writeInt32(iidf[instanceIndex].length * 2);
+
+ // Write data
+ for (let i = 0; i < iidf[instanceIndex].length; i++) {
+ helper.writeHexOctet(iidf[instanceIndex][i]);
+ }
+
+ // Write string delimiter
+ buf.writeStringDelimiter(iidf[instanceIndex].length * 2);
+
+ instanceIndex++;
+
+ if (options.callback) {
+ options.callback(options);
+ }
+ };
+
+ let onsuccess = function(icons) {
+ equal(icons.length, expected.length);
+ for (let i = 0; i < icons.length; i++) {
+ let icon = icons[i];
+ let exp = expected[i];
+ equal(icon.width, exp.width);
+ equal(icon.height, exp.height);
+ equal(icon.codingScheme, exp.codingScheme);
+
+ equal(icon.body.length, exp.body.length);
+ for (let j = 0; j < icon.body.length; j++) {
+ equal(icon.body[j], exp.body[j]);
+ }
+
+ equal(icon.clut.length, exp.clut.length);
+ for (let j = 0; j < icon.clut.length; j++) {
+ equal(icon.clut[j], exp.clut[j]);
+ }
+ }
+ };
+
+ record.readIMG(0, onsuccess);
+ }
+
+ for (let i = 0; i< test_data.length; i++) {
+ do_test(test_data[i].img, test_data[i].iidf, test_data[i].expected);
+ }
+ run_next_test();
+});
+
+/**
+ * Verify reading EF_IMG and EF_IIDF with
+ * ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY
+ */
+add_test(function test_reading_img_color() {
+ let worker = newUint8Worker();
+ let context = worker.ContextPool._contexts[0];
+ let record = context.SimRecordHelper;
+ let helper = context.GsmPDUHelper;
+ let ril = context.RIL;
+ let buf = context.Buf;
+ let io = context.ICCIOHelper;
+
+ let test_data = [
+ {img: [0x01, 0x05, 0x05, 0x22, 0x4f, 0x11, 0x00, 0x00, 0x00, 0x13],
+ iidf: [
+ [/* Header */
+ 0x05, 0x05, 0x03, 0x08, 0x00, 0x13,
+ /* Image body */
+ 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0,
+ 0xb0, 0xc0, 0xd0,
+ /* Clut entries */
+ 0x00, 0x01, 0x02,
+ 0x10, 0x11, 0x12,
+ 0x20, 0x21, 0x22,
+ 0x30, 0x31, 0x32,
+ 0x40, 0x41, 0x42,
+ 0x50, 0x51, 0x52,
+ 0x60, 0x61, 0x62,
+ 0x70, 0x71, 0x72]],
+ expected: [
+ {width: 0x05,
+ height: 0x05,
+ codingScheme: ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY,
+ bitsPerImgPoint: 0x03,
+ numOfClutEntries: 0x08,
+ body: [0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90,
+ 0xa0, 0xb0, 0xc0, 0xd0],
+ clut: [0x00, 0x01, 0x02,
+ 0x10, 0x11, 0x12,
+ 0x20, 0x21, 0x22,
+ 0x30, 0x31, 0x32,
+ 0x40, 0x41, 0x42,
+ 0x50, 0x51, 0x52,
+ 0x60, 0x61, 0x62,
+ 0x70, 0x71, 0x72]}]},
+ {img: [0x02, 0x01, 0x06, 0x22, 0x4f, 0x33, 0x00, 0x02, 0x00, 0x08, 0x01,
+ 0x06, 0x22, 0x4f, 0x33, 0x00, 0x02, 0x00, 0x08],
+ iidf: [
+ [/* Data offset */
+ 0xff, 0xff,
+ /* Header */
+ 0x01, 0x06, 0x02, 0x04, 0x00, 0x0d,
+ /* Image body */
+ 0x40, 0x50,
+ /* Clut offset */
+ 0x0a, 0x0b, 0x0c,
+ /* Clut entries */
+ 0x01, 0x03, 0x05,
+ 0x21, 0x23, 0x25,
+ 0x41, 0x43, 0x45,
+ 0x61, 0x63, 0x65],
+ [/* Data offset */
+ 0xff, 0xff,
+ /* Header */
+ 0x01, 0x06, 0x02, 0x04, 0x00, 0x0d,
+ /* Image body */
+ 0x4f, 0x5f,
+ /* Clut offset */
+ 0x0a, 0x0b, 0x0c,
+ /* Clut entries */
+ 0x11, 0x13, 0x15,
+ 0x21, 0x23, 0x25,
+ 0x41, 0x43, 0x45,
+ 0x61, 0x63, 0x65]],
+ expected: [
+ {width: 0x01,
+ height: 0x06,
+ codingScheme: ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY,
+ bitsPerImgPoint: 0x02,
+ numOfClutEntries: 0x04,
+ body: [0x40, 0x50],
+ clut: [0x01, 0x03, 0x05,
+ 0x21, 0x23, 0x25,
+ 0x41, 0x43, 0x45,
+ 0x61, 0x63, 0x65]},
+ {width: 0x01,
+ height: 0x06,
+ codingScheme: ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY,
+ bitsPerImgPoint: 0x02,
+ numOfClutEntries: 0x04,
+ body: [0x4f, 0x5f],
+ clut: [0x11, 0x13, 0x15,
+ 0x21, 0x23, 0x25,
+ 0x41, 0x43, 0x45,
+ 0x61, 0x63, 0x65]}]}];
+
+ function do_test(img, iidf, expected) {
+ io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
+ // Write data size
+ buf.writeInt32(img.length * 2);
+
+ // Write data
+ for (let i = 0; i < img.length; i++) {
+ helper.writeHexOctet(img[i]);
+ }
+
+ // Write string delimiter
+ buf.writeStringDelimiter(img.length * 2);
+
+ if (options.callback) {
+ options.callback(options);
+ }
+ };
+
+ let instanceIndex = 0;
+ io.loadTransparentEF = function fakeLoadTransparentEF(options) {
+ // Write data size
+ buf.writeInt32(iidf[instanceIndex].length * 2);
+
+ // Write data
+ for (let i = 0; i < iidf[instanceIndex].length; i++) {
+ helper.writeHexOctet(iidf[instanceIndex][i]);
+ }
+
+ // Write string delimiter
+ buf.writeStringDelimiter(iidf[instanceIndex].length * 2);
+
+ instanceIndex++;
+
+ if (options.callback) {
+ options.callback(options);
+ }
+ };
+
+ let onsuccess = function(icons) {
+ equal(icons.length, expected.length);
+ for (let i = 0; i < icons.length; i++) {
+ let icon = icons[i];
+ let exp = expected[i];
+ equal(icon.width, exp.width);
+ equal(icon.height, exp.height);
+ equal(icon.codingScheme, exp.codingScheme);
+
+ equal(icon.body.length, exp.body.length);
+ for (let j = 0; j < icon.body.length; j++) {
+ equal(icon.body[j], exp.body[j]);
+ }
+
+ equal(icon.clut.length, exp.clut.length);
+ for (let j = 0; j < icon.clut.length; j++) {
+ equal(icon.clut[j], exp.clut[j]);
+ }
+ }
+ };
+
+ record.readIMG(0, onsuccess);
+ }
+
+ for (let i = 0; i< test_data.length; i++) {
+ do_test(test_data[i].img, test_data[i].iidf, test_data[i].expected);
+ }
+ run_next_test();
+});
+
+/**
+ * Verify SimRecordHelper.readCphsInfo
+ */
+add_test(function test_read_cphs_info() {
+ let worker = newUint8Worker();
+ let context = worker.ContextPool._contexts[0];
+ let RIL = context.RIL;
+ let pduHelper = context.GsmPDUHelper;
+ let recordHelper = context.SimRecordHelper;
+ let buf = context.Buf;
+ let io = context.ICCIOHelper;
+ let cphsPDU = new Uint8Array(3);
+
+ io.loadTransparentEF = function(options) {
+ if (cphsPDU) {
+ // Write data size
+ buf.writeInt32(cphsPDU.length * 2);
+
+ // Write CPHS INFO
+ for (let i = 0; i < cphsPDU.length; i++) {
+ pduHelper.writeHexOctet(cphsPDU[i]);
+ }
+
+ // Write string delimiter
+ buf.writeStringDelimiter(cphsPDU.length * 2);
+
+ if (options.callback) {
+ options.callback(options);
+ }
+ } else {
+ do_print("cphsPDU[] is not set.");
+ }
+ };
+
+ function do_test(cphsInfo, cphsSt) {
+ let onsuccess = false;
+ let onerror = false;
+
+ delete RIL.iccInfoPrivate.cphsSt;
+ cphsPDU.set(cphsInfo);
+ recordHelper.readCphsInfo(() => { onsuccess = true; },
+ () => { onerror = true; });
+
+ ok((cphsSt) ? onsuccess : onerror);
+ ok(!((cphsSt) ? onerror : onsuccess));
+ if (cphsSt) {
+ equal(RIL.iccInfoPrivate.cphsSt.length, cphsSt.length);
+ for (let i = 0; i < cphsSt.length; i++) {
+ equal(RIL.iccInfoPrivate.cphsSt[i], cphsSt[i]);
+ }
+ } else {
+ equal(RIL.iccInfoPrivate.cphsSt, cphsSt);
+ }
+ }
+
+ do_test([
+ 0x01, // Phase 1
+ 0xFF, // All available & activated
+ 0x03 // All available & activated
+ ],
+ [
+ 0x3F, // All services except ONSF(bit 8-7) are available and activated.
+ 0x00 // INFO_NUM shall not be available & activated.
+ ]);
+
+ do_test([
+ 0x02, // Phase 2
+ 0xFF, // All available & activated
+ 0x03 // All available & activated
+ ],
+ [
+ 0xF3, // All services except ONSF are available and activated.
+ 0x03 // INFO_NUM shall not be available & activated.
+ ]);
+
+ do_test([
+ 0x03, // Phase 3
+ 0xFF, // All available & activated
+ 0x03 // All available & activated
+ ],
+ undefined); // RIL.iccInfoPrivate.cphsSt shall be remained as 'undefined'.
+
+ run_next_test();
+});
+
+/**
+ * Verify SimRecordHelper.readMBDN/SimRecordHelper.readCphsMBN
+ */
+add_test(function test_read_voicemail_number() {
+ let worker = newUint8Worker();
+ let context = worker.ContextPool._contexts[0];
+ let RIL = context.RIL;
+ let pduHelper = context.GsmPDUHelper;
+ let recordHelper = context.SimRecordHelper;
+ let buf = context.Buf;
+ let io = context.ICCIOHelper;
+ let postedMessage;
+
+ worker.postMessage = function(message) {
+ postedMessage = message;
+ };
+
+ io.loadLinearFixedEF = function(options) {
+ let mbnData = [
+ 0x56, 0x6F, 0x69, 0x63, 0x65, 0x6D, 0x61, 0x69,
+ 0x6C, 0xFF, // Alpha Identifier: Voicemail
+ 0x03, // Length of BCD number: 3
+ 0x80, // TOA: Unknown
+ 0x11, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, // Dialing Number: 111
+ 0xFF, // Capability/Configuration Record Identifier
+ 0xFF // Extension Record Identifier
+ ];
+
+ // Write data size
+ buf.writeInt32(mbnData.length * 2);
+
+ // Write MBN
+ for (let i = 0; i < mbnData.length; i++) {
+ pduHelper.writeHexOctet(mbnData[i]);
+ }
+
+ // Write string delimiter
+ buf.writeStringDelimiter(mbnData.length * 2);
+
+ options.recordSize = mbnData.length;
+ if (options.callback) {
+ options.callback(options);
+ }
+ };
+
+ function do_test(funcName, msgCount) {
+ postedMessage = null;
+ delete RIL.iccInfoPrivate.mbdn;
+ recordHelper[funcName]();
+
+ equal("iccmbdn", postedMessage.rilMessageType);
+ equal("Voicemail", postedMessage.alphaId);
+ equal("111", postedMessage.number);
+ }
+
+ do_test("readMBDN");
+ do_test("readCphsMBN");
+
+ run_next_test();
+});
+
+/**
+ * Verify the recovery from SimRecordHelper.readCphsMBN() if MBDN is not valid
+ * or is empty after SimRecordHelper.readMBDN().
+ */
+add_test(function test_read_mbdn_recovered_from_cphs_mbn() {
+ let worker = newUint8Worker();
+ let context = worker.ContextPool._contexts[0];
+ let RIL = context.RIL;
+ let pduHelper = context.GsmPDUHelper;
+ let recordHelper = context.SimRecordHelper;
+ let iccUtilsHelper = context.ICCUtilsHelper;
+ let buf = context.Buf;
+ let io = context.ICCIOHelper;
+
+ io.loadLinearFixedEF = function(options) {
+ let mbnData = [
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+ ];
+
+ // Write data size
+ buf.writeInt32(mbnData.length * 2);
+
+ // Write MBN
+ for (let i = 0; i < mbnData.length; i++) {
+ pduHelper.writeHexOctet(mbnData[i]);
+ }
+
+ // Write string delimiter
+ buf.writeStringDelimiter(mbnData.length * 2);
+
+ options.recordSize = mbnData.length;
+ if (options.callback) {
+ options.callback(options);
+ }
+ };
+
+ iccUtilsHelper.isCphsServiceAvailable = function(geckoService) {
+ return geckoService == "MBN";
+ };
+
+ let isRecovered = false;
+ recordHelper.readCphsMBN = function(onComplete) {
+ isRecovered = true;
+ };
+
+ recordHelper.readMBDN();
+
+ equal(RIL.iccInfoPrivate.mbdn, undefined);
+ ok(isRecovered);
+
+ run_next_test();
+});
+
+/**
+ * Verify reading EF_PNN with different coding scheme.
+ */
+add_test(function test_pnn_with_different_coding_scheme() {
+ let worker = newUint8Worker();
+ let context = worker.ContextPool._contexts[0];
+ let record = context.SimRecordHelper;
+ let pduHelper = context.GsmPDUHelper;
+ let ril = context.RIL;
+ let buf = context.Buf;
+ let io = context.ICCIOHelper;
+
+ let test_data = [{
+ // Cell Broadcast data coding scheme - "Test1"
+ pnn: [0x43, 0x06, 0x85, 0xD4, 0xF2, 0x9C, 0x1E, 0x03],
+ expectedResult: "Test1"
+ },{
+ // UCS2 with 0x80 - "Test1"
+ pnn: [0x43, 0x0C, 0x90, 0x80, 0x00, 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x31],
+ expectedResult: "Test1"
+ },{
+ // UCS2 with 0x81 - "Mozilla\u694a"
+ pnn: [0x43, 0x0E, 0x90, 0x81, 0x08, 0xd2, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca, 0xff, 0xff],
+ expectedResult: "Mozilla\u694a"
+ },{
+ // UCS2 with 0x82 - "Mozilla\u694a"
+ pnn: [0x43, 0x0F, 0x90, 0x82, 0x08, 0x69, 0x00, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca, 0xff, 0xff],
+ expectedResult: "Mozilla\u694a"
+ }];
+
+ function do_test_pnn(pnn, expectedResult) {
+ io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
+ // Write data size.
+ buf.writeInt32(pnn.length * 2);
+
+ // Write data.
+ for (let i = 0; i < pnn.length; i++) {
+ pduHelper.writeHexOctet(pnn[i]);
+ }
+
+ // Write string delimiter.
+ buf.writeStringDelimiter(pnn.length * 2);
+
+ if (options.callback) {
+ options.callback(options);
+ }
+ };
+
+ record.readPNN();
+
+ equal(ril.iccInfoPrivate.PNN[0].fullName, expectedResult);
+ // Reset PNN info for next test
+ ril.iccInfoPrivate.PNN = null;
+ }
+
+ ril.appType = CARD_APPTYPE_SIM;
+ for (let i = 0; i < test_data.length; i++) {
+ do_test_pnn(test_data[i].pnn, test_data[i].expectedResult);
+ }
+
+ run_next_test();
+});
+
+/**
+ * Verify reading EF_PNN with different content.
+ */
+add_test(function test_pnn_with_different_content() {
+ let worker = newUint8Worker();
+ let context = worker.ContextPool._contexts[0];
+ let record = context.SimRecordHelper;
+ let pduHelper = context.GsmPDUHelper;
+ let ril = context.RIL;
+ let buf = context.Buf;
+ let io = context.ICCIOHelper;
+
+ let test_data = [{
+ // [0]: {"fullName":"Test1","shortName":"Test1"}
+ pnn: [0x43, 0x06, 0x85, 0xD4, 0xF2, 0x9C, 0x1E, 0x03,
+ 0x45, 0x06, 0x85, 0xD4, 0xF2, 0x9C, 0x1E, 0x03],
+ expectedResult: {"fullName": "Test1","shortName": "Test1"}
+ },{
+ // [1]: {"fullName":"Test2"}
+ pnn: [0x43, 0x06, 0x85, 0xD4, 0xF2, 0x9C, 0x2E, 0x03],
+ expectedResult: {"fullName": "Test2"}
+ },{
+ // [2]: undefined
+ pnn: [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
+ },{
+ // [3]: {"fullName": "Test4"}
+ pnn: [0x43, 0x06, 0x85, 0xD4, 0xF2, 0x9C, 0x4E, 0x03],
+ expectedResult: {"fullName": "Test4"}
+ },{
+ // [4]: undefined
+ pnn: [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
+ }];
+
+ function do_test_pnn() {
+ ril.iccIO = function fakeIccIO(options) {
+ let index = options.p1 - 1;
+ let pnn = test_data[index].pnn;
+
+ // Write data size.
+ buf.writeInt32(pnn.length * 2);
+
+ // Write data.
+ for (let i = 0; i < pnn.length; i++) {
+ pduHelper.writeHexOctet(pnn[i]);
+ }
+
+ // Write string delimiter.
+ buf.writeStringDelimiter(pnn.length * 2);
+
+ if (options.callback) {
+ options.callback(options);
+ }
+ };
+
+ io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
+ options.p1 = 1;
+ options.totalRecords = test_data.length;
+
+ ril.iccIO(options);
+ };
+
+ record.readPNN();
+
+ equal(test_data.length, ril.iccInfoPrivate.PNN.length);
+ for (let i = 0; i < test_data.length; i++) {
+ if (test_data[i].expectedResult) {
+ equal(test_data[i].expectedResult.fullName,
+ ril.iccInfoPrivate.PNN[i].fullName);
+ equal(test_data[i].expectedResult.shortName,
+ ril.iccInfoPrivate.PNN[i].shortName);
+ } else {
+ equal(test_data[i].expectedResult, ril.iccInfoPrivate.PNN[i]);
+ }
+ }
+ }
+
+ ril.appType = CARD_APPTYPE_SIM;
+ do_test_pnn();
+
+ run_next_test();
+});