1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.messaging.sms; 18 19 import android.os.Bundle; 20 import androidx.appcompat.mms.CarrierConfigValuesLoader; 21 import android.telephony.SubscriptionInfo; 22 23 import com.android.messaging.Factory; 24 import com.android.messaging.datamodel.data.ParticipantData; 25 import com.android.messaging.util.Assert; 26 import com.android.messaging.util.LogUtil; 27 import com.android.messaging.util.OsUtil; 28 import com.android.messaging.util.PhoneUtils; 29 import com.android.messaging.util.SafeAsyncTask; 30 import com.google.common.collect.Maps; 31 32 import java.util.List; 33 import java.util.Map; 34 import java.util.Set; 35 36 /** 37 * MMS configuration. 38 * 39 * This is now a wrapper around the BugleCarrierConfigValuesLoader, which does 40 * the actual loading and stores the values in a Bundle. This class provides getter 41 * methods for values used in the app, which is easier to use than the raw loader 42 * class. 43 */ 44 public class MmsConfig { 45 private static final String TAG = LogUtil.BUGLE_TAG; 46 47 private static final int DEFAULT_MAX_TEXT_LENGTH = 2000; 48 49 /* 50 * Key types 51 */ 52 public static final String KEY_TYPE_INT = "int"; 53 public static final String KEY_TYPE_BOOL = "bool"; 54 public static final String KEY_TYPE_STRING = "string"; 55 56 private static final Map<String, String> sKeyTypeMap = Maps.newHashMap(); 57 static { sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_ENABLED_MMS, KEY_TYPE_BOOL)58 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_ENABLED_MMS, KEY_TYPE_BOOL); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_ENABLED_TRANS_ID, KEY_TYPE_BOOL)59 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_ENABLED_TRANS_ID, KEY_TYPE_BOOL); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_ENABLED_NOTIFY_WAP_MMSC, KEY_TYPE_BOOL)60 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_ENABLED_NOTIFY_WAP_MMSC, KEY_TYPE_BOOL); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_ALIAS_ENABLED, KEY_TYPE_BOOL)61 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_ALIAS_ENABLED, KEY_TYPE_BOOL); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_ALLOW_ATTACH_AUDIO, KEY_TYPE_BOOL)62 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_ALLOW_ATTACH_AUDIO, KEY_TYPE_BOOL); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_ENABLE_MULTIPART_SMS, KEY_TYPE_BOOL)63 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_ENABLE_MULTIPART_SMS, KEY_TYPE_BOOL); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_ENABLE_SMS_DELIVERY_REPORTS, KEY_TYPE_BOOL)64 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_ENABLE_SMS_DELIVERY_REPORTS, 65 KEY_TYPE_BOOL); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_ENABLE_GROUP_MMS, KEY_TYPE_BOOL)66 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_ENABLE_GROUP_MMS, KEY_TYPE_BOOL); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION, KEY_TYPE_BOOL)67 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION, 68 KEY_TYPE_BOOL); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_CELL_BROADCAST_APP_LINKS, KEY_TYPE_BOOL)69 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_CELL_BROADCAST_APP_LINKS, KEY_TYPE_BOOL); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES, KEY_TYPE_BOOL)70 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES, 71 KEY_TYPE_BOOL); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_ENABLE_MMS_READ_REPORTS, KEY_TYPE_BOOL)72 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_ENABLE_MMS_READ_REPORTS, KEY_TYPE_BOOL); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_ENABLE_MMS_DELIVERY_REPORTS, KEY_TYPE_BOOL)73 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_ENABLE_MMS_DELIVERY_REPORTS, 74 KEY_TYPE_BOOL); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_SUPPORT_HTTP_CHARSET_HEADER, KEY_TYPE_BOOL)75 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_SUPPORT_HTTP_CHARSET_HEADER, 76 KEY_TYPE_BOOL); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_MAX_MESSAGE_SIZE, KEY_TYPE_INT)77 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_MAX_MESSAGE_SIZE, KEY_TYPE_INT); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_MAX_IMAGE_HEIGHT, KEY_TYPE_INT)78 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_MAX_IMAGE_HEIGHT, KEY_TYPE_INT); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_MAX_IMAGE_WIDTH, KEY_TYPE_INT)79 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_MAX_IMAGE_WIDTH, KEY_TYPE_INT); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_RECIPIENT_LIMIT, KEY_TYPE_INT)80 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_RECIPIENT_LIMIT, KEY_TYPE_INT); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_HTTP_SOCKET_TIMEOUT, KEY_TYPE_INT)81 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_HTTP_SOCKET_TIMEOUT, KEY_TYPE_INT); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_ALIAS_MIN_CHARS, KEY_TYPE_INT)82 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_ALIAS_MIN_CHARS, KEY_TYPE_INT); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_ALIAS_MAX_CHARS, KEY_TYPE_INT)83 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_ALIAS_MAX_CHARS, KEY_TYPE_INT); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_SMS_TO_MMS_TEXT_THRESHOLD, KEY_TYPE_INT)84 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_SMS_TO_MMS_TEXT_THRESHOLD, KEY_TYPE_INT); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD, KEY_TYPE_INT)85 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD, 86 KEY_TYPE_INT); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_MAX_MESSAGE_TEXT_SIZE, KEY_TYPE_INT)87 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_MAX_MESSAGE_TEXT_SIZE, KEY_TYPE_INT); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_MAX_SUBJECT_LENGTH, KEY_TYPE_INT)88 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_MAX_SUBJECT_LENGTH, KEY_TYPE_INT); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_UA_PROF_TAG_NAME, KEY_TYPE_STRING)89 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_UA_PROF_TAG_NAME, KEY_TYPE_STRING); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_HTTP_PARAMS, KEY_TYPE_STRING)90 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_HTTP_PARAMS, KEY_TYPE_STRING); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_EMAIL_GATEWAY_NUMBER, KEY_TYPE_STRING)91 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_EMAIL_GATEWAY_NUMBER, KEY_TYPE_STRING); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_NAI_SUFFIX, KEY_TYPE_STRING)92 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_NAI_SUFFIX, KEY_TYPE_STRING); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_UA_PROF_URL, KEY_TYPE_STRING)93 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_UA_PROF_URL, KEY_TYPE_STRING); sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_USER_AGENT, KEY_TYPE_STRING)94 sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_USER_AGENT, KEY_TYPE_STRING); 95 } 96 97 // A map that stores all MmsConfigs, one per active subscription. For pre-LMSim, this will 98 // contain just one entry with the default self sub id; for LMSim and above, this will contain 99 // all active sub ids but the default subscription id - the default subscription id will be 100 // resolved to an active sub id during runtime. 101 private static final Map<Integer, MmsConfig> sSubIdToMmsConfigMap = Maps.newHashMap(); 102 // The fallback values 103 private static final MmsConfig sFallback = 104 new MmsConfig(ParticipantData.DEFAULT_SELF_SUB_ID, new Bundle()); 105 106 // Per-subscription configuration values. 107 private final Bundle mValues; 108 private final int mSubId; 109 110 /** 111 * Retrieves the MmsConfig instance associated with the given {@code subId} 112 */ get(final int subId)113 public static MmsConfig get(final int subId) { 114 final int realSubId = PhoneUtils.getDefault().getEffectiveSubId(subId); 115 synchronized (sSubIdToMmsConfigMap) { 116 final MmsConfig mmsConfig = sSubIdToMmsConfigMap.get(realSubId); 117 if (mmsConfig == null) { 118 // The subId is no longer valid. Fall back to the default config. 119 LogUtil.e(LogUtil.BUGLE_TAG, "Get mms config failed: invalid subId. subId=" + subId 120 + ", real subId=" + realSubId 121 + ", map=" + sSubIdToMmsConfigMap.keySet()); 122 return sFallback; 123 } 124 return mmsConfig; 125 } 126 } 127 MmsConfig(final int subId, final Bundle values)128 private MmsConfig(final int subId, final Bundle values) { 129 mSubId = subId; 130 mValues = values; 131 } 132 133 /** 134 * Same as load() but doing it using an async thread from SafeAsyncTask thread pool. 135 */ loadAsync()136 public static void loadAsync() { 137 SafeAsyncTask.executeOnThreadPool(new Runnable() { 138 @Override 139 public void run() { 140 load(); 141 } 142 }); 143 } 144 145 /** 146 * Reload the device and per-subscription settings. 147 */ load()148 public static synchronized void load() { 149 final BugleCarrierConfigValuesLoader loader = Factory.get().getCarrierConfigValuesLoader(); 150 // Rebuild the entire MmsConfig map. 151 sSubIdToMmsConfigMap.clear(); 152 loader.reset(); 153 if (OsUtil.isAtLeastL_MR1()) { 154 final List<SubscriptionInfo> subInfoRecords = 155 PhoneUtils.getDefault().toLMr1().getActiveSubscriptionInfoList(); 156 if (subInfoRecords == null) { 157 LogUtil.w(TAG, "Loading mms config failed: no active SIM"); 158 return; 159 } 160 for (SubscriptionInfo subInfoRecord : subInfoRecords) { 161 final int subId = subInfoRecord.getSubscriptionId(); 162 final Bundle values = loader.get(subId); 163 addMmsConfig(new MmsConfig(subId, values)); 164 } 165 } else { 166 final Bundle values = loader.get(ParticipantData.DEFAULT_SELF_SUB_ID); 167 addMmsConfig(new MmsConfig(ParticipantData.DEFAULT_SELF_SUB_ID, values)); 168 } 169 } 170 addMmsConfig(MmsConfig mmsConfig)171 private static void addMmsConfig(MmsConfig mmsConfig) { 172 Assert.isTrue(OsUtil.isAtLeastL_MR1() != 173 (mmsConfig.mSubId == ParticipantData.DEFAULT_SELF_SUB_ID)); 174 sSubIdToMmsConfigMap.put(mmsConfig.mSubId, mmsConfig); 175 } 176 getSmsToMmsTextThreshold()177 public int getSmsToMmsTextThreshold() { 178 return mValues.getInt(CarrierConfigValuesLoader.CONFIG_SMS_TO_MMS_TEXT_THRESHOLD, 179 CarrierConfigValuesLoader.CONFIG_SMS_TO_MMS_TEXT_THRESHOLD_DEFAULT); 180 } 181 getSmsToMmsTextLengthThreshold()182 public int getSmsToMmsTextLengthThreshold() { 183 return mValues.getInt(CarrierConfigValuesLoader.CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD, 184 CarrierConfigValuesLoader.CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD_DEFAULT); 185 } 186 getMaxMessageSize()187 public int getMaxMessageSize() { 188 return mValues.getInt(CarrierConfigValuesLoader.CONFIG_MAX_MESSAGE_SIZE, 189 CarrierConfigValuesLoader.CONFIG_MAX_MESSAGE_SIZE_DEFAULT); 190 } 191 192 /** 193 * Return the largest MaxMessageSize for any subid 194 */ getMaxMaxMessageSize()195 public static int getMaxMaxMessageSize() { 196 int maxMax = 0; 197 for (MmsConfig config : sSubIdToMmsConfigMap.values()) { 198 maxMax = Math.max(maxMax, config.getMaxMessageSize()); 199 } 200 return maxMax > 0 ? maxMax : sFallback.getMaxMessageSize(); 201 } 202 getTransIdEnabled()203 public boolean getTransIdEnabled() { 204 return mValues.getBoolean(CarrierConfigValuesLoader.CONFIG_ENABLED_TRANS_ID, 205 CarrierConfigValuesLoader.CONFIG_ENABLED_TRANS_ID_DEFAULT); 206 } 207 getEmailGateway()208 public String getEmailGateway() { 209 return mValues.getString(CarrierConfigValuesLoader.CONFIG_EMAIL_GATEWAY_NUMBER, 210 CarrierConfigValuesLoader.CONFIG_EMAIL_GATEWAY_NUMBER_DEFAULT); 211 } 212 getMaxImageHeight()213 public int getMaxImageHeight() { 214 return mValues.getInt(CarrierConfigValuesLoader.CONFIG_MAX_IMAGE_HEIGHT, 215 CarrierConfigValuesLoader.CONFIG_MAX_IMAGE_HEIGHT_DEFAULT); 216 } 217 getMaxImageWidth()218 public int getMaxImageWidth() { 219 return mValues.getInt(CarrierConfigValuesLoader.CONFIG_MAX_IMAGE_WIDTH, 220 CarrierConfigValuesLoader.CONFIG_MAX_IMAGE_WIDTH_DEFAULT); 221 } 222 getRecipientLimit()223 public int getRecipientLimit() { 224 final int limit = mValues.getInt(CarrierConfigValuesLoader.CONFIG_RECIPIENT_LIMIT, 225 CarrierConfigValuesLoader.CONFIG_RECIPIENT_LIMIT_DEFAULT); 226 return limit < 0 ? Integer.MAX_VALUE : limit; 227 } 228 getMaxTextLimit()229 public int getMaxTextLimit() { 230 final int max = mValues.getInt(CarrierConfigValuesLoader.CONFIG_MAX_MESSAGE_TEXT_SIZE, 231 CarrierConfigValuesLoader.CONFIG_MAX_MESSAGE_TEXT_SIZE_DEFAULT); 232 return max > -1 ? max : DEFAULT_MAX_TEXT_LENGTH; 233 } 234 getMultipartSmsEnabled()235 public boolean getMultipartSmsEnabled() { 236 return mValues.getBoolean(CarrierConfigValuesLoader.CONFIG_ENABLE_MULTIPART_SMS, 237 CarrierConfigValuesLoader.CONFIG_ENABLE_MULTIPART_SMS_DEFAULT); 238 } 239 getSendMultipartSmsAsSeparateMessages()240 public boolean getSendMultipartSmsAsSeparateMessages() { 241 return mValues.getBoolean( 242 CarrierConfigValuesLoader.CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES, 243 CarrierConfigValuesLoader.CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES_DEFAULT); 244 } 245 getSMSDeliveryReportsEnabled()246 public boolean getSMSDeliveryReportsEnabled() { 247 return mValues.getBoolean(CarrierConfigValuesLoader.CONFIG_ENABLE_SMS_DELIVERY_REPORTS, 248 CarrierConfigValuesLoader.CONFIG_ENABLE_SMS_DELIVERY_REPORTS_DEFAULT); 249 } 250 getNotifyWapMMSC()251 public boolean getNotifyWapMMSC() { 252 return mValues.getBoolean(CarrierConfigValuesLoader.CONFIG_ENABLED_NOTIFY_WAP_MMSC, 253 CarrierConfigValuesLoader.CONFIG_ENABLED_NOTIFY_WAP_MMSC_DEFAULT); 254 } 255 isAliasEnabled()256 public boolean isAliasEnabled() { 257 return mValues.getBoolean(CarrierConfigValuesLoader.CONFIG_ALIAS_ENABLED, 258 CarrierConfigValuesLoader.CONFIG_ALIAS_ENABLED_DEFAULT); 259 } 260 getAliasMinChars()261 public int getAliasMinChars() { 262 return mValues.getInt(CarrierConfigValuesLoader.CONFIG_ALIAS_MIN_CHARS, 263 CarrierConfigValuesLoader.CONFIG_ALIAS_MIN_CHARS_DEFAULT); 264 } 265 getAliasMaxChars()266 public int getAliasMaxChars() { 267 return mValues.getInt(CarrierConfigValuesLoader.CONFIG_ALIAS_MAX_CHARS, 268 CarrierConfigValuesLoader.CONFIG_ALIAS_MAX_CHARS_DEFAULT); 269 } 270 getAllowAttachAudio()271 public boolean getAllowAttachAudio() { 272 return mValues.getBoolean(CarrierConfigValuesLoader.CONFIG_ALLOW_ATTACH_AUDIO, 273 CarrierConfigValuesLoader.CONFIG_ALLOW_ATTACH_AUDIO_DEFAULT); 274 } 275 getMaxSubjectLength()276 public int getMaxSubjectLength() { 277 return mValues.getInt(CarrierConfigValuesLoader.CONFIG_MAX_SUBJECT_LENGTH, 278 CarrierConfigValuesLoader.CONFIG_MAX_SUBJECT_LENGTH_DEFAULT); 279 } 280 getGroupMmsEnabled()281 public boolean getGroupMmsEnabled() { 282 return mValues.getBoolean(CarrierConfigValuesLoader.CONFIG_ENABLE_GROUP_MMS, 283 CarrierConfigValuesLoader.CONFIG_ENABLE_GROUP_MMS_DEFAULT); 284 } 285 getSupportMmsContentDisposition()286 public boolean getSupportMmsContentDisposition() { 287 return mValues.getBoolean(CarrierConfigValuesLoader.CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION, 288 CarrierConfigValuesLoader.CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION_DEFAULT); 289 } 290 getShowCellBroadcast()291 public boolean getShowCellBroadcast() { 292 return mValues.getBoolean(CarrierConfigValuesLoader.CONFIG_CELL_BROADCAST_APP_LINKS, 293 CarrierConfigValuesLoader.CONFIG_CELL_BROADCAST_APP_LINKS_DEFAULT); 294 } 295 getValue(final String key)296 public Object getValue(final String key) { 297 return mValues.get(key); 298 } 299 keySet()300 public Set<String> keySet() { 301 return mValues.keySet(); 302 } 303 getKeyType(final String key)304 public static String getKeyType(final String key) { 305 return sKeyTypeMap.get(key); 306 } 307 update(final String type, final String key, final String value)308 public void update(final String type, final String key, final String value) { 309 BugleCarrierConfigValuesLoader.update(mValues, type, key, value); 310 } 311 } 312