/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.telephony;

import android.telephony.SmsMessage;
import android.telephony.TelephonyManager;
import android.telephony.Rlog;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;

import com.android.internal.telephony.SmsConstants;

import java.util.Random;

/**
 * Test cases to verify selection of the optimal 7 bit encoding tables
 * (for all combinations of enabled national language tables) for messages
 * containing Turkish, Spanish, Portuguese, Greek, and other symbols
 * present in the GSM default and national language tables defined in
 * 3GPP TS 23.038. Also verifies correct SMS encoding for CDMA, which only
 * supports the GSM 7 bit default alphabet, ASCII 8 bit, and UCS-2.
 * Tests both encoding variations: unsupported characters mapped to space,
 * and unsupported characters force entire message to UCS-2.
 */
public class SmsMessageBodyTest extends AndroidTestCase {
    private static final String TAG = "SmsMessageBodyTest";

    // ASCII chars in the GSM 7 bit default alphabet
    private static final String sAsciiChars = "@$_ !\"#%&'()*+,-./0123456789" +
            ":;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\n\r";

    // Unicode chars in the GSM 7 bit default alphabet and both locking shift tables
    private static final String sGsmDefaultChars = "\u00a3\u00a5\u00e9\u00c7\u0394\u00c9" +
            "\u00dc\u00a7\u00fc\u00e0";

    // Unicode chars in the GSM 7 bit default table and Turkish locking shift tables
    private static final String sGsmDefaultAndTurkishTables = "\u00f9\u00f2\u00c5\u00e5\u00df" +
            "\u00a4\u00c4\u00d6\u00d1\u00e4\u00f6\u00f1";

    // Unicode chars in the GSM 7 bit default table but not the locking shift tables
    private static final String sGsmDefaultTableOnly = "\u00e8\u00ec\u00d8\u00f8\u00c6\u00e6" +
            "\u00a1\u00bf";

    // ASCII chars in the GSM default extension table
    private static final String sGsmExtendedAsciiChars = "{}[]\f";

    // chars in GSM default extension table and Portuguese locking shift table
    private static final String sGsmExtendedPortugueseLocking = "^\\|~";

    // Euro currency symbol
    private static final String sGsmExtendedEuroSymbol = "\u20ac";

    // CJK ideographs, Hiragana, Katakana, full width letters, Cyrillic, etc.
    private static final String sUnicodeChars = "\u4e00\u4e01\u4e02\u4e03" +
            "\u4e04\u4e05\u4e06\u4e07\u4e08\u4e09\u4e0a\u4e0b\u4e0c\u4e0d" +
            "\u4e0e\u4e0f\u3041\u3042\u3043\u3044\u3045\u3046\u3047\u3048" +
            "\u30a1\u30a2\u30a3\u30a4\u30a5\u30a6\u30a7\u30a8" +
            "\uff10\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18" +
            "\uff70\uff71\uff72\uff73\uff74\uff75\uff76\uff77\uff78" +
            "\u0400\u0401\u0402\u0403\u0404\u0405\u0406\u0407\u0408" +
            "\u00a2\u00a9\u00ae\u2122";

    // chars in Turkish single shift and locking shift tables
    private static final String sTurkishChars = "\u0131\u011e\u011f\u015e\u015f\u0130";

    // chars in Spanish single shift table and Portuguese single and locking shift tables
    private static final String sPortugueseAndSpanishChars = "\u00c1\u00e1\u00cd\u00ed"
            + "\u00d3\u00f3\u00da\u00fa";

    // chars in all national language tables but not in the standard GSM alphabets
    private static final String sNationalLanguageTablesOnly = "\u00e7";

    // chars in Portuguese single shift and locking shift tables
    private static final String sPortugueseChars = "\u00ea\u00d4\u00f4\u00c0\u00c2\u00e2"
            + "\u00ca\u00c3\u00d5\u00e3\u00f5";

    // chars in Portuguese locking shift table only
    private static final String sPortugueseLockingShiftChars = "\u00aa\u221e\u00ba`";

    // Greek letters in GSM alphabet missing from Portuguese locking and single shift tables
    private static final String sGreekLettersNotInPortugueseTables = "\u039b\u039e";

    // Greek letters in GSM alphabet and Portuguese single shift (but not locking shift) table
    private static final String sGreekLettersInPortugueseShiftTable =
            "\u03a6\u0393\u03a9\u03a0\u03a8\u03a3\u0398";

