summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaph Levien <raph@google.com>2016-02-17 15:04:17 -0800
committerRaph Levien <raph@google.com>2016-02-19 10:05:07 -0800
commit9d26bbe1ee14fcab80e2a4faa1f473df3906351c (patch)
treee2293615f22ce68fad223f52e9d166d0c14271c4
parentdb789b1a999f8f10135405caebd7962029a78ba1 (diff)
downloadbase-9d26bbe1ee14fcab80e2a4faa1f473df3906351c.tar.gz
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. Bug: 26210851 Change-Id: Ic16637a834af0dfe40197fbcdb3471c1bf5cd6d2
-rw-r--r--src/java/com/android/internal/telephony/SmsMessageBase.java17
1 files changed, 16 insertions, 1 deletions
diff --git a/src/java/com/android/internal/telephony/SmsMessageBase.java b/src/java/com/android/internal/telephony/SmsMessageBase.java
index 1d50834d3e0f..3338772796a3 100644
--- a/src/java/com/android/internal/telephony/SmsMessageBase.java
+++ b/src/java/com/android/internal/telephony/SmsMessageBase.java
@@ -24,6 +24,7 @@ import java.util.Arrays;
import android.provider.Telephony;
import android.telephony.SmsMessage;
+import android.text.Emoji;
/**
* Base class declaring the specific methods and members for SmsMessage.
@@ -367,7 +368,21 @@ 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
+ && Emoji.isRegionalIndicatorSymbol(
+ Character.codePointAt(msgBody, breakPos))
+ && Emoji.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;