Merge "Divide a message text into correctly sized parts"

This commit is contained in:
Treehugger Robot
2019-05-21 05:25:39 +00:00
committed by Gerrit Code Review
7 changed files with 108 additions and 75 deletions

View File

@@ -1546,8 +1546,6 @@ Lcom/android/internal/telephony/Sms7BitEncodingTranslator;->DBG:Z
Lcom/android/internal/telephony/Sms7BitEncodingTranslator;->mTranslationTableCDMA:Landroid/util/SparseIntArray; Lcom/android/internal/telephony/Sms7BitEncodingTranslator;->mTranslationTableCDMA:Landroid/util/SparseIntArray;
Lcom/android/internal/telephony/Sms7BitEncodingTranslator;->mTranslationTableCommon:Landroid/util/SparseIntArray; Lcom/android/internal/telephony/Sms7BitEncodingTranslator;->mTranslationTableCommon:Landroid/util/SparseIntArray;
Lcom/android/internal/telephony/Sms7BitEncodingTranslator;->mTranslationTableGSM:Landroid/util/SparseIntArray; Lcom/android/internal/telephony/Sms7BitEncodingTranslator;->mTranslationTableGSM:Landroid/util/SparseIntArray;
Lcom/android/internal/telephony/Sms7BitEncodingTranslator;->translate(Ljava/lang/CharSequence;)Ljava/lang/String;
Lcom/android/internal/telephony/Sms7BitEncodingTranslator;->useCdmaFormatForMoSms()Z
Lcom/android/internal/telephony/SmsApplication$SmsApplicationData;->mApplicationName:Ljava/lang/String; Lcom/android/internal/telephony/SmsApplication$SmsApplicationData;->mApplicationName:Ljava/lang/String;
Lcom/android/internal/telephony/SmsApplication;->configurePreferredActivity(Landroid/content/pm/PackageManager;Landroid/content/ComponentName;I)V Lcom/android/internal/telephony/SmsApplication;->configurePreferredActivity(Landroid/content/pm/PackageManager;Landroid/content/ComponentName;I)V
Lcom/android/internal/telephony/SmsApplication;->getApplicationCollection(Landroid/content/Context;)Ljava/util/Collection; Lcom/android/internal/telephony/SmsApplication;->getApplicationCollection(Landroid/content/Context;)Ljava/util/Collection;

View File

