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.provider.SearchIndexableResource;
     20 import com.android.settings.R;
     21 
     22 import android.app.AlertDialog;
     23 import android.content.BroadcastReceiver;
     24 import android.content.Context;
     25 import android.content.Intent;
     26 import android.content.IntentFilter;
     27 import android.content.DialogInterface;
     28 import android.content.res.Resources;
     29 import android.os.Bundle;
     30 import android.os.IBinder;
     31 import android.os.RemoteException;
     32 import android.os.UserHandle;
     33 import android.preference.ListPreference;
     34 import android.preference.Preference;
     35 import android.preference.PreferenceCategory;
     36 import android.preference.Preference.OnPreferenceChangeListener;
     37 import android.preference.PreferenceScreen;
     38 import android.telephony.SubInfoRecord;
     39 import android.telephony.SubscriptionManager;
     40 import android.telephony.TelephonyManager;
     41 import android.telecom.PhoneAccount;
     42 import android.telephony.CellInfo;
     43 import android.text.TextUtils;
     44 import android.util.Log;
     45 import android.view.LayoutInflater;
     46 import android.view.View;
     47 import android.widget.ArrayAdapter;
     48 import android.widget.EditText;
     49 import android.widget.FrameLayout;
     50 import android.widget.ImageView;
     51 import android.widget.ListView;
     52 import android.widget.Spinner;
     53 import android.widget.TextView;
     54 
     55 import com.android.internal.telephony.PhoneConstants;
     56 import com.android.internal.telephony.TelephonyIntents;
     57 import com.android.settings.RestrictedSettingsFragment;
     58 import com.android.settings.SettingsPreferenceFragment;
     59 import com.android.settings.Utils;
     60 import com.android.settings.notification.DropDownPreference;
     61 import com.android.settings.search.BaseSearchIndexProvider;
     62 import com.android.settings.search.Indexable;
     63 import com.android.settings.search.Indexable.SearchIndexProvider;
     64 import com.android.settings.search.SearchIndexableRaw;
     65 
     66 import java.util.ArrayList;
     67 import java.util.List;
     68 
     69 public class SimSettings extends RestrictedSettingsFragment implements Indexable {
     70     private static final String TAG = "SimSettings";
     71 
     72     private static final String DISALLOW_CONFIG_SIM = "no_config_sim";
     73     private static final String SIM_CARD_CATEGORY = "sim_cards";
     74     private static final String KEY_CELLULAR_DATA = "sim_cellular_data";
     75     private static final String KEY_CALLS = "sim_calls";
     76     private static final String KEY_SMS = "sim_sms";
     77     private static final String KEY_ACTIVITIES = "activities";
     78 
     79     /**
     80      * By UX design we have use only one Subscription Information(SubInfo) record per SIM slot.
     81      * mAvalableSubInfos is the list of SubInfos we present to the user.
     82      * mSubInfoList is the list of all SubInfos.
     83      */
     84     private List<SubInfoRecord> mAvailableSubInfos = null;
     85     private List<SubInfoRecord> mSubInfoList = null;
     86 
     87     private SubInfoRecord mCellularData = null;
     88     private SubInfoRecord mCalls = null;
     89     private SubInfoRecord mSMS = null;
     90 
     91     private int mNumSims;
     92 
     93     public SimSettings() {
     94         super(DISALLOW_CONFIG_SIM);
     95     }
     96 
     97     @Override
     98     public void onCreate(final Bundle bundle) {
     99         super.onCreate(bundle);
    100 
    101         if (mSubInfoList == null) {
    102             mSubInfoList = SubscriptionManager.getActiveSubInfoList();
    103         }
    104 
    105         createPreferences();
    106         updateAllOptions();
    107     }
    108 
    109     private void createPreferences() {
    110         final TelephonyManager tm =
    111             (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
    112 
    113         addPreferencesFromResource(R.xml.sim_settings);
    114 
    115         final PreferenceCategory simCards = (PreferenceCategory)findPreference(SIM_CARD_CATEGORY);
    116 
    117         final int numSlots = tm.getSimCount();
    118         mAvailableSubInfos = new ArrayList<SubInfoRecord>(numSlots);
    119         mNumSims = 0;
    120         for (int i = 0; i < numSlots; ++i) {
    121             final SubInfoRecord sir = findRecordBySlotId(i);
    122             simCards.addPreference(new SimPreference(getActivity(), sir, i));
    123             mAvailableSubInfos.add(sir);
    124             if (sir != null) {
    125                 mNumSims++;
    126             }
    127         }
    128 
    129         updateActivitesCategory();
    130     }
    131 
    132     private void updateAllOptions() {
    133         updateSimSlotValues();
    134         updateActivitesCategory();
    135     }
    136 
    137     private void updateSimSlotValues() {
    138         SubscriptionManager.getAllSubInfoList();
    139         final PreferenceCategory simCards = (PreferenceCategory)findPreference(SIM_CARD_CATEGORY);
    140         final PreferenceScreen prefScreen = getPreferenceScreen();
    141 
    142         final int prefSize = prefScreen.getPreferenceCount();
    143         for (int i = 0; i < prefSize; ++i) {
    144             Preference pref = prefScreen.getPreference(i);
    145             if (pref instanceof SimPreference) {
    146                 ((SimPreference)pref).update();
    147             }
    148         }
    149     }
    150 
    151     private void updateActivitesCategory() {
    152         createDropDown((DropDownPreference) findPreference(KEY_CELLULAR_DATA));
    153         createDropDown((DropDownPreference) findPreference(KEY_CALLS));
    154         createDropDown((DropDownPreference) findPreference(KEY_SMS));
    155 
    156         updateCellularDataValues();
    157         updateCallValues();
    158         updateSmsValues();
    159     }
    160 
    161     /**
    162      * finds a record with subId.
    163      * Since the number of SIMs are few, an array is fine.
    164      */
    165     private SubInfoRecord findRecordBySubId(final long subId) {
    166         final int availableSubInfoLength = mAvailableSubInfos.size();
    167 
    168         for (int i = 0; i < availableSubInfoLength; ++i) {
    169             final SubInfoRecord sir = mAvailableSubInfos.get(i);
    170             if (sir != null && sir.subId == subId) {
    171                 return sir;
    172             }
    173         }
    174 
    175         return null;
    176     }
    177 
    178     /**
    179      * finds a record with slotId.
    180      * Since the number of SIMs are few, an array is fine.
    181      */
    182     private SubInfoRecord findRecordBySlotId(final int slotId) {
    183         if (mSubInfoList != null){
    184             final int availableSubInfoLength = mSubInfoList.size();
    185 
    186             for (int i = 0; i < availableSubInfoLength; ++i) {
    187                 final SubInfoRecord sir = mSubInfoList.get(i);
    188                 if (sir.slotId == slotId) {
    189                     //Right now we take the first subscription on a SIM.
    190                     return sir;
    191                 }
    192             }
    193         }
    194 
    195         return null;
    196     }
    197 
    198     private void updateSmsValues() {
    199         final DropDownPreference simPref = (DropDownPreference) findPreference(KEY_SMS);
    200         final SubInfoRecord sir = findRecordBySubId(SubscriptionManager.getDefaultSmsSubId());
    201         if (sir != null) {
    202             simPref.setSelectedItem(sir.slotId + 1);
    203         }
    204         simPref.setEnabled(mNumSims > 1);
    205     }
    206 
    207     private void updateCellularDataValues() {
    208         final DropDownPreference simPref = (DropDownPreference) findPreference(KEY_CELLULAR_DATA);
    209         final SubInfoRecord sir = findRecordBySubId(SubscriptionManager.getDefaultDataSubId());
    210         if (sir != null) {
    211             simPref.setSelectedItem(sir.slotId);
    212         }
    213         simPref.setEnabled(mNumSims > 1);
    214     }
    215 
    216     private void updateCallValues() {
    217         final DropDownPreference simPref = (DropDownPreference) findPreference(KEY_CALLS);
    218         final SubInfoRecord sir = findRecordBySubId(SubscriptionManager.getDefaultVoiceSubId());
    219         if (sir != null) {
    220             simPref.setSelectedItem(sir.slotId + 1);
    221         }
    222         simPref.setEnabled(mNumSims > 1);
    223     }
    224 
    225     @Override
    226     public void onResume() {
    227         super.onResume();
    228         updateAllOptions();
    229     }
    230 
    231     @Override
    232     public boolean onPreferenceTreeClick(final PreferenceScreen preferenceScreen,
    233             final Preference preference) {
    234         if (preference instanceof SimPreference) {
    235             ((SimPreference)preference).createEditDialog((SimPreference)preference);
    236         }
    237 
    238         return true;
    239     }
    240 
    241     public void createDropDown(DropDownPreference preference) {
    242         final DropDownPreference simPref = preference;
    243         final String keyPref = simPref.getKey();
    244         final boolean askFirst = keyPref.equals(KEY_CALLS) || keyPref.equals(KEY_SMS);
    245 
    246         simPref.clearItems();
    247 
    248         if (askFirst) {
    249             simPref.addItem(getResources().getString(
    250                     R.string.sim_calls_ask_first_prefs_title), null);
    251         }
    252 
    253         final int subAvailableSize = mAvailableSubInfos.size();
    254         for (int i = 0; i < subAvailableSize; ++i) {
    255             final SubInfoRecord sir = mAvailableSubInfos.get(i);
    256             if(sir != null){
    257                 simPref.addItem(sir.displayName, sir);
    258             }
    259         }
    260 
    261         simPref.setCallback(new DropDownPreference.Callback() {
    262             @Override
    263             public boolean onItemSelected(int pos, Object value) {
    264                 final long subId = value == null ? 0 : ((SubInfoRecord)value).subId;
    265 
    266                 if (simPref.getKey().equals(KEY_CELLULAR_DATA)) {
    267                     SubscriptionManager.setDefaultDataSubId(subId);
    268                 } else if (simPref.getKey().equals(KEY_CALLS)) {
    269                     SubscriptionManager.setDefaultVoiceSubId(subId);
    270                 } else if (simPref.getKey().equals(KEY_SMS)) {
    271                     // TODO: uncomment once implemented. Bug: 16520931
    272                     // SubscriptionManager.setDefaultSMSSubId(subId);
    273                 }
    274 
    275                 return true;
    276             }
    277         });
    278     }
    279 
    280     private void setActivity(Preference preference, SubInfoRecord sir) {
    281         final String key = preference.getKey();
    282 
    283         if (key.equals(KEY_CELLULAR_DATA)) {
    284             mCellularData = sir;
    285         } else if (key.equals(KEY_CALLS)) {
    286             mCalls = sir;
    287         } else if (key.equals(KEY_SMS)) {
    288             mSMS = sir;
    289         }
    290 
    291         updateActivitesCategory();
    292     }
    293 
    294     private class SimPreference extends Preference{
    295         private SubInfoRecord mSubInfoRecord;
    296         private int mSlotId;
    297 
    298         public SimPreference(Context context, SubInfoRecord subInfoRecord, int slotId) {
    299             super(context);
    300 
    301             mSubInfoRecord = subInfoRecord;
    302             mSlotId = slotId;
    303             setKey("sim" + mSlotId);
    304             update();
    305         }
    306 
    307         public void update() {
    308             final Resources res = getResources();
    309 
    310             setTitle(res.getString(R.string.sim_card_number_title, mSlotId + 1));
    311             if (mSubInfoRecord != null) {
    312                 setSummary(res.getString(R.string.sim_settings_summary,
    313                             mSubInfoRecord.displayName, mSubInfoRecord.number));
    314                 setEnabled(true);
    315             } else {
    316                 setSummary(R.string.sim_slot_empty);
    317                 setFragment(null);
    318                 setEnabled(false);
    319             }
    320         }
    321 
    322         public void createEditDialog(SimPreference simPref) {
    323             AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    324 
    325             final View dialogLayout = getActivity().getLayoutInflater().inflate(
    326                     R.layout.multi_sim_dialog, null);
    327             builder.setView(dialogLayout);
    328 
    329             EditText nameText = (EditText)dialogLayout.findViewById(R.id.sim_name);
    330             nameText.setText(mSubInfoRecord.displayName);
    331 
    332             TextView numberView = (TextView)dialogLayout.findViewById(R.id.number);
    333             numberView.setText(mSubInfoRecord.number);
    334 
    335             TextView carrierView = (TextView)dialogLayout.findViewById(R.id.carrier);
    336             carrierView.setText(mSubInfoRecord.displayName);
    337 
    338             builder.setTitle(R.string.sim_editor_title);
    339 
    340             builder.setPositiveButton(R.string.okay, new DialogInterface.OnClickListener() {
    341                 @Override
    342                 public void onClick(DialogInterface dialog, int whichButton) {
    343                     final EditText nameText = (EditText)dialogLayout.findViewById(R.id.sim_name);
    344                     final Spinner displayNumbers =
    345                         (Spinner)dialogLayout.findViewById(R.id.display_numbers);
    346 
    347                     SubscriptionManager.setDisplayNumberFormat(
    348                         displayNumbers.getSelectedItemPosition() == 0
    349                             ? SubscriptionManager.DISPLAY_NUMBER_LAST
    350                             : SubscriptionManager.DISPLAY_NUMBER_FIRST, mSubInfoRecord.subId);
    351 
    352                     mSubInfoRecord.displayName = nameText.getText().toString();
    353                     SubscriptionManager.setDisplayName(mSubInfoRecord.displayName,
    354                         mSubInfoRecord.subId);
    355 
    356                     updateAllOptions();
    357                     update();
    358                 }
    359             });
    360 
    361             builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
    362                 @Override
    363                 public void onClick(DialogInterface dialog, int whichButton) {
    364                     dialog.dismiss();
    365                 }
    366             });
    367 
    368             builder.create().show();
    369         }
    370     }
    371 
    372     /**
    373      * For search
    374      */
    375     public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
    376             new BaseSearchIndexProvider() {
    377                 @Override
    378                 public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
    379                         boolean enabled) {
    380                     ArrayList<SearchIndexableResource> result =
    381                             new ArrayList<SearchIndexableResource>();
    382 
    383                     if (Utils.showSimCardTile(context)) {
    384                         SearchIndexableResource sir = new SearchIndexableResource(context);
    385                         sir.xmlResId = R.xml.sim_settings;
    386                         result.add(sir);
    387                     }
    388 
    389                     return result;
    390                 }
    391             };
    392 
    393 }
    394