    // List of classes of characters in SMS tables
    private static final String[] sCharacterClasses = {
            sGsmExtendedAsciiChars,
            sGsmExtendedPortugueseLocking,
            sGsmDefaultChars,
            sGsmDefaultAndTurkishTables,
            sGsmDefaultTableOnly,
            sGsmExtendedEuroSymbol,
            sUnicodeChars,
            sTurkishChars,
            sPortugueseChars,
            sPortugueseLockingShiftChars,
            sPortugueseAndSpanishChars,
            sGreekLettersNotInPortugueseTables,
            sGreekLettersInPortugueseShiftTable,
            sNationalLanguageTablesOnly,
            sAsciiChars
    };

    private static final int sNumCharacterClasses = sCharacterClasses.length;

    // For each character class, whether it is present in a particular char table.
    // First three entries are locking shift tables, followed by four single shift tables
    private static final boolean[][] sCharClassPresenceInTables = {
            // ASCII chars in all GSM extension tables
            {false, false, false, true, true, true, true},
            // ASCII chars in all GSM extension tables and Portuguese locking shift table
            {false, false, true, true, true, true, true},
            // non-ASCII chars in GSM default alphabet and all locking tables
            {true, true, true, false, false, false, false},
            // non-ASCII chars in GSM default alphabet and Turkish locking shift table
            {true, true, false, false, false, false, false},
            // non-ASCII chars in GSM default alphabet table only
            {true, false, false, false, false, false, false},
            // Euro symbol is present in several tables
            {false, true, true, true, true, true, true},
            // Unicode characters not present in any 7 bit tables
            {false, false, false, false, false, false, false},
            // Characters specific to Turkish language
            {false, true, false, false, true, false, false},
            // Characters in Portuguese single shift and locking shift tables
            {false, false, true, false, false, false, true},
            // Characters in Portuguese locking shift table only
            {false, false, true, false, false, false, false},
            // Chars in Spanish single shift and Portuguese single and locking shift tables
            {false, false, true, false, false, true, true},
            // Greek letters in GSM default alphabet missing from Portuguese tables
            {true, true, false, false, false, false, false},
            // Greek letters in GSM alphabet and Portuguese single shift table
            {true, true, false, false, false, false, true},
            // Chars in all national language tables but not the standard GSM tables
            {false, true, true, false, true, true, true},
            // ASCII chars in GSM default alphabet
            {true, true, true, false, false, false, false}
    };

    private static final int sTestLengthCount = 12;

    private static final int[] sSeptetTestLengths =
            {  0,   1,   2, 80, 159, 160, 161, 240, 305, 306, 307, 320};

    private static final int[] sUnicodeTestLengths =
            {  0,   1,   2, 35,  69,  70,  71, 100, 133, 134, 135, 160};

    private static final int[] sTestMsgCounts =
            {  1,   1,   1,  1,   1,   1,   2,   2,   2,   2,   3,   3};

    private static final int[] sSeptetUnitsRemaining =
            {160, 159, 158, 80,   1,   0, 145,  66,   1,   0, 152, 139};

    private static final int[] sUnicodeUnitsRemaining =
            { 70,  69,  68, 35,   1,   0,  63,  34,   1,   0,  66,  41};

    // Combinations of enabled GSM national language single shift tables
    private static final int[][] sEnabledSingleShiftTables = {
            {},         // GSM default alphabet only
            {1},        // Turkish (single shift only)
            {1},        // Turkish (single and locking shift)
            {2},        // Spanish
            {3},        // Portuguese (single shift only)
            {3},        // Portuguese (single and locking shift)
            {1, 2},     // Turkish + Spanish (single shift only)
            {1, 2},     // Turkish + Spanish (single and locking shift)
            {1, 3},     // Turkish + Portuguese (single shift only)
            {1, 3},     // Turkish + Portuguese (single and locking shift)
            {2, 3},     // Spanish + Portuguese (single shift only)
            {2, 3},     // Spanish + Portuguese (single and locking shift)
            {1, 2, 3},  // Turkish, Spanish, Portuguese (single shift only)
            {1, 2, 3},  // Turkish, Spanish, Portuguese (single and locking shift)
            {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} // all language tables
    };

