| /* |
| * 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()); |
| } |
| 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; |
| } |
| } |
| } |