Home | History | Annotate | Download | only in sim
      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.settings.sim;
     18 
     19 import android.content.Context;
     20 import android.content.Intent;
     21 import android.content.res.Resources;
     22 import android.graphics.drawable.BitmapDrawable;
     23 import android.os.Bundle;
     24 import android.preference.Preference;
     25 import android.preference.PreferenceScreen;
     26 import android.provider.SearchIndexableResource;
     27 import android.telephony.PhoneStateListener;
     28 import android.telephony.SubscriptionInfo;
     29 import android.telephony.SubscriptionManager;
     30 import android.telephony.TelephonyManager;
     31 import android.telecom.PhoneAccountHandle;
     32 import android.telecom.TelecomManager;
     33 import android.text.TextUtils;
     34 import android.util.Log;
     35 import com.android.internal.logging.MetricsLogger;
     36 import com.android.settings.RestrictedSettingsFragment;
     37 import com.android.settings.Utils;
     38 import com.android.settings.search.BaseSearchIndexProvider;
     39 import com.android.settings.search.Indexable;
     40 import com.android.settings.R;
     41 import android.os.SystemProperties;
     42 import com.android.internal.telephony.TelephonyProperties;
     43 
     44 import java.util.ArrayList;
     45 import java.util.List;
     46 
     47 public class SimSettings extends RestrictedSettingsFragment implements Indexable {
     48     private static final String TAG = "SimSettings";
     49     private static final boolean DBG = false;
     50 
     51     private static final String DISALLOW_CONFIG_SIM = "no_config_sim";
     52     private static final String SIM_CARD_CATEGORY = "sim_cards";
     53     private static final String KEY_CELLULAR_DATA = "sim_cellular_data";
     54     private static final String KEY_CALLS = "sim_calls";
     55     private static final String KEY_SMS = "sim_sms";
     56     public static final String EXTRA_SLOT_ID = "slot_id";
     57 
     58     /**
     59      * By UX design we use only one Subscription Information(SubInfo) record per SIM slot.
     60      * mAvalableSubInfos is the list of SubInfos we present to the user.
     61      * mSubInfoList is the list of all SubInfos.
     62      * mSelectableSubInfos is the list of SubInfos that a user can select for data, calls, and SMS.
     63      */
     64     private List<SubscriptionInfo> mAvailableSubInfos = null;
     65     private List<SubscriptionInfo> mSubInfoList = null;
     66     private List<SubscriptionInfo> mSelectableSubInfos = null;
     67     private PreferenceScreen mSimCards = null;
     68     private SubscriptionManager mSubscriptionManager;
     69     private int mNumSlots;
     70     private Context mContext;
     71 
     72     public SimSettings() {
     73         super(DISALLOW_CONFIG_SIM);
     74     }
     75 
     76     @Override
     77     protected int getMetricsCategory() {
     78         return MetricsLogger.SIM;
     79     }
     80 
     81     @Override
     82     public void onCreate(final Bundle bundle) {
     83         super.onCreate(bundle);
     84         mContext = getActivity();
     85 
     86         mSubscriptionManager = SubscriptionManager.from(getActivity());
     87         final TelephonyManager tm =
     88                 (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
     89         addPreferencesFromResource(R.xml.sim_settings);
     90 
     91         mNumSlots = tm.getSimCount();
     92         mSimCards = (PreferenceScreen)findPreference(SIM_CARD_CATEGORY);
     93         mAvailableSubInfos = new ArrayList<SubscriptionInfo>(mNumSlots);
     94         mSelectableSubInfos = new ArrayList<SubscriptionInfo>();
     95         SimSelectNotification.cancelNotification(getActivity());
     96     }
     97 
     98     private final SubscriptionManager.OnSubscriptionsChangedListener mOnSubscriptionsChangeListener
     99             = new SubscriptionManager.OnSubscriptionsChangedListener() {
    100         @Override
    101         public void onSubscriptionsChanged() {
    102             if (DBG) log("onSubscriptionsChanged:");
    103             updateSubscriptions();
    104         }
    105     };
    106 
    107     private void updateSubscriptions() {
    108         mSubInfoList = mSubscriptionManager.getActiveSubscriptionInfoList();
    109         for (int i = 0; i < mNumSlots; ++i) {
    110             Preference pref = mSimCards.findPreference("sim" + i);
    111             if (pref instanceof SimPreference) {
    112                 mSimCards.removePreference(pref);
    113             }
    114         }
    115         mAvailableSubInfos.clear();
    116         mSelectableSubInfos.clear();
    117 
    118         for (int i = 0; i < mNumSlots; ++i) {
    119             final SubscriptionInfo sir = mSubscriptionManager
    120                     .getActiveSubscriptionInfoForSimSlotIndex(i);
    121             SimPreference simPreference = new SimPreference(mContext, sir, i);
    122             simPreference.setOrder(i-mNumSlots);
    123             mSimCards.addPreference(simPreference);
    124             mAvailableSubInfos.add(sir);
    125             if (sir != null) {
    126                 mSelectableSubInfos.add(sir);
    127             }
    128         }
    129         updateAllOptions();
    130     }
    131 
    132     private void updateAllOptions() {
    133         updateSimSlotValues();
    134         updateActivitesCategory();
    135     }
    136 
    137     private void updateSimSlotValues() {
    138         final int prefSize = mSimCards.getPreferenceCount();
    139         for (int i = 0; i < prefSize; ++i) {
    140             Preference pref = mSimCards.getPreference(i);
    141             if (pref instanceof SimPreference) {
    142                 ((SimPreference)pref).update();
    143             }
    144         }
    145     }
    146 
    147     private void updateActivitesCategory() {
    148         updateCellularDataValues();
    149         updateCallValues();
    150         updateSmsValues();
    151     }
    152 
    153     private void updateSmsValues() {
    154         final Preference simPref = findPreference(KEY_SMS);
    155         final SubscriptionInfo sir = mSubscriptionManager.getDefaultSmsSubscriptionInfo();
    156         simPref.setTitle(R.string.sms_messages_title);
    157         if (DBG) log("[updateSmsValues] mSubInfoList=" + mSubInfoList);
    158 
    159         if (sir != null) {
    160             simPref.setSummary(sir.getDisplayName());
    161         } else if (sir == null) {
    162             simPref.setSummary(R.string.sim_selection_required_pref);
    163         }
    164         simPref.setEnabled(mSelectableSubInfos.size() >= 1);
    165     }
    166 
    167     private void updateCellularDataValues() {
    168         final Preference simPref = findPreference(KEY_CELLULAR_DATA);
    169         final SubscriptionInfo sir = mSubscriptionManager.getDefaultDataSubscriptionInfo();
    170         simPref.setTitle(R.string.cellular_data_title);
    171         if (DBG) log("[updateCellularDataValues] mSubInfoList=" + mSubInfoList);
    172 
    173         if (sir != null) {
    174             simPref.setSummary(sir.getDisplayName());
    175         } else if (sir == null) {
    176             simPref.setSummary(R.string.sim_selection_required_pref);
    177         }
    178         simPref.setEnabled(mSelectableSubInfos.size() >= 1);
    179     }
    180 
    181     private void updateCallValues() {
    182         final Preference simPref = findPreference(KEY_CALLS);
    183         final TelecomManager telecomManager = TelecomManager.from(mContext);
    184         final PhoneAccountHandle phoneAccount =
    185             telecomManager.getUserSelectedOutgoingPhoneAccount();
    186         final List<PhoneAccountHandle> allPhoneAccounts =
    187             telecomManager.getCallCapablePhoneAccounts();
    188 
    189         simPref.setTitle(R.string.calls_title);
    190         simPref.setSummary(phoneAccount == null
    191                 ? mContext.getResources().getString(R.string.sim_calls_ask_first_prefs_title)
    192                 : (String)telecomManager.getPhoneAccount(phoneAccount).getLabel());
    193         simPref.setEnabled(allPhoneAccounts.size() > 1);
    194     }
    195 
    196     @Override
    197     public void onResume() {
    198         super.onResume();
    199         mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangeListener);
    200         final TelephonyManager tm =
    201                 (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
    202         tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
    203         updateSubscriptions();
    204     }
    205 
    206     @Override
    207     public void onPause() {
    208         super.onPause();
    209         mSubscriptionManager.removeOnSubscriptionsChangedListener(mOnSubscriptionsChangeListener);
    210         final TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    211         tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
    212     }
    213 
    214     private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
    215         // Disable Sim selection for Data when voice call is going on as changing the default data
    216         // sim causes a modem reset currently and call gets disconnected
    217         // ToDo : Add subtext on disabled preference to let user know that default data sim cannot
    218         // be changed while call is going on
    219         @Override
    220         public void onCallStateChanged(int state, String incomingNumber) {
    221             if (DBG) log("PhoneStateListener.onCallStateChanged: state=" + state);
    222              final Preference pref = findPreference(KEY_CELLULAR_DATA);
    223             if (pref != null) {
    224                 final boolean ecbMode = SystemProperties.getBoolean(
    225                         TelephonyProperties.PROPERTY_INECM_MODE, false);
    226                 pref.setEnabled((state == TelephonyManager.CALL_STATE_IDLE) && !ecbMode);
    227             }
    228         }
    229     };
    230 
    231     @Override
    232     public boolean onPreferenceTreeClick(final PreferenceScreen preferenceScreen,
    233             final Preference preference) {
    234         final Context context = mContext;
    235         Intent intent = new Intent(context, SimDialogActivity.class);
    236         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    237 
    238         if (preference instanceof SimPreference) {
    239             Intent newIntent = new Intent(context, SimPreferenceDialog.class);
    240             newIntent.putExtra(EXTRA_SLOT_ID, ((SimPreference)preference).getSlotId());
    241             startActivity(newIntent);
    242         } else if (findPreference(KEY_CELLULAR_DATA) == preference) {
    243             intent.putExtra(SimDialogActivity.DIALOG_TYPE_KEY, SimDialogActivity.DATA_PICK);
    244             context.startActivity(intent);
    245         } else if (findPreference(KEY_CALLS) == preference) {
    246             intent.putExtra(SimDialogActivity.DIALOG_TYPE_KEY, SimDialogActivity.CALLS_PICK);
    247             context.startActivity(intent);
    248         } else if (findPreference(KEY_SMS) == preference) {
    249             intent.putExtra(SimDialogActivity.DIALOG_TYPE_KEY, SimDialogActivity.SMS_PICK);
    250             context.startActivity(intent);
    251         }
    252 
    253         return true;
    254     }
    255 
    256     private class SimPreference extends Preference {
    257         private SubscriptionInfo mSubInfoRecord;
    258         private int mSlotId;
    259         Context mContext;
    260 
    261         public SimPreference(Context context, SubscriptionInfo subInfoRecord, int slotId) {
    262             super(context);
    263 
    264             mContext = context;
    265             mSubInfoRecord = subInfoRecord;
    266             mSlotId = slotId;
    267             setKey("sim" + mSlotId);
    268             update();
    269         }
    270 
    271         public void update() {
    272             final Resources res = mContext.getResources();
    273 
    274             setTitle(String.format(mContext.getResources()
    275                     .getString(R.string.sim_editor_title), (mSlotId + 1)));
    276             if (mSubInfoRecord != null) {
    277                 if (TextUtils.isEmpty(getPhoneNumber(mSubInfoRecord))) {
    278                     setSummary(mSubInfoRecord.getDisplayName());
    279                 } else {
    280                     setSummary(mSubInfoRecord.getDisplayName() + " - " +
    281                             getPhoneNumber(mSubInfoRecord));
    282                     setEnabled(true);
    283                 }
    284                 setIcon(new BitmapDrawable(res, (mSubInfoRecord.createIconBitmap(mContext))));
    285             } else {
    286                 setSummary(R.string.sim_slot_empty);
    287                 setFragment(null);
    288                 setEnabled(false);
    289             }
    290         }
    291 
    292         private int getSlotId() {
    293             return mSlotId;
    294         }
    295     }
    296 
    297     // Returns the line1Number. Line1number should always be read from TelephonyManager since it can
    298     // be overridden for display purposes.
    299     private String getPhoneNumber(SubscriptionInfo info) {
    300         final TelephonyManager tm =
    301             (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
    302         return tm.getLine1NumberForSubscriber(info.getSubscriptionId());
    303     }
    304 
    305     private void log(String s) {
    306         Log.d(TAG, s);
    307     }
    308 
    309     /**
    310      * For search
    311      */
    312     public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
    313             new BaseSearchIndexProvider() {
    314                 @Override
    315                 public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
    316                         boolean enabled) {
    317                     ArrayList<SearchIndexableResource> result =
    318                             new ArrayList<SearchIndexableResource>();
    319 
    320                     if (Utils.showSimCardTile(context)) {
    321                         SearchIndexableResource sir = new SearchIndexableResource(context);
    322                         sir.xmlResId = R.xml.sim_settings;
    323                         result.add(sir);
    324                     }
    325 
    326                     return result;
    327                 }
    328             };
    329 }
    330