aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpengfeix <pengfeix@codeaurora.org>2016-04-12 13:13:21 +0800
committerSteve Kondik <steve@cyngn.com>2016-07-02 10:55:01 -0700
commitce2ca072fee674bcf7e53ceb3367c8643869cee2 (patch)
tree7212758d2c22a845452464c20c55a634ba460d6f
parentb3571da33cd77218deb382374bddb8a043f27383 (diff)
downloadandroid_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.java21
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;