1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.mms.service; 18 19 import android.content.BroadcastReceiver; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.IntentFilter; 23 import android.os.Bundle; 24 import android.telephony.CarrierConfigManager; 25 import android.telephony.SmsManager; 26 import android.telephony.SubscriptionInfo; 27 import android.telephony.SubscriptionManager; 28 import android.util.ArrayMap; 29 30 import java.util.List; 31 import java.util.Map; 32 33 /** 34 * This class manages cached copies of all the MMS configuration for each subscription ID. 35 * A subscription ID loosely corresponds to a particular SIM. See the 36 * {@link android.telephony.SubscriptionManager} for more details. 37 * 38 */ 39 public class MmsConfigManager { 40 private static volatile MmsConfigManager sInstance = new MmsConfigManager(); 41 getInstance()42 public static MmsConfigManager getInstance() { 43 return sInstance; 44 } 45 46 // Map the various subIds to their corresponding MmsConfigs. 47 private final Map<Integer, Bundle> mSubIdConfigMap = new ArrayMap<Integer, Bundle>(); 48 private Context mContext; 49 private SubscriptionManager mSubscriptionManager; 50 51 /** This receiver listens to ACTION_CARRIER_CONFIG_CHANGED to load the MMS config. */ 52 private final BroadcastReceiver mReceiver = 53 new BroadcastReceiver() { 54 public void onReceive(Context context, Intent intent) { 55 LogUtil.i("MmsConfigManager receives ACTION_CARRIER_CONFIG_CHANGED"); 56 loadInBackground(); 57 } 58 }; 59 init(final Context context)60 public void init(final Context context) { 61 mContext = context; 62 mSubscriptionManager = SubscriptionManager.from(context); 63 context.registerReceiver( 64 mReceiver, new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)); 65 LogUtil.i("MmsConfigManager loads mms config in init()"); 66 load(context); 67 } 68 loadInBackground()69 private void loadInBackground() { 70 // TODO (ywen) - AsyncTask to avoid creating a new thread? 71 new Thread() { 72 @Override 73 public void run() { 74 load(mContext); 75 } 76 }.start(); 77 } 78 79 /** 80 * Find and return the MMS config for a particular subscription id. 81 * 82 * @param subId Subscription Id of the desired MMS config bundle 83 * @return MMS config bundle for the particular subscription Id. This function can return null 84 * if the MMS config is not loaded yet. 85 */ getMmsConfigBySubId(int subId)86 public Bundle getMmsConfigBySubId(int subId) { 87 Bundle mmsConfig; 88 synchronized(mSubIdConfigMap) { 89 mmsConfig = mSubIdConfigMap.get(subId); 90 } 91 LogUtil.i("mms config for sub " + subId + ": " + mmsConfig); 92 // Return a copy so that callers can mutate it. 93 if (mmsConfig != null) { 94 return new Bundle(mmsConfig); 95 } 96 return null; 97 } 98 99 /** 100 * This loads the MMS config for each active subscription. 101 * 102 * MMS config is fetched from SmsManager#getCarrierConfigValues(). The resulting bundles are 103 * stored in mSubIdConfigMap. 104 */ load(Context context)105 private void load(Context context) { 106 List<SubscriptionInfo> subs = mSubscriptionManager.getActiveSubscriptionInfoList(); 107 if (subs == null || subs.size() < 1) { 108 LogUtil.e(" Failed to load mms config: empty getActiveSubInfoList"); 109 return; 110 } 111 // Load all the config bundles into a new map and then swap it with the real map to avoid 112 // blocking. 113 final Map<Integer, Bundle> newConfigMap = new ArrayMap<Integer, Bundle>(); 114 for (SubscriptionInfo sub : subs) { 115 final int subId = sub.getSubscriptionId(); 116 LogUtil.i("MmsConfigManager loads mms config for " 117 + sub.getMccString() + "/" + sub.getMncString() 118 + ", CarrierId " + sub.getCarrierId()); 119 newConfigMap.put( 120 subId, 121 SmsManager.getSmsManagerForSubscriptionId(subId).getCarrierConfigValues()); 122 } 123 synchronized(mSubIdConfigMap) { 124 mSubIdConfigMap.clear(); 125 mSubIdConfigMap.putAll(newConfigMap); 126 } 127 } 128 129 } 130