Home | History | Annotate | Download | only in omtp
      1 /*
      2  * Copyright (C) 2016 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.phone.vvm.omtp;
     18 
     19 import android.annotation.Nullable;
     20 import android.content.res.Resources;
     21 import android.os.PersistableBundle;
     22 import android.util.ArrayMap;
     23 
     24 import com.android.internal.annotations.VisibleForTesting;
     25 import com.android.phone.R;
     26 import com.android.phone.vvm.omtp.utils.XmlUtils;
     27 
     28 import org.xmlpull.v1.XmlPullParser;
     29 import org.xmlpull.v1.XmlPullParserException;
     30 
     31 import java.io.IOException;
     32 import java.util.ArrayList;
     33 import java.util.Map;
     34 import java.util.Map.Entry;
     35 
     36 /**
     37  * Load and caches telephony vvm config from res/xml/vvm_config.xml
     38  */
     39 public class TelephonyVvmConfigManager {
     40 
     41     private static final String TAG = "TelephonyVvmCfgMgr";
     42 
     43     private static final boolean USE_DEBUG_CONFIG = false; //STOPSHIP if true
     44 
     45     private static final String TAG_PERSISTABLEMAP = "pbundle_as_map";
     46 
     47     static final String KEY_MCCMNC = "mccmnc";
     48 
     49     private static Map<String, PersistableBundle> sCachedConfigs;
     50 
     51     private final Map<String, PersistableBundle> mConfigs;
     52 
     53     public TelephonyVvmConfigManager(Resources resources) {
     54         if (sCachedConfigs == null) {
     55             sCachedConfigs = loadConfigs(resources.getXml(R.xml.vvm_config));
     56         }
     57         mConfigs = sCachedConfigs;
     58     }
     59 
     60     @VisibleForTesting
     61     TelephonyVvmConfigManager(XmlPullParser parser) {
     62         mConfigs = loadConfigs(parser);
     63     }
     64 
     65     @Nullable
     66     public PersistableBundle getConfig(String mccMnc) {
     67         if (USE_DEBUG_CONFIG) {
     68             return mConfigs.get("TEST");
     69         }
     70         return mConfigs.get(mccMnc);
     71     }
     72 
     73     private static Map<String, PersistableBundle> loadConfigs(XmlPullParser parser) {
     74         Map<String, PersistableBundle> configs = new ArrayMap<>();
     75         try {
     76             ArrayList list = readBundleList(parser);
     77             for (Object object : list) {
     78                 if (!(object instanceof PersistableBundle)) {
     79                     throw new IllegalArgumentException("PersistableBundle expected, got " + object);
     80                 }
     81                 PersistableBundle bundle = (PersistableBundle) object;
     82                 String[] mccMncs = bundle.getStringArray(KEY_MCCMNC);
     83                 if (mccMncs == null) {
     84                     throw new IllegalArgumentException("MCCMNC is null");
     85                 }
     86                 for (String mccMnc : mccMncs) {
     87                     configs.put(mccMnc, bundle);
     88                 }
     89             }
     90         } catch (IOException | XmlPullParserException e) {
     91             throw new RuntimeException(e);
     92         }
     93         return configs;
     94     }
     95 
     96     @Nullable
     97     public static ArrayList readBundleList(XmlPullParser in) throws IOException,
     98             XmlPullParserException {
     99         final int outerDepth = in.getDepth();
    100         int event;
    101         while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
    102                 (event != XmlPullParser.END_TAG || in.getDepth() < outerDepth)) {
    103             if (event == XmlPullParser.START_TAG) {
    104                 final String startTag = in.getName();
    105                 final String[] tagName = new String[1];
    106                 in.next();
    107                 return XmlUtils.readThisListXml(in, startTag, tagName,
    108                         new MyReadMapCallback(), false);
    109             }
    110         }
    111         return null;
    112     }
    113 
    114     public static PersistableBundle restoreFromXml(XmlPullParser in) throws IOException,
    115             XmlPullParserException {
    116         final int outerDepth = in.getDepth();
    117         final String startTag = in.getName();
    118         final String[] tagName = new String[1];
    119         int event;
    120         while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
    121                 (event != XmlPullParser.END_TAG || in.getDepth() < outerDepth)) {
    122             if (event == XmlPullParser.START_TAG) {
    123                 ArrayMap<String, ?> map =
    124                         XmlUtils.readThisArrayMapXml(in, startTag, tagName,
    125                                 new MyReadMapCallback());
    126                 PersistableBundle result = new PersistableBundle();
    127                 for (Entry<String, ?> entry : map.entrySet()) {
    128                     Object value = entry.getValue();
    129                     if (value instanceof Integer) {
    130                         result.putInt(entry.getKey(), (int) value);
    131                     } else if (value instanceof Boolean) {
    132                         result.putBoolean(entry.getKey(), (boolean) value);
    133                     } else if (value instanceof String) {
    134                         result.putString(entry.getKey(), (String) value);
    135                     } else if (value instanceof String[]) {
    136                         result.putStringArray(entry.getKey(), (String[]) value);
    137                     } else if (value instanceof PersistableBundle) {
    138                         result.putPersistableBundle(entry.getKey(), (PersistableBundle) value);
    139                     }
    140                 }
    141                 return result;
    142             }
    143         }
    144         return PersistableBundle.EMPTY;
    145     }
    146 
    147     static class MyReadMapCallback implements XmlUtils.ReadMapCallback {
    148 
    149         @Override
    150         public Object readThisUnknownObjectXml(XmlPullParser in, String tag)
    151                 throws XmlPullParserException, IOException {
    152             if (TAG_PERSISTABLEMAP.equals(tag)) {
    153                 return restoreFromXml(in);
    154             }
    155             throw new XmlPullParserException("Unknown tag=" + tag);
    156         }
    157     }
    158 }
    159