Home | History | Annotate | Download | only in datamodel
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.messaging.datamodel;
     18 
     19 import android.telephony.SmsMessage;
     20 
     21 import com.android.messaging.sms.MmsConfig;
     22 
     23 public class MessageTextStats {
     24     private boolean mMessageLengthRequiresMms;
     25     private int mMessageCount;
     26     private int mCodePointsRemainingInCurrentMessage;
     27 
     28     public MessageTextStats() {
     29         mCodePointsRemainingInCurrentMessage = Integer.MAX_VALUE;
     30     }
     31 
     32     public int getNumMessagesToBeSent() {
     33         return mMessageCount;
     34     }
     35 
     36     public int getCodePointsRemainingInCurrentMessage() {
     37         return mCodePointsRemainingInCurrentMessage;
     38     }
     39 
     40     public boolean getMessageLengthRequiresMms() {
     41         return mMessageLengthRequiresMms;
     42     }
     43 
     44     public void updateMessageTextStats(final int selfSubId, final String messageText) {
     45         final int[] params = SmsMessage.calculateLength(messageText, false);
     46         /* SmsMessage.calculateLength returns an int[4] with:
     47          *   int[0] being the number of SMS's required,
     48          *   int[1] the number of code points used,
     49          *   int[2] is the number of code points remaining until the next message.
     50          *   int[3] is the encoding type that should be used for the message.
     51          */
     52         mMessageCount = params[0];
     53         mCodePointsRemainingInCurrentMessage = params[2];
     54 
     55         final MmsConfig mmsConfig = MmsConfig.get(selfSubId);
     56         if (!mmsConfig.getMultipartSmsEnabled() &&
     57                 !mmsConfig.getSendMultipartSmsAsSeparateMessages()) {
     58             // The provider doesn't support multi-part sms's and we should use MMS to
     59             // send multi-part sms, so as soon as the user types
     60             // an sms longer than one segment, we have to turn the message into an mms.
     61             mMessageLengthRequiresMms = mMessageCount > 1;
     62         } else {
     63             final int threshold = mmsConfig.getSmsToMmsTextThreshold();
     64             mMessageLengthRequiresMms = threshold > 0 && mMessageCount > threshold;
     65         }
     66         // Some carriers require any SMS message longer than 80 to be sent as MMS
     67         // see b/12122333
     68         int smsToMmsLengthThreshold = mmsConfig.getSmsToMmsTextLengthThreshold();
     69         if (smsToMmsLengthThreshold > 0) {
     70             final int usedInCurrentMessage = params[1];
     71             /*
     72              * A little hacky way to find out if we should count characters in double bytes.
     73              * SmsMessage.calculateLength counts message code units based on the characters
     74              * in input. If all of them are ascii, the max length is
     75              * SmsMessage.MAX_USER_DATA_SEPTETS (160). If any of them are double-byte, like
     76              * Korean or Chinese, the max length is SmsMessage.MAX_USER_DATA_BYTES (140) bytes
     77              * (70 code units).
     78              * Here we check if the total code units we can use is smaller than 140. If so,
     79              * we know we should count threshold in double-byte, so divide the threshold by 2.
     80              * In this way, we will count Korean text correctly with regard to the length threshold.
     81              */
     82             if (usedInCurrentMessage + mCodePointsRemainingInCurrentMessage
     83                     < SmsMessage.MAX_USER_DATA_BYTES) {
     84                 smsToMmsLengthThreshold /= 2;
     85             }
     86             if (usedInCurrentMessage > smsToMmsLengthThreshold) {
     87                 mMessageLengthRequiresMms = true;
     88             }
     89         }
     90     }
     91 
     92 }
     93