OSDN Git Service

[Fingerprint] Remove learn more link if not provisioned. DO NOT MERGE
[android-x86/packages-apps-Settings.git] / src / com / android / settings / deviceinfo / SimStatus.java
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.deviceinfo;
18
19 import android.content.BroadcastReceiver;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.IntentFilter;
23 import android.content.pm.PackageManager.NameNotFoundException;
24 import android.content.res.Resources;
25 import android.os.Bundle;
26 import android.os.UserHandle;
27 import android.preference.Preference;
28 import android.preference.PreferenceActivity;
29 import android.telephony.CellBroadcastMessage;
30 import android.telephony.PhoneNumberUtils;
31 import android.telephony.PhoneStateListener;
32 import android.telephony.ServiceState;
33 import android.telephony.SignalStrength;
34 import android.telephony.SubscriptionInfo;
35 import android.telephony.SubscriptionManager;
36 import android.telephony.TelephonyManager;
37 import android.text.TextUtils;
38 import android.util.Log;
39
40 import com.android.internal.logging.MetricsLogger;
41 import com.android.internal.telephony.DefaultPhoneNotifier;
42 import com.android.internal.telephony.Phone;
43 import com.android.internal.telephony.PhoneFactory;
44 import com.android.settings.InstrumentedPreferenceActivity;
45 import com.android.settings.R;
46 import com.android.settings.Utils;
47
48 import android.view.View;
49 import android.widget.ListView;
50 import android.widget.TabHost;
51 import android.widget.TabHost.OnTabChangeListener;
52 import android.widget.TabHost.TabContentFactory;
53 import android.widget.TabHost.TabSpec;
54 import android.widget.TabWidget;
55
56 import java.util.ArrayList;
57 import java.util.List;
58
59
60 /**
61  * Display the following information
62  * # Phone Number
63  * # Network
64  * # Roaming
65  * # Device Id (IMEI in GSM and MEID in CDMA)
66  * # Network type
67  * # Operator info (area info cell broadcast for Brazil)
68  * # Signal Strength
69  *
70  */
71 public class SimStatus extends InstrumentedPreferenceActivity {
72     private static final String TAG = "SimStatus";
73
74     private static final String KEY_DATA_STATE = "data_state";
75     private static final String KEY_SERVICE_STATE = "service_state";
76     private static final String KEY_OPERATOR_NAME = "operator_name";
77     private static final String KEY_ROAMING_STATE = "roaming_state";
78     private static final String KEY_NETWORK_TYPE = "network_type";
79     private static final String KEY_LATEST_AREA_INFO = "latest_area_info";
80     private static final String KEY_PHONE_NUMBER = "number";
81     private static final String KEY_SIGNAL_STRENGTH = "signal_strength";
82     private static final String KEY_IMEI = "imei";
83     private static final String KEY_IMEI_SV = "imei_sv";
84     private static final String COUNTRY_ABBREVIATION_BRAZIL = "br";
85
86     static final String CB_AREA_INFO_RECEIVED_ACTION =
87             "android.cellbroadcastreceiver.CB_AREA_INFO_RECEIVED";
88
89     static final String GET_LATEST_CB_AREA_INFO_ACTION =
90             "android.cellbroadcastreceiver.GET_LATEST_CB_AREA_INFO";
91
92     // Require the sender to have this permission to prevent third-party spoofing.
93     static final String CB_AREA_INFO_SENDER_PERMISSION =
94             "android.permission.RECEIVE_EMERGENCY_BROADCAST";
95
96
97     private TelephonyManager mTelephonyManager;
98     private Phone mPhone = null;
99     private Resources mRes;
100     private Preference mSignalStrength;
101     private SubscriptionInfo mSir;
102     private boolean mShowLatestAreaInfo;
103
104     // Default summary for items
105     private String mDefaultText;
106
107     private TabHost mTabHost;
108     private TabWidget mTabWidget;
109     private ListView mListView;
110     private List<SubscriptionInfo> mSelectableSubInfos;
111
112     private PhoneStateListener mPhoneStateListener;
113     private BroadcastReceiver mAreaInfoReceiver = new BroadcastReceiver() {
114         @Override
115         public void onReceive(Context context, Intent intent) {
116             String action = intent.getAction();
117             if (CB_AREA_INFO_RECEIVED_ACTION.equals(action)) {
118                 Bundle extras = intent.getExtras();
119                 if (extras == null) {
120                     return;
121                 }
122                 CellBroadcastMessage cbMessage = (CellBroadcastMessage) extras.get("message");
123                 if (cbMessage != null
124                         && cbMessage.getServiceCategory() == 50
125                         && mSir.getSubscriptionId() == cbMessage.getSubId()) {
126                     String latestAreaInfo = cbMessage.getMessageBody();
127                     updateAreaInfo(latestAreaInfo);
128                 }
129             }
130         }
131     };
132
133     @Override
134     protected void onCreate(Bundle icicle) {
135         super.onCreate(icicle);
136         mTelephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
137
138         mSelectableSubInfos = SubscriptionManager.from(this).getActiveSubscriptionInfoList();
139
140         addPreferencesFromResource(R.xml.device_info_sim_status);
141
142         mRes = getResources();
143         mDefaultText = mRes.getString(R.string.device_info_default);
144         // Note - missing in zaku build, be careful later...
145         mSignalStrength = findPreference(KEY_SIGNAL_STRENGTH);
146
147         if (mSelectableSubInfos == null) {
148             mSir = null;
149         } else {
150             mSir = mSelectableSubInfos.size() > 0 ? mSelectableSubInfos.get(0) : null;
151
152             if (mSelectableSubInfos.size() > 1) {
153                 setContentView(com.android.internal.R.layout.common_tab_settings);
154
155                 mTabHost = (TabHost) findViewById(android.R.id.tabhost);
156                 mTabWidget = (TabWidget) findViewById(android.R.id.tabs);
157                 mListView = (ListView) findViewById(android.R.id.list);
158
159                 mTabHost.setup();
160                 mTabHost.setOnTabChangedListener(mTabListener);
161                 mTabHost.clearAllTabs();
162
163                 for (int i = 0; i < mSelectableSubInfos.size(); i++) {
164                     mTabHost.addTab(buildTabSpec(String.valueOf(i),
165                             String.valueOf(mSelectableSubInfos.get(i).getDisplayName())));
166                 }
167             }
168         }
169         updatePhoneInfos();
170     }
171
172     @Override
173     protected int getMetricsCategory() {
174         return MetricsLogger.DEVICEINFO_SIM_STATUS;
175     }
176
177     @Override
178     protected void onResume() {
179         super.onResume();
180         if (mPhone != null) {
181             updatePreference();
182
183             updateSignalStrength(mPhone.getSignalStrength());
184             updateServiceState(mPhone.getServiceState());
185             updateDataState();
186             mTelephonyManager.listen(mPhoneStateListener,
187                     PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
188                     | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
189                     | PhoneStateListener.LISTEN_SERVICE_STATE);
190             if (mShowLatestAreaInfo) {
191                 registerReceiver(mAreaInfoReceiver, new IntentFilter(CB_AREA_INFO_RECEIVED_ACTION),
192                         CB_AREA_INFO_SENDER_PERMISSION, null);
193                 // Ask CellBroadcastReceiver to broadcast the latest area info received
194                 Intent getLatestIntent = new Intent(GET_LATEST_CB_AREA_INFO_ACTION);
195                 sendBroadcastAsUser(getLatestIntent, UserHandle.ALL,
196                         CB_AREA_INFO_SENDER_PERMISSION);
197             }
198         }
199     }
200
201     @Override
202     public void onPause() {
203         super.onPause();
204
205         if (mPhone != null) {
206             mTelephonyManager.listen(mPhoneStateListener,
207                     PhoneStateListener.LISTEN_NONE);
208         }
209         if (mShowLatestAreaInfo) {
210             unregisterReceiver(mAreaInfoReceiver);
211         }
212     }
213
214     /**
215      * Removes the specified preference, if it exists.
216      * @param key the key for the Preference item
217      */
218     private void removePreferenceFromScreen(String key) {
219         Preference pref = findPreference(key);
220         if (pref != null) {
221             getPreferenceScreen().removePreference(pref);
222         }
223     }
224
225     private void setSummaryText(String key, String text) {
226         if (TextUtils.isEmpty(text)) {
227             text = mDefaultText;
228         }
229         // some preferences may be missing
230         final Preference preference = findPreference(key);
231         if (preference != null) {
232             preference.setSummary(text);
233         }
234     }
235
236     private void updateNetworkType() {
237         // Whether EDGE, UMTS, etc...
238         String networktype = null;
239         final int subId = mSir.getSubscriptionId();
240         final int actualDataNetworkType = mTelephonyManager.getDataNetworkType(
241                 mSir.getSubscriptionId());
242         final int actualVoiceNetworkType = mTelephonyManager.getVoiceNetworkType(
243                 mSir.getSubscriptionId());
244         if (TelephonyManager.NETWORK_TYPE_UNKNOWN != actualDataNetworkType) {
245             networktype = mTelephonyManager.getNetworkTypeName(actualDataNetworkType);
246         } else if (TelephonyManager.NETWORK_TYPE_UNKNOWN != actualVoiceNetworkType) {
247             networktype = mTelephonyManager.getNetworkTypeName(actualVoiceNetworkType);
248         }
249
250         boolean show4GForLTE = false;
251         try {
252             Context con = createPackageContext("com.android.systemui", 0);
253             int id = con.getResources().getIdentifier("config_show4GForLTE",
254                     "bool", "com.android.systemui");
255             show4GForLTE = con.getResources().getBoolean(id);
256         } catch (NameNotFoundException e) {
257             Log.e(TAG, "NameNotFoundException for show4GFotLTE");
258         }
259
260         if (networktype != null && networktype.equals("LTE") && show4GForLTE) {
261             networktype = "4G";
262         }
263         setSummaryText(KEY_NETWORK_TYPE, networktype);
264     }
265
266     private void updateDataState() {
267         final int state =
268                 DefaultPhoneNotifier.convertDataState(mPhone.getDataConnectionState());
269
270         String display = mRes.getString(R.string.radioInfo_unknown);
271
272         switch (state) {
273             case TelephonyManager.DATA_CONNECTED:
274                 display = mRes.getString(R.string.radioInfo_data_connected);
275                 break;
276             case TelephonyManager.DATA_SUSPENDED:
277                 display = mRes.getString(R.string.radioInfo_data_suspended);
278                 break;
279             case TelephonyManager.DATA_CONNECTING:
280                 display = mRes.getString(R.string.radioInfo_data_connecting);
281                 break;
282             case TelephonyManager.DATA_DISCONNECTED:
283                 display = mRes.getString(R.string.radioInfo_data_disconnected);
284                 break;
285         }
286
287         setSummaryText(KEY_DATA_STATE, display);
288     }
289
290     private void updateServiceState(ServiceState serviceState) {
291         final int state = serviceState.getState();
292         String display = mRes.getString(R.string.radioInfo_unknown);
293
294         switch (state) {
295             case ServiceState.STATE_IN_SERVICE:
296                 display = mRes.getString(R.string.radioInfo_service_in);
297                 break;
298             case ServiceState.STATE_OUT_OF_SERVICE:
299                 // Set signal strength to 0 when service state is STATE_OUT_OF_SERVICE
300                 mSignalStrength.setSummary("0");
301             case ServiceState.STATE_EMERGENCY_ONLY:
302                 // Set summary string of service state to radioInfo_service_out when
303                 // service state is both STATE_OUT_OF_SERVICE & STATE_EMERGENCY_ONLY
304                 display = mRes.getString(R.string.radioInfo_service_out);
305                 break;
306             case ServiceState.STATE_POWER_OFF:
307                 display = mRes.getString(R.string.radioInfo_service_off);
308                 // Also set signal strength to 0
309                 mSignalStrength.setSummary("0");
310                 break;
311         }
312
313         setSummaryText(KEY_SERVICE_STATE, display);
314
315         if (serviceState.getRoaming()) {
316             setSummaryText(KEY_ROAMING_STATE, mRes.getString(R.string.radioInfo_roaming_in));
317         } else {
318             setSummaryText(KEY_ROAMING_STATE, mRes.getString(R.string.radioInfo_roaming_not));
319         }
320         setSummaryText(KEY_OPERATOR_NAME, serviceState.getOperatorAlphaLong());
321     }
322
323     private void updateAreaInfo(String areaInfo) {
324         if (areaInfo != null) {
325             setSummaryText(KEY_LATEST_AREA_INFO, areaInfo);
326         }
327     }
328
329     void updateSignalStrength(SignalStrength signalStrength) {
330         if (mSignalStrength != null) {
331             final int state = mPhone.getServiceState().getState();
332             Resources r = getResources();
333
334             if ((ServiceState.STATE_OUT_OF_SERVICE == state) ||
335                     (ServiceState.STATE_POWER_OFF == state)) {
336                 mSignalStrength.setSummary("0");
337                 return;
338             }
339
340             int signalDbm = signalStrength.getDbm();
341             int signalAsu = signalStrength.getAsuLevel();
342
343             if (-1 == signalDbm) {
344                 signalDbm = 0;
345             }
346
347             if (-1 == signalAsu) {
348                 signalAsu = 0;
349             }
350
351             mSignalStrength.setSummary(r.getString(R.string.sim_signal_strength,
352                         signalDbm, signalAsu));
353         }
354     }
355
356     private void updatePreference() {
357         if (mPhone.getPhoneType() != TelephonyManager.PHONE_TYPE_CDMA) {
358             // only show area info when SIM country is Brazil
359             if (COUNTRY_ABBREVIATION_BRAZIL.equals(mTelephonyManager.getSimCountryIso(
360                             mSir.getSubscriptionId()))) {
361                 mShowLatestAreaInfo = true;
362             }
363         }
364
365         String rawNumber = mTelephonyManager.getLine1NumberForSubscriber(mSir.getSubscriptionId());
366         String formattedNumber = null;
367         if (!TextUtils.isEmpty(rawNumber)) {
368             formattedNumber = PhoneNumberUtils.formatNumber(rawNumber);
369         }
370         // If formattedNumber is null or empty, it'll display as "Unknown".
371         setSummaryText(KEY_PHONE_NUMBER, formattedNumber);
372         setSummaryText(KEY_IMEI, mPhone.getImei());
373         setSummaryText(KEY_IMEI_SV, mPhone.getDeviceSvn());
374
375         if (!mShowLatestAreaInfo) {
376             removePreferenceFromScreen(KEY_LATEST_AREA_INFO);
377         }
378     }
379
380     private void updatePhoneInfos() {
381         if (mSir != null) {
382             final Phone phone = PhoneFactory.getPhone(SubscriptionManager.getPhoneId(
383                         mSir.getSubscriptionId()));
384             if (UserHandle.myUserId() == UserHandle.USER_OWNER
385                     && SubscriptionManager.isValidSubscriptionId(mSir.getSubscriptionId())) {
386                 if (phone == null) {
387                     Log.e(TAG, "Unable to locate a phone object for the given Subscription ID.");
388                     return;
389                 }
390
391                 mPhone = phone;
392                 mPhoneStateListener = new PhoneStateListener(mSir.getSubscriptionId()) {
393                     @Override
394                     public void onDataConnectionStateChanged(int state) {
395                         updateDataState();
396                         updateNetworkType();
397                     }
398
399                     @Override
400                     public void onSignalStrengthsChanged(SignalStrength signalStrength) {
401                         updateSignalStrength(signalStrength);
402                     }
403
404                     @Override
405                     public void onServiceStateChanged(ServiceState serviceState) {
406                         updateServiceState(serviceState);
407                     }
408                 };
409             }
410         }
411     }
412     private OnTabChangeListener mTabListener = new OnTabChangeListener() {
413         @Override
414         public void onTabChanged(String tabId) {
415             final int slotId = Integer.parseInt(tabId);
416             mSir = mSelectableSubInfos.get(slotId);
417
418             // The User has changed tab; update the SIM information.
419             updatePhoneInfos();
420             mTelephonyManager.listen(mPhoneStateListener,
421                     PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
422                     | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
423                     | PhoneStateListener.LISTEN_SERVICE_STATE);
424             updateDataState();
425             updateNetworkType();
426             updatePreference();
427         }
428     };
429
430     private TabContentFactory mEmptyTabContent = new TabContentFactory() {
431         @Override
432         public View createTabContent(String tag) {
433             return new View(mTabHost.getContext());
434         }
435     };
436
437     private TabSpec buildTabSpec(String tag, String title) {
438         return mTabHost.newTabSpec(tag).setIndicator(title).setContent(
439                 mEmptyTabContent);
440     }
441 }