summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Basseri <misterikkit@google.com>2015-06-09 11:46:26 -0700
committerJonathan Basseri <misterikkit@google.com>2015-06-12 10:09:14 -0700
commit4467007f09a9f2319ba25aa18e04f54693e6bfa1 (patch)
tree7c882325987106e70aa3136baefef79ebd0217ee
parent6c42a4893ea571dfb9567b933ffee2cdaec091af (diff)
downloadandroid_packages_services_Mms-4467007f09a9f2319ba25aa18e04f54693e6bfa1.tar.gz
android_packages_services_Mms-4467007f09a9f2319ba25aa18e04f54693e6bfa1.tar.bz2
android_packages_services_Mms-4467007f09a9f2319ba25aa18e04f54693e6bfa1.zip
Read MMS config from CarrierConfigManager.
This updates MmsConfigManager to get MMS config from CarrierConfigManager instead of mms_config.xml resource files. There should be no visible change in the public SmsManager API, which still exposes the same data in getCarrierConfigValues. This CL eliminates classes MmsConfigXmlParser, MmsConfig, and MmsConfig.Overridden. Bundles are used instead of MmsConfig objects, and the logic contained in Overridden was moved closer to where it is used. (e.g. HTTP param "macro" expansion) Bug: 21085630 Change-Id: Ia17ab3b19e88d5cdba755979481b4208759d7767
-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);
}