Support updateAdnByIndex for USIM entity files
The EF IDs for entity files under DF telecom are not constants and
so need to be copied from existing record when updating rather than
being hardcoded.
Also add some methods to AdnRecord to get the max sizes for the name and phone number and encode and decode the name.
Bug: 154363919
Test: atest CtsSimPhonebookProviderTestCases
Change-Id: Ie2ef3cd0323e99e102de06e741807b381a77efb4
diff --git a/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java b/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
index 8ac8010..84a9d26 100644
--- a/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
+++ b/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
@@ -237,7 +237,7 @@
Request updateRequest = new Request();
synchronized (updateRequest) {
Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE, updateRequest);
- AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber);
+ AdnRecord newAdn = new AdnRecord(efid, index, newTag, newPhoneNumber);
if (mAdnCache != null) {
mAdnCache.updateAdnByIndex(efid, newAdn, index, pin2, response);
waitForResult(updateRequest);
diff --git a/src/java/com/android/internal/telephony/uicc/AdnRecord.java b/src/java/com/android/internal/telephony/uicc/AdnRecord.java
index e6968ec..7710a06 100644
--- a/src/java/com/android/internal/telephony/uicc/AdnRecord.java
+++ b/src/java/com/android/internal/telephony/uicc/AdnRecord.java
@@ -104,6 +104,45 @@
}
};
+ /**
+ * Returns the maximum number of characters that supported by the alpha tag for a record with
+ * the specified maximum size.
+ */
+ public static int getMaxAlphaTagBytes(int maxRecordLength) {
+ return Math.max(0, maxRecordLength - FOOTER_SIZE_BYTES);
+ }
+
+ /**
+ * Encodes the alphaTag to a binary representation supported by the SIM.
+ *
+ * <p>This is the same representation as is used for this field in buildAdnString but there
+ * is no restriction on the length.
+ */
+ public static byte[] encodeAlphaTag(String alphaTag) {
+ return !TextUtils.isEmpty(alphaTag) ? GsmAlphabet.stringToGsm8BitPacked(alphaTag)
+ : new byte[0];
+ }
+
+ /**
+ * Decodes an encoded alphaTag from a record or encoded tag.
+ *
+ * <p>This is the same as is used to construct an AdnRecord from byte[]
+ */
+ public static String decodeAlphaTag(byte[] encodedTagOrRecord, int offset, int length) {
+ return IccUtils.adnStringFieldToString(encodedTagOrRecord, offset, length);
+ }
+
+ /**
+ * Returns the maximum number of digits (or other dialable characters) that can be stored in
+ * the phone number.
+ *
+ * <p>Additional length is supported via the ext1 entity file but the current implementation
+ * doesn't support writing of that file so it is not included in this calculation.
+ */
+ public static int getMaxPhoneNumberDigits() {
+ // Multiply by 2 because it is packed BCD encoded (2 digits per byte).
+ return (ADN_DIALING_NUMBER_END - ADN_DIALING_NUMBER_START + 1) * 2;
+ }
//***** Constructor
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -260,8 +299,7 @@
return null;
}
- byteTag = !TextUtils.isEmpty(mAlphaTag) ? GsmAlphabet.stringToGsm8BitPacked(mAlphaTag)
- : new byte[0];
+ byteTag = encodeAlphaTag(mAlphaTag);
if (byteTag.length > footerOffset) {
Rlog.w(LOG_TAG, "[buildAdnString] Max length of tag is " + footerOffset);
@@ -329,7 +367,7 @@
private void
parseRecord(byte[] record) {
try {
- mAlphaTag = IccUtils.adnStringFieldToString(
+ mAlphaTag = decodeAlphaTag(
record, 0, record.length - FOOTER_SIZE_BYTES);
int footerOffset = record.length - FOOTER_SIZE_BYTES;
diff --git a/src/java/com/android/internal/telephony/uicc/AdnRecordCache.java b/src/java/com/android/internal/telephony/uicc/AdnRecordCache.java
index d86b8c6..21a6e37 100644
--- a/src/java/com/android/internal/telephony/uicc/AdnRecordCache.java
+++ b/src/java/com/android/internal/telephony/uicc/AdnRecordCache.java
@@ -124,7 +124,9 @@
case EF_FDN: return EF_EXT2;
case EF_MSISDN: return EF_EXT1;
case EF_PBR: return 0; // The EF PBR doesn't have an extension record
- default: return -1;
+ default:
+ // See TS 131.102 4.4.2.1 '4FXX' are entity files from EF PBR
+ return (0x4FFF & efid) == efid ? 0 : -1;
}
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/AdnRecordTest.java b/tests/telephonytests/src/com/android/internal/telephony/AdnRecordTest.java
index 3b786b0..8fe809c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/AdnRecordTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/AdnRecordTest.java
@@ -16,19 +16,23 @@
package com.android.internal.telephony;
+import static com.google.common.truth.Truth.assertThat;
+
import android.os.Parcel;
-import java.util.Arrays;
-import junit.framework.TestCase;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.internal.telephony.uicc.AdnRecord;
import com.android.internal.telephony.uicc.IccUtils;
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+
/**
* {@hide}
*/
public class AdnRecordTest extends TestCase {
-
+
@SmallTest
public void testBasic() throws Exception {
AdnRecord adn;
@@ -189,6 +193,20 @@
assertEquals(adn.getNumber(), copy.getNumber());
assertTrue(Arrays.equals(adn.getEmails(), copy.getEmails()));
}
+
+ public void testGetMaxAlphaTagBytes() {
+ assertThat(AdnRecord.getMaxAlphaTagBytes(-1)).isEqualTo(0);
+ assertThat(AdnRecord.getMaxAlphaTagBytes(0)).isEqualTo(0);
+ assertThat(AdnRecord.getMaxAlphaTagBytes(5)).isEqualTo(0);
+ assertThat(AdnRecord.getMaxAlphaTagBytes(14)).isEqualTo(0);
+ assertThat(AdnRecord.getMaxAlphaTagBytes(15)).isEqualTo(1);
+ assertThat(AdnRecord.getMaxAlphaTagBytes(25)).isEqualTo(11);
+ assertThat(AdnRecord.getMaxAlphaTagBytes(30)).isEqualTo(16);
+ }
+
+ public void testGetMaxPhoneNumberDigits() {
+ assertThat(AdnRecord.getMaxPhoneNumberDigits()).isEqualTo(20);
+ }
}