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 com.android.internal.telephony.flags.Flags; 31 32 import java.util.List; 33 import java.util.Map; 34 35 /** 36 * This class manages cached copies of all the MMS configuration for each subscription ID. 37 * A subscription ID loosely corresponds to a particular SIM. See the 38 * {@link android.telephony.SubscriptionManager} for more details. 39 * 40 */ 41 public class MmsConfigManager { 42 private static volatile MmsConfigManager sInstance = new MmsConfigManager(); 43 getInstance()44 public static MmsConfigManager getInstance() { 45 return sInstance; 46 } 47 48 // Map the various subIds to their corresponding MmsConfigs. 49 private final Map<Integer, Bundle> mSubIdConfigMap = new ArrayMap<Integer, Bundle>(); 50 private Context mContext; 51 private SubscriptionManager mSubscriptionManager; 52 53 /** This receiver listens to ACTION_CARRIER_CONFIG_CHANGED to load the MMS config. */ 54 private final BroadcastReceiver mReceiver = 55 new BroadcastReceiver() { 56 public void onReceive(Context context, Intent intent) { 57 LogUtil.i("MmsConfigManager receives ACTION_CARRIER_CONFIG_CHANGED"); 58 loadInBackground(); 59 } 60 }; 61 init(final Context context)62 public void init(final Context context) { 63 mContext = context; 64 mSubscriptionManager = SubscriptionManager.from(context); 65 if (Flags.workProfileApiSplit()) { 66 mSubscriptionManager = mSubscriptionManager.createForAllUserProfiles(); 67 } 68 context.registerReceiver( 69 mReceiver, new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)); 70 LogUtil.i("MmsConfigManager loads mms config in init()"); 71 load(context); 72 } 73 loadInBackground()74 private void loadInBackground() { 75 // TODO (ywen) - AsyncTask to avoid creating a new thread? 76 new Thread() { 77 @Override 78 public void run() { 79 load(mContext); 80 } 81 }.start(); 82 } 83 84 /** 85 * Find and return the MMS config for a particular subscription id. 86 * 87 * @param subId Subscription Id of the desired MMS config bundle 88 * @return MMS config bundle for the particular subscription Id. This function can return null 89 * if the MMS config is not loaded yet. 90 */ getMmsConfigBySubId(int subId)91 public Bundle getMmsConfigBySubId(int subId) { 92 Bundle mmsConfig; 93 synchronized(mSubIdConfigMap) { 94 mmsConfig = mSubIdConfigMap.get(subId); 95 } 96 LogUtil.i("mms config for sub " + subId + ": " + mmsConfig); 97 // Return a copy so that callers can mutate it. 98 if (mmsConfig != null) { 99 return new Bundle(mmsConfig); 100 } 101 return null; 102 } 103 104 /** 105 * This loads the MMS config for each active subscription. 106 * 107 * MMS config is fetched from SmsManager#getCarrierConfigValues(). The resulting bundles are 108 * stored in mSubIdConfigMap. 109 */ load(Context context)110 private void load(Context context) { 111 List<SubscriptionInfo> subs = mSubscriptionManager.getActiveSubscriptionInfoList(); 112 if (subs == null || subs.size() < 1) { 113 LogUtil.e(" Failed to load mms config: empty getActiveSubInfoList"); 114 return; 115 } 116 // Load all the config bundles into a new map and then swap it with the real map to avoid 117 // blocking. 118 final Map<Integer, Bundle> newConfigMap = new ArrayMap<Integer, Bundle>(); 119 for (SubscriptionInfo sub : subs) { 120 final int subId = sub.getSubscriptionId(); 121 LogUtil.i("MmsConfigManager loads mms config for " 122 + sub.getMccString() + "/" + sub.getMncString() 123 + ", CarrierId " + sub.getCarrierId()); 124 newConfigMap.put( 125 subId, 126 SmsManager.getSmsManagerForSubscriptionId(subId).getCarrierConfigValues()); 127 } 128 synchronized(mSubIdConfigMap) { 129 mSubIdConfigMap.clear(); 130 mSubIdConfigMap.putAll(newConfigMap); 131 } 132 } 133 134 } 135