diff options
author | PauloftheWest <paulofthewest@google.com> | 2014-11-13 15:15:46 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-11-13 15:15:46 +0000 |
commit | f95f2590c1ea6023c9c88d6fb031d622a609df2a (patch) | |
tree | 36179e3bfee2cb8e36d8d778a5440771177b63e2 | |
parent | 22ab79dd47e882fc3e7417fa148da89234b0ad35 (diff) | |
parent | 0f4254fab38fc7b47e4532446dd13338aa4c2cf0 (diff) | |
download | packages_apps_Settings-f95f2590c1ea6023c9c88d6fb031d622a609df2a.zip packages_apps_Settings-f95f2590c1ea6023c9c88d6fb031d622a609df2a.tar.gz packages_apps_Settings-f95f2590c1ea6023c9c88d6fb031d622a609df2a.tar.bz2 |
am 0f4254fa: am 26104298: Merge "Adding Sim Status menu to Settings." into lmp-mr1-dev
* commit '0f4254fab38fc7b47e4532446dd13338aa4c2cf0':
Adding Sim Status menu to Settings.
-rw-r--r-- | AndroidManifest.xml | 12 | ||||
-rw-r--r-- | res/layout/sim_information.xml | 60 | ||||
-rw-r--r-- | res/values/strings.xml | 2 | ||||
-rw-r--r-- | res/xml/device_info_sim_status.xml | 80 | ||||
-rw-r--r-- | src/com/android/settings/deviceinfo/SimStatus.java | 413 |
5 files changed, 567 insertions, 0 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index b4841dc..a800b4b 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1179,6 +1179,18 @@ </activity> <!-- Runs in the phone process since it needs access to the Phone object --> + <activity android:name=".deviceinfo.SimStatus" + android:label="@string/sim_status_title" + android:theme="@style/Theme.SubSettingsDialogWhenLarge" + android:process="com.android.phone"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.DEFAULT" /> + <category android:name="android.intent.category.VOICE_LAUNCH" /> + </intent-filter> + </activity> + + <!-- Runs in the phone process since it needs access to the Phone object --> <activity android:name=".deviceinfo.ImeiInformation" android:label="@string/imei_information_title" android:theme="@style/Theme.SubSettingsDialogWhenLarge" diff --git a/res/layout/sim_information.xml b/res/layout/sim_information.xml new file mode 100644 index 0000000..d2a4acc --- /dev/null +++ b/res/layout/sim_information.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<TabHost xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@android:id/tabhost" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <LinearLayout + android:id="@+id/tabs_container" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:scrollbars="none" + android:fillViewport="true"> + + <TabWidget + android:id="@android:id/tabs" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + style="?android:attr/tabWidgetStyle" /> + + </HorizontalScrollView> + + <!-- give an empty content area to make tabhost happy --> + <FrameLayout + android:id="@android:id/tabcontent" + android:layout_width="0dip" + android:layout_height="0dip" /> + + <ListView + android:id="@android:id/list" + android:layout_width="match_parent" + android:layout_height="0dip" + android:layout_weight="1" + android:clipChildren="false" + android:clipToPadding="false" + android:smoothScrollbar="false" /> + + </LinearLayout> + +</TabHost> diff --git a/res/values/strings.xml b/res/values/strings.xml index e7effb6..f6f4d5a 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -5546,6 +5546,8 @@ <string name="preferred_network_offload_footer">Disable Network Name Broadcast protects from third parties getting access to your network information.</string> <!-- Preferred Network offload Popup. [CHAR LIMIT=100] --> <string name="preferred_network_offload_popup">Disabling Network Name Broadcast will prevent automatic connection to hidden networks.</string> + <!-- Summary text describing signal strength to the user. [CHAR LIMIT=60] --> + <string name="sim_signal_strength"><xliff:g id="dbm">%1$d</xliff:g> dBm <xliff:g id="asu">%2$d</xliff:g> asu</string> <!-- This is a divider in the SIM cards preferences that is the header of various settings where the user chooses which SIM to use for phone calls, data, and SMS messages [CHAR LIMIT=50] --> <string name="sim_pref_divider">Preferred SIM for</string> diff --git a/res/xml/device_info_sim_status.xml b/res/xml/device_info_sim_status.xml new file mode 100644 index 0000000..9e9444d --- /dev/null +++ b/res/xml/device_info_sim_status.xml @@ -0,0 +1,80 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" + android:title="@string/sim_status_title"> + + <Preference android:key="operator_name" + style="?android:attr/preferenceInformationStyle" + android:title="@string/status_operator" + android:summary="@string/device_info_not_available" + android:persistent="false" /> + + <Preference android:key="signal_strength" + style="?android:attr/preferenceInformationStyle" + android:title="@string/status_signal_strength" + android:summary="@string/device_info_not_available" + android:persistent="false" /> + + <Preference android:key="network_type" + style="?android:attr/preferenceInformationStyle" + android:title="@string/status_network_type" + android:summary="@string/device_info_not_available" + android:persistent="false" /> + + <Preference android:key="latest_area_info" + style="?android:attr/preferenceInformationStyle" + android:title="@string/status_latest_area_info" + android:summary="@string/device_info_not_available" + android:persistent="false" /> + + <Preference android:key="service_state" + style="?android:attr/preferenceInformationStyle" + android:title="@string/status_service_state" + android:summary="@string/device_info_not_available" + android:persistent="false" /> + + <Preference android:key="roaming_state" + style="?android:attr/preferenceInformationStyle" + android:title="@string/status_roaming" + android:summary="@string/device_info_not_available" + android:persistent="false" /> + + <Preference android:key="data_state" + style="?android:attr/preferenceInformationStyle" + android:title="@string/status_data_state" + android:summary="@string/device_info_not_available" + android:persistent="false" /> + + <Preference android:key="number" + style="?android:attr/preferenceInformationStyle" + android:title="@string/status_number" + android:summary="@string/device_info_not_available" + android:persistent="false" /> + + <Preference android:key="imei" + style="?android:attr/preferenceInformationStyle" + android:title="@string/status_imei" + android:summary="@string/device_info_not_available" + android:persistent="false" /> + + <Preference android:key="imei_sv" + style="?android:attr/preferenceInformationStyle" + android:title="@string/status_imei_sv" + android:summary="@string/device_info_not_available" + android:persistent="false" /> + +</PreferenceScreen> diff --git a/src/com/android/settings/deviceinfo/SimStatus.java b/src/com/android/settings/deviceinfo/SimStatus.java new file mode 100644 index 0000000..46addf3 --- /dev/null +++ b/src/com/android/settings/deviceinfo/SimStatus.java @@ -0,0 +1,413 @@ +/* + * 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); + } +} |