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 androidx.appcompat.mms;
18 
19 import android.content.Context;
20 import android.content.res.Resources;
21 import android.content.res.XmlResourceParser;
22 import android.os.Bundle;
23 import android.util.Log;
24 import android.util.SparseArray;
25 
26 import com.android.messaging.R;
27 
28 /**
29  * The default implementation of loader for carrier config values
30  */
31 class DefaultCarrierConfigValuesLoader implements CarrierConfigValuesLoader {
32     /*
33      * Key types
34      */
35     public static final String KEY_TYPE_INT = "int";
36     public static final String KEY_TYPE_BOOL = "bool";
37     public static final String KEY_TYPE_STRING = "string";
38 
39     private final Context mContext;
40 
41     // Cached values for subIds
42     private final SparseArray<Bundle> mValuesCache;
43 
DefaultCarrierConfigValuesLoader(final Context context)44     DefaultCarrierConfigValuesLoader(final Context context) {
45         mContext = context;
46         mValuesCache = new SparseArray<>();
47     }
48 
49     @Override
get(int subId)50     public Bundle get(int subId) {
51         subId = Utils.getEffectiveSubscriptionId(subId);
52         Bundle values;
53         boolean didLoad = false;
54         synchronized (this) {
55             values = mValuesCache.get(subId);
56             if (values == null) {
57                 values = new Bundle();
58                 mValuesCache.put(subId, values);
59                 loadLocked(subId, values);
60                 didLoad = true;
61             }
62         }
63         if (didLoad) {
64             Log.i(MmsService.TAG, "Carrier configs loaded: " + values);
65         }
66         return values;
67     }
68 
loadLocked(final int subId, final Bundle values)69     private void loadLocked(final int subId, final Bundle values) {
70         // For K and earlier, load from resources
71         loadFromResources(subId, values);
72         if (Utils.hasMmsApi()) {
73             // For L and later, also load from system MMS service
74             loadFromSystem(subId, values);
75         }
76     }
77 
78     /**
79      * Load from system, using MMS API
80      *
81      * @param subId which SIM to load for
82      * @param values the result to add to
83      */
loadFromSystem(final int subId, final Bundle values)84     private static void loadFromSystem(final int subId, final Bundle values) {
85         try {
86             final Bundle systemValues = Utils.getSmsManager(subId).getCarrierConfigValues();
87             if (systemValues != null) {
88                 values.putAll(systemValues);
89             }
90         } catch (final Exception e) {
91             Log.w(MmsService.TAG, "Calling system getCarrierConfigValues exception", e);
92         }
93     }
94 
loadFromResources(final int subId, final Bundle values)95     private void loadFromResources(final int subId, final Bundle values) {
96         // Get a subscription-dependent context for loading the mms_config.xml
97         final Context subContext = Utils.getSubDepContext(mContext, subId);
98         XmlResourceParser xml = null;
99         try {
100             xml = subContext.getResources().getXml(R.xml.mms_config);
101             new CarrierConfigXmlParser(xml, new CarrierConfigXmlParser.KeyValueProcessor() {
102                 @Override
103                 public void process(String type, String key, String value) {
104                     try {
105                         if (KEY_TYPE_INT.equals(type)) {
106                             values.putInt(key, Integer.parseInt(value));
107                         } else if (KEY_TYPE_BOOL.equals(type)) {
108                             values.putBoolean(key, Boolean.parseBoolean(value));
109                         } else if (KEY_TYPE_STRING.equals(type)) {
110                             values.putString(key, value);
111                         }
112                     } catch (final NumberFormatException e) {
113                         Log.w(MmsService.TAG, "Load carrier value from resources: "
114                                 + "invalid " + key + "," + value + "," + type);
115                     }
116                 }
117             }).parse();
118         } catch (final Resources.NotFoundException e) {
119             Log.w(MmsService.TAG, "Can not get mms_config.xml");
120         } finally {
121             if (xml != null) {
122                 xml.close();
123             }
124         }
125     }
126 }
127