2 * Copyright (C) 2014 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.settings.sim;
19 import android.provider.SearchIndexableResource;
20 import com.android.settings.R;
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.telecomm.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;
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;
66 import java.util.ArrayList;
67 import java.util.List;
69 public class SimSettings extends RestrictedSettingsFragment implements Indexable {
70 private static final String TAG = "SimSettings";
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";
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.
84 private List<SubInfoRecord> mAvailableSubInfos = null;
85 private List<SubInfoRecord> mSubInfoList = null;
87 private SubInfoRecord mCellularData = null;
88 private SubInfoRecord mCalls = null;
89 private SubInfoRecord mSMS = null;
93 public SimSettings() {
94 super(DISALLOW_CONFIG_SIM);
98 public void onCreate(final Bundle bundle) {
99 super.onCreate(bundle);
101 if (mSubInfoList == null) {
102 mSubInfoList = SubscriptionManager.getActiveSubInfoList();
109 private void createPreferences() {
110 final TelephonyManager tm =
111 (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
113 addPreferencesFromResource(R.xml.sim_settings);
115 final PreferenceCategory simCards = (PreferenceCategory)findPreference(SIM_CARD_CATEGORY);
117 final int numSlots = tm.getSimCount();
118 mAvailableSubInfos = new ArrayList<SubInfoRecord>(numSlots);
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);
129 updateActivitesCategory();
132 private void updateAllOptions() {
133 updateSimSlotValues();
134 updateActivitesCategory();
137 private void updateSimSlotValues() {
138 SubscriptionManager.getAllSubInfoList();
139 final PreferenceCategory simCards = (PreferenceCategory)findPreference(SIM_CARD_CATEGORY);
140 final PreferenceScreen prefScreen = getPreferenceScreen();
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();
151 private void updateActivitesCategory() {
152 createDropDown((DropDownPreference) findPreference(KEY_CELLULAR_DATA));
153 createDropDown((DropDownPreference) findPreference(KEY_CALLS));
154 createDropDown((DropDownPreference) findPreference(KEY_SMS));
156 updateCellularDataValues();
162 * finds a record with subId.
163 * Since the number of SIMs are few, an array is fine.
165 private SubInfoRecord findRecordBySubId(final long subId) {
166 final int availableSubInfoLength = mAvailableSubInfos.size();
168 for (int i = 0; i < availableSubInfoLength; ++i) {
169 final SubInfoRecord sir = mAvailableSubInfos.get(i);
170 if (sir != null && sir.subId == subId) {
179 * finds a record with slotId.
180 * Since the number of SIMs are few, an array is fine.
182 private SubInfoRecord findRecordBySlotId(final int slotId) {
183 if (mSubInfoList != null){
184 final int availableSubInfoLength = mSubInfoList.size();
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.
198 private void updateSmsValues() {
199 final DropDownPreference simPref = (DropDownPreference) findPreference(KEY_SMS);
200 final SubInfoRecord sir = findRecordBySubId(SubscriptionManager.getDefaultSmsSubId());
202 simPref.setSelectedItem(sir.slotId + 1);
204 simPref.setEnabled(mNumSims > 1);
207 private void updateCellularDataValues() {
208 final DropDownPreference simPref = (DropDownPreference) findPreference(KEY_CELLULAR_DATA);
209 final SubInfoRecord sir = findRecordBySubId(SubscriptionManager.getDefaultDataSubId());
211 simPref.setSelectedItem(sir.slotId);
213 simPref.setEnabled(mNumSims > 1);
216 private void updateCallValues() {
217 final DropDownPreference simPref = (DropDownPreference) findPreference(KEY_CALLS);
218 final SubInfoRecord sir = findRecordBySubId(SubscriptionManager.getDefaultVoiceSubId());
220 simPref.setSelectedItem(sir.slotId + 1);
222 simPref.setEnabled(mNumSims > 1);
226 public void onResume() {
232 public boolean onPreferenceTreeClick(final PreferenceScreen preferenceScreen,
233 final Preference preference) {
234 if (preference instanceof SimPreference) {
235 ((SimPreference)preference).createEditDialog((SimPreference)preference);
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);
246 simPref.clearItems();
249 simPref.addItem(getResources().getString(
250 R.string.sim_calls_ask_first_prefs_title), null);
253 final int subAvailableSize = mAvailableSubInfos.size();
254 for (int i = 0; i < subAvailableSize; ++i) {
255 final SubInfoRecord sir = mAvailableSubInfos.get(i);
257 simPref.addItem(sir.displayName, sir);
261 simPref.setCallback(new DropDownPreference.Callback() {
263 public boolean onItemSelected(int pos, Object value) {
264 final long subId = value == null ? 0 : ((SubInfoRecord)value).subId;
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);
280 private void setActivity(Preference preference, SubInfoRecord sir) {
281 final String key = preference.getKey();
283 if (key.equals(KEY_CELLULAR_DATA)) {
285 } else if (key.equals(KEY_CALLS)) {
287 } else if (key.equals(KEY_SMS)) {
291 updateActivitesCategory();
294 private class SimPreference extends Preference{
295 private SubInfoRecord mSubInfoRecord;
298 public SimPreference(Context context, SubInfoRecord subInfoRecord, int slotId) {
301 mSubInfoRecord = subInfoRecord;
303 setKey("sim" + mSlotId);
307 public void update() {
308 final Resources res = getResources();
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));
316 setSummary(R.string.sim_slot_empty);
322 public void createEditDialog(SimPreference simPref) {
323 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
325 final View dialogLayout = getActivity().getLayoutInflater().inflate(
326 R.layout.multi_sim_dialog, null);
327 builder.setView(dialogLayout);
329 EditText nameText = (EditText)dialogLayout.findViewById(R.id.sim_name);
330 nameText.setText(mSubInfoRecord.displayName);
332 TextView numberView = (TextView)dialogLayout.findViewById(R.id.number);
333 numberView.setText(mSubInfoRecord.number);
335 TextView carrierView = (TextView)dialogLayout.findViewById(R.id.carrier);
336 carrierView.setText(mSubInfoRecord.displayName);
338 builder.setTitle(R.string.sim_editor_title);
340 builder.setPositiveButton(R.string.okay, new DialogInterface.OnClickListener() {
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);
347 SubscriptionManager.setDisplayNumberFormat(
348 displayNumbers.getSelectedItemPosition() == 0
349 ? SubscriptionManager.DISPLAY_NUMBER_LAST
350 : SubscriptionManager.DISPLAY_NUMBER_FIRST, mSubInfoRecord.subId);
352 mSubInfoRecord.displayName = nameText.getText().toString();
353 SubscriptionManager.setDisplayName(mSubInfoRecord.displayName,
354 mSubInfoRecord.subId);
361 builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
363 public void onClick(DialogInterface dialog, int whichButton) {
368 builder.create().show();
375 public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
376 new BaseSearchIndexProvider() {
378 public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
380 ArrayList<SearchIndexableResource> result =
381 new ArrayList<SearchIndexableResource>();
383 if (Utils.showSimCardTile(context)) {
384 SearchIndexableResource sir = new SearchIndexableResource(context);
385 sir.xmlResId = R.xml.sim_settings;