• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 android.content.Context;
25 import android.content.res.XmlResourceParser;
26 import android.util.Log;
27 
28 import com.android.internal.telephony.TelephonyProperties;
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     // If mEnableMultipartSMS is true, long sms messages are always sent as multi-part sms
67     // messages, with no checked limit on the number of segments.
68     // If mEnableMultipartSMS is false, then as soon as the user types a message longer
69     // than a single segment (i.e. 140 chars), then the message will turn into and be sent
70     // as an mms message. This feature exists for carriers that don't support multi-part sms's.
71     private static boolean mEnableMultipartSMS = true;
72 
73     // If mEnableMultipartSMS is true and mSmsToMmsTextThreshold > 1, then multi-part SMS messages
74     // will be converted into a single mms message. For example, if the mms_config.xml file
75     // specifies <int name="smsToMmsTextThreshold">4</int>, then on the 5th sms segment, the
76     // message will be converted to an mms.
77     private static int mSmsToMmsTextThreshold = -1;
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     // If mEnableGroupMms is true, a message with multiple recipients, regardless of contents,
99     // will be sent as a single MMS message with multiple "TO" fields set for each recipient.
100     // If mEnableGroupMms is false, the group MMS setting/preference will be hidden in the settings
101     // activity.
102     private static boolean mEnableGroupMms = true;
103 
init(Context context)104     public static void init(Context context) {
105         if (LOCAL_LOGV) {
106             Log.v(TAG, "MmsConfig.init()");
107         }
108         // Always put the mnc/mcc in the log so we can tell which mms_config.xml was loaded.
109         Log.v(TAG, "mnc/mcc: " +
110                 android.os.SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC));
111 
112         loadMmsSettings(context);
113     }
114 
getSmsToMmsTextThreshold()115     public static int getSmsToMmsTextThreshold() {
116         return mSmsToMmsTextThreshold;
117     }
118 
getMmsEnabled()119     public static boolean getMmsEnabled() {
120         return mMmsEnabled == 1 ? true : false;
121     }
122 
getMaxMessageSize()123     public static int getMaxMessageSize() {
124         if (LOCAL_LOGV) {
125             Log.v(TAG, "MmsConfig.getMaxMessageSize(): " + mMaxMessageSize);
126         }
127        return mMaxMessageSize;
128     }
129 
130     /**
131      * This function returns the value of "enabledTransID" present in mms_config file.
132      * In case of single segment wap push message, this "enabledTransID" indicates whether
133      * TransactionID should be appended to URI or not.
134      */
getTransIdEnabled()135     public static boolean getTransIdEnabled() {
136         return mTransIdEnabled;
137     }
138 
getUserAgent()139     public static String getUserAgent() {
140         return mUserAgent;
141     }
142 
getUaProfTagName()143     public static String getUaProfTagName() {
144         return mUaProfTagName;
145     }
146 
getUaProfUrl()147     public static String getUaProfUrl() {
148         return mUaProfUrl;
149     }
150 
getHttpParams()151     public static String getHttpParams() {
152         return mHttpParams;
153     }
154 
getHttpParamsLine1Key()155     public static String getHttpParamsLine1Key() {
156         return mHttpParamsLine1Key;
157     }
158 
getEmailGateway()159     public static String getEmailGateway() {
160         return mEmailGateway;
161     }
162 
getMaxImageHeight()163     public static int getMaxImageHeight() {
164         return mMaxImageHeight;
165     }
166 
getMaxImageWidth()167     public static int getMaxImageWidth() {
168         return mMaxImageWidth;
169     }
170 
getRecipientLimit()171     public static int getRecipientLimit() {
172         return mRecipientLimit;
173     }
174 
getMaxTextLimit()175     public static int getMaxTextLimit() {
176         return mMaxTextLength > -1 ? mMaxTextLength : MAX_TEXT_LENGTH;
177     }
178 
getDefaultSMSMessagesPerThread()179     public static int getDefaultSMSMessagesPerThread() {
180         return mDefaultSMSMessagesPerThread;
181     }
182 
getDefaultMMSMessagesPerThread()183     public static int getDefaultMMSMessagesPerThread() {
184         return mDefaultMMSMessagesPerThread;
185     }
186 
getMinMessageCountPerThread()187     public static int getMinMessageCountPerThread() {
188         return mMinMessageCountPerThread;
189     }
190 
getMaxMessageCountPerThread()191     public static int getMaxMessageCountPerThread() {
192         return mMaxMessageCountPerThread;
193     }
194 
getHttpSocketTimeout()195     public static int getHttpSocketTimeout() {
196         return mHttpSocketTimeout;
197     }
198 
getMinimumSlideElementDuration()199     public static int getMinimumSlideElementDuration() {
200         return mMinimumSlideElementDuration;
201     }
202 
getMultipartSmsEnabled()203     public static boolean getMultipartSmsEnabled() {
204         return mEnableMultipartSMS;
205     }
206 
getSlideDurationEnabled()207     public static boolean getSlideDurationEnabled() {
208         return mEnableSlideDuration;
209     }
210 
getMMSReadReportsEnabled()211     public static boolean getMMSReadReportsEnabled() {
212         return mEnableMMSReadReports;
213     }
214 
getSMSDeliveryReportsEnabled()215     public static boolean getSMSDeliveryReportsEnabled() {
216         return mEnableSMSDeliveryReports;
217     }
218 
getMMSDeliveryReportsEnabled()219     public static boolean getMMSDeliveryReportsEnabled() {
220         return mEnableMMSDeliveryReports;
221     }
222 
getNotifyWapMMSC()223     public static boolean getNotifyWapMMSC() {
224         return mNotifyWapMMSC;
225     }
226 
getMaxSizeScaleForPendingMmsAllowed()227     public static int getMaxSizeScaleForPendingMmsAllowed() {
228         return mMaxSizeScaleForPendingMmsAllowed;
229     }
230 
isAliasEnabled()231     public static boolean isAliasEnabled() {
232         return mAliasEnabled;
233     }
234 
getAliasMinChars()235     public static int getAliasMinChars() {
236         return mAliasRuleMinChars;
237     }
238 
getAliasMaxChars()239     public static int getAliasMaxChars() {
240         return mAliasRuleMaxChars;
241     }
242 
getAllowAttachAudio()243     public static boolean getAllowAttachAudio() {
244         return mAllowAttachAudio;
245     }
246 
getMaxSubjectLength()247     public static int getMaxSubjectLength() {
248         return mMaxSubjectLength;
249     }
250 
getGroupMmsEnabled()251     public static boolean getGroupMmsEnabled() {
252         return mEnableGroupMms;
253     }
254 
beginDocument(XmlPullParser parser, String firstElementName)255     public static final void beginDocument(XmlPullParser parser, String firstElementName) throws XmlPullParserException, IOException
256     {
257         int type;
258         while ((type=parser.next()) != parser.START_TAG
259                    && type != parser.END_DOCUMENT) {
260             ;
261         }
262 
263         if (type != parser.START_TAG) {
264             throw new XmlPullParserException("No start tag found");
265         }
266 
267         if (!parser.getName().equals(firstElementName)) {
268             throw new XmlPullParserException("Unexpected start tag: found " + parser.getName() +
269                     ", expected " + firstElementName);
270         }
271     }
272 
nextElement(XmlPullParser parser)273     public static final void nextElement(XmlPullParser parser) throws XmlPullParserException, IOException
274     {
275         int type;
276         while ((type=parser.next()) != parser.START_TAG
277                    && type != parser.END_DOCUMENT) {
278             ;
279         }
280     }
281 
loadMmsSettings(Context context)282     private static void loadMmsSettings(Context context) {
283         XmlResourceParser parser = context.getResources().getXml(R.xml.mms_config);
284 
285         try {
286             beginDocument(parser, "mms_config");
287 
288             while (true) {
289                 nextElement(parser);
290                 String tag = parser.getName();
291                 if (tag == null) {
292                     break;
293                 }
294                 String name = parser.getAttributeName(0);
295                 String value = parser.getAttributeValue(0);
296                 String text = null;
297                 if (parser.next() == XmlPullParser.TEXT) {
298                     text = parser.getText();
299                 }
300 
301                 if (DEBUG) {
302                     Log.v(TAG, "tag: " + tag + " value: " + value + " - " +
303                             text);
304                 }
305                 if ("name".equalsIgnoreCase(name)) {
306                     if ("bool".equals(tag)) {
307                         // bool config tags go here
308                         if ("enabledMMS".equalsIgnoreCase(value)) {
309                             mMmsEnabled = "true".equalsIgnoreCase(text) ? 1 : 0;
310                         } else if ("enabledTransID".equalsIgnoreCase(value)) {
311                             mTransIdEnabled = "true".equalsIgnoreCase(text);
312                         } else if ("enabledNotifyWapMMSC".equalsIgnoreCase(value)) {
313                             mNotifyWapMMSC = "true".equalsIgnoreCase(text);
314                         } else if ("aliasEnabled".equalsIgnoreCase(value)) {
315                             mAliasEnabled = "true".equalsIgnoreCase(text);
316                         } else if ("allowAttachAudio".equalsIgnoreCase(value)) {
317                             mAllowAttachAudio = "true".equalsIgnoreCase(text);
318                         } else if ("enableMultipartSMS".equalsIgnoreCase(value)) {
319                             mEnableMultipartSMS = "true".equalsIgnoreCase(text);
320                         } else if ("enableSlideDuration".equalsIgnoreCase(value)) {
321                             mEnableSlideDuration = "true".equalsIgnoreCase(text);
322                         } else if ("enableMMSReadReports".equalsIgnoreCase(value)) {
323                             mEnableMMSReadReports = "true".equalsIgnoreCase(text);
324                         } else if ("enableSMSDeliveryReports".equalsIgnoreCase(value)) {
325                             mEnableSMSDeliveryReports = "true".equalsIgnoreCase(text);
326                         } else if ("enableMMSDeliveryReports".equalsIgnoreCase(value)) {
327                             mEnableMMSDeliveryReports = "true".equalsIgnoreCase(text);
328                         } else if ("enableGroupMms".equalsIgnoreCase(value)) {
329                             mEnableGroupMms = "true".equalsIgnoreCase(text);
330                         }
331                     } else if ("int".equals(tag)) {
332                         // int config tags go here
333                         if ("maxMessageSize".equalsIgnoreCase(value)) {
334                             mMaxMessageSize = Integer.parseInt(text);
335                         } else if ("maxImageHeight".equalsIgnoreCase(value)) {
336                             mMaxImageHeight = Integer.parseInt(text);
337                         } else if ("maxImageWidth".equalsIgnoreCase(value)) {
338                             mMaxImageWidth = Integer.parseInt(text);
339                         } else if ("defaultSMSMessagesPerThread".equalsIgnoreCase(value)) {
340                             mDefaultSMSMessagesPerThread = Integer.parseInt(text);
341                         } else if ("defaultMMSMessagesPerThread".equalsIgnoreCase(value)) {
342                             mDefaultMMSMessagesPerThread = Integer.parseInt(text);
343                         } else if ("minMessageCountPerThread".equalsIgnoreCase(value)) {
344                             mMinMessageCountPerThread = Integer.parseInt(text);
345                         } else if ("maxMessageCountPerThread".equalsIgnoreCase(value)) {
346                             mMaxMessageCountPerThread = Integer.parseInt(text);
347                         } else if ("recipientLimit".equalsIgnoreCase(value)) {
348                             mRecipientLimit = Integer.parseInt(text);
349                             if (mRecipientLimit < 0) {
350                                 mRecipientLimit = Integer.MAX_VALUE;
351                             }
352                         } else if ("httpSocketTimeout".equalsIgnoreCase(value)) {
353                             mHttpSocketTimeout = Integer.parseInt(text);
354                         } else if ("minimumSlideElementDuration".equalsIgnoreCase(value)) {
355                             mMinimumSlideElementDuration = Integer.parseInt(text);
356                         } else if ("maxSizeScaleForPendingMmsAllowed".equalsIgnoreCase(value)) {
357                             mMaxSizeScaleForPendingMmsAllowed = Integer.parseInt(text);
358                         } else if ("aliasMinChars".equalsIgnoreCase(value)) {
359                             mAliasRuleMinChars = Integer.parseInt(text);
360                         } else if ("aliasMaxChars".equalsIgnoreCase(value)) {
361                             mAliasRuleMaxChars = Integer.parseInt(text);
362                         } else if ("smsToMmsTextThreshold".equalsIgnoreCase(value)) {
363                             mSmsToMmsTextThreshold = Integer.parseInt(text);
364                         } else if ("maxMessageTextSize".equalsIgnoreCase(value)) {
365                             mMaxTextLength = Integer.parseInt(text);
366                         } else if ("maxSubjectLength".equalsIgnoreCase(value)) {
367                             mMaxSubjectLength = Integer.parseInt(text);
368                         }
369                     } else if ("string".equals(tag)) {
370                         // string config tags go here
371                         if ("userAgent".equalsIgnoreCase(value)) {
372                             mUserAgent = text;
373                         } else if ("uaProfTagName".equalsIgnoreCase(value)) {
374                             mUaProfTagName = text;
375                         } else if ("uaProfUrl".equalsIgnoreCase(value)) {
376                             mUaProfUrl = text;
377                         } else if ("httpParams".equalsIgnoreCase(value)) {
378                             mHttpParams = text;
379                         } else if ("httpParamsLine1Key".equalsIgnoreCase(value)) {
380                             mHttpParamsLine1Key = text;
381                         } else if ("emailGatewayNumber".equalsIgnoreCase(value)) {
382                             mEmailGateway = text;
383                         }
384                     }
385                 }
386             }
387         } catch (XmlPullParserException e) {
388             Log.e(TAG, "loadMmsSettings caught ", e);
389         } catch (NumberFormatException e) {
390             Log.e(TAG, "loadMmsSettings caught ", e);
391         } catch (IOException e) {
392             Log.e(TAG, "loadMmsSettings caught ", e);
393         } finally {
394             parser.close();
395         }
396 
397         String errorStr = null;
398 
399         if (getMmsEnabled() && mUaProfUrl == null) {
400             errorStr = "uaProfUrl";
401         }
402 
403         if (errorStr != null) {
404             String err =
405                 String.format("MmsConfig.loadMmsSettings mms_config.xml missing %s setting",
406                         errorStr);
407             Log.e(TAG, err);
408         }
409     }
410 
411 }
412