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.deviceinfo;
19 import android.app.ActionBar;
20 import android.content.BroadcastReceiver;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.IntentFilter;
24 import android.content.pm.PackageManager.NameNotFoundException;
25 import android.content.res.Resources;
26 import android.os.Bundle;
27 import android.os.UserHandle;
28 import android.preference.Preference;
29 import android.preference.PreferenceActivity;
30 import android.telephony.CellBroadcastMessage;
31 import android.telephony.PhoneNumberUtils;
32 import android.telephony.PhoneStateListener;
33 import android.telephony.ServiceState;
34 import android.telephony.SignalStrength;
35 import android.telephony.SubscriptionInfo;
36 import android.telephony.SubscriptionManager;
37 import android.telephony.TelephonyManager;
38 import android.text.TextUtils;
39 import android.util.Log;
40 import android.view.MenuItem;
41 import android.view.View;
42 import android.widget.ListView;
44 import com.android.internal.logging.MetricsLogger;
45 import com.android.internal.telephony.DefaultPhoneNotifier;
46 import com.android.internal.telephony.Phone;
47 import com.android.internal.telephony.PhoneConstants;
48 import com.android.internal.telephony.PhoneFactory;
49 import com.android.settings.InstrumentedPreferenceActivity;
50 import com.android.settings.R;
51 import com.android.settings.Utils;
53 import java.util.ArrayList;
54 import java.util.List;
58 * Display the following information
63 * # Operator info (area info cell broadcast for Brazil)
67 public class SimStatus extends InstrumentedPreferenceActivity {
68 private static final String TAG = "SimStatus";
70 private static final String KEY_DATA_STATE = "data_state";
71 private static final String KEY_SERVICE_STATE = "service_state";
72 private static final String KEY_OPERATOR_NAME = "operator_name";
73 private static final String KEY_ROAMING_STATE = "roaming_state";
74 private static final String KEY_NETWORK_TYPE = "network_type";
75 private static final String KEY_LATEST_AREA_INFO = "latest_area_info";
76 private static final String KEY_PHONE_NUMBER = "number";
77 private static final String KEY_SIGNAL_STRENGTH = "signal_strength";
78 private static final String COUNTRY_ABBREVIATION_BRAZIL = "br";
80 static final String CB_AREA_INFO_RECEIVED_ACTION =
81 "android.cellbroadcastreceiver.CB_AREA_INFO_RECEIVED";
83 static final String GET_LATEST_CB_AREA_INFO_ACTION =
84 "android.cellbroadcastreceiver.GET_LATEST_CB_AREA_INFO";
86 // Require the sender to have this permission to prevent third-party spoofing.
87 static final String CB_AREA_INFO_SENDER_PERMISSION =
88 "android.permission.RECEIVE_EMERGENCY_BROADCAST";
90 static final String EXTRA_SLOT_ID = "slot_id";
92 private TelephonyManager mTelephonyManager;
93 private Phone mPhone = null;
94 private Resources mRes;
95 private Preference mSignalStrength;
96 private SubscriptionInfo mSir;
97 private boolean mShowLatestAreaInfo;
99 // Default summary for items
100 private String mDefaultText;
102 private PhoneStateListener mPhoneStateListener;
103 private BroadcastReceiver mAreaInfoReceiver = new BroadcastReceiver() {
105 public void onReceive(Context context, Intent intent) {
106 String action = intent.getAction();
107 if (CB_AREA_INFO_RECEIVED_ACTION.equals(action)) {
108 Bundle extras = intent.getExtras();
109 if (extras == null) {
112 CellBroadcastMessage cbMessage = (CellBroadcastMessage) extras.get("message");
113 if (cbMessage != null
114 && cbMessage.getServiceCategory() == 50
115 && mSir.getSubscriptionId() == cbMessage.getSubId()) {
116 String latestAreaInfo = cbMessage.getMessageBody();
117 updateAreaInfo(latestAreaInfo);
124 protected void onCreate(Bundle icicle) {
125 super.onCreate(icicle);
126 mTelephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
128 addPreferencesFromResource(R.xml.device_info_sim_status);
130 mRes = getResources();
131 mDefaultText = mRes.getString(R.string.device_info_default);
132 // Note - missing in zaku build, be careful later...
133 mSignalStrength = findPreference(KEY_SIGNAL_STRENGTH);
135 SubscriptionManager subscriptionManager = SubscriptionManager.from(this);
136 int slotId = getIntent().getIntExtra(EXTRA_SLOT_ID, 0);
137 mSir = subscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(slotId);
141 if (getIntent().hasExtra(EXTRA_SLOT_ID)) {
142 setTitle(getString(R.string.sim_card_status_title, slotId + 1));
145 ActionBar actionBar = getActionBar();
146 if (actionBar != null) {
147 actionBar.setDisplayHomeAsUpEnabled(true);
152 protected int getMetricsCategory() {
153 return MetricsLogger.DEVICEINFO_SIM_STATUS;
157 protected void onResume() {
159 if (mPhone != null) {
162 updateSignalStrength(mPhone.getSignalStrength());
163 updateServiceState(mPhone.getServiceState());
165 mTelephonyManager.listen(mPhoneStateListener,
166 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
167 | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
168 | PhoneStateListener.LISTEN_SERVICE_STATE);
169 if (mShowLatestAreaInfo) {
170 registerReceiver(mAreaInfoReceiver, new IntentFilter(CB_AREA_INFO_RECEIVED_ACTION),
171 CB_AREA_INFO_SENDER_PERMISSION, null);
172 // Ask CellBroadcastReceiver to broadcast the latest area info received
173 Intent getLatestIntent = new Intent(GET_LATEST_CB_AREA_INFO_ACTION);
174 getLatestIntent.putExtra(PhoneConstants.SUBSCRIPTION_KEY,
175 mSir.getSubscriptionId());
176 sendBroadcastAsUser(getLatestIntent, UserHandle.ALL,
177 CB_AREA_INFO_SENDER_PERMISSION);
183 public void onPause() {
186 if (mPhone != null) {
187 mTelephonyManager.listen(mPhoneStateListener,
188 PhoneStateListener.LISTEN_NONE);
190 if (mShowLatestAreaInfo) {
191 unregisterReceiver(mAreaInfoReceiver);
196 public boolean onOptionsItemSelected(MenuItem item) {
197 if (item.getItemId() == android.R.id.home) {
205 * Removes the specified preference, if it exists.
206 * @param key the key for the Preference item
208 private void removePreferenceFromScreen(String key) {
209 Preference pref = findPreference(key);
211 getPreferenceScreen().removePreference(pref);
215 private void setSummaryText(String key, String text) {
216 if (TextUtils.isEmpty(text)) {
219 // some preferences may be missing
220 final Preference preference = findPreference(key);
221 if (preference != null) {
222 preference.setSummary(text);
226 private void updateNetworkType() {
227 // Whether EDGE, UMTS, etc...
228 String networktype = null;
229 final int subId = mSir.getSubscriptionId();
230 final int actualDataNetworkType = mTelephonyManager.getDataNetworkType(
231 mSir.getSubscriptionId());
232 final int actualVoiceNetworkType = mTelephonyManager.getVoiceNetworkType(
233 mSir.getSubscriptionId());
234 if (TelephonyManager.NETWORK_TYPE_UNKNOWN != actualDataNetworkType) {
235 networktype = mTelephonyManager.getNetworkTypeName(actualDataNetworkType);
236 } else if (TelephonyManager.NETWORK_TYPE_UNKNOWN != actualVoiceNetworkType) {
237 networktype = mTelephonyManager.getNetworkTypeName(actualVoiceNetworkType);
240 boolean show4GForLTE = false;
242 Context con = createPackageContext("com.android.systemui", 0);
243 int id = con.getResources().getIdentifier("config_show4GForLTE",
244 "bool", "com.android.systemui");
245 show4GForLTE = con.getResources().getBoolean(id);
246 } catch (NameNotFoundException e) {
247 Log.e(TAG, "NameNotFoundException for show4GFotLTE");
250 if (networktype != null && networktype.equals("LTE") && show4GForLTE) {
253 setSummaryText(KEY_NETWORK_TYPE, networktype);
256 private void updateDataState() {
258 DefaultPhoneNotifier.convertDataState(mPhone.getDataConnectionState());
260 String display = mRes.getString(R.string.radioInfo_unknown);
263 case TelephonyManager.DATA_CONNECTED:
264 display = mRes.getString(R.string.radioInfo_data_connected);
266 case TelephonyManager.DATA_SUSPENDED:
267 display = mRes.getString(R.string.radioInfo_data_suspended);
269 case TelephonyManager.DATA_CONNECTING:
270 display = mRes.getString(R.string.radioInfo_data_connecting);
272 case TelephonyManager.DATA_DISCONNECTED:
273 display = mRes.getString(R.string.radioInfo_data_disconnected);
277 setSummaryText(KEY_DATA_STATE, display);
280 private void updateServiceState(ServiceState serviceState) {
281 final int state = serviceState.getState();
282 final int dataState = mPhone.getServiceState().getDataRegState();
285 case ServiceState.STATE_OUT_OF_SERVICE:
286 // Set signal strength to 0 when service state is STATE_OUT_OF_SERVICE
287 if (ServiceState.STATE_OUT_OF_SERVICE == dataState) {
288 mSignalStrength.setSummary("0");
291 case ServiceState.STATE_POWER_OFF:
292 // Also set signal strength to 0
293 mSignalStrength.setSummary("0");
296 String voiceDisplay = Utils.getServiceStateString(state, mRes);
298 String dataDisplay = Utils.getServiceStateString(dataState, mRes);
300 setSummaryText(KEY_SERVICE_STATE, "Voice: " + voiceDisplay + " / Data: " + dataDisplay);
302 if (serviceState.getRoaming()) {
303 setSummaryText(KEY_ROAMING_STATE, mRes.getString(R.string.radioInfo_roaming_in));
305 setSummaryText(KEY_ROAMING_STATE, mRes.getString(R.string.radioInfo_roaming_not));
307 setSummaryText(KEY_OPERATOR_NAME, serviceState.getOperatorAlphaLong());
310 private void updateAreaInfo(String areaInfo) {
311 if (areaInfo != null) {
312 setSummaryText(KEY_LATEST_AREA_INFO, areaInfo);
316 void updateSignalStrength(SignalStrength signalStrength) {
317 if (mSignalStrength != null) {
318 final int state = mPhone.getServiceState().getState();
319 final int dataState = mPhone.getServiceState().getDataRegState();
320 Resources r = getResources();
322 if (((ServiceState.STATE_OUT_OF_SERVICE == state) &&
323 (ServiceState.STATE_OUT_OF_SERVICE == dataState)) ||
324 (ServiceState.STATE_POWER_OFF == state)) {
325 mSignalStrength.setSummary("0");
329 int signalDbm = signalStrength.getDbm();
330 int signalAsu = signalStrength.getAsuLevel();
332 if (-1 == signalDbm) {
336 if (-1 == signalAsu) {
340 mSignalStrength.setSummary(r.getString(R.string.sim_signal_strength,
341 signalDbm, signalAsu));
345 private void updatePreference() {
346 if (mPhone.getPhoneType() != TelephonyManager.PHONE_TYPE_CDMA) {
347 // only show area info when SIM country is Brazil
348 if (COUNTRY_ABBREVIATION_BRAZIL.equals(mTelephonyManager.getSimCountryIso(
349 mSir.getSubscriptionId()))) {
350 mShowLatestAreaInfo = true;
354 String rawNumber = mTelephonyManager.getLine1NumberForSubscriber(mSir.getSubscriptionId());
355 String formattedNumber = null;
356 if (!TextUtils.isEmpty(rawNumber)) {
357 formattedNumber = PhoneNumberUtils.formatNumber(rawNumber);
359 // If formattedNumber is null or empty, it'll display as "Unknown".
360 setSummaryText(KEY_PHONE_NUMBER, formattedNumber);
362 if (!mShowLatestAreaInfo) {
363 removePreferenceFromScreen(KEY_LATEST_AREA_INFO);
367 private void updatePhoneInfos() {
369 final Phone phone = PhoneFactory.getPhone(SubscriptionManager.getPhoneId(
370 mSir.getSubscriptionId()));
371 if (UserHandle.myUserId() == UserHandle.USER_OWNER
372 && SubscriptionManager.isValidSubscriptionId(mSir.getSubscriptionId())) {
374 Log.e(TAG, "Unable to locate a phone object for the given Subscription ID.");
380 Intent getLatestIntent = new Intent(GET_LATEST_CB_AREA_INFO_ACTION);
381 getLatestIntent.putExtra(PhoneConstants.SUBSCRIPTION_KEY,
382 mSir.getSubscriptionId());
383 sendBroadcastAsUser(getLatestIntent, UserHandle.ALL,
384 CB_AREA_INFO_SENDER_PERMISSION);
385 mPhoneStateListener = new PhoneStateListener(mSir.getSubscriptionId()) {
387 public void onDataConnectionStateChanged(int state) {
393 public void onSignalStrengthsChanged(SignalStrength signalStrength) {
394 updateSignalStrength(signalStrength);
398 public void onServiceStateChanged(ServiceState serviceState) {
399 updateServiceState(serviceState);