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.Config; 27 import android.util.Log; 28 29 public class MmsConfig { 30 private static final String TAG = "MmsConfig"; 31 private static final boolean DEBUG = false; 32 private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV; 33 34 private static final String DEFAULT_HTTP_KEY_X_WAP_PROFILE = "x-wap-profile"; 35 private static final String DEFAULT_USER_AGENT = "Android-Mms/2.0"; 36 37 private static final int MAX_IMAGE_HEIGHT = 480; 38 private static final int MAX_IMAGE_WIDTH = 640; 39 private static final int MAX_TEXT_LENGTH = 2000; 40 41 /** 42 * Whether to hide MMS functionality from the user (i.e. SMS only). 43 */ 44 private static boolean mTransIdEnabled = false; 45 private static int mMmsEnabled = 1; // default to true 46 private static int mMaxMessageSize = 300 * 1024; // default to 300k max size 47 private static String mUserAgent = DEFAULT_USER_AGENT; 48 private static String mUaProfTagName = DEFAULT_HTTP_KEY_X_WAP_PROFILE; 49 private static String mUaProfUrl = null; 50 private static String mHttpParams = null; 51 private static String mHttpParamsLine1Key = null; 52 private static String mEmailGateway = null; 53 private static int mMaxImageHeight = MAX_IMAGE_HEIGHT; // default value 54 private static int mMaxImageWidth = MAX_IMAGE_WIDTH; // default value 55 private static int mRecipientLimit = Integer.MAX_VALUE; // default value 56 private static int mDefaultSMSMessagesPerThread = 200; // default value 57 private static int mDefaultMMSMessagesPerThread = 20; // default value 58 private static int mMinMessageCountPerThread = 2; // default value 59 private static int mMaxMessageCountPerThread = 5000; // default value 60 private static int mHttpSocketTimeout = 60*1000; // default to 1 min 61 private static int mMinimumSlideElementDuration = 7; // default to 7 sec 62 private static boolean mNotifyWapMMSC = false; 63 private static boolean mAllowAttachAudio = true; 64 private static int mSmsToMmsTextThreshold = 4; 65 private static boolean mEnableMultipartSMS = true; 66 private static boolean mEnableSlideDuration = true; 67 private static int mMaxTextLength = -1; 68 69 // This is the max amount of storage multiplied by mMaxMessageSize that we 70 // allow of unsent messages before blocking the user from sending any more 71 // MMS's. 72 private static int mMaxSizeScaleForPendingMmsAllowed = 4; // default value 73 74 // Email gateway alias support, including the master switch and different rules 75 private static boolean mAliasEnabled = false; 76 private static int mAliasRuleMinChars = 2; 77 private static int mAliasRuleMaxChars = 48; 78 79 public static void init(Context context) { 80 if (LOCAL_LOGV) { 81 Log.v(TAG, "MmsConfig.init()"); 82 } 83 84 loadMmsSettings(context); 85 } 86 87 public static int getSmsToMmsTextThreshold() { 88 return mSmsToMmsTextThreshold; 89 } 90 91 public static boolean getMmsEnabled() { 92 return mMmsEnabled == 1 ? true : false; 93 } 94 95 public static int getMaxMessageSize() { 96 return mMaxMessageSize; 97 } 98 99 /** 100 * This function returns the value of "enabledTransID" present in mms_config file. 101 * In case of single segment wap push message, this "enabledTransID" indicates whether 102 * TransactionID should be appended to URI or not. 103 */ 104 public static boolean getTransIdEnabled() { 105 return mTransIdEnabled; 106 } 107 108 public static String getUserAgent() { 109 return mUserAgent; 110 } 111 112 public static String getUaProfTagName() { 113 return mUaProfTagName; 114 } 115 116 public static String getUaProfUrl() { 117 return mUaProfUrl; 118 } 119 120 public static String getHttpParams() { 121 return mHttpParams; 122 } 123 124 public static String getHttpParamsLine1Key() { 125 return mHttpParamsLine1Key; 126 } 127 128 public static String getEmailGateway() { 129 return mEmailGateway; 130 } 131 132 public static int getMaxImageHeight() { 133 return mMaxImageHeight; 134 } 135 136 public static int getMaxImageWidth() { 137 return mMaxImageWidth; 138 } 139 140 public static int getRecipientLimit() { 141 return mRecipientLimit; 142 } 143 144 public static int getMaxTextLimit() { 145 return mMaxTextLength > -1 ? mMaxTextLength : MAX_TEXT_LENGTH; 146 } 147 148 public static int getDefaultSMSMessagesPerThread() { 149 return mDefaultSMSMessagesPerThread; 150 } 151 152 public static int getDefaultMMSMessagesPerThread() { 153 return mDefaultMMSMessagesPerThread; 154 } 155 156 public static int getMinMessageCountPerThread() { 157 return mMinMessageCountPerThread; 158 } 159 160 public static int getMaxMessageCountPerThread() { 161 return mMaxMessageCountPerThread; 162 } 163 164 public static int getHttpSocketTimeout() { 165 return mHttpSocketTimeout; 166 } 167 168 public static int getMinimumSlideElementDuration() { 169 return mMinimumSlideElementDuration; 170 } 171 172 public static boolean getMultipartSmsEnabled() { 173 return mEnableMultipartSMS; 174 } 175 176 public static boolean getSlideDurationEnabled() { 177 return mEnableSlideDuration; 178 } 179 180 public static boolean getNotifyWapMMSC() { 181 return mNotifyWapMMSC; 182 } 183 184 public static int getMaxSizeScaleForPendingMmsAllowed() { 185 return mMaxSizeScaleForPendingMmsAllowed; 186 } 187 188 public static boolean isAliasEnabled() { 189 return mAliasEnabled; 190 } 191 192 public static int getAliasMinChars() { 193 return mAliasRuleMinChars; 194 } 195 196 public static int getAliasMaxChars() { 197 return mAliasRuleMaxChars; 198 } 199 200 public static boolean getAllowAttachAudio() { 201 return mAllowAttachAudio; 202 } 203 204 public static final void beginDocument(XmlPullParser parser, String firstElementName) throws XmlPullParserException, IOException 205 { 206 int type; 207 while ((type=parser.next()) != parser.START_TAG 208 && type != parser.END_DOCUMENT) { 209 ; 210 } 211 212 if (type != parser.START_TAG) { 213 throw new XmlPullParserException("No start tag found"); 214 } 215 216 if (!parser.getName().equals(firstElementName)) { 217 throw new XmlPullParserException("Unexpected start tag: found " + parser.getName() + 218 ", expected " + firstElementName); 219 } 220 } 221 222 public static final void nextElement(XmlPullParser parser) throws XmlPullParserException, IOException 223 { 224 int type; 225 while ((type=parser.next()) != parser.START_TAG 226 && type != parser.END_DOCUMENT) { 227 ; 228 } 229 } 230 231 private static void loadMmsSettings(Context context) { 232 XmlResourceParser parser = context.getResources().getXml(R.xml.mms_config); 233 234 try { 235 beginDocument(parser, "mms_config"); 236 237 while (true) { 238 nextElement(parser); 239 String tag = parser.getName(); 240 if (tag == null) { 241 break; 242 } 243 String name = parser.getAttributeName(0); 244 String value = parser.getAttributeValue(0); 245 String text = null; 246 if (parser.next() == XmlPullParser.TEXT) { 247 text = parser.getText(); 248 } 249 250 if (DEBUG) { 251 Log.v(TAG, "tag: " + tag + " value: " + value); 252 } 253 if ("name".equalsIgnoreCase(name)) { 254 if ("bool".equals(tag)) { 255 // bool config tags go here 256 if ("enabledMMS".equalsIgnoreCase(value)) { 257 mMmsEnabled = "true".equalsIgnoreCase(text) ? 1 : 0; 258 } else if ("enabledTransID".equalsIgnoreCase(value)) { 259 mTransIdEnabled = "true".equalsIgnoreCase(text); 260 } else if ("enabledNotifyWapMMSC".equalsIgnoreCase(value)) { 261 mNotifyWapMMSC = "true".equalsIgnoreCase(text); 262 } else if ("aliasEnabled".equalsIgnoreCase(value)) { 263 mAliasEnabled = "true".equalsIgnoreCase(text); 264 } else if ("allowAttachAudio".equalsIgnoreCase(value)) { 265 mAllowAttachAudio = "true".equalsIgnoreCase(text); 266 } else if ("enableMultipartSMS".equalsIgnoreCase(value)) { 267 mEnableMultipartSMS = "true".equalsIgnoreCase(text); 268 } else if ("enableSlideDuration".equalsIgnoreCase(value)) { 269 mEnableSlideDuration = "true".equalsIgnoreCase(text); 270 } 271 } else if ("int".equals(tag)) { 272 // int config tags go here 273 if ("maxMessageSize".equalsIgnoreCase(value)) { 274 mMaxMessageSize = Integer.parseInt(text); 275 } else if ("maxImageHeight".equalsIgnoreCase(value)) { 276 mMaxImageHeight = Integer.parseInt(text); 277 } else if ("maxImageWidth".equalsIgnoreCase(value)) { 278 mMaxImageWidth = Integer.parseInt(text); 279 } else if ("defaultSMSMessagesPerThread".equalsIgnoreCase(value)) { 280 mDefaultSMSMessagesPerThread = Integer.parseInt(text); 281 } else if ("defaultMMSMessagesPerThread".equalsIgnoreCase(value)) { 282 mDefaultMMSMessagesPerThread = Integer.parseInt(text); 283 } else if ("minMessageCountPerThread".equalsIgnoreCase(value)) { 284 mMinMessageCountPerThread = Integer.parseInt(text); 285 } else if ("maxMessageCountPerThread".equalsIgnoreCase(value)) { 286 mMaxMessageCountPerThread = Integer.parseInt(text); 287 } else if ("recipientLimit".equalsIgnoreCase(value)) { 288 mRecipientLimit = Integer.parseInt(text); 289 if (mRecipientLimit < 0) { 290 mRecipientLimit = Integer.MAX_VALUE; 291 } 292 } else if ("httpSocketTimeout".equalsIgnoreCase(value)) { 293 mHttpSocketTimeout = Integer.parseInt(text); 294 } else if ("minimumSlideElementDuration".equalsIgnoreCase(value)) { 295 mMinimumSlideElementDuration = Integer.parseInt(text); 296 } else if ("maxSizeScaleForPendingMmsAllowed".equalsIgnoreCase(value)) { 297 mMaxSizeScaleForPendingMmsAllowed = Integer.parseInt(text); 298 } else if ("aliasMinChars".equalsIgnoreCase(value)) { 299 mAliasRuleMinChars = Integer.parseInt(text); 300 } else if ("aliasMaxChars".equalsIgnoreCase(value)) { 301 mAliasRuleMaxChars = Integer.parseInt(text); 302 } else if ("smsToMmsTextThreshold".equalsIgnoreCase(value)) { 303 mSmsToMmsTextThreshold = Integer.parseInt(text); 304 } else if ("maxMessageTextSize".equalsIgnoreCase(value)) { 305 mMaxTextLength = Integer.parseInt(text); 306 } 307 } else if ("string".equals(tag)) { 308 // string config tags go here 309 if ("userAgent".equalsIgnoreCase(value)) { 310 mUserAgent = text; 311 } else if ("uaProfTagName".equalsIgnoreCase(value)) { 312 mUaProfTagName = text; 313 } else if ("uaProfUrl".equalsIgnoreCase(value)) { 314 mUaProfUrl = text; 315 } else if ("httpParams".equalsIgnoreCase(value)) { 316 mHttpParams = text; 317 } else if ("httpParamsLine1Key".equalsIgnoreCase(value)) { 318 mHttpParamsLine1Key = text; 319 } else if ("emailGatewayNumber".equalsIgnoreCase(value)) { 320 mEmailGateway = text; 321 } 322 } 323 } 324 } 325 } catch (XmlPullParserException e) { 326 Log.e(TAG, "loadMmsSettings caught ", e); 327 } catch (NumberFormatException e) { 328 Log.e(TAG, "loadMmsSettings caught ", e); 329 } catch (IOException e) { 330 Log.e(TAG, "loadMmsSettings caught ", e); 331 } finally { 332 parser.close(); 333 } 334 335 String errorStr = null; 336 337 if (getMmsEnabled() && mUaProfUrl == null) { 338 errorStr = "uaProfUrl"; 339 } 340 341 if (errorStr != null) { 342 String err = 343 String.format("MmsConfig.loadMmsSettings mms_config.xml missing %s setting", 344 errorStr); 345 Log.e(TAG, err); 346 throw new ContentRestrictionException(err); 347 } 348 } 349 350 } 351