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