diff options
| author | pengfeix <pengfeix@codeaurora.org> | 2016-04-12 13:13:21 +0800 |
|---|---|---|
| committer | Steve Kondik <steve@cyngn.com> | 2016-07-02 10:55:01 -0700 |
| commit | ce2ca072fee674bcf7e53ceb3367c8643869cee2 (patch) | |
| tree | 7212758d2c22a845452464c20c55a634ba460d6f | |
| parent | b3571da33cd77218deb382374bddb8a043f27383 (diff) | |
| download | android_frameworks_opt_telephony-ce2ca072fee674bcf7e53ceb3367c8643869cee2.tar.gz android_frameworks_opt_telephony-ce2ca072fee674bcf7e53ceb3367c8643869cee2.tar.bz2 android_frameworks_opt_telephony-ce2ca072fee674bcf7e53ceb3367c8643869cee2.zip | |
Finer grained character boundaries in computing SMS fragment lengths
The standard Java character iterator has potentially unbounded
distance between character boundaries, meaning that when
breaking an SMS message into fragments it's not safe to assume that
the fragment will contain such a boundary. This patch
special-cases flags (pairs of Regional Indicator Symbols) and also
guarantees some progress in the case of no boundary found.
Change-Id: I35990b44ad72887e1fdd436223808e18b04bd578
CRs-Fixed: 994916
| -rw-r--r-- | src/java/com/android/internal/telephony/SmsMessageBase.java | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/src/java/com/android/internal/telephony/SmsMessageBase.java b/src/java/com/android/internal/telephony/SmsMessageBase.java index 0b8dfdfd7..a4cc690b1 100644 --- a/src/java/com/android/internal/telephony/SmsMessageBase.java +++ b/src/java/com/android/internal/telephony/SmsMessageBase.java @@ -352,6 +352,10 @@ public abstract class SmsMessageBase { mIsEmail = Telephony.Mms.isEmailAddress(mEmailFrom); } + //Returns true if the given code point is regional indicator symbol + private static boolean isRegionalIndicatorSymbol(int codepoint) { + return (0x1F1E6 <= codepoint && codepoint <= 0x1F1FF); + } /** * Find the next position to start a new fragment of a multipart SMS. * @@ -370,7 +374,22 @@ public abstract class SmsMessageBase { BreakIterator breakIterator = BreakIterator.getCharacterInstance(); breakIterator.setText(msgBody.toString()); if (!breakIterator.isBoundary(nextPos)) { - nextPos = breakIterator.preceding(nextPos); + int breakPos = breakIterator.preceding(nextPos); + while (breakPos + 4 <= nextPos + && isRegionalIndicatorSymbol( + Character.codePointAt(msgBody, breakPos)) + && isRegionalIndicatorSymbol( + Character.codePointAt(msgBody, breakPos + 2))) { + // skip forward over flags (pairs of Regional Indicator Symbol) + breakPos += 4; + } + if (breakPos > currentPosition) { + nextPos = breakPos; + } else if (Character.isHighSurrogate(msgBody.charAt(nextPos - 1))) { + // no character boundary in this fragment, try to at least land on a code point + nextPos -= 1; + } + } } return nextPos; |