@@ -567,20 +567,17 @@ public final class SmsManager {
} }
/** /**
* Divide a message text into several fragments, none bigger than * Divide a message text into several fragments, none bigger than the maximum SMS message size.
* the maximum SMS message size.
* *
* @param text the original message. Must not be null. * @param text the original message. Must not be null.
* @return an <code>ArrayList</code> of strings that, in order, * @return an <code>ArrayList</code> of strings that, in order, comprise the original message.
* comprise the original message * @throws IllegalArgumentException if text is null.
*
* @throws IllegalArgumentException if text is null
*/ */
public ArrayList<String> divideMessage(String text) { public ArrayList<String> divideMessage(String text) {
if (null == text) { if (null == text) {
throw new IllegalArgumentException("text is null"); throw new IllegalArgumentException("text is null");
} }
return SmsMessage.fragmentText(text); return SmsMessage.fragmentText(text, getSubscriptionId());
} }
/** /**

View File

@@ -337,27 +337,45 @@ public class SmsMessage {
*/ */
/** /**
* Calculates the number of SMS's required to encode the message body and * Calculates the number of SMS's required to encode the message body and the number of
* the number of characters remaining until the next message. * characters remaining until the next message.
* *
* @param msgBody the message to encode * @param msgBody the message to encode
* @param use7bitOnly if true, characters that are not part of the * @param use7bitOnly if true, characters that are not part of the radio-specific 7-bit encoding
* radio-specific 7-bit encoding are counted as single * are counted as single space chars. If false, and if the messageBody contains non-7-bit
* space chars. If false, and if the messageBody contains * encodable characters, length is calculated using a 16-bit encoding.
* non-7-bit encodable characters, length is calculated * @return an int[4] with int[0] being the number of SMS's required, int[1] the number of code
* using a 16-bit encoding. * units used, and int[2] is the number of code units remaining until the next message.
* @return an int[4] with int[0] being the number of SMS's * int[3] is an indicator of the encoding code unit size (see the ENCODING_* definitions in
* required, int[1] the number of code units used, and * SmsConstants).
* int[2] is the number of code units remaining until the
* next message. int[3] is an indicator of the encoding
* code unit size (see the ENCODING_* definitions in SmsConstants)
*/ */
public static int[] calculateLength(CharSequence msgBody, boolean use7bitOnly) { public static int[] calculateLength(CharSequence msgBody, boolean use7bitOnly) {
return calculateLength(msgBody, use7bitOnly, SmsManager.getDefaultSmsSubscriptionId());
}
/**
* Calculates the number of SMS's required to encode the message body and the number of
* characters remaining until the next message.
*
* @param msgBody the message to encode
* @param use7bitOnly if true, characters that are not part of the radio-specific 7-bit encoding
* are counted as single space chars. If false, and if the messageBody contains non-7-bit
* encodable characters, length is calculated using a 16-bit encoding.
* @param subId Subscription to take SMS format.
* @return an int[4] with int[0] being the number of SMS's required, int[1] the number of code
* units used, and int[2] is the number of code units remaining until the next message.
* int[3] is an indicator of the encoding code unit size (see the ENCODING_* definitions in
* SmsConstants).
* @hide
*/
public static int[] calculateLength(CharSequence msgBody, boolean use7bitOnly, int subId) {
// this function is for MO SMS // this function is for MO SMS
TextEncodingDetails ted = (useCdmaFormatForMoSms()) ? TextEncodingDetails ted =
com.android.internal.telephony.cdma.SmsMessage.calculateLength(msgBody, use7bitOnly, useCdmaFormatForMoSms(subId)
true) : ? com.android.internal.telephony.cdma.SmsMessage.calculateLength(
com.android.internal.telephony.gsm.SmsMessage.calculateLength(msgBody, use7bitOnly); msgBody, use7bitOnly, true)
: com.android.internal.telephony.gsm.SmsMessage.calculateLength(
msgBody, use7bitOnly);
int ret[] = new int[4]; int ret[] = new int[4];
ret[0] = ted.msgCount; ret[0] = ted.msgCount;
ret[1] = ted.codeUnitCount; ret[1] = ted.codeUnitCount;
@@ -367,21 +385,37 @@ public class SmsMessage {
} }
/** /**
* Divide a message text into several fragments, none bigger than * Divide a message text into several fragments, none bigger than the maximum SMS message text
* the maximum SMS message text size. * size.
* *
* @param text text, must not be null. * @param text text, must not be null.
* @return an <code>ArrayList</code> of strings that, in order, * @return an <code>ArrayList</code> of strings that, in order, comprise the original msg text.
* comprise the original msg text
*
* @hide * @hide
*/ */
@UnsupportedAppUsage @UnsupportedAppUsage
public static ArrayList<String> fragmentText(String text) { public static ArrayList<String> fragmentText(String text) {
return fragmentText(text, SmsManager.getDefaultSmsSubscriptionId());
}
/**
* Divide a message text into several fragments, none bigger than the maximum SMS message text
* size.
*
* @param text text, must not be null.
* @param subId Subscription to take SMS format.
* @return an <code>ArrayList</code> of strings that, in order, comprise the original msg text.
* @hide
*/
public static ArrayList<String> fragmentText(String text, int subId) {
// This function is for MO SMS // This function is for MO SMS
TextEncodingDetails ted = (useCdmaFormatForMoSms()) ? final boolean isCdma = useCdmaFormatForMoSms(subId);
com.android.internal.telephony.cdma.SmsMessage.calculateLength(text, false, true) :
com.android.internal.telephony.gsm.SmsMessage.calculateLength(text, false); TextEncodingDetails ted =
isCdma
? com.android.internal.telephony.cdma.SmsMessage.calculateLength(
text, false, true)
: com.android.internal.telephony.gsm.SmsMessage.calculateLength(
text, false);
// TODO(cleanup): The code here could be rolled into the logic // TODO(cleanup): The code here could be rolled into the logic
// below cleanly if these MAX_* constants were defined more // below cleanly if these MAX_* constants were defined more
@@ -427,18 +461,19 @@ public class SmsMessage {
String newMsgBody = null; String newMsgBody = null;
Resources r = Resources.getSystem(); Resources r = Resources.getSystem();
if (r.getBoolean(com.android.internal.R.bool.config_sms_force_7bit_encoding)) { if (r.getBoolean(com.android.internal.R.bool.config_sms_force_7bit_encoding)) {
newMsgBody = Sms7BitEncodingTranslator.translate(text); newMsgBody = Sms7BitEncodingTranslator.translate(text, isCdma);
} }
if (TextUtils.isEmpty(newMsgBody)) { if (TextUtils.isEmpty(newMsgBody)) {
newMsgBody = text; newMsgBody = text;
} }
int pos = 0; // Index in code units. int pos = 0; // Index in code units.
int textLen = newMsgBody.length(); int textLen = newMsgBody.length();
ArrayList<String> result = new ArrayList<String>(ted.msgCount); ArrayList<String> result = new ArrayList<String>(ted.msgCount);
while (pos < textLen) { while (pos < textLen) {
int nextPos = 0; // Counts code units. int nextPos = 0; // Counts code units.
if (ted.codeUnitSize == SmsConstants.ENCODING_7BIT) { if (ted.codeUnitSize == SmsConstants.ENCODING_7BIT) {
if (useCdmaFormatForMoSms() && ted.msgCount == 1) { if (isCdma && ted.msgCount == 1) {
// For a singleton CDMA message, the encoding must be ASCII... // For a singleton CDMA message, the encoding must be ASCII...
nextPos = pos + Math.min(limit, textLen - pos); nextPos = pos + Math.min(limit, textLen - pos);
} else { } else {
@@ -461,25 +496,39 @@ public class SmsMessage {
} }
/** /**
* Calculates the number of SMS's required to encode the message body and * Calculates the number of SMS's required to encode the message body and the number of
* the number of characters remaining until the next message, given the * characters remaining until the next message, given the current encoding.
* current encoding.
* *
* @param messageBody the message to encode * @param messageBody the message to encode
* @param use7bitOnly if true, characters that are not part of the radio * @param use7bitOnly if true, characters that are not part of the radio specific (GSM / CDMA)
* specific (GSM / CDMA) alphabet encoding are converted to as a * alphabet encoding are converted to as a single space characters. If false, a messageBody
* single space characters. If false, a messageBody containing * containing non-GSM or non-CDMA alphabet characters are encoded using 16-bit encoding.
* non-GSM or non-CDMA alphabet characters are encoded using * @return an int[4] with int[0] being the number of SMS's required, int[1] the number of code
* 16-bit encoding. * units used, and int[2] is the number of code units remaining until the next message.
* @return an int[4] with int[0] being the number of SMS's required, int[1] * int[3] is the encoding type that should be used for the message.
* the number of code units used, and int[2] is the number of code
* units remaining until the next message. int[3] is the encoding
* type that should be used for the message.
*/ */
public static int[] calculateLength(String messageBody, boolean use7bitOnly) { public static int[] calculateLength(String messageBody, boolean use7bitOnly) {
return calculateLength((CharSequence)messageBody, use7bitOnly); return calculateLength((CharSequence)messageBody, use7bitOnly);
} }
/**
* Calculates the number of SMS's required to encode the message body and the number of
* characters remaining until the next message, given the current encoding.
*
* @param messageBody the message to encode
* @param use7bitOnly if true, characters that are not part of the radio specific (GSM / CDMA)
* alphabet encoding are converted to as a single space characters. If false, a messageBody
* containing non-GSM or non-CDMA alphabet characters are encoded using 16-bit encoding.
* @param subId Subscription to take SMS format.
* @return an int[4] with int[0] being the number of SMS's required, int[1] the number of code
* units used, and int[2] is the number of code units remaining until the next message.
* int[3] is the encoding type that should be used for the message.
* @hide
*/
public static int[] calculateLength(String messageBody, boolean use7bitOnly, int subId) {
return calculateLength((CharSequence) messageBody, use7bitOnly, subId);
}
/* /*
* TODO(cleanup): It looks like there is now no useful reason why * TODO(cleanup): It looks like there is now no useful reason why
* apps should generate pdus themselves using these routines, * apps should generate pdus themselves using these routines,
@@ -510,8 +559,12 @@ public class SmsMessage {
*/ */
public static SubmitPdu getSubmitPdu(String scAddress, public static SubmitPdu getSubmitPdu(String scAddress,
String destinationAddress, String message, boolean statusReportRequested) { String destinationAddress, String message, boolean statusReportRequested) {
return getSubmitPdu(scAddress, destinationAddress, message, statusReportRequested, return getSubmitPdu(
SubscriptionManager.getDefaultSmsSubscriptionId()); scAddress,
destinationAddress,
message,
statusReportRequested,
SmsManager.getDefaultSmsSubscriptionId());
} }
/** /**
@@ -834,7 +887,7 @@ public class SmsMessage {
@UnsupportedAppUsage @UnsupportedAppUsage
private static boolean useCdmaFormatForMoSms() { private static boolean useCdmaFormatForMoSms() {
// IMS is registered with SMS support, check the SMS format supported // IMS is registered with SMS support, check the SMS format supported
return useCdmaFormatForMoSms(SubscriptionManager.getDefaultSmsSubscriptionId()); return useCdmaFormatForMoSms(SmsManager.getDefaultSmsSubscriptionId());
} }
/** /**
@@ -863,7 +916,7 @@ public class SmsMessage {
* @return true if current phone type is cdma, false otherwise. * @return true if current phone type is cdma, false otherwise.
*/ */
private static boolean isCdmaVoice() { private static boolean isCdmaVoice() {
return isCdmaVoice(SubscriptionManager.getDefaultSmsSubscriptionId()); return isCdmaVoice(SmsManager.getDefaultSmsSubscriptionId());
} }
/** /**

View File

@@ -868,7 +868,6 @@ public class GsmAlphabet {
ted.msgCount = 1; ted.msgCount = 1;
ted.codeUnitsRemaining = SmsConstants.MAX_USER_DATA_SEPTETS - septets; ted.codeUnitsRemaining = SmsConstants.MAX_USER_DATA_SEPTETS - septets;
} }
ted.codeUnitSize = SmsConstants.ENCODING_7BIT;
return ted; return ted;
} }

View File

@@ -47,17 +47,14 @@ public class Sms7BitEncodingTranslator {
private static final String XML_TO_TAG = "to"; private static final String XML_TO_TAG = "to";
/** /**
* Translates each message character that is not supported by GSM 7bit * Translates each message character that is not supported by GSM 7bit alphabet into a supported
* alphabet into a supported one * one.
* *
* @param message * @param message message to be translated.
* message to be translated * @param isCdmaFormat true if cdma format should be used.
* @param throwsException * @return translated message or null if some error occur.
* if true and some error occurs during translation, an exception
* is thrown; otherwise a null String is returned
* @return translated message or null if some error occur
*/ */
public static String translate(CharSequence message) { public static String translate(CharSequence message, boolean isCdmaFormat) {
if (message == null) { if (message == null) {
Rlog.w(TAG, "Null message can not be translated"); Rlog.w(TAG, "Null message can not be translated");
return null; return null;
@@ -80,7 +77,6 @@ public class Sms7BitEncodingTranslator {
(mTranslationTableGSM != null && mTranslationTableGSM.size() > 0) || (mTranslationTableGSM != null && mTranslationTableGSM.size() > 0) ||
(mTranslationTableCDMA != null && mTranslationTableCDMA.size() > 0)) { (mTranslationTableCDMA != null && mTranslationTableCDMA.size() > 0)) {
char[] output = new char[size]; char[] output = new char[size];
boolean isCdmaFormat = useCdmaFormatForMoSms();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
output[i] = translateIfNeeded(message.charAt(i), isCdmaFormat); output[i] = translateIfNeeded(message.charAt(i), isCdmaFormat);
} }
@@ -159,16 +155,6 @@ public class Sms7BitEncodingTranslator {
} }
} }
private static boolean useCdmaFormatForMoSms() {
if (!SmsManager.getDefault().isImsSmsSupported()) {
// use Voice technology to determine SMS format.
return TelephonyManager.getDefault().getCurrentPhoneType()
== PhoneConstants.PHONE_TYPE_CDMA;
}
// IMS is registered with SMS support, check the SMS format supported
return (SmsConstants.FORMAT_3GPP2.equals(SmsManager.getDefault().getImsSmsFormat()));
}
/** /**
* Load the whole translation table file from the framework resource * Load the whole translation table file from the framework resource
* encoded in XML. * encoded in XML.

View File

@@ -418,7 +418,7 @@ public class SmsMessage extends SmsMessageBase {
CharSequence newMsgBody = null; CharSequence newMsgBody = null;
Resources r = Resources.getSystem(); Resources r = Resources.getSystem();
if (r.getBoolean(com.android.internal.R.bool.config_sms_force_7bit_encoding)) { if (r.getBoolean(com.android.internal.R.bool.config_sms_force_7bit_encoding)) {
newMsgBody = Sms7BitEncodingTranslator.translate(messageBody); newMsgBody = Sms7BitEncodingTranslator.translate(messageBody, true);
} }
if (TextUtils.isEmpty(newMsgBody)) { if (TextUtils.isEmpty(newMsgBody)) {
newMsgBody = messageBody; newMsgBody = messageBody;

View File

@@ -914,7 +914,7 @@ public class SmsMessage extends SmsMessageBase {
CharSequence newMsgBody = null; CharSequence newMsgBody = null;
Resources r = Resources.getSystem(); Resources r = Resources.getSystem();
if (r.getBoolean(com.android.internal.R.bool.config_sms_force_7bit_encoding)) { if (r.getBoolean(com.android.internal.R.bool.config_sms_force_7bit_encoding)) {
newMsgBody = Sms7BitEncodingTranslator.translate(msgBody); newMsgBody = Sms7BitEncodingTranslator.translate(msgBody, false);
} }
if (TextUtils.isEmpty(newMsgBody)) { if (TextUtils.isEmpty(newMsgBody)) {
newMsgBody = msgBody; newMsgBody = msgBody;