    // Combinations of enabled GSM national language locking shift tables
    private static final int[][] sEnabledLockingShiftTables = {
            {},         // GSM default alphabet only
            {},         // Turkish (single shift only)
            {1},        // Turkish (single and locking shift)
            {},         // Spanish (no locking shift table)
            {},         // Portuguese (single shift only)
            {3},        // Portuguese (single and locking shift)
            {},         // Turkish + Spanish (single shift only)
            {1},        // Turkish + Spanish (single and locking shift)
            {},         // Turkish + Portuguese (single shift only)
            {1, 3},     // Turkish + Portuguese (single and locking shift)
            {},         // Spanish + Portuguese (single shift only)
            {3},        // Spanish + Portuguese (single and locking shift)
            {},         // Turkish, Spanish, Portuguese (single shift only)
            {1, 3},     // Turkish, Spanish, Portuguese (single and locking shift)
            {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} // all language tables
    };

    // LanguagePair counter indexes to check for each entry above
    private static final int[][] sLanguagePairIndexesByEnabledIndex = {
            {0},                            // default tables only
            {0, 1},                         // Turkish (single shift only)
            {0, 1, 4, 5},                   // Turkish (single and locking shift)
            {0, 2},                         // Spanish
            {0, 3},                         // Portuguese (single shift only)
            {0, 3, 8, 11},                  // Portuguese (single and locking shift)
            {0, 1, 2},                      // Turkish + Spanish (single shift only)
            {0, 1, 2, 4, 5, 6},             // Turkish + Spanish (single and locking shift)
            {0, 1, 3},                      // Turkish + Portuguese (single shift only)
            {0, 1, 3, 4, 5, 7, 8, 9, 11},   // Turkish + Portuguese (single and locking shift)
            {0, 2, 3},                      // Spanish + Portuguese (single shift only)
            {0, 2, 3, 8, 10, 11},           // Spanish + Portuguese (single and locking shift)
            {0, 1, 2, 3},                   // all languages (single shift only)
            {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, // all languages (single and locking shift)
            {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}  // all languages (no Indic chars in test)
    };

    /**
     * User data header requires one octet for length. Count as one septet, because
     * 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;

    /**
     * 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;

    /**
     * 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;

    /**
     * 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;

    @SmallTest
    public void testCalcLengthAscii() throws Exception {
        StringBuilder sb = new StringBuilder(320);
        int[] values = {0, 0, 0, SmsConstants.ENCODING_7BIT, 0, 0};
        int startPos = 0;
        int asciiCharsLen = sAsciiChars.length();

        for (int i = 0; i < sTestLengthCount; i++) {
            int len = sSeptetTestLengths[i];
            assertTrue(sb.length() <= len);

            while (sb.length() < len) {
                int addCount = len - sb.length();
                int endPos = (asciiCharsLen - startPos > addCount) ?
                        (startPos + addCount) : asciiCharsLen;
                sb.append(sAsciiChars, startPos, endPos);
                startPos = (endPos == asciiCharsLen) ? 0 : endPos;
            }
            assertEquals(len, sb.length());

            String testStr = sb.toString();
            values[0] = sTestMsgCounts[i];
            values[1] = len;
            values[2] = sSeptetUnitsRemaining[i];

            callGsmLengthMethods(testStr, false, values);
            callGsmLengthMethods(testStr, true, values);
            callCdmaLengthMethods(testStr, false, values);
            callCdmaLengthMethods(testStr, true, values);
        }
    }

    @SmallTest
    public void testCalcLengthUnicode() throws Exception {
        StringBuilder sb = new StringBuilder(160);
        int[] values = {0, 0, 0, SmsConstants.ENCODING_16BIT, 0, 0};
        int[] values7bit = {1, 0, 0, SmsConstants.ENCODING_7BIT, 0, 0};
        int startPos = 0;
        int unicodeCharsLen = sUnicodeChars.length();

        // start with length 1: empty string uses ENCODING_7BIT
        for (int i = 1; i < sTestLengthCount; i++) {
            int len = sUnicodeTestLengths[i];
            assertTrue(sb.length() <= len);

            while (sb.length() < len) {
                int addCount = len - sb.length();
                int endPos = (unicodeCharsLen - startPos > addCount) ?
                        (startPos + addCount) : unicodeCharsLen;
                sb.append(sUnicodeChars, startPos, endPos);
                startPos = (endPos == unicodeCharsLen) ? 0 : endPos;
            }
            assertEquals(len, sb.length());

            String testStr = sb.toString();
            values[0] = sTestMsgCounts[i];
            values[1] = len;
            values[2] = sUnicodeUnitsRemaining[i];
            values7bit[1] = len;
            values7bit[2] = SmsConstants.MAX_USER_DATA_SEPTETS - len;

            callGsmLengthMethods(testStr, false, values);
            callCdmaLengthMethods(testStr, false, values);
            callGsmLengthMethods(testStr, true, values7bit);
            callCdmaLengthMethods(testStr, true, values7bit);
        }
    }

    private static class LanguagePair {
        // index is 2 for Portuguese locking shift because there is no Spanish locking shift table
        private final int langTableIndex;
        private final int langShiftTableIndex;
        int length;
        int missingChars7bit;

        LanguagePair(int langTable, int langShiftTable) {
            langTableIndex = langTable;
            langShiftTableIndex = langShiftTable;
        }

        void clear() {
            length = 0;
            missingChars7bit = 0;
        }

        void addChar(boolean[] charClassTableRow) {
            if (charClassTableRow[langTableIndex]) {
                length++;
            } else if (charClassTableRow[3 + langShiftTableIndex]) {
                length += 2;
            } else {
                length++;    // use ' ' for unmapped char in 7 bit only mode
                missingChars7bit++;
            }
        }
    }

    private static class CounterHelper {
        LanguagePair[] mCounters;
        int[] mStatsCounters;
        int mUnicodeCounter;

        CounterHelper() {
            mCounters = new LanguagePair[12];
            mStatsCounters = new int[12];
            for (int i = 0; i < 12; i++) {
                mCounters[i] = new LanguagePair(i/4, i%4);
            }
        }

        void clear() {
            // Note: don't clear stats counters
            for (int i = 0; i < 12; i++) {
                mCounters[i].clear();
            }
        }

        void addChar(int charClass) {
            boolean[] charClassTableRow = sCharClassPresenceInTables[charClass];
            for (int i = 0; i < 12; i++) {
                mCounters[i].addChar(charClassTableRow);
            }
        }

        void fillData(int enabledLangsIndex, boolean use7bitOnly, int[] values, int length) {
            int[] languagePairs = sLanguagePairIndexesByEnabledIndex[enabledLangsIndex];
            int minNumSeptets = Integer.MAX_VALUE;
            int minNumSeptetsWithHeader = Integer.MAX_VALUE;
            int minNumMissingChars = Integer.MAX_VALUE;
            int langIndex = -1;
            int langShiftIndex = -1;
            for (int i : languagePairs) {
                LanguagePair pair = mCounters[i];
                int udhLength = 0;
                if (i != 0) {
                    udhLength = UDH_SEPTET_COST_LENGTH;
                    if (i < 4 || i % 4 == 0) {
                        udhLength += UDH_SEPTET_COST_ONE_SHIFT_TABLE;
                    } else {
                        udhLength += UDH_SEPTET_COST_TWO_SHIFT_TABLES;
                    }
                }
                int numSeptetsWithHeader;
                if (pair.length > (SmsConstants.MAX_USER_DATA_SEPTETS - udhLength)) {
                    if (udhLength == 0) {
                        udhLength = UDH_SEPTET_COST_LENGTH;
                    }
                    udhLength += UDH_SEPTET_COST_CONCATENATED_MESSAGE;
                    int septetsPerPart = SmsConstants.MAX_USER_DATA_SEPTETS - udhLength;
                    int msgCount = (pair.length + septetsPerPart - 1) / septetsPerPart;
                    numSeptetsWithHeader = udhLength * msgCount + pair.length;
                } else {
                    numSeptetsWithHeader = udhLength + pair.length;
                }

                if (use7bitOnly) {
                    if (pair.missingChars7bit < minNumMissingChars || (pair.missingChars7bit ==
                            minNumMissingChars && numSeptetsWithHeader < minNumSeptetsWithHeader)) {
                        minNumSeptets = pair.length;
                        minNumSeptetsWithHeader = numSeptetsWithHeader;
                        minNumMissingChars = pair.missingChars7bit;
                        langIndex = pair.langTableIndex;
                        langShiftIndex = pair.langShiftTableIndex;
                    }
                } else {
                    if (pair.missingChars7bit == 0 && numSeptetsWithHeader < minNumSeptetsWithHeader) {
                        minNumSeptets = pair.length;
                        minNumSeptetsWithHeader = numSeptetsWithHeader;
                        langIndex = pair.langTableIndex;
                        langShiftIndex = pair.langShiftTableIndex;
                    }
                }
            }
            if (langIndex == -1) {
                // nothing matches, use values for Unicode
                int byteCount = length * 2;
                if (byteCount > SmsConstants.MAX_USER_DATA_BYTES) {
                    values[0] = (byteCount + SmsConstants.MAX_USER_DATA_BYTES_WITH_HEADER - 1) /
                            SmsConstants.MAX_USER_DATA_BYTES_WITH_HEADER;
                    values[2] = ((values[0] * SmsConstants.MAX_USER_DATA_BYTES_WITH_HEADER) -
                            byteCount) / 2;
                } else {
                    values[0] = 1;
                    values[2] = (SmsConstants.MAX_USER_DATA_BYTES - byteCount) / 2;
                }
                values[1] = length;
                values[3] = SmsConstants.ENCODING_16BIT;
                values[4] = 0;
                values[5] = 0;
                mUnicodeCounter++;
            } else {
                int udhLength = 0;
                if (langIndex != 0 || langShiftIndex != 0) {
                    udhLength = UDH_SEPTET_COST_LENGTH;
                    if (langIndex == 0 || langShiftIndex == 0) {
                        udhLength += UDH_SEPTET_COST_ONE_SHIFT_TABLE;
                    } else {
                        udhLength += UDH_SEPTET_COST_TWO_SHIFT_TABLES;
                    }
                }
                int msgCount;
                if (minNumSeptets > (SmsConstants.MAX_USER_DATA_SEPTETS - udhLength)) {
                    if (udhLength == 0) {
                        udhLength = UDH_SEPTET_COST_LENGTH;
                    }
                    udhLength += UDH_SEPTET_COST_CONCATENATED_MESSAGE;
                    int septetsPerPart = SmsConstants.MAX_USER_DATA_SEPTETS - udhLength;
                    msgCount = (minNumSeptets + septetsPerPart - 1) / septetsPerPart;
                } else {
                    msgCount = 1;
                }
                values[0] = msgCount;
                values[1] = minNumSeptets;
                values[2] = (values[0] * (SmsConstants.MAX_USER_DATA_SEPTETS - udhLength)) -
                        minNumSeptets;
                values[3] = SmsConstants.ENCODING_7BIT;
                values[4] = (langIndex == 2 ? 3 : langIndex); // Portuguese is code 3, index 2
                values[5] = langShiftIndex;
                assertEquals("minNumSeptetsWithHeader", minNumSeptetsWithHeader,
                        udhLength * msgCount + minNumSeptets);
                mStatsCounters[langIndex * 4 + langShiftIndex]++;
            }
        }

        void printStats() {
            Rlog.d(TAG, "Unicode selection count: " + mUnicodeCounter);
            for (int i = 0; i < 12; i++) {
                Rlog.d(TAG, "Language pair index " + i + " count: " + mStatsCounters[i]);
            }
        }
    }

    @LargeTest
    public void testCalcLengthMixed7bit() throws Exception {
        StringBuilder sb = new StringBuilder(320);
        CounterHelper ch = new CounterHelper();
        Random r = new Random(0x4321);  // use the same seed for reproducibility
        int[] expectedValues = new int[6];
        int[] origLockingShiftTables = GsmAlphabet.getEnabledLockingShiftTables();
        int[] origSingleShiftTables = GsmAlphabet.getEnabledSingleShiftTables();
        int enabledLanguagesTestCases = sEnabledSingleShiftTables.length;
        long startTime = System.currentTimeMillis();

        // Repeat for 10 test runs
        for (int run = 0; run < 10; run++) {
            sb.setLength(0);
            ch.clear();
            int unicodeOnlyCount = 0;

            // Test incrementally from 1 to 320 character random messages
            for (int i = 1; i < 320; i++) {
                // 1% chance to add from each special character class, else add an ASCII char
                int charClass = r.nextInt(100);
                if (charClass >= sNumCharacterClasses) {
                    charClass = sNumCharacterClasses - 1;   // last class is ASCII
                }
                int classLength = sCharacterClasses[charClass].length();
                char nextChar = sCharacterClasses[charClass].charAt(r.nextInt(classLength));
                sb.append(nextChar);
                ch.addChar(charClass);

//                if (i % 20 == 0) {
//                    Rlog.d(TAG, "test string: " + sb);
//                }

                // Test string against all combinations of enabled languages
                boolean unicodeOnly = true;
                for (int j = 0; j < enabledLanguagesTestCases; j++) {
                    GsmAlphabet.setEnabledSingleShiftTables(sEnabledSingleShiftTables[j]);
                    GsmAlphabet.setEnabledLockingShiftTables(sEnabledLockingShiftTables[j]);
                    ch.fillData(j, false, expectedValues, i);
                    if (expectedValues[3] == SmsConstants.ENCODING_7BIT) {
                        unicodeOnly = false;
                    }
                    callGsmLengthMethods(sb, false, expectedValues);
                    // test 7 bit only mode
                    ch.fillData(j, true, expectedValues, i);
                    callGsmLengthMethods(sb, true, expectedValues);
                }
                // after 10 iterations with a Unicode-only string, skip to next test string
                // so we can spend more time testing strings that do encode into 7 bits.
                if (unicodeOnly && ++unicodeOnlyCount == 10) {
//                    Rlog.d(TAG, "Unicode only: skipping to next test string");
                    break;
                }
            }
        }
        ch.printStats();
        Rlog.d(TAG, "Completed in " + (System.currentTimeMillis() - startTime) + " ms");
        GsmAlphabet.setEnabledLockingShiftTables(origLockingShiftTables);
        GsmAlphabet.setEnabledSingleShiftTables(origSingleShiftTables);
    }

    private void callGsmLengthMethods(CharSequence msgBody, boolean use7bitOnly,
            int[] expectedValues)
    {
        // deprecated GSM-specific method
        int[] values = android.telephony.gsm.SmsMessage.calculateLength(msgBody, use7bitOnly);
        assertEquals("msgCount",           expectedValues[0], values[0]);
        assertEquals("codeUnitCount",      expectedValues[1], values[1]);
        assertEquals("codeUnitsRemaining", expectedValues[2], values[2]);
        assertEquals("codeUnitSize",       expectedValues[3], values[3]);

        int activePhone = TelephonyManager.getDefault().getPhoneType();
        if (TelephonyManager.PHONE_TYPE_GSM == activePhone) {
            values = android.telephony.SmsMessage.calculateLength(msgBody, use7bitOnly);
            assertEquals("msgCount",           expectedValues[0], values[0]);
            assertEquals("codeUnitCount",      expectedValues[1], values[1]);
            assertEquals("codeUnitsRemaining", expectedValues[2], values[2]);
            assertEquals("codeUnitSize",       expectedValues[3], values[3]);
        }

        GsmAlphabet.TextEncodingDetails ted =
                com.android.internal.telephony.gsm.SmsMessage.calculateLength(msgBody, use7bitOnly);
        assertEquals("msgCount",           expectedValues[0], ted.msgCount);
        assertEquals("codeUnitCount",      expectedValues[1], ted.codeUnitCount);
        assertEquals("codeUnitsRemaining", expectedValues[2], ted.codeUnitsRemaining);
        assertEquals("codeUnitSize",       expectedValues[3], ted.codeUnitSize);
        assertEquals("languageTable",      expectedValues[4], ted.languageTable);
        assertEquals("languageShiftTable", expectedValues[5], ted.languageShiftTable);
    }

    private void callCdmaLengthMethods(CharSequence msgBody, boolean use7bitOnly,
            int[] expectedValues)
    {
        int activePhone = TelephonyManager.getDefault().getPhoneType();
        if (TelephonyManager.PHONE_TYPE_CDMA == activePhone) {
            int[] values = android.telephony.SmsMessage.calculateLength(msgBody, use7bitOnly);
            assertEquals("msgCount",           expectedValues[0], values[0]);
            assertEquals("codeUnitCount",      expectedValues[1], values[1]);
            assertEquals("codeUnitsRemaining", expectedValues[2], values[2]);
            assertEquals("codeUnitSize",       expectedValues[3], values[3]);
        }

        GsmAlphabet.TextEncodingDetails ted =
                com.android.internal.telephony.cdma.SmsMessage.calculateLength(msgBody, use7bitOnly, true);
        assertEquals("msgCount",           expectedValues[0], ted.msgCount);
        assertEquals("codeUnitCount",      expectedValues[1], ted.codeUnitCount);
        assertEquals("codeUnitsRemaining", expectedValues[2], ted.codeUnitsRemaining);
        assertEquals("codeUnitSize",       expectedValues[3], ted.codeUnitSize);

        ted = com.android.internal.telephony.cdma.sms.BearerData.calcTextEncodingDetails(msgBody, use7bitOnly, true);
        assertEquals("msgCount",           expectedValues[0], ted.msgCount);
        assertEquals("codeUnitCount",      expectedValues[1], ted.codeUnitCount);
        assertEquals("codeUnitsRemaining", expectedValues[2], ted.codeUnitsRemaining);
        assertEquals("codeUnitSize",       expectedValues[3], ted.codeUnitSize);
    }
}
