1d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/* 2d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Copyright (C) 2015 The Android Open Source Project 3d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 4d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Licensed under the Apache License, Version 2.0 (the "License"); 5d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * you may not use this file except in compliance with the License. 6d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * You may obtain a copy of the License at 7d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 8d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * http://www.apache.org/licenses/LICENSE-2.0 9d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 10d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Unless required by applicable law or agreed to in writing, software 11d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * distributed under the License is distributed on an "AS IS" BASIS, 12d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * See the License for the specific language governing permissions and 14d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * limitations under the License. 15d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 16d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 17d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpackage com.android.messaging.sms; 18d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 19d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.Context; 20d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.res.Configuration; 21d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.res.Resources; 22d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.res.XmlResourceParser; 23d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.os.Bundle; 24d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.support.v7.mms.CarrierConfigValuesLoader; 25d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.util.SparseArray; 26d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 27d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.R; 28d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.LogUtil; 29d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.OsUtil; 30d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.PhoneUtils; 31d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 32d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/** 33d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Carrier configuration loader 34d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 35d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Loader tries to load from resources. If there is MMS API available, also 36d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * load from system. 37d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 38d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpublic class BugleCarrierConfigValuesLoader implements CarrierConfigValuesLoader { 39d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /* 40d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Key types 41d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 42d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String KEY_TYPE_INT = "int"; 43d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String KEY_TYPE_BOOL = "bool"; 44d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String KEY_TYPE_STRING = "string"; 45d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 46d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private final Context mContext; 47d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 48d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Cached values for subIds 49d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private final SparseArray<Bundle> mValuesCache; 50d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 51d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public BugleCarrierConfigValuesLoader(final Context context) { 52d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mContext = context; 53d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mValuesCache = new SparseArray<>(); 54d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 55d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 56d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 57d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public Bundle get(int subId) { 58d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd subId = PhoneUtils.getDefault().getEffectiveSubId(subId); 59d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Bundle values; 60d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd String loadSource = null; 61d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd synchronized (this) { 62d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd values = mValuesCache.get(subId); 63d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (values == null) { 64d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd values = new Bundle(); 65d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mValuesCache.put(subId, values); 66d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd loadSource = loadLocked(subId, values); 67d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 68d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 69d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (loadSource != null) { 70d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.i(LogUtil.BUGLE_TAG, "Carrier configs loaded: " + values 71d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + " from " + loadSource + " for subId=" + subId); 72d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 73d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return values; 74d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 75d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 76d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 77d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Clear the cache for reloading 78d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 79d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void reset() { 80d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd synchronized (this) { 81d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mValuesCache.clear(); 82d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 83d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 84d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 85d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 86d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Loading carrier config values 87d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 88d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param subId which SIM to load for 89d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param values the result to add to 90d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the source of the config, could be "resources" or "resources+system" 91d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 92d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private String loadLocked(final int subId, final Bundle values) { 93d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Load from resources in earlier platform 94d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd loadFromResources(subId, values); 95d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (OsUtil.isAtLeastL()) { 96d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Load from system to override if system API exists 97d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd loadFromSystem(subId, values); 98d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return "resources+system"; 99d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 100d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return "resources"; 101d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 102d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 103d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 104d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Load from system, using MMS API 105d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 106d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param subId which SIM to load for 107d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param values the result to add to 108d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 109d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static void loadFromSystem(final int subId, final Bundle values) { 110d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 111d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Bundle systemValues = 112d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd PhoneUtils.get(subId).getSmsManager().getCarrierConfigValues(); 113d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (systemValues != null) { 114d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd values.putAll(systemValues); 115d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 116d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (final Exception e) { 117d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.w(LogUtil.BUGLE_TAG, "Calling system getCarrierConfigValues exception", e); 118d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 119d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 120d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 121d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 122d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Load from SIM-dependent resources 123d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 124d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param subId which SIM to load for 125d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param values the result to add to 126d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 127d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private void loadFromResources(final int subId, final Bundle values) { 128d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Get a subscription-dependent context for loading the mms_config.xml 129d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Context subContext = getSubDepContext(mContext, subId); 130d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Load and parse the XML 131d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd XmlResourceParser parser = null; 132d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 133d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd parser = subContext.getResources().getXml(R.xml.mms_config); 134d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final ApnsXmlProcessor processor = ApnsXmlProcessor.get(parser); 135d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd processor.setMmsConfigHandler(new ApnsXmlProcessor.MmsConfigHandler() { 136d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 137d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void process(final String mccMnc, final String key, final String value, 138d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String type) { 139d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd update(values, type, key, value); 140d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 141d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd }); 142d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd processor.process(); 143d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (final Resources.NotFoundException e) { 144d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.w(LogUtil.BUGLE_TAG, "Can not find mms_config.xml"); 145d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } finally { 146d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (parser != null) { 147d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd parser.close(); 148d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 149d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 150d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 151d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 152d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 153d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Get a subscription's Context so we can load resources from it 154d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 155d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param context the sub-independent Context 156d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param subId the SIM's subId 157d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the sub-dependent Context 158d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 159d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static Context getSubDepContext(final Context context, final int subId) { 160d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (!OsUtil.isAtLeastL_MR1()) { 161d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return context; 162d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 163d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int[] mccMnc = PhoneUtils.get(subId).getMccMnc(); 164d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int mcc = mccMnc[0]; 165d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int mnc = mccMnc[1]; 166d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Configuration subConfig = new Configuration(); 167d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (mcc == 0 && mnc == 0) { 168d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Configuration config = context.getResources().getConfiguration(); 169d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd subConfig.mcc = config.mcc; 170d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd subConfig.mnc = config.mnc; 171d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 172d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd subConfig.mcc = mcc; 173d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd subConfig.mnc = mnc; 174d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 175d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return context.createConfigurationContext(subConfig); 176d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 177d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 178d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 179d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Add or update a carrier config key/value pair to the Bundle 180d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 181d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param values the result Bundle to add to 182d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param type the value type 183d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param key the key 184d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param value the value 185d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 186d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static void update(final Bundle values, final String type, final String key, 187d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String value) { 188d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 189d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (KEY_TYPE_INT.equals(type)) { 190d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd values.putInt(key, Integer.parseInt(value)); 191d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else if (KEY_TYPE_BOOL.equals(type)) { 192d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd values.putBoolean(key, Boolean.parseBoolean(value)); 193d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else if (KEY_TYPE_STRING.equals(type)){ 194d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd values.putString(key, value); 195d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 196d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (final NumberFormatException e) { 197d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.w(LogUtil.BUGLE_TAG, "Add carrier values: " 198d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + "invalid " + key + "," + value + "," + type); 199d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 200d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 201d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd} 202