Home | History | Annotate | Download | only in mms
      1 /*
      2  * Copyright (C) 2009 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.mms;
     18 
     19 import java.io.IOException;
     20 
     21 import org.xmlpull.v1.XmlPullParser;
     22 import org.xmlpull.v1.XmlPullParserException;
     23 
     24 import com.android.internal.telephony.TelephonyProperties;
     25 
     26 import android.content.Context;
     27 import android.content.res.XmlResourceParser;
     28 import android.util.Log;
     29 
     30 public class MmsConfig {
     31     private static final String TAG = "MmsConfig";
     32     private static final boolean DEBUG = true;
     33     private static final boolean LOCAL_LOGV = false;
     34 
     35     private static final String DEFAULT_HTTP_KEY_X_WAP_PROFILE = "x-wap-profile";
     36     private static final String DEFAULT_USER_AGENT = "Android-Mms/2.0";
     37 
     38     private static final int MAX_IMAGE_HEIGHT = 480;
     39     private static final int MAX_IMAGE_WIDTH = 640;
     40     private static final int MAX_TEXT_LENGTH = 2000;
     41 
     42     /**
     43      * Whether to hide MMS functionality from the user (i.e. SMS only).
     44      */
     45     private static boolean mTransIdEnabled = false;
     46     private static int mMmsEnabled = 1;                         // default to true
     47     private static int mMaxMessageSize = 300 * 1024;            // default to 300k max size
     48     private static String mUserAgent = DEFAULT_USER_AGENT;
     49     private static String mUaProfTagName = DEFAULT_HTTP_KEY_X_WAP_PROFILE;
     50     private static String mUaProfUrl = null;
     51     private static String mHttpParams = null;
     52     private static String mHttpParamsLine1Key = null;
     53     private static String mEmailGateway = null;
     54     private static int mMaxImageHeight = MAX_IMAGE_HEIGHT;      // default value
     55     private static int mMaxImageWidth = MAX_IMAGE_WIDTH;        // default value
     56     private static int mRecipientLimit = Integer.MAX_VALUE;     // default value
     57     private static int mDefaultSMSMessagesPerThread = 500;      // default value
     58     private static int mDefaultMMSMessagesPerThread = 50;       // default value
     59     private static int mMinMessageCountPerThread = 2;           // default value
     60     private static int mMaxMessageCountPerThread = 5000;        // default value
     61     private static int mHttpSocketTimeout = 60*1000;            // default to 1 min
     62     private static int mMinimumSlideElementDuration = 7;        // default to 7 sec
     63     private static boolean mNotifyWapMMSC = false;
     64     private static boolean mAllowAttachAudio = true;
     65 
     66     // See the comment below for mEnableMultipartSMS.
     67     private static int mSmsToMmsTextThreshold = 4;
     68 
     69     // This flag is somewhat confusing. If mEnableMultipartSMS is true, long sms messages are
     70     // always sent as multi-part sms messages, with no checked limit on the number of segments.
     71     // If mEnableMultipartSMS is false, then mSmsToMmsTextThreshold is used to determine the
     72     // limit of the number of sms segments before turning the long sms message into an mms
     73     // message. For example, if mSmsToMmsTextThreshold is 4, then a long sms message with three
     74     // or fewer segments will be sent as a multi-part sms. When the user types more characters
     75     // to cause the message to be 4 segments or more, the send button will show the MMS tag to
     76     // indicate the message will be sent as an mms.
     77     private static boolean mEnableMultipartSMS = true;
     78 
     79     private static boolean mEnableSlideDuration = true;
     80     private static boolean mEnableMMSReadReports = true;        // key: "enableMMSReadReports"
     81     private static boolean mEnableSMSDeliveryReports = true;    // key: "enableSMSDeliveryReports"
     82     private static boolean mEnableMMSDeliveryReports = true;    // key: "enableMMSDeliveryReports"
     83     private static int mMaxTextLength = -1;
     84 
     85     // This is the max amount of storage multiplied by mMaxMessageSize that we
     86     // allow of unsent messages before blocking the user from sending any more
     87     // MMS's.
     88     private static int mMaxSizeScaleForPendingMmsAllowed = 4;       // default value
     89 
     90     // Email gateway alias support, including the master switch and different rules
     91     private static boolean mAliasEnabled = false;
     92     private static int mAliasRuleMinChars = 2;
     93     private static int mAliasRuleMaxChars = 48;
     94 
     95     private static int mMaxSubjectLength = 40;  // maximum number of characters allowed for mms
     96                                                 // subject
     97 
     98     public static void init(Context context) {
     99         if (LOCAL_LOGV) {
    100             Log.v(TAG, "MmsConfig.init()");
    101         }
    102         // Always put the mnc/mcc in the log so we can tell which mms_config.xml was loaded.
    103         Log.v(TAG, "mnc/mcc: " +
    104                 android.os.SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC));
    105 
    106         loadMmsSettings(context);
    107     }
    108 
    109     public static int getSmsToMmsTextThreshold() {
    110         return mSmsToMmsTextThreshold;
    111     }
    112 
    113     public static boolean getMmsEnabled() {
    114         return mMmsEnabled == 1 ? true : false;
    115     }
    116 
    117     public static int getMaxMessageSize() {
    118         if (LOCAL_LOGV) {
    119             Log.v(TAG, "MmsConfig.getMaxMessageSize(): " + mMaxMessageSize);
    120         }
    121        return mMaxMessageSize;
    122     }
    123 
    124     /**
    125      * This function returns the value of "enabledTransID" present in mms_config file.
    126      * In case of single segment wap push message, this "enabledTransID" indicates whether
    127      * TransactionID should be appended to URI or not.
    128      */
    129     public static boolean getTransIdEnabled() {
    130         return mTransIdEnabled;
    131     }
    132 
    133     public static String getUserAgent() {
    134         return mUserAgent;
    135     }
    136 
    137     public static String getUaProfTagName() {
    138         return mUaProfTagName;
    139     }
    140 
    141     public static String getUaProfUrl() {
    142         return mUaProfUrl;
    143     }
    144 
    145     public static String getHttpParams() {
    146         return mHttpParams;
    147     }
    148 
    149     public static String getHttpParamsLine1Key() {
    150         return mHttpParamsLine1Key;
    151     }
    152 
    153     public static String getEmailGateway() {
    154         return mEmailGateway;
    155     }
    156 
    157     public static int getMaxImageHeight() {
    158         return mMaxImageHeight;
    159     }
    160 
    161     public static int getMaxImageWidth() {
    162         return mMaxImageWidth;
    163     }
    164 
    165     public static int getRecipientLimit() {
    166         return mRecipientLimit;
    167     }
    168 
    169     public static int getMaxTextLimit() {
    170         return mMaxTextLength > -1 ? mMaxTextLength : MAX_TEXT_LENGTH;
    171     }
    172 
    173     public static int getDefaultSMSMessagesPerThread() {
    174         return mDefaultSMSMessagesPerThread;
    175     }
    176 
    177     public static int getDefaultMMSMessagesPerThread() {
    178         return mDefaultMMSMessagesPerThread;
    179     }
    180 
    181     public static int getMinMessageCountPerThread() {
    182         return mMinMessageCountPerThread;
    183     }
    184 
    185     public static int getMaxMessageCountPerThread() {
    186         return mMaxMessageCountPerThread;
    187     }
    188 
    189     public static int getHttpSocketTimeout() {
    190         return mHttpSocketTimeout;
    191     }
    192 
    193     public static int getMinimumSlideElementDuration() {
    194         return mMinimumSlideElementDuration;
    195     }
    196 
    197     public static boolean getMultipartSmsEnabled() {
    198         return mEnableMultipartSMS;
    199     }
    200 
    201     public static boolean getSlideDurationEnabled() {
    202         return mEnableSlideDuration;
    203     }
    204 
    205     public static boolean getMMSReadReportsEnabled() {
    206         return mEnableMMSReadReports;
    207     }
    208 
    209     public static boolean getSMSDeliveryReportsEnabled() {
    210         return mEnableSMSDeliveryReports;
    211     }
    212 
    213     public static boolean getMMSDeliveryReportsEnabled() {
    214         return mEnableMMSDeliveryReports;
    215     }
    216 
    217     public static boolean getNotifyWapMMSC() {
    218         return mNotifyWapMMSC;
    219     }
    220 
    221     public static int getMaxSizeScaleForPendingMmsAllowed() {
    222         return mMaxSizeScaleForPendingMmsAllowed;
    223     }
    224 
    225     public static boolean isAliasEnabled() {
    226         return mAliasEnabled;
    227     }
    228 
    229     public static int getAliasMinChars() {
    230         return mAliasRuleMinChars;
    231     }
    232 
    233     public static int getAliasMaxChars() {
    234         return mAliasRuleMaxChars;
    235     }
    236 
    237     public static boolean getAllowAttachAudio() {
    238         return mAllowAttachAudio;
    239     }
    240 
    241     public static int getMaxSubjectLength() {
    242         return mMaxSubjectLength;
    243     }
    244 
    245     public static final void beginDocument(XmlPullParser parser, String firstElementName) throws XmlPullParserException, IOException
    246     {
    247         int type;
    248         while ((type=parser.next()) != parser.START_TAG
    249                    && type != parser.END_DOCUMENT) {
    250             ;
    251         }
    252 
    253         if (type != parser.START_TAG) {
    254             throw new XmlPullParserException("No start tag found");
    255         }
    256 
    257         if (!parser.getName().equals(firstElementName)) {
    258             throw new XmlPullParserException("Unexpected start tag: found " + parser.getName() +
    259                     ", expected " + firstElementName);
    260         }
    261     }
    262 
    263     public static final void nextElement(XmlPullParser parser) throws XmlPullParserException, IOException
    264     {
    265         int type;
    266         while ((type=parser.next()) != parser.START_TAG
    267                    && type != parser.END_DOCUMENT) {
    268             ;
    269         }
    270     }
    271 
    272     private static void loadMmsSettings(Context context) {
    273         XmlResourceParser parser = context.getResources().getXml(R.xml.mms_config);
    274 
    275         try {
    276             beginDocument(parser, "mms_config");
    277 
    278             while (true) {
    279                 nextElement(parser);
    280                 String tag = parser.getName();
    281                 if (tag == null) {
    282                     break;
    283                 }
    284                 String name = parser.getAttributeName(0);
    285                 String value = parser.getAttributeValue(0);
    286                 String text = null;
    287                 if (parser.next() == XmlPullParser.TEXT) {
    288                     text = parser.getText();
    289                 }
    290 
    291                 if (DEBUG) {
    292                     Log.v(TAG, "tag: " + tag + " value: " + value + " - " +
    293                             text);
    294                 }
    295                 if ("name".equalsIgnoreCase(name)) {
    296                     if ("bool".equals(tag)) {
    297                         // bool config tags go here
    298                         if ("enabledMMS".equalsIgnoreCase(value)) {
    299                             mMmsEnabled = "true".equalsIgnoreCase(text) ? 1 : 0;
    300                         } else if ("enabledTransID".equalsIgnoreCase(value)) {
    301                             mTransIdEnabled = "true".equalsIgnoreCase(text);
    302                         } else if ("enabledNotifyWapMMSC".equalsIgnoreCase(value)) {
    303                             mNotifyWapMMSC = "true".equalsIgnoreCase(text);
    304                         } else if ("aliasEnabled".equalsIgnoreCase(value)) {
    305                             mAliasEnabled = "true".equalsIgnoreCase(text);
    306                         } else if ("allowAttachAudio".equalsIgnoreCase(value)) {
    307                             mAllowAttachAudio = "true".equalsIgnoreCase(text);
    308                         } else if ("enableMultipartSMS".equalsIgnoreCase(value)) {
    309                             mEnableMultipartSMS = "true".equalsIgnoreCase(text);
    310                         } else if ("enableSlideDuration".equalsIgnoreCase(value)) {
    311                             mEnableSlideDuration = "true".equalsIgnoreCase(text);
    312                         } else if ("enableMMSReadReports".equalsIgnoreCase(value)) {
    313                             mEnableMMSReadReports = "true".equalsIgnoreCase(text);
    314                         } else if ("enableSMSDeliveryReports".equalsIgnoreCase(value)) {
    315                             mEnableSMSDeliveryReports = "true".equalsIgnoreCase(text);
    316                         } else if ("enableMMSDeliveryReports".equalsIgnoreCase(value)) {
    317                             mEnableMMSDeliveryReports = "true".equalsIgnoreCase(text);
    318                         }
    319                     } else if ("int".equals(tag)) {
    320                         // int config tags go here
    321                         if ("maxMessageSize".equalsIgnoreCase(value)) {
    322                             mMaxMessageSize = Integer.parseInt(text);
    323                         } else if ("maxImageHeight".equalsIgnoreCase(value)) {
    324                             mMaxImageHeight = Integer.parseInt(text);
    325                         } else if ("maxImageWidth".equalsIgnoreCase(value)) {
    326                             mMaxImageWidth = Integer.parseInt(text);
    327                         } else if ("defaultSMSMessagesPerThread".equalsIgnoreCase(value)) {
    328                             mDefaultSMSMessagesPerThread = Integer.parseInt(text);
    329                         } else if ("defaultMMSMessagesPerThread".equalsIgnoreCase(value)) {
    330                             mDefaultMMSMessagesPerThread = Integer.parseInt(text);
    331                         } else if ("minMessageCountPerThread".equalsIgnoreCase(value)) {
    332                             mMinMessageCountPerThread = Integer.parseInt(text);
    333                         } else if ("maxMessageCountPerThread".equalsIgnoreCase(value)) {
    334                             mMaxMessageCountPerThread = Integer.parseInt(text);
    335                         } else if ("recipientLimit".equalsIgnoreCase(value)) {
    336                             mRecipientLimit = Integer.parseInt(text);
    337                             if (mRecipientLimit < 0) {
    338                                 mRecipientLimit = Integer.MAX_VALUE;
    339                             }
    340                         } else if ("httpSocketTimeout".equalsIgnoreCase(value)) {
    341                             mHttpSocketTimeout = Integer.parseInt(text);
    342                         } else if ("minimumSlideElementDuration".equalsIgnoreCase(value)) {
    343                             mMinimumSlideElementDuration = Integer.parseInt(text);
    344                         } else if ("maxSizeScaleForPendingMmsAllowed".equalsIgnoreCase(value)) {
    345                             mMaxSizeScaleForPendingMmsAllowed = Integer.parseInt(text);
    346                         } else if ("aliasMinChars".equalsIgnoreCase(value)) {
    347                             mAliasRuleMinChars = Integer.parseInt(text);
    348                         } else if ("aliasMaxChars".equalsIgnoreCase(value)) {
    349                             mAliasRuleMaxChars = Integer.parseInt(text);
    350                         } else if ("smsToMmsTextThreshold".equalsIgnoreCase(value)) {
    351                             mSmsToMmsTextThreshold = Integer.parseInt(text);
    352                         } else if ("maxMessageTextSize".equalsIgnoreCase(value)) {
    353                             mMaxTextLength = Integer.parseInt(text);
    354                         } else if ("maxSubjectLength".equalsIgnoreCase(value)) {
    355                             mMaxSubjectLength = Integer.parseInt(text);
    356                         }
    357                     } else if ("string".equals(tag)) {
    358                         // string config tags go here
    359                         if ("userAgent".equalsIgnoreCase(value)) {
    360                             mUserAgent = text;
    361                         } else if ("uaProfTagName".equalsIgnoreCase(value)) {
    362                             mUaProfTagName = text;
    363                         } else if ("uaProfUrl".equalsIgnoreCase(value)) {
    364                             mUaProfUrl = text;
    365                         } else if ("httpParams".equalsIgnoreCase(value)) {
    366                             mHttpParams = text;
    367                         } else if ("httpParamsLine1Key".equalsIgnoreCase(value)) {
    368                             mHttpParamsLine1Key = text;
    369                         } else if ("emailGatewayNumber".equalsIgnoreCase(value)) {
    370                             mEmailGateway = text;
    371                         }
    372                     }
    373                 }
    374             }
    375         } catch (XmlPullParserException e) {
    376             Log.e(TAG, "loadMmsSettings caught ", e);
    377         } catch (NumberFormatException e) {
    378             Log.e(TAG, "loadMmsSettings caught ", e);
    379         } catch (IOException e) {
    380             Log.e(TAG, "loadMmsSettings caught ", e);
    381         } finally {
    382             parser.close();
    383         }
    384 
    385         String errorStr = null;
    386 
    387         if (getMmsEnabled() && mUaProfUrl == null) {
    388             errorStr = "uaProfUrl";
    389         }
    390 
    391         if (errorStr != null) {
    392             String err =
    393                 String.format("MmsConfig.loadMmsSettings mms_config.xml missing %s setting",
    394                         errorStr);
    395             Log.e(TAG, err);
    396         }
    397     }
    398 
    399 }
    400