diff options
author | bi4004.lee <bi4004.lee@samsung.com> | 2011-11-02 14:43:43 +0900 |
---|---|---|
committer | Jake Hamby <jhamby@google.com> | 2011-11-07 18:03:45 -0800 |
commit | 141da403c0ad2d06b8f55e737ddf5d9e2b64c536 (patch) | |
tree | d95b72697e260641e2e09a21bc4aef677146530a /telephony | |
parent | 7311bd4b709750384b058d8e988e2e983c97b3f2 (diff) | |
download | frameworks_base-141da403c0ad2d06b8f55e737ddf5d9e2b64c536.zip frameworks_base-141da403c0ad2d06b8f55e737ddf5d9e2b64c536.tar.gz frameworks_base-141da403c0ad2d06b8f55e737ddf5d9e2b64c536.tar.bz2 |
Fix exception when sending multi-page SMS with Turkish characters.
- Precondition: config_sms_enabled_single_shift_tables is configured as
1 (Turkish) in frameworks/base/core/res/res/values/config.xml
- Cause: There is no consideration for National Language Shift Tables in
SmsMessage::fragmentText function.
- Solution: The header length is calculated properly according to
National Language Shift Table
- modified to add test cases and fix calculation bug (jhamby@google.com)
Bug: 5553544
Change-Id: I9eaefbbd6b3d75f8c41cbf9d0cb03a701cfa1cb3
Diffstat (limited to 'telephony')
3 files changed, 137 insertions, 11 deletions
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java index fc8a145..1410747 100644 --- a/telephony/java/android/telephony/SmsMessage.java +++ b/telephony/java/android/telephony/SmsMessage.java @@ -291,12 +291,31 @@ public class SmsMessage { // flexibly... int limit; - if (ted.msgCount > 1) { - limit = (ted.codeUnitSize == ENCODING_7BIT) ? - MAX_USER_DATA_SEPTETS_WITH_HEADER : MAX_USER_DATA_BYTES_WITH_HEADER; + if (ted.codeUnitSize == ENCODING_7BIT) { + int udhLength; + if (ted.languageTable != 0 && ted.languageShiftTable != 0) { + udhLength = GsmAlphabet.UDH_SEPTET_COST_TWO_SHIFT_TABLES; + } else if (ted.languageTable != 0 || ted.languageShiftTable != 0) { + udhLength = GsmAlphabet.UDH_SEPTET_COST_ONE_SHIFT_TABLE; + } else { + udhLength = 0; + } + + if (ted.msgCount > 1) { + udhLength += GsmAlphabet.UDH_SEPTET_COST_CONCATENATED_MESSAGE; + } + + if (udhLength != 0) { + udhLength += GsmAlphabet.UDH_SEPTET_COST_LENGTH; + } + + limit = MAX_USER_DATA_SEPTETS - udhLength; } else { - limit = (ted.codeUnitSize == ENCODING_7BIT) ? - MAX_USER_DATA_SEPTETS : MAX_USER_DATA_BYTES; + if (ted.msgCount > 1) { + limit = MAX_USER_DATA_BYTES_WITH_HEADER; + } else { + limit = MAX_USER_DATA_BYTES; + } } int pos = 0; // Index in code units. diff --git a/telephony/java/com/android/internal/telephony/GsmAlphabet.java b/telephony/java/com/android/internal/telephony/GsmAlphabet.java index 2e99849..25647ac 100644 --- a/telephony/java/com/android/internal/telephony/GsmAlphabet.java +++ b/telephony/java/com/android/internal/telephony/GsmAlphabet.java @@ -60,25 +60,25 @@ public class GsmAlphabet { * all combinations of header elements below will have at least one free bit * when padding to the nearest septet boundary. */ - private static final int UDH_SEPTET_COST_LENGTH = 1; + public static final int UDH_SEPTET_COST_LENGTH = 1; /** * Using a non-default language locking shift table OR single shift table * requires a user data header of 3 octets, or 4 septets, plus UDH length. */ - private static final int UDH_SEPTET_COST_ONE_SHIFT_TABLE = 4; + public static final int UDH_SEPTET_COST_ONE_SHIFT_TABLE = 4; /** * Using a non-default language locking shift table AND single shift table * requires a user data header of 6 octets, or 7 septets, plus UDH length. */ - private static final int UDH_SEPTET_COST_TWO_SHIFT_TABLES = 7; + public static final int UDH_SEPTET_COST_TWO_SHIFT_TABLES = 7; /** * Multi-part messages require a user data header of 5 octets, or 6 septets, * plus UDH length. */ - private static final int UDH_SEPTET_COST_CONCATENATED_MESSAGE = 6; + public static final int UDH_SEPTET_COST_CONCATENATED_MESSAGE = 6; /** * Converts a char to a GSM 7 bit table index. diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java index 41a719e..5950669 100644 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java +++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java @@ -16,11 +16,14 @@ package com.android.internal.telephony; +import android.telephony.TelephonyManager; +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.SmallTest; + import com.android.internal.telephony.gsm.SmsMessage; import com.android.internal.util.HexDump; -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; +import java.util.ArrayList; public class GsmSmsTest extends AndroidTestCase { @@ -232,6 +235,110 @@ public class GsmSmsTest extends AndroidTestCase { }; @SmallTest + public void testFragmentText() throws Exception { + boolean isGsmPhone = (TelephonyManager.getDefault().getPhoneType() == + TelephonyManager.PHONE_TYPE_GSM); + + // Valid 160 character 7-bit text. + String text = "123456789012345678901234567890123456789012345678901234567890" + + "1234567890123456789012345678901234567890123456789012345678901234567890" + + "123456789012345678901234567890"; + SmsMessageBase.TextEncodingDetails ted = SmsMessage.calculateLength(text, false); + assertEquals(1, ted.msgCount); + assertEquals(160, ted.codeUnitCount); + assertEquals(1, ted.codeUnitSize); + assertEquals(0, ted.languageTable); + assertEquals(0, ted.languageShiftTable); + if (isGsmPhone) { + ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text); + assertEquals(1, fragments.size()); + } + + // Valid 161 character 7-bit text. + text = "123456789012345678901234567890123456789012345678901234567890" + + "1234567890123456789012345678901234567890123456789012345678901234567890" + + "1234567890123456789012345678901"; + ted = SmsMessage.calculateLength(text, false); + assertEquals(2, ted.msgCount); + assertEquals(161, ted.codeUnitCount); + assertEquals(1, ted.codeUnitSize); + assertEquals(0, ted.languageTable); + assertEquals(0, ted.languageShiftTable); + if (isGsmPhone) { + ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text); + assertEquals(2, fragments.size()); + assertEquals(text, fragments.get(0) + fragments.get(1)); + assertEquals(153, fragments.get(0).length()); + assertEquals(8, fragments.get(1).length()); + } + } + + @SmallTest + public void testFragmentTurkishText() throws Exception { + boolean isGsmPhone = (TelephonyManager.getDefault().getPhoneType() == + TelephonyManager.PHONE_TYPE_GSM); + + int[] oldTables = GsmAlphabet.getEnabledSingleShiftTables(); + int[] turkishTable = { 1 }; + GsmAlphabet.setEnabledSingleShiftTables(turkishTable); + + // Valid 77 character text with Turkish characters. + String text = "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı" + + "ĞŞİğşıĞŞİğşıĞŞİğş"; + SmsMessageBase.TextEncodingDetails ted = SmsMessage.calculateLength(text, false); + assertEquals(1, ted.msgCount); + assertEquals(154, ted.codeUnitCount); + assertEquals(1, ted.codeUnitSize); + assertEquals(0, ted.languageTable); + assertEquals(1, ted.languageShiftTable); + if (isGsmPhone) { + ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text); + assertEquals(1, fragments.size()); + assertEquals(text, fragments.get(0)); + assertEquals(77, fragments.get(0).length()); + } + + // Valid 78 character text with Turkish characters. + text = "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı" + + "ĞŞİğşıĞŞİğşıĞŞİğşı"; + ted = SmsMessage.calculateLength(text, false); + assertEquals(2, ted.msgCount); + assertEquals(156, ted.codeUnitCount); + assertEquals(1, ted.codeUnitSize); + assertEquals(0, ted.languageTable); + assertEquals(1, ted.languageShiftTable); + if (isGsmPhone) { + ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text); + assertEquals(2, fragments.size()); + assertEquals(text, fragments.get(0) + fragments.get(1)); + assertEquals(74, fragments.get(0).length()); + assertEquals(4, fragments.get(1).length()); + } + + // Valid 160 character text with Turkish characters. + text = "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı" + + "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğ" + + "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı"; + ted = SmsMessage.calculateLength(text, false); + assertEquals(3, ted.msgCount); + assertEquals(320, ted.codeUnitCount); + assertEquals(1, ted.codeUnitSize); + assertEquals(0, ted.languageTable); + assertEquals(1, ted.languageShiftTable); + if (isGsmPhone) { + ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text); + assertEquals(3, fragments.size()); + assertEquals(text, fragments.get(0) + fragments.get(1) + fragments.get(2)); + assertEquals(74, fragments.get(0).length()); + assertEquals(74, fragments.get(1).length()); + assertEquals(12, fragments.get(2).length()); + } + + GsmAlphabet.setEnabledSingleShiftTables(oldTables); + } + + + @SmallTest public void testDecode() throws Exception { decodeSingle(0); // default table decodeSingle(1); // Turkish locking shift table |