SimSettings.java revision 86e452f9577e37dfae4f7160a28448b66084e5d9
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
17package com.android.settings.sim;
18
19import android.provider.SearchIndexableResource;
20import com.android.settings.R;
21
22import android.app.AlertDialog;
23import android.content.BroadcastReceiver;
24import android.content.Context;
25import android.content.Intent;
26import android.content.IntentFilter;
27import android.content.DialogInterface;
28import android.content.res.Resources;
29import android.os.Bundle;
30import android.os.IBinder;
31import android.os.RemoteException;
32import android.os.UserHandle;
33import android.preference.ListPreference;
34import android.preference.Preference;
35import android.preference.PreferenceCategory;
36import android.preference.Preference.OnPreferenceChangeListener;
37import android.preference.PreferenceScreen;
38import android.telephony.SubInfoRecord;
39import android.telephony.SubscriptionManager;
40import android.telephony.TelephonyManager;
41import android.telecom.PhoneAccount;
42import android.telephony.CellInfo;
43import android.text.TextUtils;
44import android.util.Log;
45import android.view.LayoutInflater;
46import android.view.View;
47import android.widget.ArrayAdapter;
48import android.widget.EditText;
49import android.widget.FrameLayout;
50import android.widget.ImageView;
51import android.widget.ListView;
52import android.widget.Spinner;
53import android.widget.TextView;
54
55import com.android.internal.telephony.PhoneConstants;
56import com.android.internal.telephony.TelephonyIntents;
57import com.android.settings.RestrictedSettingsFragment;
58import com.android.settings.SettingsPreferenceFragment;
59import com.android.settings.Utils;
60import com.android.settings.notification.DropDownPreference;
61import com.android.settings.search.BaseSearchIndexProvider;
62import com.android.settings.search.Indexable;
63import com.android.settings.search.Indexable.SearchIndexProvider;
64import com.android.settings.search.SearchIndexableRaw;
65
66import java.util.ArrayList;
67import java.util.List;
68
69public 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                    SubscriptionManager.setDefaultSmsSubId(subId);
272                }
273
274                return true;
275            }
276        });
277    }
278
279    private void setActivity(Preference preference, SubInfoRecord sir) {
280        final String key = preference.getKey();
281
282        if (key.equals(KEY_CELLULAR_DATA)) {
283            mCellularData = sir;
284        } else if (key.equals(KEY_CALLS)) {
285            mCalls = sir;
286        } else if (key.equals(KEY_SMS)) {
287            mSMS = sir;
288        }
289
290        updateActivitesCategory();
291    }
292
293    private class SimPreference extends Preference{
294        private SubInfoRecord mSubInfoRecord;
295        private int mSlotId;
296
297        public SimPreference(Context context, SubInfoRecord subInfoRecord, int slotId) {
298            super(context);
299
300            mSubInfoRecord = subInfoRecord;
301            mSlotId = slotId;
302            setKey("sim" + mSlotId);
303            update();
304        }
305
306        public void update() {
307            final Resources res = getResources();
308
309            setTitle(res.getString(R.string.sim_card_number_title, mSlotId + 1));
310            if (mSubInfoRecord != null) {
311                setSummary(res.getString(R.string.sim_settings_summary,
312                            mSubInfoRecord.displayName, mSubInfoRecord.number));
313                setEnabled(true);
314            } else {
315                setSummary(R.string.sim_slot_empty);
316                setFragment(null);
317                setEnabled(false);
318            }
319        }
320
321        public void createEditDialog(SimPreference simPref) {
322            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
323
324            final View dialogLayout = getActivity().getLayoutInflater().inflate(
325                    R.layout.multi_sim_dialog, null);
326            builder.setView(dialogLayout);
327
328            EditText nameText = (EditText)dialogLayout.findViewById(R.id.sim_name);
329            nameText.setText(mSubInfoRecord.displayName);
330
331            TextView numberView = (TextView)dialogLayout.findViewById(R.id.number);
332            numberView.setText(mSubInfoRecord.number);
333
334            TextView carrierView = (TextView)dialogLayout.findViewById(R.id.carrier);
335            carrierView.setText(mSubInfoRecord.displayName);
336
337            builder.setTitle(R.string.sim_editor_title);
338
339            builder.setPositiveButton(R.string.okay, new DialogInterface.OnClickListener() {
340                @Override
341                public void onClick(DialogInterface dialog, int whichButton) {
342                    final EditText nameText = (EditText)dialogLayout.findViewById(R.id.sim_name);
343                    final Spinner displayNumbers =
344                        (Spinner)dialogLayout.findViewById(R.id.display_numbers);
345
346                    SubscriptionManager.setDisplayNumberFormat(
347                        displayNumbers.getSelectedItemPosition() == 0
348                            ? SubscriptionManager.DISPLAY_NUMBER_LAST
349                            : SubscriptionManager.DISPLAY_NUMBER_FIRST, mSubInfoRecord.subId);
350
351                    mSubInfoRecord.displayName = nameText.getText().toString();
352                    SubscriptionManager.setDisplayName(mSubInfoRecord.displayName,
353                        mSubInfoRecord.subId);
354
355                    updateAllOptions();
356                    update();
357                }
358            });
359
360            builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
361                @Override
362                public void onClick(DialogInterface dialog, int whichButton) {
363                    dialog.dismiss();
364                }
365            });
366
367            builder.create().show();
368        }
369    }
370
371    /**
372     * For search
373     */
374    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
375            new BaseSearchIndexProvider() {
376                @Override
377                public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
378                        boolean enabled) {
379                    ArrayList<SearchIndexableResource> result =
380                            new ArrayList<SearchIndexableResource>();
381
382                    if (Utils.showSimCardTile(context)) {
383                        SearchIndexableResource sir = new SearchIndexableResource(context);
384                        sir.xmlResId = R.xml.sim_settings;
385                        result.add(sir);
386                    }
387
388                    return result;
389                }
390            };
391
392}
393