summaryrefslogtreecommitdiffstats
path: root/src/com/android
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android')
-rw-r--r--src/com/android/mms/service/DownloadRequest.java13
-rwxr-xr-xsrc/com/android/mms/service/MmsConfig.java571
-rw-r--r--src/com/android/mms/service/MmsConfigManager.java61
-rw-r--r--src/com/android/mms/service/MmsConfigXmlProcessor.java197
-rw-r--r--src/com/android/mms/service/MmsHttpClient.java171
-rw-r--r--src/com/android/mms/service/MmsRequest.java31
-rw-r--r--src/com/android/mms/service/MmsService.java10
-rw-r--r--src/com/android/mms/service/SendRequest.java12
8 files changed, 207 insertions, 859 deletions
diff --git a/src/com/android/mms/service/DownloadRequest.java b/src/com/android/mms/service/DownloadRequest.java
index c9f6789..5e4d0a4 100644
--- a/src/com/android/mms/service/DownloadRequest.java
+++ b/src/com/android/mms/service/DownloadRequest.java
@@ -36,6 +36,7 @@ import android.service.carrier.CarrierMessagingService;
import android.service.carrier.ICarrierMessagingCallback;
import android.service.carrier.ICarrierMessagingService;
import android.telephony.CarrierMessagingServiceManager;
+import android.telephony.SmsManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
@@ -65,8 +66,8 @@ public class DownloadRequest extends MmsRequest {
public DownloadRequest(RequestManager manager, int subId, String locationUrl,
Uri contentUri, PendingIntent downloadedIntent, String creator,
- Bundle configOverrides) {
- super(manager, subId, creator, configOverrides);
+ Bundle configOverrides, Context context) {
+ super(manager, subId, creator, configOverrides, context);
mLocationUrl = locationUrl;
mDownloadedIntent = downloadedIntent;
mContentUri = contentUri;
@@ -87,7 +88,8 @@ public class DownloadRequest extends MmsRequest {
apn.isProxySet(),
apn.getProxyAddress(),
apn.getProxyPort(),
- mMmsConfig);
+ mMmsConfig,
+ mSubId);
}
@Override
@@ -115,8 +117,9 @@ public class DownloadRequest extends MmsRequest {
}
final long identity = Binder.clearCallingIdentity();
try {
- final GenericPdu pdu =
- (new PduParser(response, mMmsConfig.getSupportMmsContentDisposition())).parse();
+ final boolean supportMmsContentDisposition =
+ mMmsConfig.getBoolean(SmsManager.MMS_CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION);
+ final GenericPdu pdu = (new PduParser(response, supportMmsContentDisposition)).parse();
if (pdu == null || !(pdu instanceof RetrieveConf)) {
Log.e(MmsService.TAG, "DownloadRequest.persistIfRequired: invalid parsed PDU");
return null;
diff --git a/src/com/android/mms/service/MmsConfig.java b/src/com/android/mms/service/MmsConfig.java
deleted file mode 100755
index c5505aa..0000000
--- a/src/com/android/mms/service/MmsConfig.java
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mms.service;
-
-import android.content.Context;
-import android.content.res.XmlResourceParser;
-import android.os.Bundle;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.Base64;
-import android.util.Log;
-
-import java.io.UnsupportedEncodingException;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * This class manages a cached copy of current MMS configuration key values
- *
- * The steps to add a key
- * 1. Add a String constant for the key
- * 2. Add a default value for the key by putting a typed value to DEFAULTS
- * (null means String type only)
- * 3. Add a getter for the key
- * 4. Add key/value for relevant mms_config.xml of a specific carrier (mcc/mnc)
- */
-public class MmsConfig {
- private static final String TAG = MmsService.TAG;
-
- private static final String DEFAULT_HTTP_KEY_X_WAP_PROFILE = "x-wap-profile";
-
- private static final int MAX_IMAGE_HEIGHT = 480;
- private static final int MAX_IMAGE_WIDTH = 640;
- private static final int MAX_TEXT_LENGTH = 2000;
-
- /*
- * MmsConfig keys. These have to stay in sync with the MMS_CONFIG_* values defined in
- * SmsManager.
- */
- public static final String CONFIG_ENABLED_MMS = "enabledMMS";
- // In case of single segment wap push message, this CONFIG_ENABLED_TRANS_ID indicates whether
- // TransactionID should be appended to URI or not.
- public static final String CONFIG_ENABLED_TRANS_ID = "enabledTransID";
- public static final String CONFIG_ENABLED_NOTIFY_WAP_MMSC = "enabledNotifyWapMMSC";
- public static final String CONFIG_ALIAS_ENABLED = "aliasEnabled";
- public static final String CONFIG_ALLOW_ATTACH_AUDIO = "allowAttachAudio";
- // If CONFIG_ENABLE_MULTIPART_SMS is true, long sms messages are always sent as multi-part sms
- // messages, with no checked limit on the number of segments.
- // If CONFIG_ENABLE_MULTIPART_SMS is false, then as soon as the user types a message longer
- // than a single segment (i.e. 140 chars), then the message will turn into and be sent
- // as an mms message or separate, independent SMS messages
- // (which is dependent on CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES flag).
- // This feature exists for carriers that don't support multi-part sms's.
- public static final String CONFIG_ENABLE_MULTIPART_SMS = "enableMultipartSMS";
- public static final String CONFIG_ENABLE_SMS_DELIVERY_REPORTS = "enableSMSDeliveryReports";
- // If CONFIG_ENABLE_GROUP_MMS is true, a message with multiple recipients,
- // regardless of contents, will be sent as a single MMS message with multiple "TO" fields set
- // for each recipient.
- // If CONFIG_ENABLE_GROUP_MMS is false, the group MMS setting/preference will be hidden
- // in the settings activity.
- public static final String CONFIG_ENABLE_GROUP_MMS = "enableGroupMms";
- // If this is true, then we should read the content_disposition field of an MMS part
- // Check wap-230-wsp-20010705-a.pdf, chapter 8.4.2.21
- // Most carriers support it except Sprint.
- // There is a system resource defining it:
- // com.android.internal.R.bool.config_mms_content_disposition_support.
- // But Shem can not read it. Add here so that we can configure for different carriers.
- public static final String CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION =
- "supportMmsContentDisposition";
- // if true, show the cell broadcast (amber alert) in the SMS settings. Some carriers
- // don't want this shown.
- public static final String CONFIG_CELL_BROADCAST_APP_LINKS = "config_cellBroadcastAppLinks";
- // If this is true, we will send multipart SMS as separate SMS messages
- public static final String CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES =
- "sendMultipartSmsAsSeparateMessages";
- // FLAG(ywen): the following two is not supported yet.
- public static final String CONFIG_ENABLE_MMS_READ_REPORTS = "enableMMSReadReports";
- public static final String CONFIG_ENABLE_MMS_DELIVERY_REPORTS = "enableMMSDeliveryReports";
- // Bouygues Telecom (20820) MMSC does not support "charset" with "Content-Type" header
- // It would fail and return 500. See b/18604507
- // If this is false, then we don't add "charset" to "Content-Type"
- public static final String CONFIG_SUPPORT_HTTP_CHARSET_HEADER = "supportHttpCharsetHeader";
- public static final String CONFIG_MAX_MESSAGE_SIZE = "maxMessageSize"; // in bytes
- public static final String CONFIG_MAX_IMAGE_HEIGHT = "maxImageHeight"; // in pixels
- public static final String CONFIG_MAX_IMAGE_WIDTH = "maxImageWidth"; // in pixels
- public static final String CONFIG_RECIPIENT_LIMIT = "recipientLimit";
- public static final String CONFIG_HTTP_SOCKET_TIMEOUT = "httpSocketTimeout";
- public static final String CONFIG_ALIAS_MIN_CHARS = "aliasMinChars";
- public static final String CONFIG_ALIAS_MAX_CHARS = "aliasMaxChars";
- // If CONFIG_ENABLE_MULTIPART_SMS is true and CONFIG_SMS_TO_MMS_TEXT_THRESHOLD > 1,
- // then multi-part SMS messages will be converted into a single mms message.
- // For example, if the mms_config.xml file specifies <int name="smsToMmsTextThreshold">4</int>,
- // then on the 5th sms segment, the message will be converted to an mms.
- public static final String CONFIG_SMS_TO_MMS_TEXT_THRESHOLD = "smsToMmsTextThreshold";
- // LGU+ temporarily requires any SMS message longer than 80 bytes to be sent as MMS
- // see b/12122333
- public static final String CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD =
- "smsToMmsTextLengthThreshold";
- public static final String CONFIG_MAX_MESSAGE_TEXT_SIZE = "maxMessageTextSize";
- // maximum number of characters allowed for mms subject
- public static final String CONFIG_MAX_SUBJECT_LENGTH = "maxSubjectLength";
- public static final String CONFIG_UA_PROF_TAG_NAME = "uaProfTagName";
- public static final String CONFIG_USER_AGENT = "userAgent";
- public static final String CONFIG_UA_PROF_URL = "uaProfUrl";
- public static final String CONFIG_HTTP_PARAMS = "httpParams";
- // Email gateway alias support, including the master switch and different rules
- public static final String CONFIG_EMAIL_GATEWAY_NUMBER = "emailGatewayNumber";
- // String to append to the NAI header, e.g. ":pcs"
- public static final String CONFIG_NAI_SUFFIX = "naiSuffix";
-
- /*
- * Key types
- */
- public static final String KEY_TYPE_INT = "int";
- public static final String KEY_TYPE_BOOL = "bool";
- public static final String KEY_TYPE_STRING = "string";
-
- /*
- * Macro names
- */
- // The raw phone number from TelephonyManager.getLine1Number
- public static final String MACRO_LINE1 = "LINE1";
- // The phone number without country code
- public static final String MACRO_LINE1NOCOUNTRYCODE = "LINE1NOCOUNTRYCODE";
- // NAI (Network Access Identifier), used by Sprint for authentication
- public static final String MACRO_NAI = "NAI";
-
- // Default values. This is read-only. Don't write into it.
- // This provides the info on valid keys, their types and default values
- private static final Map<String, Object> DEFAULTS = new ConcurrentHashMap<String, Object>();
- static {
- DEFAULTS.put(CONFIG_ENABLED_MMS, Boolean.valueOf(true));
- DEFAULTS.put(CONFIG_ENABLED_TRANS_ID, Boolean.valueOf(false));
- DEFAULTS.put(CONFIG_ENABLED_NOTIFY_WAP_MMSC, Boolean.valueOf(false));
- DEFAULTS.put(CONFIG_ALIAS_ENABLED, Boolean.valueOf(false));
- DEFAULTS.put(CONFIG_ALLOW_ATTACH_AUDIO, Boolean.valueOf(true));
- DEFAULTS.put(CONFIG_ENABLE_MULTIPART_SMS, Boolean.valueOf(true));
- DEFAULTS.put(CONFIG_ENABLE_SMS_DELIVERY_REPORTS, Boolean.valueOf(true));
- DEFAULTS.put(CONFIG_ENABLE_GROUP_MMS, Boolean.valueOf(true));
- DEFAULTS.put(CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION, Boolean.valueOf(true));
- DEFAULTS.put(CONFIG_CELL_BROADCAST_APP_LINKS, Boolean.valueOf(true));
- DEFAULTS.put(CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES, Boolean.valueOf(false));
- DEFAULTS.put(CONFIG_ENABLE_MMS_READ_REPORTS, Boolean.valueOf(false));
- DEFAULTS.put(CONFIG_ENABLE_MMS_DELIVERY_REPORTS, Boolean.valueOf(false));
- DEFAULTS.put(CONFIG_SUPPORT_HTTP_CHARSET_HEADER, Boolean.valueOf(false));
- DEFAULTS.put(CONFIG_MAX_MESSAGE_SIZE, Integer.valueOf(300 * 1024));
- DEFAULTS.put(CONFIG_MAX_IMAGE_HEIGHT, Integer.valueOf(MAX_IMAGE_HEIGHT));
- DEFAULTS.put(CONFIG_MAX_IMAGE_WIDTH, Integer.valueOf(MAX_IMAGE_WIDTH));
- DEFAULTS.put(CONFIG_RECIPIENT_LIMIT, Integer.valueOf(Integer.MAX_VALUE));
- DEFAULTS.put(CONFIG_HTTP_SOCKET_TIMEOUT, Integer.valueOf(60 * 1000));
- DEFAULTS.put(CONFIG_ALIAS_MIN_CHARS, Integer.valueOf(2));
- DEFAULTS.put(CONFIG_ALIAS_MAX_CHARS, Integer.valueOf(48));
- DEFAULTS.put(CONFIG_SMS_TO_MMS_TEXT_THRESHOLD, Integer.valueOf(-1));
- DEFAULTS.put(CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD, Integer.valueOf(-1));
- DEFAULTS.put(CONFIG_MAX_MESSAGE_TEXT_SIZE, Integer.valueOf(-1));
- DEFAULTS.put(CONFIG_MAX_SUBJECT_LENGTH, Integer.valueOf(40));
- DEFAULTS.put(CONFIG_UA_PROF_TAG_NAME, DEFAULT_HTTP_KEY_X_WAP_PROFILE);
- DEFAULTS.put(CONFIG_USER_AGENT, "");
- DEFAULTS.put(CONFIG_UA_PROF_URL, "");
- DEFAULTS.put(CONFIG_HTTP_PARAMS, "");
- DEFAULTS.put(CONFIG_EMAIL_GATEWAY_NUMBER, "");
- DEFAULTS.put(CONFIG_NAI_SUFFIX, "");
- }
-
- private final int mSubId;
-
- /**
- * This class manages a cached copy of current MMS configuration key values for a particular
- * subscription id. (See the {@link android.telephony.SubscriptionManager}).
- *
- * @param context Context of the particular subscription to load. The context's mcc/mnc
- * should be set to that of the subscription id
- * @param subId Subscription id of the mcc/mnc in the context
- */
- public MmsConfig(Context context, int subId) {
- mSubId = subId;
- // Load defaults
- mKeyValues.clear();
- mKeyValues.putAll(DEFAULTS);
- // Load User-Agent and UA profile URL settings
- loadDeviceUaSettings(context);
- Log.v(TAG, "MmsConfig: mUserAgent=" + mUserAgent + ", mUaProfUrl=" + mUaProfUrl);
- // Load mms_config.xml resource overlays
- loadFromResources(context);
- Log.v(TAG, "MmsConfig: all settings -- " + mKeyValues);
- }
-
- /**
- * Return the subscription ID associated with this MmsConfig
- *
- * @return subId the subId associated with this MmsConfig
- */
- public int getSubId() {
- return mSubId;
- }
-
- /**
- * Check a key and its type match the predefined keys and corresponding types
- *
- * @param key
- * @param type Including "int" "bool" and "string"
- * @return True if key and type both matches and false otherwise
- */
- public static boolean isValidKey(String key, String type) {
- if (!TextUtils.isEmpty(key) && DEFAULTS.containsKey(key)) {
- Object defVal = DEFAULTS.get(key);
- Class<?> valueType = defVal != null ? defVal.getClass() : String.class;
- if (KEY_TYPE_INT.equals(type)) {
- return valueType == Integer.class;
- } else if (KEY_TYPE_BOOL.equals(type)) {
- return valueType == Boolean.class;
- } else if (KEY_TYPE_STRING.equals(type)) {
- return valueType == String.class;
- }
- }
- return false;
- }
-
- /**
- * Check a key and its type match the predefined keys and corresponding types
- *
- * @param key The key of the config
- * @param value The value of the config
- * @return True if key and type both matches and false otherwise
- */
- public static boolean isValidValue(String key, Object value) {
- if (!TextUtils.isEmpty(key) && DEFAULTS.containsKey(key)) {
- Object defVal = DEFAULTS.get(key);
- Class<?> valueType = defVal != null ? defVal.getClass() : String.class;
- return value.getClass().equals(valueType);
- }
- return false;
- }
-
- private String mUserAgent = null;
- private String mUaProfUrl = null;
-
- // The current values
- private final Map<String, Object> mKeyValues = new ConcurrentHashMap<String, Object>();
-
- /**
- * Get a config value by its type
- *
- * @param key The key of the config
- * @param type The type of the config value
- * @return The expected typed value or null if no match
- */
- public Object getValueAsType(String key, String type) {
- if (isValidKey(key, type)) {
- return mKeyValues.get(key);
- }
- return null;
- }
-
- public Bundle getCarrierConfigValues() {
- final Bundle bundle = new Bundle();
- final Iterator<Map.Entry<String, Object>> iter = mKeyValues.entrySet().iterator();
- while(iter.hasNext()) {
- final Map.Entry<String, Object> entry = iter.next();
- final String key = entry.getKey();
- final Object val = entry.getValue();
- Class<?> valueType = val != null ? val.getClass() : String.class;
- if (valueType == Integer.class) {
- bundle.putInt(key, (Integer)val);
- } else if (valueType == Boolean.class) {
- bundle.putBoolean(key, (Boolean)val);
- } else if (valueType == String.class) {
- bundle.putString(key, (String)val);
- }
- }
- return bundle;
- }
-
- private String getNullableStringValue(String key) {
- final Object value = mKeyValues.get(key);
- if (value != null) {
- return (String) value;
- }
- return null;
- }
-
- private void update(String key, String value, String type) {
- try {
- if (KEY_TYPE_INT.equals(type)) {
- mKeyValues.put(key, Integer.parseInt(value));
- } else if (KEY_TYPE_BOOL.equals(type)) {
- mKeyValues.put(key, Boolean.parseBoolean(value));
- } else if (KEY_TYPE_STRING.equals(type)){
- mKeyValues.put(key, value);
- }
- } catch (NumberFormatException e) {
- Log.e(TAG, "MmsConfig.update: invalid " + key + "," + value + "," + type);
- }
- }
-
- private void loadDeviceUaSettings(Context context) {
- // load the MMS User agent and UaProfUrl from TelephonyManager APIs
- final TelephonyManager telephonyManager =
- (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
- mUserAgent = telephonyManager.getMmsUserAgent();
- mUaProfUrl = telephonyManager.getMmsUAProfUrl();
- }
-
- private void loadFromResources(Context context) {
- Log.d(TAG, "MmsConfig.loadFromResources");
- final XmlResourceParser parser = context.getResources().getXml(R.xml.mms_config);
- final MmsConfigXmlProcessor processor = MmsConfigXmlProcessor.get(parser);
- processor.setMmsConfigHandler(new MmsConfigXmlProcessor.MmsConfigHandler() {
- @Override
- public void process(String key, String value, String type) {
- update(key, value, type);
- }
- });
- try {
- processor.process();
- } finally {
- parser.close();
- }
- }
-
- /**
- * This class returns corresponding MmsConfig values which can be overridden by
- * externally provided values.
- */
- public static class Overridden {
- // The base MmsConfig
- private final MmsConfig mBase;
- // The overridden values
- private final Bundle mOverrides;
-
- public Overridden(MmsConfig base, Bundle overrides) {
- mBase = base;
- mOverrides = overrides;
- }
-
- private int getInt(String key) {
- final Integer def = (Integer) mBase.mKeyValues.get(key);
- return mOverrides != null ? mOverrides.getInt(key, def) : def;
- }
-
- private boolean getBoolean(String key) {
- final Boolean def = (Boolean) mBase.mKeyValues.get(key);
- return mOverrides != null ? mOverrides.getBoolean(key, def) : def;
- }
-
- private String getString(String key) {
- if (mOverrides != null && mOverrides.containsKey(key)) {
- return mOverrides.getString(key);
- }
- return mBase.getNullableStringValue(key);
- }
-
- public int getSmsToMmsTextThreshold() {
- return getInt(CONFIG_SMS_TO_MMS_TEXT_THRESHOLD);
- }
-
- public int getSmsToMmsTextLengthThreshold() {
- return getInt(CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD);
- }
-
- public boolean getMmsEnabled() {
- return getBoolean(CONFIG_ENABLED_MMS);
- }
-
- public int getMaxMessageSize() {
- return getInt(CONFIG_MAX_MESSAGE_SIZE);
- }
-
- public boolean getTransIdEnabled() {
- return getBoolean(CONFIG_ENABLED_TRANS_ID);
- }
-
- public String getUserAgent() {
- if (mOverrides != null && mOverrides.containsKey(CONFIG_USER_AGENT)) {
- return mOverrides.getString(CONFIG_USER_AGENT);
- }
- return !TextUtils.isEmpty(mBase.mUserAgent) ?
- mBase.mUserAgent : mBase.getNullableStringValue(CONFIG_USER_AGENT);
- }
-
- public String getUaProfTagName() {
- return getString(CONFIG_UA_PROF_TAG_NAME);
- }
-
- public String getUaProfUrl() {
- if (mOverrides != null && mOverrides.containsKey(CONFIG_UA_PROF_URL)) {
- return mOverrides.getString(CONFIG_UA_PROF_URL);
- }
- return !TextUtils.isEmpty(mBase.mUaProfUrl) ?
- mBase.mUaProfUrl : mBase.getNullableStringValue(CONFIG_UA_PROF_URL);
- }
-
- public String getHttpParams() {
- return getString(CONFIG_HTTP_PARAMS);
- }
-
- public String getEmailGateway() {
- return getString(CONFIG_EMAIL_GATEWAY_NUMBER);
- }
-
- public int getMaxImageHeight() {
- return getInt(CONFIG_MAX_IMAGE_HEIGHT);
- }
-
- public int getMaxImageWidth() {
- return getInt(CONFIG_MAX_IMAGE_WIDTH);
- }
-
- public int getRecipientLimit() {
- final int limit = getInt(CONFIG_RECIPIENT_LIMIT);
- return limit < 0 ? Integer.MAX_VALUE : limit;
- }
-
- public int getMaxTextLimit() {
- final int max = getInt(CONFIG_MAX_MESSAGE_TEXT_SIZE);
- return max > -1 ? max : MAX_TEXT_LENGTH;
- }
-
- public int getHttpSocketTimeout() {
- return getInt(CONFIG_HTTP_SOCKET_TIMEOUT);
- }
-
- public boolean getMultipartSmsEnabled() {
- return getBoolean(CONFIG_ENABLE_MULTIPART_SMS);
- }
-
- public boolean getSendMultipartSmsAsSeparateMessages() {
- return getBoolean(CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES);
- }
-
- public boolean getSMSDeliveryReportsEnabled() {
- return getBoolean(CONFIG_ENABLE_SMS_DELIVERY_REPORTS);
- }
-
- public boolean getNotifyWapMMSC() {
- return getBoolean(CONFIG_ENABLED_NOTIFY_WAP_MMSC);
- }
-
- public boolean isAliasEnabled() {
- return getBoolean(CONFIG_ALIAS_ENABLED);
- }
-
- public int getAliasMinChars() {
- return getInt(CONFIG_ALIAS_MIN_CHARS);
- }
-
- public int getAliasMaxChars() {
- return getInt(CONFIG_ALIAS_MAX_CHARS);
- }
-
- public boolean getAllowAttachAudio() {
- return getBoolean(CONFIG_ALLOW_ATTACH_AUDIO);
- }
-
- public int getMaxSubjectLength() {
- return getInt(CONFIG_MAX_SUBJECT_LENGTH);
- }
-
- public boolean getGroupMmsEnabled() {
- return getBoolean(CONFIG_ENABLE_GROUP_MMS);
- }
-
- public boolean getSupportMmsContentDisposition() {
- return getBoolean(CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION);
- }
-
- public boolean getShowCellBroadcast() {
- return getBoolean(CONFIG_CELL_BROADCAST_APP_LINKS);
- }
-
- public String getNaiSuffix() {
- return getString(CONFIG_NAI_SUFFIX);
- }
-
- public boolean isMmsReadReportsEnabled() {
- return getBoolean(CONFIG_ENABLE_MMS_READ_REPORTS);
- }
-
- public boolean isMmsDeliveryReportsEnabled() {
- return getBoolean(CONFIG_ENABLE_MMS_DELIVERY_REPORTS);
- }
-
- public boolean getSupportHttpCharsetHeader() {
- return getBoolean(CONFIG_SUPPORT_HTTP_CHARSET_HEADER);
- }
-
- /**
- * Return the HTTP param macro value.
- * Example: LINE1 returns the phone number, etc.
- *
- * @param macro The macro name
- * @return The value of the defined macro
- */
- public String getHttpParamMacro(Context context, String macro) {
- if (MACRO_LINE1.equals(macro)) {
- return getLine1(context, mBase.getSubId());
- } else if (MACRO_LINE1NOCOUNTRYCODE.equals(macro)) {
- return getLine1NoCountryCode(context, mBase.getSubId());
- } else if (MACRO_NAI.equals(macro)) {
- return getNai(context, mBase.getSubId());
- }
- Log.e(MmsService.TAG, "MmsConfig: invalid macro " + macro);
- return null;
- }
-
- /**
- * @return the phone number
- */
- private static String getLine1(Context context, int subId) {
- final TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(
- Context.TELEPHONY_SERVICE);
- return telephonyManager.getLine1NumberForSubscriber(subId);
- }
-
- private static String getLine1NoCountryCode(Context context, int subId) {
- final TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(
- Context.TELEPHONY_SERVICE);
- return PhoneUtils.getNationalNumber(
- telephonyManager,
- subId,
- telephonyManager.getLine1NumberForSubscriber(subId));
- }
-
- /**
- * @return the NAI (Network Access Identifier) from SystemProperties
- */
- private String getNai(Context context, int subId) {
- final TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(
- Context.TELEPHONY_SERVICE);
- String nai = telephonyManager.getNai(SubscriptionManager.getSlotId(subId));
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "MmsConfig.getNai: nai=" + nai);
- }
-
- if (!TextUtils.isEmpty(nai)) {
- String naiSuffix = getNaiSuffix();
- if (!TextUtils.isEmpty(naiSuffix)) {
- nai = nai + naiSuffix;
- }
- byte[] encoded = null;
- try {
- encoded = Base64.encode(nai.getBytes("UTF-8"), Base64.NO_WRAP);
- } catch (UnsupportedEncodingException e) {
- encoded = Base64.encode(nai.getBytes(), Base64.NO_WRAP);
- }
- try {
- nai = new String(encoded, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- nai = new String(encoded);
- }
- }
- return nai;
- }
- }
-}
diff --git a/src/com/android/mms/service/MmsConfigManager.java b/src/com/android/mms/service/MmsConfigManager.java
index de1522c..7aa60f6 100644
--- a/src/com/android/mms/service/MmsConfigManager.java
+++ b/src/com/android/mms/service/MmsConfigManager.java
@@ -21,9 +21,13 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SmsManager;
import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
+import android.telephony.SubscriptionManager;
import android.util.ArrayMap;
import android.util.Log;
@@ -48,7 +52,7 @@ public class MmsConfigManager {
}
// Map the various subIds to their corresponding MmsConfigs.
- private final Map<Integer, MmsConfig> mSubIdConfigMap = new ArrayMap<Integer, MmsConfig>();
+ private final Map<Integer, Bundle> mSubIdConfigMap = new ArrayMap<Integer, Bundle>();
private Context mContext;
private SubscriptionManager mSubscriptionManager;
@@ -114,28 +118,32 @@ public class MmsConfigManager {
}
/**
- * Find and return the MmsConfig for a particular subscription id.
+ * Find and return the MMS config for a particular subscription id.
*
- * @param subId Subscription id of the desired MmsConfig
- * @return MmsConfig for the particular subscription id. This function can return null if
- * the MmsConfig cannot be found or if this function is called before the
- * TelephonyManager has setup the SIMs or if loadInBackground is still spawning a
+ * @param subId Subscription id of the desired MMS config bundle
+ * @return MMS config bundle for the particular subscription id. This function can return null
+ * if the MMS config cannot be found or if this function is called before the
+ * TelephonyManager has set up the SIMs, or if loadInBackground is still spawning a
* thread after a recent LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED event.
*/
- public MmsConfig getMmsConfigBySubId(int subId) {
- MmsConfig mmsConfig;
+ public Bundle getMmsConfigBySubId(int subId) {
+ Bundle mmsConfig;
synchronized(mSubIdConfigMap) {
mmsConfig = mSubIdConfigMap.get(subId);
}
Log.i(TAG, "getMmsConfigBySubId -- for sub: " + subId + " mmsConfig: " + mmsConfig);
- return mmsConfig;
+ // Return a copy so that callers can mutate it.
+ if (mmsConfig != null) {
+ return new Bundle(mmsConfig);
+ }
+ return null;
}
/**
- * This function goes through all the activated subscription ids (the actual SIMs in the
- * device), builds a context with that SIM's mcc/mnc and loads the appropriate mms_config.xml
- * file via the ResourceManager. With single-SIM devices, there will be a single subId.
+ * This loads the MMS config for each active subscription.
*
+ * MMS config is fetched from CarrierConfigManager and filtered to only include MMS config
+ * variables. The resulting bundles are stored in mSubIdConfigMap.
*/
private void load(Context context) {
List<SubscriptionInfo> subs = mSubscriptionManager.getActiveSubscriptionInfoList();
@@ -143,28 +151,15 @@ public class MmsConfigManager {
Log.e(TAG, "MmsConfigManager.load -- empty getActiveSubInfoList");
return;
}
- // Load all the mms_config.xml files in a separate map and then swap with the
- // real map at the end so we don't block anyone sync'd on the real map.
- final Map<Integer, MmsConfig> newConfigMap = new ArrayMap<Integer, MmsConfig>();
+ // Load all the config bundles into a new map and then swap it with the real map to avoid
+ // blocking.
+ final Map<Integer, Bundle> newConfigMap = new ArrayMap<Integer, Bundle>();
+ CarrierConfigManager configManager =
+ (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
for (SubscriptionInfo sub : subs) {
- Configuration configuration = new Configuration();
- if (sub.getMcc() == 0 && sub.getMnc() == 0) {
- Configuration config = mContext.getResources().getConfiguration();
- configuration.mcc = config.mcc;
- configuration.mnc = config.mnc;
- Log.i(TAG, "MmsConfigManager.load -- no mcc/mnc for sub: " + sub +
- " using mcc/mnc from main context: " + configuration.mcc + "/" +
- configuration.mnc);
- } else {
- Log.i(TAG, "MmsConfigManager.load -- mcc/mnc for sub: " + sub);
-
- configuration.mcc = sub.getMcc();
- configuration.mnc = sub.getMnc();
- }
- Context subContext = context.createConfigurationContext(configuration);
-
int subId = sub.getSubscriptionId();
- newConfigMap.put(subId, new MmsConfig(subContext, subId));
+ PersistableBundle config = configManager.getConfigForSubId(subId);
+ newConfigMap.put(subId, SmsManager.getMmsConfig(config));
}
synchronized(mSubIdConfigMap) {
mSubIdConfigMap.clear();
diff --git a/src/com/android/mms/service/MmsConfigXmlProcessor.java b/src/com/android/mms/service/MmsConfigXmlProcessor.java
deleted file mode 100644
index 9eaebcd..0000000
--- a/src/com/android/mms/service/MmsConfigXmlProcessor.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mms.service;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.ContentValues;
-import android.util.Log;
-
-import java.io.IOException;
-
-/*
- * XML processor for mms_config.xml
- */
-public class MmsConfigXmlProcessor {
- private static final String TAG = MmsService.TAG;
-
- public interface MmsConfigHandler {
- public void process(String key, String value, String type);
- }
-
- private static final String TAG_MMS_CONFIG = "mms_config";
-
- // Handler to process one mms_config key/value pair
- private MmsConfigHandler mMmsConfigHandler;
-
- private final StringBuilder mLogStringBuilder = new StringBuilder();
-
- private final XmlPullParser mInputParser;
-
- private MmsConfigXmlProcessor(XmlPullParser parser) {
- mInputParser = parser;
- mMmsConfigHandler = null;
- }
-
- public static MmsConfigXmlProcessor get(XmlPullParser parser) {
- return new MmsConfigXmlProcessor(parser);
- }
-
- public MmsConfigXmlProcessor setMmsConfigHandler(MmsConfigHandler handler) {
- mMmsConfigHandler = handler;
- return this;
- }
-
- /**
- * Move XML parser forward to next event type or the end of doc
- *
- * @param eventType
- * @return The final event type we meet
- * @throws org.xmlpull.v1.XmlPullParserException
- * @throws java.io.IOException
- */
- private int advanceToNextEvent(int eventType) throws XmlPullParserException, IOException {
- for (;;) {
- int nextEvent = mInputParser.next();
- if (nextEvent == eventType
- || nextEvent == XmlPullParser.END_DOCUMENT) {
- return nextEvent;
- }
- }
- }
-
- public void process() {
- try {
- // Find the first element
- if (advanceToNextEvent(XmlPullParser.START_TAG) != XmlPullParser.START_TAG) {
- throw new XmlPullParserException("MmsConfigXmlProcessor: expecting start tag @"
- + xmlParserDebugContext());
- }
- // A single ContentValues object for holding the parsing result of
- // an apn element
- final ContentValues values = new ContentValues();
- String tagName = mInputParser.getName();
- // Top level tag can be "apns" (apns.xml, or APN OTA XML)
- // or "mms_config" (mms_config.xml)
- if (TAG_MMS_CONFIG.equals(tagName)) {
- // mms_config.xml resource
- processMmsConfig();
- }
- } catch (IOException e) {
- Log.e(TAG, "MmsConfigXmlProcessor: I/O failure " + e, e);
- } catch (XmlPullParserException e) {
- Log.e(TAG, "MmsConfigXmlProcessor: parsing failure " + e, e);
- }
- }
-
- private static String xmlParserEventString(int event) {
- switch (event) {
- case XmlPullParser.START_DOCUMENT: return "START_DOCUMENT";
- case XmlPullParser.END_DOCUMENT: return "END_DOCUMENT";
- case XmlPullParser.START_TAG: return "START_TAG";
- case XmlPullParser.END_TAG: return "END_TAG";
- case XmlPullParser.TEXT: return "TEXT";
- }
- return Integer.toString(event);
- }
-
- /**
- * @return The debugging information of the parser's current position
- */
- private String xmlParserDebugContext() {
- mLogStringBuilder.setLength(0);
- if (mInputParser != null) {
- try {
- final int eventType = mInputParser.getEventType();
- mLogStringBuilder.append(xmlParserEventString(eventType));
- if (eventType == XmlPullParser.START_TAG
- || eventType == XmlPullParser.END_TAG
- || eventType == XmlPullParser.TEXT) {
- mLogStringBuilder.append('<').append(mInputParser.getName());
- for (int i = 0; i < mInputParser.getAttributeCount(); i++) {
- mLogStringBuilder.append(' ')
- .append(mInputParser.getAttributeName(i))
- .append('=')
- .append(mInputParser.getAttributeValue(i));
- }
- mLogStringBuilder.append("/>");
- }
- return mLogStringBuilder.toString();
- } catch (XmlPullParserException e) {
- Log.e(TAG, "xmlParserDebugContext: " + e, e);
- }
- }
- return "Unknown";
- }
-
- /**
- * Process one mms_config.
- *
- * @throws java.io.IOException
- * @throws org.xmlpull.v1.XmlPullParserException
- */
- private void processMmsConfig()
- throws IOException, XmlPullParserException {
- // We are at the start tag
- for (;;) {
- int nextEvent;
- // Skipping spaces
- while ((nextEvent = mInputParser.next()) == XmlPullParser.TEXT);
- if (nextEvent == XmlPullParser.START_TAG) {
- // Parse one mms config key/value
- processMmsConfigKeyValue();
- } else if (nextEvent == XmlPullParser.END_TAG) {
- break;
- } else {
- throw new XmlPullParserException("MmsConfig: expecting start or end tag @"
- + xmlParserDebugContext());
- }
- }
- }
-
- /**
- * Process one mms_config key/value pair
- *
- * @throws java.io.IOException
- * @throws org.xmlpull.v1.XmlPullParserException
- */
- private void processMmsConfigKeyValue() throws IOException, XmlPullParserException {
- final String key = mInputParser.getAttributeValue(null, "name");
- // We are at the start tag, the name of the tag is the type
- // e.g. <int name="key">value</int>
- final String type = mInputParser.getName();
- int nextEvent = mInputParser.next();
- String value = null;
- if (nextEvent == XmlPullParser.TEXT) {
- value = mInputParser.getText();
- nextEvent = mInputParser.next();
- }
- if (nextEvent != XmlPullParser.END_TAG) {
- throw new XmlPullParserException("MmsConfigXmlProcessor: expecting end tag @"
- + xmlParserDebugContext());
- }
- if (MmsConfig.isValidKey(key, type)) {
- // We are done parsing one mms_config key/value, call the handler
- if (mMmsConfigHandler != null) {
- mMmsConfigHandler.process(key, value, type);
- }
- } else {
- Log.w(TAG, "MmsConfig: invalid key=" + key + " or type=" + type);
- }
- }
-}
diff --git a/src/com/android/mms/service/MmsHttpClient.java b/src/com/android/mms/service/MmsHttpClient.java
index 10b8aa2..da36f26 100644
--- a/src/com/android/mms/service/MmsHttpClient.java
+++ b/src/com/android/mms/service/MmsHttpClient.java
@@ -18,7 +18,12 @@ package com.android.mms.service;
import android.content.Context;
import android.net.Network;
+import android.os.Bundle;
+import android.telephony.SmsManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
import android.text.TextUtils;
+import android.util.Base64;
import android.util.Log;
import com.android.mms.service.exception.MmsHttpException;
@@ -29,6 +34,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
@@ -87,11 +93,12 @@ public class MmsHttpClient {
* @param proxyHost The proxy host
* @param proxyPort The proxy port
* @param mmsConfig The MMS config to use
+ * @param subId The subscription ID used to get line number, etc.
* @return The HTTP response body
* @throws MmsHttpException For any failures
*/
public byte[] execute(String urlString, byte[] pdu, String method, boolean isProxySet,
- String proxyHost, int proxyPort, MmsConfig.Overridden mmsConfig)
+ String proxyHost, int proxyPort, Bundle mmsConfig, int subId)
throws MmsHttpException {
Log.d(MmsService.TAG, "HTTP: " + method + " " + redactUrlForNonVerbose(urlString)
+ (isProxySet ? (", proxy=" + proxyHost + ":" + proxyPort) : "")
@@ -107,7 +114,8 @@ public class MmsHttpClient {
// Now get the connection
connection = (HttpURLConnection) mNetwork.openConnection(url, proxy);
connection.setDoInput(true);
- connection.setConnectTimeout(mmsConfig.getHttpSocketTimeout());
+ connection.setConnectTimeout(
+ mmsConfig.getInt(SmsManager.MMS_CONFIG_HTTP_SOCKET_TIMEOUT));
// ------- COMMON HEADERS ---------
// Header: Accept
connection.setRequestProperty(HEADER_ACCEPT, HEADER_VALUE_ACCEPT);
@@ -115,18 +123,19 @@ public class MmsHttpClient {
connection.setRequestProperty(
HEADER_ACCEPT_LANGUAGE, getCurrentAcceptLanguage(Locale.getDefault()));
// Header: User-Agent
- final String userAgent = mmsConfig.getUserAgent();
+ final String userAgent = mmsConfig.getString(SmsManager.MMS_CONFIG_USER_AGENT);
Log.i(MmsService.TAG, "HTTP: User-Agent=" + userAgent);
connection.setRequestProperty(HEADER_USER_AGENT, userAgent);
// Header: x-wap-profile
- final String uaProfUrlTagName = mmsConfig.getUaProfTagName();
- final String uaProfUrl = mmsConfig.getUaProfUrl();
+ final String uaProfUrlTagName =
+ mmsConfig.getString(SmsManager.MMS_CONFIG_UA_PROF_TAG_NAME);
+ final String uaProfUrl = mmsConfig.getString(SmsManager.MMS_CONFIG_UA_PROF_URL);
if (uaProfUrl != null) {
Log.i(MmsService.TAG, "HTTP: UaProfUrl=" + uaProfUrl);
connection.setRequestProperty(uaProfUrlTagName, uaProfUrl);
}
// Add extra headers specified by mms_config.xml's httpparams
- addExtraHeaders(connection, mmsConfig);
+ addExtraHeaders(connection, mmsConfig, subId);
// Different stuff for GET and POST
if (METHOD_POST.equals(method)) {
if (pdu == null || pdu.length < 1) {
@@ -135,7 +144,7 @@ public class MmsHttpClient {
}
connection.setDoOutput(true);
connection.setRequestMethod(METHOD_POST);
- if (mmsConfig.getSupportHttpCharsetHeader()) {
+ if (mmsConfig.getBoolean(SmsManager.MMS_CONFIG_SUPPORT_HTTP_CHARSET_HEADER)) {
connection.setRequestProperty(HEADER_CONTENT_TYPE,
HEADER_VALUE_CONTENT_TYPE_WITH_CHARSET);
} else {
@@ -276,16 +285,45 @@ public class MmsHttpClient {
}
}
+ /**
+ * Add extra HTTP headers from mms_config.xml's httpParams, which is a list of key/value
+ * pairs separated by "|". Each key/value pair is separated by ":". Value may contain
+ * macros like "##LINE1##" or "##NAI##" which is resolved with methods in this class
+ *
+ * @param connection The HttpURLConnection that we add headers to
+ * @param mmsConfig The MmsConfig object
+ * @param subId The subscription ID used to get line number, etc.
+ */
+ private void addExtraHeaders(HttpURLConnection connection, Bundle mmsConfig, int subId) {
+ final String extraHttpParams = mmsConfig.getString(SmsManager.MMS_CONFIG_HTTP_PARAMS);
+ if (!TextUtils.isEmpty(extraHttpParams)) {
+ // Parse the parameter list
+ String paramList[] = extraHttpParams.split("\\|");
+ for (String paramPair : paramList) {
+ String splitPair[] = paramPair.split(":", 2);
+ if (splitPair.length == 2) {
+ final String name = splitPair[0].trim();
+ final String value =
+ resolveMacro(mContext, splitPair[1].trim(), mmsConfig, subId);
+ if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(value)) {
+ // Add the header if the param is valid
+ connection.setRequestProperty(name, value);
+ }
+ }
+ }
+ }
+ }
+
private static final Pattern MACRO_P = Pattern.compile("##(\\S+)##");
/**
* Resolve the macro in HTTP param value text
* For example, "something##LINE1##something" is resolved to "something9139531419something"
*
* @param value The HTTP param value possibly containing macros
- * @return The HTTP param with macro resolved to real value
+ * @param subId The subscription ID used to get line number, etc.
+ * @return The HTTP param with macros resolved to real value
*/
- private static String resolveMacro(Context context, String value,
- MmsConfig.Overridden mmsConfig) {
+ private static String resolveMacro(Context context, String value, Bundle mmsConfig, int subId) {
if (TextUtils.isEmpty(value)) {
return value;
}
@@ -301,7 +339,7 @@ public class MmsHttpClient {
replaced.append(value.substring(nextStart, matchedStart));
}
final String macro = matcher.group(1);
- final String macroValue = mmsConfig.getHttpParamMacro(context, macro);
+ final String macroValue = getMacroValue(context, macro, mmsConfig, subId);
if (macroValue != null) {
replaced.append(macroValue);
}
@@ -314,33 +352,6 @@ public class MmsHttpClient {
}
/**
- * Add extra HTTP headers from mms_config.xml's httpParams, which is a list of key/value
- * pairs separated by "|". Each key/value pair is separated by ":". Value may contain
- * macros like "##LINE1##" or "##NAI##" which is resolved with methods in this class
- *
- * @param connection The HttpURLConnection that we add headers to
- * @param mmsConfig The MmsConfig object
- */
- private void addExtraHeaders(HttpURLConnection connection, MmsConfig.Overridden mmsConfig) {
- final String extraHttpParams = mmsConfig.getHttpParams();
- if (!TextUtils.isEmpty(extraHttpParams)) {
- // Parse the parameter list
- String paramList[] = extraHttpParams.split("\\|");
- for (String paramPair : paramList) {
- String splitPair[] = paramPair.split(":", 2);
- if (splitPair.length == 2) {
- final String name = splitPair[0].trim();
- final String value = resolveMacro(mContext, splitPair[1].trim(), mmsConfig);
- if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(value)) {
- // Add the header if the param is valid
- connection.setRequestProperty(name, value);
- }
- }
- }
- }
- }
-
- /**
* Redact the URL for non-VERBOSE logging. Replace url with only the host part and the length
* of the input URL string.
*
@@ -370,4 +381,88 @@ public class MmsHttpClient {
.append("[").append(urlString.length()).append("]");
return sb.toString();
}
+
+ /*
+ * Macro names
+ */
+ // The raw phone number from TelephonyManager.getLine1Number
+ private static final String MACRO_LINE1 = "LINE1";
+ // The phone number without country code
+ private static final String MACRO_LINE1NOCOUNTRYCODE = "LINE1NOCOUNTRYCODE";
+ // NAI (Network Access Identifier), used by Sprint for authentication
+ private static final String MACRO_NAI = "NAI";
+ /**
+ * Return the HTTP param macro value.
+ * Example: "LINE1" returns the phone number, etc.
+ *
+ * @param macro The macro name
+ * @param mmsConfig The MMS config which contains NAI suffix.
+ * @param subId The subscription ID used to get line number, etc.
+ * @return The value of the defined macro
+ */
+ private static String getMacroValue(Context context, String macro, Bundle mmsConfig,
+ int subId) {
+ if (MACRO_LINE1.equals(macro)) {
+ return getLine1(context, subId);
+ } else if (MACRO_LINE1NOCOUNTRYCODE.equals(macro)) {
+ return getLine1NoCountryCode(context, subId);
+ } else if (MACRO_NAI.equals(macro)) {
+ return getNai(context, mmsConfig, subId);
+ }
+ Log.e(MmsService.TAG, "invalid macro " + macro);
+ return null;
+ }
+
+ /**
+ * Returns the phone number for the given subscription ID.
+ */
+ private static String getLine1(Context context, int subId) {
+ final TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(
+ Context.TELEPHONY_SERVICE);
+ return telephonyManager.getLine1NumberForSubscriber(subId);
+ }
+
+ /**
+ * Returns the phone number (without country code) for the given subscription ID.
+ */
+ private static String getLine1NoCountryCode(Context context, int subId) {
+ final TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(
+ Context.TELEPHONY_SERVICE);
+ return PhoneUtils.getNationalNumber(
+ telephonyManager,
+ subId,
+ telephonyManager.getLine1NumberForSubscriber(subId));
+ }
+
+ /**
+ * Returns the NAI (Network Access Identifier) from SystemProperties for the given subscription
+ * ID.
+ */
+ private static String getNai(Context context, Bundle mmsConfig, int subId) {
+ final TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(
+ Context.TELEPHONY_SERVICE);
+ String nai = telephonyManager.getNai(SubscriptionManager.getSlotId(subId));
+ if (Log.isLoggable(MmsService.TAG, Log.VERBOSE)) {
+ Log.v(MmsService.TAG, "getNai: nai=" + nai);
+ }
+
+ if (!TextUtils.isEmpty(nai)) {
+ String naiSuffix = mmsConfig.getString(SmsManager.MMS_CONFIG_NAI_SUFFIX);
+ if (!TextUtils.isEmpty(naiSuffix)) {
+ nai = nai + naiSuffix;
+ }
+ byte[] encoded = null;
+ try {
+ encoded = Base64.encode(nai.getBytes("UTF-8"), Base64.NO_WRAP);
+ } catch (UnsupportedEncodingException e) {
+ encoded = Base64.encode(nai.getBytes(), Base64.NO_WRAP);
+ }
+ try {
+ nai = new String(encoded, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ nai = new String(encoded);
+ }
+ }
+ return nai;
+ }
}
diff --git a/src/com/android/mms/service/MmsRequest.java b/src/com/android/mms/service/MmsRequest.java
index f43f1b4..9255c16 100644
--- a/src/com/android/mms/service/MmsRequest.java
+++ b/src/com/android/mms/service/MmsRequest.java
@@ -25,6 +25,8 @@ import android.os.Bundle;
import android.service.carrier.CarrierMessagingService;
import android.service.carrier.ICarrierMessagingCallback;
import android.telephony.SmsManager;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
import android.util.Log;
import com.android.mms.service.exception.ApnException;
@@ -77,17 +79,20 @@ public abstract class MmsRequest {
// The creator app
protected String mCreator;
// MMS config
- protected MmsConfig.Overridden mMmsConfig;
- // MMS config overrides
+ protected Bundle mMmsConfig;
+ // MMS config overrides that will be applied to mMmsConfig when we eventually load it.
protected Bundle mMmsConfigOverrides;
+ // Context used to get TelephonyManager.
+ protected Context mContext;
public MmsRequest(RequestManager requestManager, int subId, String creator,
- Bundle configOverrides) {
+ Bundle configOverrides, Context context) {
mRequestManager = requestManager;
mSubId = subId;
mCreator = creator;
mMmsConfigOverrides = configOverrides;
mMmsConfig = null;
+ mContext = context;
}
public int getSubId() {
@@ -97,9 +102,25 @@ public abstract class MmsRequest {
private boolean ensureMmsConfigLoaded() {
if (mMmsConfig == null) {
// Not yet retrieved from mms config manager. Try getting it.
- final MmsConfig config = MmsConfigManager.getInstance().getMmsConfigBySubId(mSubId);
+ final Bundle config = MmsConfigManager.getInstance().getMmsConfigBySubId(mSubId);
if (config != null) {
- mMmsConfig = new MmsConfig.Overridden(config, mMmsConfigOverrides);
+ mMmsConfig = config;
+ // TODO: Make MmsConfigManager authoritative for user agent and don't consult
+ // TelephonyManager.
+ TelephonyManager telephonyManager =
+ (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+ String userAgent = telephonyManager.getMmsUserAgent();
+ if (!TextUtils.isEmpty(userAgent)) {
+ config.putString(SmsManager.MMS_CONFIG_USER_AGENT, userAgent);
+ }
+ String userAgentProfileUrl = telephonyManager.getMmsUAProfUrl();
+ if (!TextUtils.isEmpty(userAgentProfileUrl)) {
+ config.putString(SmsManager.MMS_CONFIG_UA_PROF_URL, userAgentProfileUrl);
+ }
+ // Apply overrides
+ if (mMmsConfigOverrides != null) {
+ mMmsConfig.putAll(mMmsConfigOverrides);
+ }
}
}
return mMmsConfig != null;
diff --git a/src/com/android/mms/service/MmsService.java b/src/com/android/mms/service/MmsService.java
index b6058c9..c6a3b8f 100644
--- a/src/com/android/mms/service/MmsService.java
+++ b/src/com/android/mms/service/MmsService.java
@@ -172,7 +172,7 @@ public class MmsService extends Service implements MmsRequest.RequestManager {
}
final SendRequest request = new SendRequest(MmsService.this, subId, contentUri,
- locationUrl, sentIntent, callingPkg, configOverrides);
+ locationUrl, sentIntent, callingPkg, configOverrides, MmsService.this);
final String carrierMessagingServicePackage =
getCarrierMessagingServicePackageIfExists();
@@ -199,8 +199,8 @@ public class MmsService extends Service implements MmsRequest.RequestManager {
// download anyway.
// TODO: Fail fast when downloading will fail (i.e. SIM swapped)
- final DownloadRequest request = new DownloadRequest(MmsService.this, subId,
- locationUrl, contentUri, downloadedIntent, callingPkg, configOverrides);
+ final DownloadRequest request = new DownloadRequest(MmsService.this, subId, locationUrl,
+ contentUri, downloadedIntent, callingPkg, configOverrides, MmsService.this);
final String carrierMessagingServicePackage =
getCarrierMessagingServicePackageIfExists();
if (carrierMessagingServicePackage != null) {
@@ -215,11 +215,11 @@ public class MmsService extends Service implements MmsRequest.RequestManager {
Log.d(TAG, "getCarrierConfigValues");
// Make sure the subId is correct
subId = checkSubId(subId);
- final MmsConfig mmsConfig = MmsConfigManager.getInstance().getMmsConfigBySubId(subId);
+ final Bundle mmsConfig = MmsConfigManager.getInstance().getMmsConfigBySubId(subId);
if (mmsConfig == null) {
return new Bundle();
}
- return mmsConfig.getCarrierConfigValues();
+ return mmsConfig;
}
@Override
diff --git a/src/com/android/mms/service/SendRequest.java b/src/com/android/mms/service/SendRequest.java
index 70d19b1..d1781b1 100644
--- a/src/com/android/mms/service/SendRequest.java
+++ b/src/com/android/mms/service/SendRequest.java
@@ -60,8 +60,8 @@ public class SendRequest extends MmsRequest {
private final PendingIntent mSentIntent;
public SendRequest(RequestManager manager, int subId, Uri contentUri, String locationUrl,
- PendingIntent sentIntent, String creator, Bundle configOverrides) {
- super(manager, subId, creator, configOverrides);
+ PendingIntent sentIntent, String creator, Bundle configOverrides, Context context) {
+ super(manager, subId, creator, configOverrides, context);
mPduUri = contentUri;
mPduData = null;
mLocationUrl = locationUrl;
@@ -83,7 +83,8 @@ public class SendRequest extends MmsRequest {
apn.isProxySet(),
apn.getProxyAddress(),
apn.getProxyPort(),
- mMmsConfig);
+ mMmsConfig,
+ mSubId);
}
@Override
@@ -109,7 +110,8 @@ public class SendRequest extends MmsRequest {
}
final long identity = Binder.clearCallingIdentity();
try {
- final boolean supportContentDisposition = mMmsConfig.getSupportMmsContentDisposition();
+ final boolean supportContentDisposition =
+ mMmsConfig.getBoolean(SmsManager.MMS_CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION);
// Persist the request PDU first
GenericPdu pdu = (new PduParser(mPduData, supportContentDisposition)).parse();
if (pdu == null) {
@@ -185,7 +187,7 @@ public class SendRequest extends MmsRequest {
if (mPduData != null) {
return true;
}
- final int bytesTobeRead = mMmsConfig.getMaxMessageSize();
+ final int bytesTobeRead = mMmsConfig.getInt(SmsManager.MMS_CONFIG_MAX_MESSAGE_SIZE);
mPduData = mRequestManager.readPduFromContentUri(mPduUri, bytesTobeRead);
return (mPduData != null);
}