Home | History | Annotate | Download | only in stk
      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.stk;
     18 
     19 import android.content.Context;
     20 import android.content.res.XmlResourceParser;
     21 import android.graphics.Bitmap;
     22 import android.graphics.BitmapFactory;
     23 import android.os.Build;
     24 import android.telephony.SubscriptionManager;
     25 import android.telephony.TelephonyManager;
     26 import android.text.TextUtils;
     27 
     28 import com.android.internal.telephony.PhoneConstants;
     29 import com.android.internal.telephony.cat.CatLog;
     30 import com.android.internal.util.XmlUtils;
     31 
     32 import java.util.ArrayList;
     33 
     34 /**
     35  * Provides preset label and/or icon in accordance with mcc/mnc
     36  * conbination of the inserted SIM card for Multi-SIM model.
     37  */
     38 public class StkMenuConfig {
     39     private static final String LOG_TAG = "StkMenuConfig";
     40     private static final boolean DBG = Build.IS_DEBUGGABLE;
     41 
     42     private static final String XML_OPERATORS_TAG = "operators";
     43     private static final String XML_OPERATOR_TAG = "operator";
     44 
     45     private static final String XML_MCC_ATTR = "mcc";
     46     private static final String XML_MNC_ATTR = "mnc";
     47     private static final String XML_LABEL_ATTR = "label";
     48     private static final String XML_ICON_ATTR = "icon";
     49     private static final String RESOURCE_TYPE = "drawable";
     50 
     51     private static final int UNSPECIFIED = -1;
     52 
     53     private static final Config NO_CONFIG = new Config(0, 0, null, null);
     54 
     55     private static final Object sLock = new Object();
     56     private static StkMenuConfig sInstance;
     57 
     58     private Context mContext;
     59     private ArrayList<Config> mArray;
     60     private Config mConfigs[] = null;
     61 
     62     private static class Config {
     63         public int mcc;
     64         public int mnc;
     65         public String label;
     66         public String icon;
     67 
     68         public Config(int mcc, int mnc, String label, String icon) {
     69             this.mcc = mcc;
     70             this.mnc = mnc;
     71             this.label = label;
     72             this.icon = icon;
     73         }
     74     }
     75 
     76     public static StkMenuConfig getInstance(Context applicationContext) {
     77         synchronized (sLock) {
     78             if (sInstance == null) {
     79                 sInstance = new StkMenuConfig();
     80                 sInstance.initialize(applicationContext);
     81             }
     82             return sInstance;
     83         }
     84     }
     85 
     86     /**
     87      * Returns a preset label, if exists.
     88      */
     89     public String getLabel(int slotId) {
     90         findConfig(slotId);
     91 
     92         if (DBG) CatLog.d(LOG_TAG, "getLabel: " + mConfigs[slotId].label + ", slot id: " + slotId);
     93         return mConfigs[slotId].label;
     94     }
     95 
     96     /**
     97      * Returns a preset icon, if exists.
     98      */
     99     public Bitmap getIcon(int slotId) {
    100         findConfig(slotId);
    101 
    102         Bitmap bitmap = null;
    103         if (mConfigs[slotId].icon != null) {
    104             int resId = mContext.getResources().getIdentifier(mConfigs[slotId].icon,
    105                     RESOURCE_TYPE, mContext.getPackageName());
    106             bitmap = resId == UNSPECIFIED ? null :
    107                     BitmapFactory.decodeResource(mContext.getResources(), resId);
    108         }
    109         if (DBG) CatLog.d(LOG_TAG, "getIcon: " + mConfigs[slotId].icon + ", slot id: " + slotId);
    110         return bitmap;
    111     }
    112 
    113     private void findConfig(int slotId) {
    114         int[] subId = SubscriptionManager.getSubId(slotId);
    115         if (subId == null) {
    116             mConfigs[slotId] = NO_CONFIG;
    117             return;
    118         }
    119 
    120         TelephonyManager telephony =
    121                 (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
    122         String operator = telephony.getSimOperator(subId[0]);
    123         if (TextUtils.isEmpty(operator) || (operator.length() < 5)) {
    124             mConfigs[slotId] = NO_CONFIG;
    125             return;
    126         }
    127 
    128         int mcc = Integer.parseInt(operator.substring(0, 3));
    129         int mnc = Integer.parseInt(operator.substring(3));
    130 
    131         if (mConfigs[slotId] != null && mConfigs[slotId].mcc == mcc
    132                 && mConfigs[slotId].mnc == mnc) {
    133             if (DBG) CatLog.d(LOG_TAG, "Return the cached config, slot id: " + slotId);
    134             return;
    135         }
    136 
    137         if (DBG) CatLog.d(LOG_TAG, "Find config and create the cached config, slot id: " + slotId);
    138         for (Config config : mArray) {
    139             if ((config.mcc == mcc) && (config.mnc == mnc)) {
    140                 mConfigs[slotId] = config;
    141                 return;
    142             }
    143         }
    144 
    145         mConfigs[slotId] = new Config(mcc, mnc, null, null);
    146     }
    147 
    148     private void initialize(Context context) {
    149         mContext = context;
    150         mArray = new ArrayList<Config>();
    151         mConfigs = new Config[TelephonyManager.from(mContext).getSimCount()];
    152 
    153         XmlResourceParser parser = mContext.getResources().getXml(R.xml.menu_conf);
    154 
    155         try {
    156             XmlUtils.beginDocument(parser, XML_OPERATORS_TAG);
    157 
    158             do {
    159                 XmlUtils.nextElement(parser);
    160 
    161                 if (!XML_OPERATOR_TAG.equals(parser.getName())) {
    162                     break;
    163                 }
    164 
    165                 int mcc = parser.getAttributeIntValue(null, XML_MCC_ATTR, UNSPECIFIED);
    166                 int mnc = parser.getAttributeIntValue(null, XML_MNC_ATTR, UNSPECIFIED);
    167 
    168                 if ((mcc == UNSPECIFIED) || (mnc == UNSPECIFIED)) {
    169                     continue;
    170                 }
    171 
    172                 String label = parser.getAttributeValue(null, XML_LABEL_ATTR);
    173                 String icon = parser.getAttributeValue(null, XML_ICON_ATTR);
    174 
    175                 Config config = new Config(mcc, mnc, label, icon);
    176                 mArray.add(config);
    177             } while (true);
    178         } catch (Exception e) {
    179             CatLog.e(LOG_TAG, "Something wrong happened while interpreting the xml file" + e);
    180         } finally {
    181             parser.close();
    182         }
    183     }
    184 }
    185