414 lines
15 KiB
Java
414 lines
15 KiB
Java
/*
|
||
* Copyright (C) 2014 The Android Open Source Project
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
* you may not use this file except in compliance with the License.
|
||
* You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software
|
||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
* See the License for the specific language governing permissions and
|
||
* limitations under the License.
|
||
*/
|
||
|
||
package com.android.settings.deviceinfo;
|
||
|
||
import android.content.BroadcastReceiver;
|
||
import android.content.Context;
|
||
import android.content.Intent;
|
||
import android.content.IntentFilter;
|
||
import android.content.res.Resources;
|
||
import android.os.Bundle;
|
||
import android.os.SystemProperties;
|
||
import android.os.UserHandle;
|
||
import android.preference.Preference;
|
||
import android.preference.PreferenceActivity;
|
||
import android.telephony.CellBroadcastMessage;
|
||
import android.telephony.PhoneNumberUtils;
|
||
import android.telephony.PhoneStateListener;
|
||
import android.telephony.ServiceState;
|
||
import android.telephony.SignalStrength;
|
||
import android.telephony.SubscriptionInfo;
|
||
import android.telephony.SubscriptionManager;
|
||
import android.telephony.TelephonyManager;
|
||
import android.text.TextUtils;
|
||
import android.util.Log;
|
||
|
||
import com.android.internal.telephony.DefaultPhoneNotifier;
|
||
import com.android.internal.telephony.Phone;
|
||
import com.android.internal.telephony.PhoneFactory;
|
||
import com.android.settings.R;
|
||
import com.android.settings.Utils;
|
||
|
||
import android.view.View;
|
||
import android.widget.ListView;
|
||
import android.widget.TabHost;
|
||
import android.widget.TabHost.OnTabChangeListener;
|
||
import android.widget.TabHost.TabContentFactory;
|
||
import android.widget.TabHost.TabSpec;
|
||
import android.widget.TabWidget;
|
||
|
||
import java.util.ArrayList;
|
||
import java.util.List;
|
||
|
||
|
||
/**
|
||
* Display the following information
|
||
* # Phone Number
|
||
* # Network
|
||
* # Roaming
|
||
* # Device Id (IMEI in GSM and MEID in CDMA)
|
||
* # Network type
|
||
* # Operator info (area info cell broadcast for Brazil)
|
||
* # Signal Strength
|
||
*
|
||
*/
|
||
public class SimStatus extends PreferenceActivity {
|
||
private static final String TAG = "SimStatus";
|
||
|
||
private static final String KEY_DATA_STATE = "data_state";
|
||
private static final String KEY_SERVICE_STATE = "service_state";
|
||
private static final String KEY_OPERATOR_NAME = "operator_name";
|
||
private static final String KEY_ROAMING_STATE = "roaming_state";
|
||
private static final String KEY_NETWORK_TYPE = "network_type";
|
||
private static final String KEY_LATEST_AREA_INFO = "latest_area_info";
|
||
private static final String KEY_PHONE_NUMBER = "number";
|
||
private static final String KEY_SIGNAL_STRENGTH = "signal_strength";
|
||
private static final String KEY_IMEI = "imei";
|
||
private static final String KEY_IMEI_SV = "imei_sv";
|
||
private static final String COUNTRY_ABBREVIATION_BRAZIL = "br";
|
||
|
||
static final String CB_AREA_INFO_RECEIVED_ACTION =
|
||
"android.cellbroadcastreceiver.CB_AREA_INFO_RECEIVED";
|
||
|
||
static final String GET_LATEST_CB_AREA_INFO_ACTION =
|
||
"android.cellbroadcastreceiver.GET_LATEST_CB_AREA_INFO";
|
||
|
||
// Require the sender to have this permission to prevent third-party spoofing.
|
||
static final String CB_AREA_INFO_SENDER_PERMISSION =
|
||
"android.permission.RECEIVE_EMERGENCY_BROADCAST";
|
||
|
||
|
||
private TelephonyManager mTelephonyManager;
|
||
private Phone mPhone = null;
|
||
private Resources mRes;
|
||
private Preference mSignalStrength;
|
||
private SubscriptionInfo mSir;
|
||
private boolean mShowLatestAreaInfo;
|
||
|
||
// Default summary for items
|
||
private String mDefaultText;
|
||
|
||
private TabHost mTabHost;
|
||
private TabWidget mTabWidget;
|
||
private ListView mListView;
|
||
private List<SubscriptionInfo> mSelectableSubInfos;
|
||
|
||
private PhoneStateListener mPhoneStateListener;
|
||
private BroadcastReceiver mAreaInfoReceiver = new BroadcastReceiver() {
|
||
@Override
|
||
public void onReceive(Context context, Intent intent) {
|
||
String action = intent.getAction();
|
||
if (CB_AREA_INFO_RECEIVED_ACTION.equals(action)) {
|
||
Bundle extras = intent.getExtras();
|
||
if (extras == null) {
|
||
return;
|
||
}
|
||
CellBroadcastMessage cbMessage = (CellBroadcastMessage) extras.get("message");
|
||
if (cbMessage != null
|
||
&& cbMessage.getServiceCategory() == 50
|
||
&& mSir.getSubscriptionId() == cbMessage.getSubId()) {
|
||
String latestAreaInfo = cbMessage.getMessageBody();
|
||
updateAreaInfo(latestAreaInfo);
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
@Override
|
||
protected void onCreate(Bundle icicle) {
|
||
super.onCreate(icicle);
|
||
|
||
mSelectableSubInfos = new ArrayList<SubscriptionInfo>();
|
||
mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
|
||
|
||
addPreferencesFromResource(R.xml.device_info_sim_status);
|
||
|
||
mRes = getResources();
|
||
mDefaultText = mRes.getString(R.string.device_info_default);
|
||
// Note - missing in zaku build, be careful later...
|
||
mSignalStrength = findPreference(KEY_SIGNAL_STRENGTH);
|
||
|
||
for (int i = 0; i < mTelephonyManager.getSimCount(); i++) {
|
||
final SubscriptionInfo sir = Utils.findRecordBySlotId(i);
|
||
if (sir != null) {
|
||
mSelectableSubInfos.add(sir);
|
||
}
|
||
}
|
||
|
||
mSir = mSelectableSubInfos.get(0);
|
||
if (mSelectableSubInfos.size() > 1) {
|
||
setContentView(R.layout.sim_information);
|
||
|
||
mTabHost = (TabHost) findViewById(android.R.id.tabhost);
|
||
mTabWidget = (TabWidget) findViewById(android.R.id.tabs);
|
||
mListView = (ListView) findViewById(android.R.id.list);
|
||
|
||
mTabHost.setup();
|
||
mTabHost.setOnTabChangedListener(mTabListener);
|
||
mTabHost.clearAllTabs();
|
||
|
||
for (int i = 0; i < mSelectableSubInfos.size(); i++) {
|
||
mTabHost.addTab(buildTabSpec(String.valueOf(i),
|
||
String.valueOf(mSelectableSubInfos.get(i).getDisplayName())));
|
||
}
|
||
}
|
||
|
||
updatePhoneInfos();
|
||
}
|
||
|
||
@Override
|
||
protected void onResume() {
|
||
super.onResume();
|
||
if (mPhone != null) {
|
||
updatePreference();
|
||
|
||
updateSignalStrength(mPhone.getSignalStrength());
|
||
updateServiceState(mPhone.getServiceState());
|
||
updateDataState();
|
||
mTelephonyManager.listen(mPhoneStateListener,
|
||
PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
|
||
| PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
|
||
| PhoneStateListener.LISTEN_SERVICE_STATE);
|
||
if (mShowLatestAreaInfo) {
|
||
registerReceiver(mAreaInfoReceiver, new IntentFilter(CB_AREA_INFO_RECEIVED_ACTION),
|
||
CB_AREA_INFO_SENDER_PERMISSION, null);
|
||
// Ask CellBroadcastReceiver to broadcast the latest area info received
|
||
Intent getLatestIntent = new Intent(GET_LATEST_CB_AREA_INFO_ACTION);
|
||
sendBroadcastAsUser(getLatestIntent, UserHandle.ALL,
|
||
CB_AREA_INFO_SENDER_PERMISSION);
|
||
}
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void onPause() {
|
||
super.onPause();
|
||
|
||
if (mPhone != null) {
|
||
mTelephonyManager.listen(mPhoneStateListener,
|
||
PhoneStateListener.LISTEN_NONE);
|
||
}
|
||
if (mShowLatestAreaInfo) {
|
||
unregisterReceiver(mAreaInfoReceiver);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Removes the specified preference, if it exists.
|
||
* @param key the key for the Preference item
|
||
*/
|
||
private void removePreferenceFromScreen(String key) {
|
||
Preference pref = findPreference(key);
|
||
if (pref != null) {
|
||
getPreferenceScreen().removePreference(pref);
|
||
}
|
||
}
|
||
|
||
private void setSummaryText(String key, String text) {
|
||
if (TextUtils.isEmpty(text)) {
|
||
text = mDefaultText;
|
||
}
|
||
// some preferences may be missing
|
||
final Preference preference = findPreference(key);
|
||
if (preference != null) {
|
||
preference.setSummary(text);
|
||
}
|
||
}
|
||
|
||
private void updateNetworkType() {
|
||
// Whether EDGE, UMTS, etc...
|
||
String networktype = null;
|
||
if (TelephonyManager.NETWORK_TYPE_UNKNOWN
|
||
!= mTelephonyManager.getNetworkType(mSir.getSubscriptionId())) {
|
||
networktype = mTelephonyManager.getNetworkTypeName(
|
||
mTelephonyManager.getNetworkType(mSir.getSubscriptionId()));
|
||
}
|
||
setSummaryText(KEY_NETWORK_TYPE, networktype);
|
||
}
|
||
|
||
private void updateDataState() {
|
||
final int state =
|
||
DefaultPhoneNotifier.convertDataState(mPhone.getDataConnectionState());
|
||
|
||
String display = mRes.getString(R.string.radioInfo_unknown);
|
||
|
||
switch (state) {
|
||
case TelephonyManager.DATA_CONNECTED:
|
||
display = mRes.getString(R.string.radioInfo_data_connected);
|
||
break;
|
||
case TelephonyManager.DATA_SUSPENDED:
|
||
display = mRes.getString(R.string.radioInfo_data_suspended);
|
||
break;
|
||
case TelephonyManager.DATA_CONNECTING:
|
||
display = mRes.getString(R.string.radioInfo_data_connecting);
|
||
break;
|
||
case TelephonyManager.DATA_DISCONNECTED:
|
||
display = mRes.getString(R.string.radioInfo_data_disconnected);
|
||
break;
|
||
}
|
||
|
||
setSummaryText(KEY_DATA_STATE, display);
|
||
}
|
||
|
||
private void updateServiceState(ServiceState serviceState) {
|
||
final int state = serviceState.getState();
|
||
String display = mRes.getString(R.string.radioInfo_unknown);
|
||
|
||
switch (state) {
|
||
case ServiceState.STATE_IN_SERVICE:
|
||
display = mRes.getString(R.string.radioInfo_service_in);
|
||
break;
|
||
case ServiceState.STATE_OUT_OF_SERVICE:
|
||
case ServiceState.STATE_EMERGENCY_ONLY:
|
||
display = mRes.getString(R.string.radioInfo_service_out);
|
||
break;
|
||
case ServiceState.STATE_POWER_OFF:
|
||
display = mRes.getString(R.string.radioInfo_service_off);
|
||
break;
|
||
}
|
||
|
||
setSummaryText(KEY_SERVICE_STATE, display);
|
||
|
||
if (serviceState.getRoaming()) {
|
||
setSummaryText(KEY_ROAMING_STATE, mRes.getString(R.string.radioInfo_roaming_in));
|
||
} else {
|
||
setSummaryText(KEY_ROAMING_STATE, mRes.getString(R.string.radioInfo_roaming_not));
|
||
}
|
||
setSummaryText(KEY_OPERATOR_NAME, serviceState.getOperatorAlphaLong());
|
||
}
|
||
|
||
private void updateAreaInfo(String areaInfo) {
|
||
if (areaInfo != null) {
|
||
setSummaryText(KEY_LATEST_AREA_INFO, areaInfo);
|
||
}
|
||
}
|
||
|
||
void updateSignalStrength(SignalStrength signalStrength) {
|
||
if (mSignalStrength != null) {
|
||
final int state = mPhone.getServiceState().getState();
|
||
Resources r = getResources();
|
||
|
||
if ((ServiceState.STATE_OUT_OF_SERVICE == state) ||
|
||
(ServiceState.STATE_POWER_OFF == state)) {
|
||
mSignalStrength.setSummary("0");
|
||
}
|
||
|
||
int signalDbm = signalStrength.getDbm();
|
||
int signalAsu = signalStrength.getAsuLevel();
|
||
|
||
if (-1 == signalDbm) {
|
||
signalDbm = 0;
|
||
}
|
||
|
||
if (-1 == signalAsu) {
|
||
signalAsu = 0;
|
||
}
|
||
|
||
mSignalStrength.setSummary(r.getString(R.string.sim_signal_strength,
|
||
signalDbm, signalAsu));
|
||
}
|
||
}
|
||
|
||
private void updatePreference() {
|
||
if (mPhone.getPhoneType() != TelephonyManager.PHONE_TYPE_CDMA) {
|
||
// only show area info when SIM country is Brazil
|
||
if (COUNTRY_ABBREVIATION_BRAZIL.equals(mTelephonyManager.getSimCountryIso(
|
||
mSir.getSubscriptionId()))) {
|
||
mShowLatestAreaInfo = true;
|
||
}
|
||
}
|
||
|
||
String rawNumber = mPhone.getLine1Number(); // may be null or empty
|
||
String formattedNumber = null;
|
||
if (!TextUtils.isEmpty(rawNumber)) {
|
||
formattedNumber = PhoneNumberUtils.formatNumber(rawNumber);
|
||
}
|
||
// If formattedNumber is null or empty, it'll display as "Unknown".
|
||
setSummaryText(KEY_PHONE_NUMBER, formattedNumber);
|
||
final String imei = mPhone.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA
|
||
? mPhone.getImei() : mPhone.getDeviceId();
|
||
setSummaryText(KEY_IMEI, imei);
|
||
setSummaryText(KEY_IMEI_SV,
|
||
((TelephonyManager) getSystemService(TELEPHONY_SERVICE))
|
||
.getDeviceSoftwareVersion(/*slotId*/));
|
||
|
||
if (!mShowLatestAreaInfo) {
|
||
removePreferenceFromScreen(KEY_LATEST_AREA_INFO);
|
||
}
|
||
}
|
||
|
||
private void updatePhoneInfos() {
|
||
final Phone phone = PhoneFactory.getPhone(SubscriptionManager.getPhoneId(
|
||
mSir.getSubscriptionId()));
|
||
if (UserHandle.myUserId() == UserHandle.USER_OWNER
|
||
&& mSir.getSubscriptionId() != SubscriptionManager.INVALID_SUB_ID) {
|
||
if (phone == null) {
|
||
Log.e(TAG, "Unable to locate a phone object for the given Subscription ID.");
|
||
return;
|
||
}
|
||
|
||
mPhone = phone;
|
||
mPhoneStateListener = new PhoneStateListener(mSir.getSubscriptionId()) {
|
||
@Override
|
||
public void onDataConnectionStateChanged(int state) {
|
||
updateDataState();
|
||
updateNetworkType();
|
||
}
|
||
|
||
@Override
|
||
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
|
||
updateSignalStrength(signalStrength);
|
||
}
|
||
|
||
@Override
|
||
public void onServiceStateChanged(ServiceState serviceState) {
|
||
updateServiceState(serviceState);
|
||
}
|
||
};
|
||
}
|
||
}
|
||
private OnTabChangeListener mTabListener = new OnTabChangeListener() {
|
||
@Override
|
||
public void onTabChanged(String tabId) {
|
||
final int slotId = Integer.parseInt(tabId);
|
||
mSir = mSelectableSubInfos.get(slotId);
|
||
|
||
// The User has changed tab; update the SIM information.
|
||
updatePhoneInfos();
|
||
mTelephonyManager.listen(mPhoneStateListener,
|
||
PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
|
||
| PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
|
||
| PhoneStateListener.LISTEN_SERVICE_STATE);
|
||
updateDataState();
|
||
updateNetworkType();
|
||
updatePreference();
|
||
}
|
||
};
|
||
|
||
private TabContentFactory mEmptyTabContent = new TabContentFactory() {
|
||
@Override
|
||
public View createTabContent(String tag) {
|
||
return new View(mTabHost.getContext());
|
||
}
|
||
};
|
||
|
||
private TabSpec buildTabSpec(String tag, String title) {
|
||
return mTabHost.newTabSpec(tag).setIndicator(title).setContent(
|
||
mEmptyTabContent);
|
||
}
|
||
}
|