Merge "[RadioInfo] Move from Settings to Telephony"
diff --git a/res/layout/band_mode.xml b/res/layout/band_mode.xml
new file mode 100644
index 0000000..b43dd1d
--- /dev/null
+++ b/res/layout/band_mode.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:padding="4dip"
+ android:gravity="center_horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <ListView android:id="@+id/band"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:textSize="7sp">
+ </ListView>
+
+</LinearLayout>
diff --git a/res/layout/radio_info.xml b/res/layout/radio_info.xml
new file mode 100644
index 0000000..40c2e53
--- /dev/null
+++ b/res/layout/radio_info.xml
@@ -0,0 +1,414 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/Settings/assets/res/any/layout/radio_info.xml
+**
+** Copyright 2006, 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.
+*/
+-->
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout style="@style/info_layout"
+ android:descendantFocusability="beforeDescendants"
+ android:focusableInTouchMode="true">
+
+ <!-- Phone index -->
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/phone_index_label"
+ style="@style/info_label"
+ />
+
+ <Spinner android:id="@+id/phoneIndex"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
+
+ <!-- IMEI -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_imei_label" style="@style/info_label" />
+ <TextView android:id="@+id/imei" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Phone Number -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_phone_number_label" style="@style/info_label" />
+ <TextView android:id="@+id/number" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Subscription ID -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_subid" style="@style/info_label" />
+ <TextView android:id="@+id/subid" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Default data subscription -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_dds" style="@style/info_label" />
+ <TextView android:id="@+id/dds" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- IMSI -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_imsi_label" style="@style/info_label" />
+ <TextView android:id="@+id/imsi" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Network Identifier -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_current_network_label" style="@style/info_label" />
+ <TextView android:id="@+id/operator" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Roaming -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_roaming_label" style="@style/info_label" />
+ <TextView android:id="@+id/roaming" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Data Service Status -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_gprs_service_label" style="@style/info_label" />
+ <TextView android:id="@+id/gprs" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Data Network Type -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_data_network_type_label" style="@style/info_label" />
+ <TextView android:id="@+id/data_network" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Voice Service Status -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_gsm_service_label" style="@style/info_label" />
+ <TextView android:id="@+id/gsm" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Voice Network Type -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_voice_network_type_label" style="@style/info_label" />
+ <TextView android:id="@+id/voice_network" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Signal Strength -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_signal_strength_label" style="@style/info_label" />
+ <TextView android:id="@+id/dbm" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Link Bandwidth -->
+ <LinearLayout style="@style/RadioInfo_entry_layout" android:orientation="horizontal">
+ <TextView android:text="@string/radio_info_dl_kbps" style="@style/info_label" />
+ <TextView android:id="@+id/dl_kbps" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Link Bandwidth -->
+ <LinearLayout style="@style/RadioInfo_entry_layout" android:orientation="horizontal">
+ <TextView android:text="@string/radio_info_ul_kbps" style="@style/info_label" />
+ <TextView android:id="@+id/ul_kbps" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Physical Channel Config -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_phy_chan_config" style="@style/info_label" />
+ <TextView android:id="@+id/phy_chan_config" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Horizontal Rule -->
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <!-- Preferred Network Type -->
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/radio_info_set_perferred_label"
+ style="@style/info_label"
+ />
+
+ <Spinner android:id="@+id/preferredNetworkType"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
+
+ <!-- Horizontal Rule -->
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <!-- Radio Power -->
+ <Switch android:id="@+id/radio_power"
+ android:textSize="14sp"
+ android:layout_marginTop="8dip"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/radio_info_radio_power"/>
+
+ <!-- VoLTE provisioned -->
+ <Switch android:id="@+id/volte_provisioned_switch"
+ android:textSize="14sp"
+ android:layout_marginTop="8dip"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/volte_provisioned_switch_string"/>
+
+ <!-- VT provisioned -->
+ <Switch android:id="@+id/vt_provisioned_switch"
+ android:textSize="14sp"
+ android:layout_marginTop="8dip"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/vt_provisioned_switch_string"/>
+
+ <!-- Wifi Calling provisioned -->
+ <Switch android:id="@+id/wfc_provisioned_switch"
+ android:textSize="14sp"
+ android:layout_marginTop="8dip"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/wfc_provisioned_switch_string"/>
+
+ <!-- EAB/Presence provisioned -->
+ <Switch android:id="@+id/eab_provisioned_switch"
+ android:textSize="14sp"
+ android:layout_marginTop="8dip"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/eab_provisioned_switch_string"/>
+
+ <!-- Horizontal Rule -->
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <!-- Enable/Disable CBRS data -->
+ <Switch android:id="@+id/cbrs_data_switch"
+ android:textSize="14sp"
+ android:layout_marginTop="8dip"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/cbrs_data_switch_string" />
+
+ <!-- Switch between SSSS(single sim single standby) and DSDS(dual sim dual standby). -->
+ <Switch android:id="@+id/dsds_switch"
+ android:textSize="14sp"
+ android:layout_marginTop="8dip"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/dsds_switch_string" />
+
+ <!-- Horizontal Rule -->
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <!-- Ping stats -->
+ <Button android:id="@+id/ping_test"
+ android:textSize="14sp"
+ android:layout_marginTop="8dip"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/ping_test_label"
+ />
+
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_ping_hostname_v4" style="@style/info_label" />
+ <TextView android:id="@+id/pingHostnameV4" style="@style/info_value" />
+ </LinearLayout>
+
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_ping_hostname_v6" style="@style/info_label" />
+ <TextView android:id="@+id/pingHostnameV6" style="@style/info_value" />
+ </LinearLayout>
+
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_http_client_test" style="@style/info_label" />
+ <TextView android:id="@+id/httpClientTest" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Horizontal Rule -->
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <!-- PPP Sent -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_ppp_sent_label"
+ style="@style/info_label" />
+ <TextView android:id="@+id/sent" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- PPP Received -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_ppp_received_label"
+ style="@style/info_label" />
+ <TextView android:id="@+id/received" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- PPP Sent since last received -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_ppp_resets_label"
+ style="@style/info_label" />
+ <TextView android:id="@+id/sentSinceReceived" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Horizontal Rule -->
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <!-- Call Status -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_call_status_label" style="@style/info_label" />
+ <TextView android:id="@+id/call" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Message Waiting Indicator -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_message_waiting_label" style="@style/info_label" />
+ <TextView android:id="@+id/mwi" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Call Forwarding Indicator -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_call_redirect_label" style="@style/info_label" />
+ <TextView android:id="@+id/cfi" style="@style/info_value" />
+ </LinearLayout>
+
+ <!-- Horizontal Rule -->
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <!-- CellInfoListRate Selection -->
+ <!-- Location -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_signal_location_label" style="@style/info_label" />
+ <TextView android:id="@+id/location" style="@style/info_value" />
+ </LinearLayout>
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/radio_info_cell_info_refresh_rate"
+ style="@style/info_label"
+ />
+
+ <Spinner android:id="@+id/cell_info_rate_select"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
+
+ <!-- CellInfo -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:text="@string/radio_info_cellinfo_label"
+ style="@style/info_label" />
+ </LinearLayout>
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <TextView android:id="@+id/cellinfo"
+ style="@style/info_value"
+ android:minHeight="300dip"
+ android:textSize="12sp" />
+ </LinearLayout>
+
+ <!-- Horizontal Rule -->
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <!-- Launch OEM-specific Info/Settings Activity (if any) -->
+ <!-- Carrier Provisioning -->
+ <LinearLayout style="@style/RadioInfo_entry_layout"
+ android:orientation="horizontal" >
+ <Button android:id="@+id/carrier_provisioning"
+ android:layout_marginTop="8dip"
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:text="@string/carrier_provisioning"
+ android:textSize="14sp"/>
+ <Button android:id="@+id/trigger_carrier_provisioning"
+ android:layout_marginTop="8dip"
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:text="@string/trigger_carrier_provisioning"
+ android:textSize="14sp"/>
+ <Button android:id="@+id/oem_info"
+ android:layout_marginTop="8dip"
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:text="@string/oem_radio_info_label"
+ android:textSize="14sp"/>
+ </LinearLayout>
+
+ <!-- SMSC -->
+ <RelativeLayout android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <TextView android:id="@+id/smsc_label"
+ android:text="@string/radio_info_smsc_label"
+ android:layout_alignBaseline="@+id/update_smsc"
+ style="@style/info_label" />
+ <Button android:id="@+id/refresh_smsc"
+ android:textSize="14sp"
+ android:layout_marginTop="8dip"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/radio_info_smsc_refresh_label"
+ android:layout_alignParentEnd="true"
+ />
+ <Button android:id="@+id/update_smsc"
+ android:textSize="14sp"
+ android:layout_marginTop="8dip"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/radio_info_smsc_update_label"
+ android:layout_toStartOf="@+id/refresh_smsc"
+ android:layout_alignBaseline="@+id/refresh_smsc"
+ />
+ <EditText android:id="@+id/smsc"
+ style="@style/form_value"
+ android:layout_alignBaseline="@+id/refresh_smsc"
+ android:layout_toStartOf="@id/update_smsc"
+ android:layout_toEndOf="@id/smsc_label" />
+ </RelativeLayout>
+
+ <!-- Test setting to ignore bad DNS, useful in lab environments -->
+ <LinearLayout style="@style/RadioInfo_entry_layout">
+ <Button android:id="@+id/dns_check_toggle"
+ android:textSize="14sp"
+ android:layout_marginTop="8dip"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/radio_info_toggle_dns_check_label"
+ />
+ <TextView android:id="@+id/dnsCheckState" style="@style/info_value" />
+ </LinearLayout>
+
+
+ </LinearLayout>
+</ScrollView>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index e6dd4f9..b97ef10 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1890,4 +1890,209 @@
<string name="supp_service_over_ut_precautions_roaming_dual_sim">To use <xliff:g id="supp service">%1$s</xliff:g>, make sure mobile data and data roaming are turned on for SIM <xliff:g id="sim number">%2$d</xliff:g>. You can change these in mobile network settings.</string>
<!-- supplementary services over ut precaution exit dialog choice -->
<string name="supp_service_over_ut_precautions_dialog_dismiss">Dismiss</string>
+
+ <!-- Data Connection Enable. Only shown in diagnostic screen, so precise translation is not needed. -->
+ <string name="radio_info_data_connection_enable">Enable Data Connection</string>
+ <!-- Data Connection Disable. Only shown in diagnostic screen, so precise translation is not needed. -->
+ <string name="radio_info_data_connection_disable">Disable Data Connection</string>
+
+ <!-- VoLTE provisioning flag on. Only shown in diagnostic screen, so precise translation is not needed. -->
+ <string name="volte_provisioned_switch_string">VoLTE Provisioned</string>
+
+ <!-- Video calling provisioning flag on. Only shown in diagnostic screen, so precise translation is not needed. -->
+ <string name="vt_provisioned_switch_string">Video Calling Provisioned</string>
+
+ <!-- Wifi Calling provisioning flag on. Only shown in diagnostic screen, so precise translation is not needed. -->
+ <string name="wfc_provisioned_switch_string">Wifi Calling Provisioned</string>
+
+ <!-- EAB provisioning flag on. Only shown in diagnostic screen, so precise translation is not needed. -->
+ <string name="eab_provisioned_switch_string">EAB/Presence Provisioned</string>
+
+ <!-- Cbrs enable disable flag. Only shown in diagnostic screen, so precise translation is not needed -->
+ <string name="cbrs_data_switch_string">Cbrs Data</string>
+
+ <!-- Dsds enable/disable flag. Only shown in diagnostic screen, so precise translation is not needed, [CHAR LIMIT=none] -->
+ <string name="dsds_switch_string">Enable DSDS</string>
+
+ <!-- UI debug setting: Enable/Disable DSDS [CHAR LIMIT=none] -->
+ <string name="dsds_dialog_title">Restart Device?</string>
+
+ <!-- UI debug setting: Enable/Disable DSDS [CHAR LIMIT=none] -->
+ <string name="dsds_dialog_message">You need to restart your device to change this setting.</string>
+
+ <!-- UI debug setting: Enable/Disable DSDS [CHAR LIMIT=none] -->
+ <string name="dsds_dialog_confirm">Restart</string>
+
+ <!-- UI debug setting: Enable/Disable DSDS [CHAR LIMIT=none] -->
+ <string name="dsds_dialog_cancel">Cancel</string>
+
+ <!-- Title for controlling on/off for Mobile phone's radio power. Only shown in diagnostic screen, so precise translation is not needed. -->
+ <string name="radio_info_radio_power">Mobile Radio Power</string>
+
+ <!-- Phone Info screen. Menu item label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_menu_viewADN">View SIM Address Book</string>
+ <!-- Phone Info screen. Menu item label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_menu_viewFDN">View Fixed Dialing Numbers</string>
+ <!-- Phone Info screen. Menu item label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_menu_viewSDN">View Service Dialing Numbers</string>
+ <!-- Phone Info screen. Menu item label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_menu_getIMS">IMS Service Status</string>
+
+ <!-- Phone Info screen. IMS Registration Title. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_ims_reg_status_title">IMS Status</string>
+
+ <!-- Phone Info screen. IMS Status - Registered. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_ims_reg_status_registered">Registered</string>
+ <!-- Phone Info screen. Ims Status - Unregistered. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_ims_reg_status_not_registered">Not Registered</string>
+
+ <!-- Phone Info screen. Ims Feature Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_ims_feature_status_available">Available</string>
+ <!-- Phone Info screen. Ims Feature status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_ims_feature_status_unavailable">Unavailable</string>
+
+ <!-- Phone Info screen. IMS Registration. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_ims_reg_status">IMS Registration: <xliff:g id="status" example="registered">%1$s</xliff:g>\u000AVoice over LTE: <xliff:g id="availability" example="available">%2$s</xliff:g>\u000AVoice over WiFi: <xliff:g id="availability" example="available">%3$s</xliff:g>\u000AVideo Calling: <xliff:g id="availability" example="available">%4$s</xliff:g>\u000AUT Interface: <xliff:g id="availability" example="available">%5$s</xliff:g></string>
+
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_service_in">In Service</string>
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_service_out">Out of Service</string>
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_service_emergency">Emergency Calls Only</string>
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_service_off">Radio Off</string>
+
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_roaming_in">Roaming</string>
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_roaming_not">Not Roaming</string>
+
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_phone_idle">Idle</string>
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_phone_ringing">Ringing</string>
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_phone_offhook">Call in Progress</string>
+
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_data_disconnected">Disconnected</string>
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_data_connecting">Connecting</string>
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_data_connected">Connected</string>
+ <!-- Phone Info screen. Status label. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_data_suspended">Suspended</string>
+
+ <!-- Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_unknown">Unknown</string>
+ <!-- Phone Info screen. Units shown after a value. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_display_packets">pkts</string>
+ <!-- Phone Info screen. Units shown after a value. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_display_bytes">bytes</string>
+ <!-- Phone Info screen. Units shown after a value. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_display_dbm">dBm</string>
+ <!-- Phone Info screen. Units shown after a value. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_display_asu">asu</string>
+ <!-- Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_lac">LAC</string>
+ <!-- Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radioInfo_cid">CID</string>
+
+
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_subid">Current subId:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_dds">SubId of default data SIM:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_dl_kbps">DL Bandwidth (kbps):</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_ul_kbps">UL Bandwidth (kbps):</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_signal_location_label">Cell Location Info (deprecated):</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_phy_chan_config">LTE Physical Channel Configuration:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_cell_info_refresh_rate">Cell Info Refresh Rate:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_cellinfo_label">All Cell Measurement Info:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_gprs_service_label">Data Service:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_roaming_label">Roaming:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_imei_label">IMEI:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, DO NOT TRANSLATE. -->
+ <string name="radio_info_imsi_label">IMSI:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_call_redirect_label">Call Redirect:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_ppp_resets_label">Number of PPP Reset Since Boot:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_current_network_label">Current Network:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_ppp_received_label">Data Received:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_gsm_service_label">Voice Service:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_signal_strength_label">Signal Strength:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_call_status_label">Voice Call Status:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_ppp_sent_label">Data Sent:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_message_waiting_label">Message Waiting:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_phone_number_label">Phone Number:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_band_mode_label">Select Radio Band</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_voice_network_type_label">Voice Network Type:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_data_network_type_label">Data Network Type:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="phone_index_label">Select phone index</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_set_perferred_label">Set Preferred Network Type:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_ping_hostname_v4">Ping Hostname(www.google.com) IPv4:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_ping_hostname_v6">Ping Hostname(www.google.com) IPv6:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_http_client_test">HTTP Client Test:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="ping_test_label">Run Ping Test</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_smsc_label">SMSC:</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_smsc_update_label">Update</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_smsc_refresh_label">Refresh</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="radio_info_toggle_dns_check_label">Toggle DNS Check</string>
+ <!-- Radio Info screen. Label for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="oem_radio_info_label">OEM-specific Info/Settings</string>
+
+ <!-- Band Mode Selection -->
+ <!-- Band mode screen. Title of activity. -->
+ <string name="band_mode_title">Set Radio Band Mode</string>
+ <!-- Band mode screen. Loading message. -->
+ <string name="band_mode_loading">Loading Band List\u2026</string>
+ <!-- Band mode screen. Button caption to set the bandmode. -->
+ <string name="band_mode_set">Set</string>
+ <!-- Band mode screen. Status message when unsuccessful. -->
+ <string name="band_mode_failed">Unsuccessful</string>
+ <!-- Band mode screen. Statusm essage when successful. -->
+ <string name="band_mode_succeeded">Successful</string>
+
+ <!-- The title of the activity to see phone info -->
+ <string name="phone_info_label" product="tablet">Tablet info</string>
+ <!-- The title of the activity to see phone info -->
+ <string name="phone_info_label" product="default">Phone info</string>
+
+ <!-- Carrier Provisioning Info [CHAR LIMIT=NONE] -->
+ <string name="carrier_provisioning">Carrier Provisioning Info</string>
+ <!-- Trigger Carrier Provisioning [CHAR LIMIT=NONE] -->
+ <string name="trigger_carrier_provisioning">Trigger Carrier Provisioning</string>
+
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index fc95803..e95142b 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -45,6 +45,23 @@
<item name="android:layout_height">wrap_content</item>
</style>
+ <style name="RadioInfo_entry_layout">
+ <item name="android:orientation">horizontal</item>
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">wrap_content</item>
+ </style>
+
+ <style name="info_value">
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:textAppearance">@style/TextAppearance.info_value</item>
+ </style>
+
+ <style name="form_value">
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:layout_width">match_parent</item>
+ </style>
+
<style name="TextAppearance" parent="android:TextAppearance">
</style>
@@ -53,6 +70,11 @@
<item name="android:textStyle">bold</item>
</style>
+ <style name="TextAppearance.info_value">
+ <item name="android:textSize">14sp</item>
+ <item name="android:textStyle">normal</item>
+ </style>
+
<!-- Preference Style for the phone number preferences -->
<style name="EditPhoneNumberPreference">
<item name="enableButtonText">@string/enable</item>
diff --git a/src/com/android/phone/settings/BandMode.java b/src/com/android/phone/settings/BandMode.java
new file mode 100644
index 0000000..853075a
--- /dev/null
+++ b/src/com/android/phone/settings/BandMode.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2019 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.phone.settings;
+
+import android.app.Activity;
+import android.content.DialogInterface;
+import android.os.AsyncResult;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+import android.view.View;
+import android.view.Window;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+import androidx.appcompat.app.AlertDialog;
+
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.phone.R;
+
+/**
+ * Radio Band Mode Selection Class
+ *
+ * It will query baseband about all available band modes and display them
+ * in screen. It will display all six band modes if the query failed.
+ *
+ * After user select one band, it will send the selection to baseband.
+ *
+ * It will alter user the result of select operation and exit, no matter success
+ * or not.
+ *
+ */
+public class BandMode extends Activity {
+ private static final String LOG_TAG = "phone";
+ private static final boolean DBG = false;
+
+ private static final int EVENT_BAND_SCAN_COMPLETED = 100;
+ private static final int EVENT_BAND_SELECTION_DONE = 200;
+
+ //Directly maps to RIL_RadioBandMode from ril.h
+ private static final String[] BAND_NAMES = new String[] {
+ "Automatic",
+ "Europe",
+ "United States",
+ "Japan",
+ "Australia",
+ "Australia 2",
+ "Cellular 800",
+ "PCS",
+ "Class 3 (JTACS)",
+ "Class 4 (Korea-PCS)",
+ "Class 5",
+ "Class 6 (IMT2000)",
+ "Class 7 (700Mhz-Upper)",
+ "Class 8 (1800Mhz-Upper)",
+ "Class 9 (900Mhz)",
+ "Class 10 (800Mhz-Secondary)",
+ "Class 11 (Europe PAMR 400Mhz)",
+ "Class 15 (US-AWS)",
+ "Class 16 (US-2500Mhz)"
+ };
+
+ private ListView mBandList;
+ private ArrayAdapter mBandListAdapter;
+ private BandListItem mTargetBand = null;
+ private DialogInterface mProgressPanel;
+
+ private Phone mPhone = null;
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+ setContentView(R.layout.band_mode);
+
+ mPhone = PhoneFactory.getDefaultPhone();
+
+ mBandList = (ListView) findViewById(R.id.band);
+ mBandListAdapter = new ArrayAdapter<BandListItem>(this,
+ android.R.layout.simple_list_item_1);
+ mBandList.setAdapter(mBandListAdapter);
+ mBandList.setOnItemClickListener(mBandSelectionHandler);
+
+ loadBandList();
+ }
+
+ private AdapterView.OnItemClickListener mBandSelectionHandler =
+ new AdapterView.OnItemClickListener() {
+ public void onItemClick(AdapterView parent, View v,
+ int position, long id) {
+
+ getWindow().setFeatureInt(
+ Window.FEATURE_INDETERMINATE_PROGRESS,
+ Window.PROGRESS_VISIBILITY_ON);
+
+ mTargetBand = (BandListItem) parent.getAdapter().getItem(position);
+
+ if (DBG) log("Select band : " + mTargetBand.toString());
+
+ Message msg =
+ mHandler.obtainMessage(EVENT_BAND_SELECTION_DONE);
+ mPhone.setBandMode(mTargetBand.getBand(), msg);
+ }
+ };
+
+ private static class BandListItem {
+ private int mBandMode = Phone.BM_UNSPECIFIED;
+
+ BandListItem(int bm) {
+ mBandMode = bm;
+ }
+
+ public int getBand() {
+ return mBandMode;
+ }
+
+ public String toString() {
+ if (mBandMode >= BAND_NAMES.length) return "Band mode " + mBandMode;
+ return BAND_NAMES[mBandMode];
+ }
+ }
+
+ private void loadBandList() {
+ String str = getString(R.string.band_mode_loading);
+
+ if (DBG) log(str);
+
+
+ //ProgressDialog.show(this, null, str, true, true, null);
+ mProgressPanel = new AlertDialog.Builder(this)
+ .setMessage(str)
+ .show();
+
+ Message msg = mHandler.obtainMessage(EVENT_BAND_SCAN_COMPLETED);
+ mPhone.queryAvailableBandMode(msg);
+
+ }
+
+ private void bandListLoaded(AsyncResult result) {
+ if (DBG) log("network list loaded");
+
+ if (mProgressPanel != null) mProgressPanel.dismiss();
+
+ clearList();
+
+ boolean addBandSuccess = false;
+ BandListItem item;
+
+ if (result.result != null) {
+ int [] bands = (int []) result.result;
+
+ if (bands.length == 0) {
+ Log.wtf(LOG_TAG, "No Supported Band Modes");
+ return;
+ }
+
+ int size = bands[0];
+
+ if (size > 0) {
+ mBandListAdapter.add(
+ new BandListItem(Phone.BM_UNSPECIFIED)); //Always include AUTOMATIC
+ for (int i = 1; i <= size; i++) {
+ if (bands[i] == Phone.BM_UNSPECIFIED) {
+ continue;
+ }
+ item = new BandListItem(bands[i]);
+ mBandListAdapter.add(item);
+ if (DBG) log("Add " + item.toString());
+ }
+ addBandSuccess = true;
+ }
+ }
+
+ if (!addBandSuccess) {
+ if (DBG) log("Error in query, add default list");
+ for (int i = 0; i < Phone.BM_NUM_BAND_MODES; i++) {
+ item = new BandListItem(i);
+ mBandListAdapter.add(item);
+ if (DBG) log("Add default " + item.toString());
+ }
+ }
+ mBandList.requestFocus();
+ }
+
+ private void displayBandSelectionResult(Throwable ex) {
+ String status = getString(R.string.band_mode_set)
+ + " [" + mTargetBand.toString() + "] ";
+
+ if (ex != null) {
+ status = status + getString(R.string.band_mode_failed);
+ } else {
+ status = status + getString(R.string.band_mode_succeeded);
+ }
+
+ mProgressPanel = new AlertDialog.Builder(this)
+ .setMessage(status)
+ .setPositiveButton(android.R.string.ok, null).show();
+ }
+
+ private void clearList() {
+ while (mBandListAdapter.getCount() > 0) {
+ mBandListAdapter.remove(
+ mBandListAdapter.getItem(0));
+ }
+ }
+
+ private void log(String msg) {
+ Log.d(LOG_TAG, "[BandsList] " + msg);
+ }
+
+ private Handler mHandler = new Handler() {
+ public void handleMessage(Message msg) {
+ AsyncResult ar;
+ switch (msg.what) {
+ case EVENT_BAND_SCAN_COMPLETED:
+ ar = (AsyncResult) msg.obj;
+
+ bandListLoaded(ar);
+ break;
+
+ case EVENT_BAND_SELECTION_DONE:
+ ar = (AsyncResult) msg.obj;
+
+ getWindow().setFeatureInt(
+ Window.FEATURE_INDETERMINATE_PROGRESS,
+ Window.PROGRESS_VISIBILITY_OFF);
+
+ if (!isFinishing()) {
+ displayBandSelectionResult(ar.exception);
+ }
+ break;
+ }
+ }
+ };
+
+
+}
diff --git a/src/com/android/phone/settings/RadioInfo.java b/src/com/android/phone/settings/RadioInfo.java
new file mode 100644
index 0000000..04045f1
--- /dev/null
+++ b/src/com/android/phone/settings/RadioInfo.java
@@ -0,0 +1,1768 @@
+/*
+ * Copyright (C) 2019 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.phone.settings;
+
+import static android.net.ConnectivityManager.NetworkCallback;
+import static android.provider.Settings.Global.PREFERRED_NETWORK_MODE;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.graphics.Typeface;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
+import android.net.TrafficStats;
+import android.net.Uri;
+import android.os.AsyncResult;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemProperties;
+import android.provider.Settings;
+import android.telephony.CarrierConfigManager;
+import android.telephony.CellIdentityCdma;
+import android.telephony.CellIdentityGsm;
+import android.telephony.CellIdentityLte;
+import android.telephony.CellIdentityWcdma;
+import android.telephony.CellInfo;
+import android.telephony.CellInfoCdma;
+import android.telephony.CellInfoGsm;
+import android.telephony.CellInfoLte;
+import android.telephony.CellInfoWcdma;
+import android.telephony.CellLocation;
+import android.telephony.CellSignalStrengthCdma;
+import android.telephony.CellSignalStrengthGsm;
+import android.telephony.CellSignalStrengthLte;
+import android.telephony.CellSignalStrengthWcdma;
+import android.telephony.PhoneStateListener;
+import android.telephony.PhysicalChannelConfig;
+import android.telephony.PreciseCallState;
+import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.telephony.cdma.CdmaCellLocation;
+import android.telephony.gsm.GsmCellLocation;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.CompoundButton;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+import android.widget.EditText;
+import android.widget.Spinner;
+import android.widget.Switch;
+import android.widget.TextView;
+
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.app.AlertDialog.Builder;
+import androidx.appcompat.app.AppCompatActivity;
+
+import com.android.ims.ImsConfig;
+import com.android.ims.ImsException;
+import com.android.ims.ImsManager;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.phone.R;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.List;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Radio Information Class
+ *
+ * Allows user to read and alter some of the radio related information.
+ *
+ */
+public class RadioInfo extends AppCompatActivity {
+ private static final String TAG = "RadioInfo";
+
+ private static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
+
+ private static final String[] PREFERRED_NETWORK_LABELS = {
+ "WCDMA preferred",
+ "GSM only",
+ "WCDMA only",
+ "GSM auto (PRL)",
+ "CDMA auto (PRL)",
+ "CDMA only",
+ "EvDo only",
+ "Global auto (PRL)",
+ "LTE/CDMA auto (PRL)",
+ "LTE/UMTS auto (PRL)",
+ "LTE/CDMA/UMTS auto (PRL)",
+ "LTE only",
+ "LTE/WCDMA",
+ "TD-SCDMA only",
+ "TD-SCDMA/WCDMA",
+ "LTE/TD-SCDMA",
+ "TD-SCDMA/GSM",
+ "TD-SCDMA/UMTS",
+ "LTE/TD-SCDMA/WCDMA",
+ "LTE/TD-SCDMA/UMTS",
+ "TD-SCDMA/CDMA/UMTS",
+ "Global/TD-SCDMA",
+ "Unknown"
+ };
+
+ private static String[] sPhoneIndexLabels;
+
+ private static final int sCellInfoListRateDisabled = Integer.MAX_VALUE;
+ private static final int sCellInfoListRateMax = 0;
+
+ private static final String OEM_RADIO_INFO_INTENT =
+ "com.android.phone.settings.OEM_RADIO_INFO";
+
+ private static final String DSDS_MODE_PROPERTY = "ro.boot.hardware.dsds";
+
+ /**
+ * A value indicates the device is always on dsds mode.
+ * @see {@link #DSDS_MODE_PROPERTY}
+ */
+ private static final int ALWAYS_ON_DSDS_MODE = 1;
+
+ private static final int IMS_VOLTE_PROVISIONED_CONFIG_ID =
+ ImsConfig.ConfigConstants.VLT_SETTING_ENABLED;
+
+ private static final int IMS_VT_PROVISIONED_CONFIG_ID =
+ ImsConfig.ConfigConstants.LVC_SETTING_ENABLED;
+
+ private static final int IMS_WFC_PROVISIONED_CONFIG_ID =
+ ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED;
+
+ private static final int EAB_PROVISIONED_CONFIG_ID =
+ ImsConfig.ConfigConstants.EAB_SETTING_ENABLED;
+
+ //Values in must match CELL_INFO_REFRESH_RATES
+ private static final String[] CELL_INFO_REFRESH_RATE_LABELS = {
+ "Disabled",
+ "Immediate",
+ "Min 5s",
+ "Min 10s",
+ "Min 60s"
+ };
+
+ //Values in seconds, must match CELL_INFO_REFRESH_RATE_LABELS
+ private static final int [] CELL_INFO_REFRESH_RATES = {
+ sCellInfoListRateDisabled,
+ sCellInfoListRateMax,
+ 5000,
+ 10000,
+ 60000
+ };
+
+ private static void log(String s) {
+ Log.d(TAG, s);
+ }
+
+ private static final int EVENT_CFI_CHANGED = 302;
+
+ private static final int EVENT_QUERY_PREFERRED_TYPE_DONE = 1000;
+ private static final int EVENT_SET_PREFERRED_TYPE_DONE = 1001;
+ private static final int EVENT_QUERY_SMSC_DONE = 1005;
+ private static final int EVENT_UPDATE_SMSC_DONE = 1006;
+
+ private static final int MENU_ITEM_SELECT_BAND = 0;
+ private static final int MENU_ITEM_VIEW_ADN = 1;
+ private static final int MENU_ITEM_VIEW_FDN = 2;
+ private static final int MENU_ITEM_VIEW_SDN = 3;
+ private static final int MENU_ITEM_GET_IMS_STATUS = 4;
+ private static final int MENU_ITEM_TOGGLE_DATA = 5;
+
+ private TextView mDeviceId; //DeviceId is the IMEI in GSM and the MEID in CDMA
+ private TextView mLine1Number;
+ private TextView mSubscriptionId;
+ private TextView mDds;
+ private TextView mSubscriberId;
+ private TextView mCallState;
+ private TextView mOperatorName;
+ private TextView mRoamingState;
+ private TextView mGsmState;
+ private TextView mGprsState;
+ private TextView mVoiceNetwork;
+ private TextView mDataNetwork;
+ private TextView mDBm;
+ private TextView mMwi;
+ private TextView mCfi;
+ private TextView mLocation;
+ private TextView mCellInfo;
+ private TextView mSent;
+ private TextView mReceived;
+ private TextView mPingHostnameV4;
+ private TextView mPingHostnameV6;
+ private TextView mHttpClientTest;
+ private TextView mPhyChanConfig;
+ private TextView mDnsCheckState;
+ private TextView mDownlinkKbps;
+ private TextView mUplinkKbps;
+ private EditText mSmsc;
+ private Switch mRadioPowerOnSwitch;
+ private Button mCellInfoRefreshRateButton;
+ private Button mDnsCheckToggleButton;
+ private Button mPingTestButton;
+ private Button mUpdateSmscButton;
+ private Button mRefreshSmscButton;
+ private Button mOemInfoButton;
+ private Button mCarrierProvisioningButton;
+ private Button mTriggerCarrierProvisioningButton;
+ private Switch mImsVolteProvisionedSwitch;
+ private Switch mImsVtProvisionedSwitch;
+ private Switch mImsWfcProvisionedSwitch;
+ private Switch mEabProvisionedSwitch;
+ private Switch mCbrsDataSwitch;
+ private Switch mDsdsSwitch;
+ private Spinner mPreferredNetworkType;
+ private Spinner mSelectPhoneIndex;
+ private Spinner mCellInfoRefreshRateSpinner;
+
+ private static final long RUNNABLE_TIMEOUT_MS = 5 * 60 * 1000L;
+
+ private ThreadPoolExecutor mQueuedWork;
+
+ private ConnectivityManager mConnectivityManager;
+ private TelephonyManager mTelephonyManager;
+ private ImsManager mImsManager = null;
+ private Phone mPhone = null;
+
+ private String mPingHostnameResultV4;
+ private String mPingHostnameResultV6;
+ private String mHttpClientTestResult;
+ private boolean mMwiValue = false;
+ private boolean mCfiValue = false;
+
+ private List<CellInfo> mCellInfoResult = null;
+ private CellLocation mCellLocationResult = null;
+
+ private int mPreferredNetworkTypeResult;
+ private int mCellInfoRefreshRateIndex;
+ private int mSelectedPhoneIndex;
+
+ private final NetworkRequest mDefaultNetworkRequest = new NetworkRequest.Builder()
+ .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+ .build();
+
+ private final NetworkCallback mNetworkCallback = new NetworkCallback() {
+ public void onCapabilitiesChanged(Network n, NetworkCapabilities nc) {
+ int dlbw = nc.getLinkDownstreamBandwidthKbps();
+ int ulbw = nc.getLinkUpstreamBandwidthKbps();
+ updateBandwidths(dlbw, ulbw);
+ }
+ };
+
+ // not final because we need to recreate this object to register on a new subId (b/117555407)
+ private PhoneStateListener mPhoneStateListener = new RadioInfoPhoneStateListener();
+ private class RadioInfoPhoneStateListener extends PhoneStateListener {
+ @Override
+ public void onDataConnectionStateChanged(int state) {
+ updateDataState();
+ updateNetworkType();
+ }
+
+ @Override
+ public void onDataActivity(int direction) {
+ updateDataStats2();
+ }
+
+ @Override
+ public void onCallStateChanged(int state, String incomingNumber) {
+ updateNetworkType();
+ updatePhoneState(state);
+ }
+
+ @Override
+ public void onPreciseCallStateChanged(PreciseCallState preciseState) {
+ updateNetworkType();
+ }
+
+ @Override
+ public void onCellLocationChanged(CellLocation location) {
+ updateLocation(location);
+ }
+
+ @Override
+ public void onMessageWaitingIndicatorChanged(boolean mwi) {
+ mMwiValue = mwi;
+ updateMessageWaiting();
+ }
+
+ @Override
+ public void onCallForwardingIndicatorChanged(boolean cfi) {
+ mCfiValue = cfi;
+ updateCallRedirect();
+ }
+
+ @Override
+ public void onCellInfoChanged(List<CellInfo> arrayCi) {
+ log("onCellInfoChanged: arrayCi=" + arrayCi);
+ mCellInfoResult = arrayCi;
+ updateCellInfo(mCellInfoResult);
+ }
+
+ @Override
+ public void onSignalStrengthsChanged(SignalStrength signalStrength) {
+ log("onSignalStrengthChanged: SignalStrength=" + signalStrength);
+ updateSignalStrength(signalStrength);
+ }
+
+ @Override
+ public void onServiceStateChanged(ServiceState serviceState) {
+ log("onServiceStateChanged: ServiceState=" + serviceState);
+ updateServiceState(serviceState);
+ updateRadioPowerState();
+ updateNetworkType();
+ updateImsProvisionedState();
+ }
+
+ @Override
+ public void onPhysicalChannelConfigurationChanged(
+ List<PhysicalChannelConfig> configs) {
+ updatePhysicalChannelConfiguration(configs);
+ }
+
+ }
+
+ private void updatePhysicalChannelConfiguration(List<PhysicalChannelConfig> configs) {
+ StringBuilder sb = new StringBuilder();
+ String div = "";
+ sb.append("{");
+ if (configs != null) {
+ for (PhysicalChannelConfig c : configs) {
+ sb.append(div).append(c);
+ div = ",";
+ }
+ }
+ sb.append("}");
+ mPhyChanConfig.setText(sb.toString());
+ }
+
+ private void updatePreferredNetworkType(int type) {
+ if (type >= PREFERRED_NETWORK_LABELS.length || type < 0) {
+ log("EVENT_QUERY_PREFERRED_TYPE_DONE: unknown "
+ + "type=" + type);
+ type = PREFERRED_NETWORK_LABELS.length - 1; //set to Unknown
+ }
+ mPreferredNetworkTypeResult = type;
+
+ mPreferredNetworkType.setSelection(mPreferredNetworkTypeResult, true);
+ }
+
+ private void updatePhoneIndex(int phoneIndex, int subId) {
+ // unregister listeners on the old subId
+ unregisterPhoneStateListener();
+ mTelephonyManager.setCellInfoListRate(sCellInfoListRateDisabled);
+
+ // update the subId
+ mTelephonyManager = mTelephonyManager.createForSubscriptionId(subId);
+
+ // update the phoneId
+ mImsManager = ImsManager.getInstance(getApplicationContext(), phoneIndex);
+ mPhone = PhoneFactory.getPhone(phoneIndex);
+
+ updateAllFields();
+ }
+
+ private Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ AsyncResult ar;
+ switch (msg.what) {
+ case EVENT_QUERY_PREFERRED_TYPE_DONE:
+ ar = (AsyncResult) msg.obj;
+ if (ar.exception == null && ar.result != null) {
+ updatePreferredNetworkType(((int []) ar.result)[0]);
+ } else {
+ //In case of an exception, we will set this to unknown
+ updatePreferredNetworkType(PREFERRED_NETWORK_LABELS.length - 1);
+ }
+ break;
+ case EVENT_SET_PREFERRED_TYPE_DONE:
+ ar = (AsyncResult) msg.obj;
+ if (ar.exception != null) {
+ log("Set preferred network type failed.");
+ }
+ break;
+ case EVENT_QUERY_SMSC_DONE:
+ ar = (AsyncResult) msg.obj;
+ if (ar.exception != null) {
+ mSmsc.setText("refresh error");
+ } else {
+ mSmsc.setText((String) ar.result);
+ }
+ break;
+ case EVENT_UPDATE_SMSC_DONE:
+ mUpdateSmscButton.setEnabled(true);
+ ar = (AsyncResult) msg.obj;
+ if (ar.exception != null) {
+ mSmsc.setText("update error");
+ }
+ break;
+ default:
+ super.handleMessage(msg);
+ break;
+
+ }
+ }
+ };
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ if (!android.os.Process.myUserHandle().isSystem()) {
+ Log.e(TAG, "Not run from system user, don't do anything.");
+ finish();
+ return;
+ }
+
+ setContentView(R.layout.radio_info);
+
+ log("Started onCreate");
+
+ mQueuedWork = new ThreadPoolExecutor(1, 1, RUNNABLE_TIMEOUT_MS, TimeUnit.MICROSECONDS,
+ new LinkedBlockingDeque<Runnable>());
+ mTelephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
+ mConnectivityManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
+ mPhone = PhoneFactory.getDefaultPhone();
+
+ mImsManager = ImsManager.getInstance(getApplicationContext(),
+ SubscriptionManager.getDefaultVoicePhoneId());
+
+ sPhoneIndexLabels = getPhoneIndexLabels(mTelephonyManager);
+
+ mDeviceId = (TextView) findViewById(R.id.imei);
+ mLine1Number = (TextView) findViewById(R.id.number);
+ mSubscriptionId = (TextView) findViewById(R.id.subid);
+ mDds = (TextView) findViewById(R.id.dds);
+ mSubscriberId = (TextView) findViewById(R.id.imsi);
+ mCallState = (TextView) findViewById(R.id.call);
+ mOperatorName = (TextView) findViewById(R.id.operator);
+ mRoamingState = (TextView) findViewById(R.id.roaming);
+ mGsmState = (TextView) findViewById(R.id.gsm);
+ mGprsState = (TextView) findViewById(R.id.gprs);
+ mVoiceNetwork = (TextView) findViewById(R.id.voice_network);
+ mDataNetwork = (TextView) findViewById(R.id.data_network);
+ mDBm = (TextView) findViewById(R.id.dbm);
+ mMwi = (TextView) findViewById(R.id.mwi);
+ mCfi = (TextView) findViewById(R.id.cfi);
+ mLocation = (TextView) findViewById(R.id.location);
+ mCellInfo = (TextView) findViewById(R.id.cellinfo);
+ mCellInfo.setTypeface(Typeface.MONOSPACE);
+
+ mSent = (TextView) findViewById(R.id.sent);
+ mReceived = (TextView) findViewById(R.id.received);
+ mSmsc = (EditText) findViewById(R.id.smsc);
+ mDnsCheckState = (TextView) findViewById(R.id.dnsCheckState);
+ mPingHostnameV4 = (TextView) findViewById(R.id.pingHostnameV4);
+ mPingHostnameV6 = (TextView) findViewById(R.id.pingHostnameV6);
+ mHttpClientTest = (TextView) findViewById(R.id.httpClientTest);
+
+ mPhyChanConfig = (TextView) findViewById(R.id.phy_chan_config);
+
+ mPreferredNetworkType = (Spinner) findViewById(R.id.preferredNetworkType);
+ ArrayAdapter<String> mPreferredNetworkTypeAdapter = new ArrayAdapter<String>(this,
+ android.R.layout.simple_spinner_item, PREFERRED_NETWORK_LABELS);
+ mPreferredNetworkTypeAdapter
+ .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ mPreferredNetworkType.setAdapter(mPreferredNetworkTypeAdapter);
+
+ mSelectPhoneIndex = (Spinner) findViewById(R.id.phoneIndex);
+ ArrayAdapter<String> phoneIndexAdapter = new ArrayAdapter<String>(this,
+ android.R.layout.simple_spinner_item, sPhoneIndexLabels);
+ phoneIndexAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ mSelectPhoneIndex.setAdapter(phoneIndexAdapter);
+
+ mCellInfoRefreshRateSpinner = (Spinner) findViewById(R.id.cell_info_rate_select);
+ ArrayAdapter<String> cellInfoAdapter = new ArrayAdapter<String>(this,
+ android.R.layout.simple_spinner_item, CELL_INFO_REFRESH_RATE_LABELS);
+ cellInfoAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ mCellInfoRefreshRateSpinner.setAdapter(cellInfoAdapter);
+
+ mImsVolteProvisionedSwitch = (Switch) findViewById(R.id.volte_provisioned_switch);
+ mImsVtProvisionedSwitch = (Switch) findViewById(R.id.vt_provisioned_switch);
+ mImsWfcProvisionedSwitch = (Switch) findViewById(R.id.wfc_provisioned_switch);
+ mEabProvisionedSwitch = (Switch) findViewById(R.id.eab_provisioned_switch);
+
+ if (!ImsManager.isImsSupportedOnDevice(mPhone.getContext())) {
+ mImsVolteProvisionedSwitch.setVisibility(View.GONE);
+ mImsVtProvisionedSwitch.setVisibility(View.GONE);
+ mImsWfcProvisionedSwitch.setVisibility(View.GONE);
+ mEabProvisionedSwitch.setVisibility(View.GONE);
+ }
+
+ mCbrsDataSwitch = (Switch) findViewById(R.id.cbrs_data_switch);
+ mCbrsDataSwitch.setVisibility(isCbrsSupported() ? View.VISIBLE : View.GONE);
+
+ mDsdsSwitch = findViewById(R.id.dsds_switch);
+ if (isDsdsSupported() && !dsdsModeOnly()) {
+ mDsdsSwitch.setVisibility(View.VISIBLE);
+ mDsdsSwitch.setOnClickListener(v -> {
+ if (mTelephonyManager.doesSwitchMultiSimConfigTriggerReboot()) {
+ // Undo the click action until user clicks the confirm dialog.
+ mDsdsSwitch.toggle();
+ showDsdsChangeDialog();
+ } else {
+ performDsdsSwitch();
+ }
+ });
+ mDsdsSwitch.setChecked(isDsdsEnabled());
+ } else {
+ mDsdsSwitch.setVisibility(View.GONE);
+ }
+
+ mRadioPowerOnSwitch = (Switch) findViewById(R.id.radio_power);
+
+ mDownlinkKbps = (TextView) findViewById(R.id.dl_kbps);
+ mUplinkKbps = (TextView) findViewById(R.id.ul_kbps);
+ updateBandwidths(0, 0);
+
+ mPingTestButton = (Button) findViewById(R.id.ping_test);
+ mPingTestButton.setOnClickListener(mPingButtonHandler);
+ mUpdateSmscButton = (Button) findViewById(R.id.update_smsc);
+ mUpdateSmscButton.setOnClickListener(mUpdateSmscButtonHandler);
+ mRefreshSmscButton = (Button) findViewById(R.id.refresh_smsc);
+ mRefreshSmscButton.setOnClickListener(mRefreshSmscButtonHandler);
+ mDnsCheckToggleButton = (Button) findViewById(R.id.dns_check_toggle);
+ mDnsCheckToggleButton.setOnClickListener(mDnsCheckButtonHandler);
+ mCarrierProvisioningButton = (Button) findViewById(R.id.carrier_provisioning);
+ mCarrierProvisioningButton.setOnClickListener(mCarrierProvisioningButtonHandler);
+ mTriggerCarrierProvisioningButton = (Button) findViewById(
+ R.id.trigger_carrier_provisioning);
+ mTriggerCarrierProvisioningButton.setOnClickListener(
+ mTriggerCarrierProvisioningButtonHandler);
+
+ mOemInfoButton = (Button) findViewById(R.id.oem_info);
+ mOemInfoButton.setOnClickListener(mOemInfoButtonHandler);
+ PackageManager pm = getPackageManager();
+ Intent oemInfoIntent = new Intent(OEM_RADIO_INFO_INTENT);
+ List<ResolveInfo> oemInfoIntentList = pm.queryIntentActivities(oemInfoIntent, 0);
+ if (oemInfoIntentList.size() == 0) {
+ mOemInfoButton.setEnabled(false);
+ }
+
+ mCellInfoRefreshRateIndex = 0; //disabled
+ mPreferredNetworkTypeResult = PREFERRED_NETWORK_LABELS.length - 1; //Unknown
+ mSelectedPhoneIndex = 0; //phone 0
+
+ //FIXME: Replace with TelephonyManager call
+ mPhone.getPreferredNetworkType(
+ mHandler.obtainMessage(EVENT_QUERY_PREFERRED_TYPE_DONE));
+
+ restoreFromBundle(icicle);
+ }
+
+ @Override
+ public Intent getParentActivityIntent() {
+ Intent parentActivity = super.getParentActivityIntent();
+ if (parentActivity == null) {
+ parentActivity = (new Intent()).setClassName("com.android.settings",
+ "com.android.settings.Settings$TestingSettingsActivity");
+ }
+ return parentActivity;
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ log("Started onResume");
+
+ updateAllFields();
+ }
+
+ private void updateAllFields() {
+ updateMessageWaiting();
+ updateCallRedirect();
+ updateDataState();
+ updateDataStats2();
+ updateRadioPowerState();
+ updateImsProvisionedState();
+ updateProperties();
+ updateDnsCheckState();
+ updateNetworkType();
+
+ updateLocation(mCellLocationResult);
+ updateCellInfo(mCellInfoResult);
+ updateSubscriptionIds();
+
+ mPingHostnameV4.setText(mPingHostnameResultV4);
+ mPingHostnameV6.setText(mPingHostnameResultV6);
+ mHttpClientTest.setText(mHttpClientTestResult);
+
+ mCellInfoRefreshRateSpinner.setOnItemSelectedListener(mCellInfoRefreshRateHandler);
+ //set selection after registering listener to force update
+ mCellInfoRefreshRateSpinner.setSelection(mCellInfoRefreshRateIndex);
+
+ //set selection before registering to prevent update
+ mPreferredNetworkType.setSelection(mPreferredNetworkTypeResult, true);
+ mPreferredNetworkType.setOnItemSelectedListener(mPreferredNetworkHandler);
+
+ // set phone index
+ mSelectPhoneIndex.setSelection(mSelectedPhoneIndex, true);
+ mSelectPhoneIndex.setOnItemSelectedListener(mSelectPhoneIndexHandler);
+
+ mRadioPowerOnSwitch.setOnCheckedChangeListener(mRadioPowerOnChangeListener);
+ mImsVolteProvisionedSwitch.setOnCheckedChangeListener(mImsVolteCheckedChangeListener);
+ mImsVtProvisionedSwitch.setOnCheckedChangeListener(mImsVtCheckedChangeListener);
+ mImsWfcProvisionedSwitch.setOnCheckedChangeListener(mImsWfcCheckedChangeListener);
+ mEabProvisionedSwitch.setOnCheckedChangeListener(mEabCheckedChangeListener);
+
+ if (isCbrsSupported()) {
+ mCbrsDataSwitch.setChecked(getCbrsDataState());
+ mCbrsDataSwitch.setOnCheckedChangeListener(mCbrsDataSwitchChangeListener);
+ }
+
+ unregisterPhoneStateListener();
+ registerPhoneStateListener();
+
+ mConnectivityManager.registerNetworkCallback(
+ mDefaultNetworkRequest, mNetworkCallback, mHandler);
+
+ mSmsc.clearFocus();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+
+ log("onPause: unregister phone & data intents");
+
+ mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
+ mTelephonyManager.setCellInfoListRate(sCellInfoListRateDisabled);
+ mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
+
+ }
+
+ private void restoreFromBundle(Bundle b) {
+ if (b == null) {
+ return;
+ }
+
+ mPingHostnameResultV4 = b.getString("mPingHostnameResultV4", "");
+ mPingHostnameResultV6 = b.getString("mPingHostnameResultV6", "");
+ mHttpClientTestResult = b.getString("mHttpClientTestResult", "");
+
+ mPingHostnameV4.setText(mPingHostnameResultV4);
+ mPingHostnameV6.setText(mPingHostnameResultV6);
+ mHttpClientTest.setText(mHttpClientTestResult);
+
+ mPreferredNetworkTypeResult = b.getInt("mPreferredNetworkTypeResult",
+ PREFERRED_NETWORK_LABELS.length - 1);
+
+ mSelectedPhoneIndex = b.getInt("mSelectedPhoneIndex", 0);
+
+ mCellInfoRefreshRateIndex = b.getInt("mCellInfoRefreshRateIndex", 0);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ outState.putString("mPingHostnameResultV4", mPingHostnameResultV4);
+ outState.putString("mPingHostnameResultV6", mPingHostnameResultV6);
+ outState.putString("mHttpClientTestResult", mHttpClientTestResult);
+
+ outState.putInt("mPreferredNetworkTypeResult", mPreferredNetworkTypeResult);
+ outState.putInt("mSelectedPhoneIndex", mSelectedPhoneIndex);
+ outState.putInt("mCellInfoRefreshRateIndex", mCellInfoRefreshRateIndex);
+
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ menu.add(0, MENU_ITEM_SELECT_BAND, 0, R.string.radio_info_band_mode_label)
+ .setOnMenuItemClickListener(mSelectBandCallback)
+ .setAlphabeticShortcut('b');
+ menu.add(1, MENU_ITEM_VIEW_ADN, 0,
+ R.string.radioInfo_menu_viewADN).setOnMenuItemClickListener(mViewADNCallback);
+ menu.add(1, MENU_ITEM_VIEW_FDN, 0,
+ R.string.radioInfo_menu_viewFDN).setOnMenuItemClickListener(mViewFDNCallback);
+ menu.add(1, MENU_ITEM_VIEW_SDN, 0,
+ R.string.radioInfo_menu_viewSDN).setOnMenuItemClickListener(mViewSDNCallback);
+ if (ImsManager.isImsSupportedOnDevice(mPhone.getContext())) {
+ menu.add(1, MENU_ITEM_GET_IMS_STATUS,
+ 0, R.string.radioInfo_menu_getIMS).setOnMenuItemClickListener(mGetImsStatus);
+ }
+ menu.add(1, MENU_ITEM_TOGGLE_DATA,
+ 0, R.string.radio_info_data_connection_disable)
+ .setOnMenuItemClickListener(mToggleData);
+ return true;
+ }
+
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ // Get the TOGGLE DATA menu item in the right state.
+ MenuItem item = menu.findItem(MENU_ITEM_TOGGLE_DATA);
+ int state = mTelephonyManager.getDataState();
+ boolean visible = true;
+
+ switch (state) {
+ case TelephonyManager.DATA_CONNECTED:
+ case TelephonyManager.DATA_SUSPENDED:
+ item.setTitle(R.string.radio_info_data_connection_disable);
+ break;
+ case TelephonyManager.DATA_DISCONNECTED:
+ item.setTitle(R.string.radio_info_data_connection_enable);
+ break;
+ default:
+ visible = false;
+ break;
+ }
+ item.setVisible(visible);
+ return true;
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mQueuedWork.shutdown();
+ }
+
+ // returns array of string labels for each phone index. The array index is equal to the phone
+ // index.
+ private static String[] getPhoneIndexLabels(TelephonyManager tm) {
+ int phones = tm.getPhoneCount();
+ String[] labels = new String[phones];
+ for (int i = 0; i < phones; i++) {
+ labels[i] = "Phone " + i;
+ }
+ return labels;
+ }
+
+ private void unregisterPhoneStateListener() {
+ mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
+
+ // clear all fields so they are blank until the next listener event occurs
+ mOperatorName.setText("");
+ mGprsState.setText("");
+ mDataNetwork.setText("");
+ mVoiceNetwork.setText("");
+ mSent.setText("");
+ mReceived.setText("");
+ mCallState.setText("");
+ mLocation.setText("");
+ mMwiValue = false;
+ mMwi.setText("");
+ mCfiValue = false;
+ mCfi.setText("");
+ mCellInfo.setText("");
+ mDBm.setText("");
+ mGsmState.setText("");
+ mRoamingState.setText("");
+ mPhyChanConfig.setText("");
+ }
+
+ // register mPhoneStateListener for relevant fields using the current TelephonyManager
+ private void registerPhoneStateListener() {
+ mPhoneStateListener = new RadioInfoPhoneStateListener();
+ mTelephonyManager.listen(mPhoneStateListener,
+ PhoneStateListener.LISTEN_CALL_STATE
+ //b/27803938 - RadioInfo currently cannot read PRECISE_CALL_STATE
+ // | PhoneStateListener.LISTEN_PRECISE_CALL_STATE
+ | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
+ | PhoneStateListener.LISTEN_DATA_ACTIVITY
+ | PhoneStateListener.LISTEN_CELL_LOCATION
+ | PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR
+ | PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR
+ | PhoneStateListener.LISTEN_CELL_INFO
+ | PhoneStateListener.LISTEN_SERVICE_STATE
+ | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
+ | PhoneStateListener.LISTEN_PHYSICAL_CHANNEL_CONFIGURATION);
+ }
+
+ private void updateDnsCheckState() {
+ //FIXME: Replace with a TelephonyManager call
+ mDnsCheckState.setText(mPhone.isDnsCheckDisabled()
+ ? "0.0.0.0 allowed" : "0.0.0.0 not allowed");
+ }
+
+ private void updateBandwidths(int dlbw, int ulbw) {
+ dlbw = (dlbw < 0 || dlbw == Integer.MAX_VALUE) ? -1 : dlbw;
+ ulbw = (ulbw < 0 || ulbw == Integer.MAX_VALUE) ? -1 : ulbw;
+ mDownlinkKbps.setText(String.format("%-5d", dlbw));
+ mUplinkKbps.setText(String.format("%-5d", ulbw));
+ }
+
+
+ private void updateSignalStrength(SignalStrength signalStrength) {
+ Resources r = getResources();
+
+ int signalDbm = signalStrength.getDbm();
+
+ int signalAsu = signalStrength.getAsuLevel();
+
+ if (-1 == signalAsu) signalAsu = 0;
+
+ mDBm.setText(String.valueOf(signalDbm) + " "
+ + r.getString(R.string.radioInfo_display_dbm) + " "
+ + String.valueOf(signalAsu) + " "
+ + r.getString(R.string.radioInfo_display_asu));
+ }
+
+ private void updateLocation(CellLocation location) {
+ Resources r = getResources();
+ if (location instanceof GsmCellLocation) {
+ GsmCellLocation loc = (GsmCellLocation) location;
+ int lac = loc.getLac();
+ int cid = loc.getCid();
+ mLocation.setText(r.getString(R.string.radioInfo_lac) + " = "
+ + ((lac == -1) ? "unknown" : Integer.toHexString(lac))
+ + " "
+ + r.getString(R.string.radioInfo_cid) + " = "
+ + ((cid == -1) ? "unknown" : Integer.toHexString(cid)));
+ } else if (location instanceof CdmaCellLocation) {
+ CdmaCellLocation loc = (CdmaCellLocation) location;
+ int bid = loc.getBaseStationId();
+ int sid = loc.getSystemId();
+ int nid = loc.getNetworkId();
+ int lat = loc.getBaseStationLatitude();
+ int lon = loc.getBaseStationLongitude();
+ mLocation.setText("BID = "
+ + ((bid == -1) ? "unknown" : Integer.toHexString(bid))
+ + " "
+ + "SID = "
+ + ((sid == -1) ? "unknown" : Integer.toHexString(sid))
+ + " "
+ + "NID = "
+ + ((nid == -1) ? "unknown" : Integer.toHexString(nid))
+ + "\n"
+ + "LAT = "
+ + ((lat == -1) ? "unknown" : Integer.toHexString(lat))
+ + " "
+ + "LONG = "
+ + ((lon == -1) ? "unknown" : Integer.toHexString(lon)));
+ } else {
+ mLocation.setText("unknown");
+ }
+
+
+ }
+
+ private String getCellInfoDisplayString(int i) {
+ return (i != Integer.MAX_VALUE) ? Integer.toString(i) : "";
+ }
+
+ private String getCellInfoDisplayString(long i) {
+ return (i != Long.MAX_VALUE) ? Long.toString(i) : "";
+ }
+
+ private String getConnectionStatusString(CellInfo ci) {
+ String regStr = "";
+ String connStatStr = "";
+ String connector = "";
+
+ if (ci.isRegistered()) {
+ regStr = "R";
+ }
+ switch (ci.getCellConnectionStatus()) {
+ case CellInfo.CONNECTION_PRIMARY_SERVING: connStatStr = "P"; break;
+ case CellInfo.CONNECTION_SECONDARY_SERVING: connStatStr = "S"; break;
+ case CellInfo.CONNECTION_NONE: connStatStr = "N"; break;
+ case CellInfo.CONNECTION_UNKNOWN: /* Field is unsupported */ break;
+ default: break;
+ }
+ if (!TextUtils.isEmpty(regStr) && !TextUtils.isEmpty(connStatStr)) {
+ connector = "+";
+ }
+
+ return regStr + connector + connStatStr;
+ }
+
+ private String buildCdmaInfoString(CellInfoCdma ci) {
+ CellIdentityCdma cidCdma = ci.getCellIdentity();
+ CellSignalStrengthCdma ssCdma = ci.getCellSignalStrength();
+
+ return String.format("%-3.3s %-5.5s %-5.5s %-5.5s %-6.6s %-6.6s %-6.6s %-6.6s %-5.5s",
+ getConnectionStatusString(ci),
+ getCellInfoDisplayString(cidCdma.getSystemId()),
+ getCellInfoDisplayString(cidCdma.getNetworkId()),
+ getCellInfoDisplayString(cidCdma.getBasestationId()),
+ getCellInfoDisplayString(ssCdma.getCdmaDbm()),
+ getCellInfoDisplayString(ssCdma.getCdmaEcio()),
+ getCellInfoDisplayString(ssCdma.getEvdoDbm()),
+ getCellInfoDisplayString(ssCdma.getEvdoEcio()),
+ getCellInfoDisplayString(ssCdma.getEvdoSnr()));
+ }
+
+ private String buildGsmInfoString(CellInfoGsm ci) {
+ CellIdentityGsm cidGsm = ci.getCellIdentity();
+ CellSignalStrengthGsm ssGsm = ci.getCellSignalStrength();
+
+ return String.format("%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-4.4s %-4.4s\n",
+ getConnectionStatusString(ci),
+ getCellInfoDisplayString(cidGsm.getMcc()),
+ getCellInfoDisplayString(cidGsm.getMnc()),
+ getCellInfoDisplayString(cidGsm.getLac()),
+ getCellInfoDisplayString(cidGsm.getCid()),
+ getCellInfoDisplayString(cidGsm.getArfcn()),
+ getCellInfoDisplayString(cidGsm.getBsic()),
+ getCellInfoDisplayString(ssGsm.getDbm()));
+ }
+
+ private String buildLteInfoString(CellInfoLte ci) {
+ CellIdentityLte cidLte = ci.getCellIdentity();
+ CellSignalStrengthLte ssLte = ci.getCellSignalStrength();
+
+ return String.format(
+ "%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-3.3s %-6.6s %-2.2s %-4.4s %-4.4s %-2.2s\n",
+ getConnectionStatusString(ci),
+ getCellInfoDisplayString(cidLte.getMcc()),
+ getCellInfoDisplayString(cidLte.getMnc()),
+ getCellInfoDisplayString(cidLte.getTac()),
+ getCellInfoDisplayString(cidLte.getCi()),
+ getCellInfoDisplayString(cidLte.getPci()),
+ getCellInfoDisplayString(cidLte.getEarfcn()),
+ getCellInfoDisplayString(cidLte.getBandwidth()),
+ getCellInfoDisplayString(ssLte.getDbm()),
+ getCellInfoDisplayString(ssLte.getRsrq()),
+ getCellInfoDisplayString(ssLte.getTimingAdvance()));
+ }
+
+ private String buildWcdmaInfoString(CellInfoWcdma ci) {
+ CellIdentityWcdma cidWcdma = ci.getCellIdentity();
+ CellSignalStrengthWcdma ssWcdma = ci.getCellSignalStrength();
+
+ return String.format("%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-3.3s %-4.4s\n",
+ getConnectionStatusString(ci),
+ getCellInfoDisplayString(cidWcdma.getMcc()),
+ getCellInfoDisplayString(cidWcdma.getMnc()),
+ getCellInfoDisplayString(cidWcdma.getLac()),
+ getCellInfoDisplayString(cidWcdma.getCid()),
+ getCellInfoDisplayString(cidWcdma.getUarfcn()),
+ getCellInfoDisplayString(cidWcdma.getPsc()),
+ getCellInfoDisplayString(ssWcdma.getDbm()));
+ }
+
+ private String buildCellInfoString(List<CellInfo> arrayCi) {
+ String value = new String();
+ StringBuilder cdmaCells = new StringBuilder(),
+ gsmCells = new StringBuilder(),
+ lteCells = new StringBuilder(),
+ wcdmaCells = new StringBuilder();
+
+ if (arrayCi != null) {
+ for (CellInfo ci : arrayCi) {
+
+ if (ci instanceof CellInfoLte) {
+ lteCells.append(buildLteInfoString((CellInfoLte) ci));
+ } else if (ci instanceof CellInfoWcdma) {
+ wcdmaCells.append(buildWcdmaInfoString((CellInfoWcdma) ci));
+ } else if (ci instanceof CellInfoGsm) {
+ gsmCells.append(buildGsmInfoString((CellInfoGsm) ci));
+ } else if (ci instanceof CellInfoCdma) {
+ cdmaCells.append(buildCdmaInfoString((CellInfoCdma) ci));
+ }
+ }
+ if (lteCells.length() != 0) {
+ value += String.format(
+ "LTE\n%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-3.3s"
+ + " %-6.6s %-2.2s %-4.4s %-4.4s %-2.2s\n",
+ "SRV", "MCC", "MNC", "TAC", "CID", "PCI",
+ "EARFCN", "BW", "RSRP", "RSRQ", "TA");
+ value += lteCells.toString();
+ }
+ if (wcdmaCells.length() != 0) {
+ value += String.format(
+ "WCDMA\n%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-3.3s %-4.4s\n",
+ "SRV", "MCC", "MNC", "LAC", "CID", "UARFCN", "PSC", "RSCP");
+ value += wcdmaCells.toString();
+ }
+ if (gsmCells.length() != 0) {
+ value += String.format(
+ "GSM\n%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-4.4s %-4.4s\n",
+ "SRV", "MCC", "MNC", "LAC", "CID", "ARFCN", "BSIC", "RSSI");
+ value += gsmCells.toString();
+ }
+ if (cdmaCells.length() != 0) {
+ value += String.format(
+ "CDMA/EVDO\n%-3.3s %-5.5s %-5.5s %-5.5s"
+ + " %-6.6s %-6.6s %-6.6s %-6.6s %-5.5s\n",
+ "SRV", "SID", "NID", "BSID",
+ "C-RSSI", "C-ECIO", "E-RSSI", "E-ECIO", "E-SNR");
+ value += cdmaCells.toString();
+ }
+ } else {
+ value = "unknown";
+ }
+
+ return value.toString();
+ }
+
+ private void updateCellInfo(List<CellInfo> arrayCi) {
+ mCellInfo.setText(buildCellInfoString(arrayCi));
+ }
+
+ private void updateSubscriptionIds() {
+ mSubscriptionId.setText(Integer.toString(mPhone.getSubId()));
+ mDds.setText(Integer.toString(SubscriptionManager.getDefaultDataSubscriptionId()));
+ }
+
+ private void updateMessageWaiting() {
+ mMwi.setText(String.valueOf(mMwiValue));
+ }
+
+ private void updateCallRedirect() {
+ mCfi.setText(String.valueOf(mCfiValue));
+ }
+
+
+ private void updateServiceState(ServiceState serviceState) {
+ int state = serviceState.getState();
+ Resources r = getResources();
+ String display = r.getString(R.string.radioInfo_unknown);
+
+ switch (state) {
+ case ServiceState.STATE_IN_SERVICE:
+ display = r.getString(R.string.radioInfo_service_in);
+ break;
+ case ServiceState.STATE_OUT_OF_SERVICE:
+ case ServiceState.STATE_EMERGENCY_ONLY:
+ display = r.getString(R.string.radioInfo_service_emergency);
+ break;
+ case ServiceState.STATE_POWER_OFF:
+ display = r.getString(R.string.radioInfo_service_off);
+ break;
+ }
+
+ mGsmState.setText(display);
+
+ if (serviceState.getRoaming()) {
+ mRoamingState.setText(R.string.radioInfo_roaming_in);
+ } else {
+ mRoamingState.setText(R.string.radioInfo_roaming_not);
+ }
+
+ mOperatorName.setText(serviceState.getOperatorAlphaLong());
+ }
+
+ private void updatePhoneState(int state) {
+ Resources r = getResources();
+ String display = r.getString(R.string.radioInfo_unknown);
+
+ switch (state) {
+ case TelephonyManager.CALL_STATE_IDLE:
+ display = r.getString(R.string.radioInfo_phone_idle);
+ break;
+ case TelephonyManager.CALL_STATE_RINGING:
+ display = r.getString(R.string.radioInfo_phone_ringing);
+ break;
+ case TelephonyManager.CALL_STATE_OFFHOOK:
+ display = r.getString(R.string.radioInfo_phone_offhook);
+ break;
+ }
+
+ mCallState.setText(display);
+ }
+
+ private void updateDataState() {
+ int state = mTelephonyManager.getDataState();
+ Resources r = getResources();
+ String display = r.getString(R.string.radioInfo_unknown);
+
+ switch (state) {
+ case TelephonyManager.DATA_CONNECTED:
+ display = r.getString(R.string.radioInfo_data_connected);
+ break;
+ case TelephonyManager.DATA_CONNECTING:
+ display = r.getString(R.string.radioInfo_data_connecting);
+ break;
+ case TelephonyManager.DATA_DISCONNECTED:
+ display = r.getString(R.string.radioInfo_data_disconnected);
+ break;
+ case TelephonyManager.DATA_SUSPENDED:
+ display = r.getString(R.string.radioInfo_data_suspended);
+ break;
+ }
+
+ mGprsState.setText(display);
+ }
+
+ private void updateNetworkType() {
+ if (mPhone != null) {
+ ServiceState ss = mPhone.getServiceState();
+ mDataNetwork.setText(ServiceState.rilRadioTechnologyToString(
+ mPhone.getServiceState().getRilDataRadioTechnology()));
+ mVoiceNetwork.setText(ServiceState.rilRadioTechnologyToString(
+ mPhone.getServiceState().getRilVoiceRadioTechnology()));
+ }
+ }
+
+ private void updateProperties() {
+ String s;
+ Resources r = getResources();
+
+ s = mPhone.getDeviceId();
+ if (s == null) s = r.getString(R.string.radioInfo_unknown);
+ mDeviceId.setText(s);
+
+ s = mPhone.getSubscriberId();
+ if (s == null) s = r.getString(R.string.radioInfo_unknown);
+ mSubscriberId.setText(s);
+
+ //FIXME: Replace with a TelephonyManager call
+ s = mPhone.getLine1Number();
+ if (s == null) s = r.getString(R.string.radioInfo_unknown);
+ mLine1Number.setText(s);
+ }
+
+ private void updateDataStats2() {
+ Resources r = getResources();
+
+ long txPackets = TrafficStats.getMobileTxPackets();
+ long rxPackets = TrafficStats.getMobileRxPackets();
+ long txBytes = TrafficStats.getMobileTxBytes();
+ long rxBytes = TrafficStats.getMobileRxBytes();
+
+ String packets = r.getString(R.string.radioInfo_display_packets);
+ String bytes = r.getString(R.string.radioInfo_display_bytes);
+
+ mSent.setText(txPackets + " " + packets + ", " + txBytes + " " + bytes);
+ mReceived.setText(rxPackets + " " + packets + ", " + rxBytes + " " + bytes);
+ }
+
+ /**
+ * Ping a host name
+ */
+ private void pingHostname() {
+ try {
+ try {
+ Process p4 = Runtime.getRuntime().exec("ping -c 1 www.google.com");
+ int status4 = p4.waitFor();
+ if (status4 == 0) {
+ mPingHostnameResultV4 = "Pass";
+ } else {
+ mPingHostnameResultV4 = String.format("Fail(%d)", status4);
+ }
+ } catch (IOException e) {
+ mPingHostnameResultV4 = "Fail: IOException";
+ }
+ try {
+ Process p6 = Runtime.getRuntime().exec("ping6 -c 1 www.google.com");
+ int status6 = p6.waitFor();
+ if (status6 == 0) {
+ mPingHostnameResultV6 = "Pass";
+ } else {
+ mPingHostnameResultV6 = String.format("Fail(%d)", status6);
+ }
+ } catch (IOException e) {
+ mPingHostnameResultV6 = "Fail: IOException";
+ }
+ } catch (InterruptedException e) {
+ mPingHostnameResultV4 = mPingHostnameResultV6 = "Fail: InterruptedException";
+ }
+ }
+
+ /**
+ * This function checks for basic functionality of HTTP Client.
+ */
+ private void httpClientTest() {
+ HttpURLConnection urlConnection = null;
+ try {
+ // TODO: Hardcoded for now, make it UI configurable
+ URL url = new URL("https://www.google.com");
+ urlConnection = (HttpURLConnection) url.openConnection();
+ if (urlConnection.getResponseCode() == 200) {
+ mHttpClientTestResult = "Pass";
+ } else {
+ mHttpClientTestResult = "Fail: Code: " + urlConnection.getResponseMessage();
+ }
+ } catch (IOException e) {
+ mHttpClientTestResult = "Fail: IOException";
+ } finally {
+ if (urlConnection != null) {
+ urlConnection.disconnect();
+ }
+ }
+ }
+
+ private void refreshSmsc() {
+ mQueuedWork.execute(new Runnable() {
+ public void run() {
+ //FIXME: Replace with a TelephonyManager call
+ mPhone.getSmscAddress(mHandler.obtainMessage(EVENT_QUERY_SMSC_DONE));
+ }
+ });
+ }
+
+ private void updateAllCellInfo() {
+
+ mCellInfo.setText("");
+ mLocation.setText("");
+
+ final Runnable updateAllCellInfoResults = new Runnable() {
+ public void run() {
+ updateLocation(mCellLocationResult);
+ updateCellInfo(mCellInfoResult);
+ }
+ };
+
+ mQueuedWork.execute(new Runnable() {
+ @Override
+ public void run() {
+ mCellInfoResult = mTelephonyManager.getAllCellInfo();
+ mCellLocationResult = mTelephonyManager.getCellLocation();
+
+ mHandler.post(updateAllCellInfoResults);
+ }
+ });
+ }
+
+ private void updatePingState() {
+ // Set all to unknown since the threads will take a few secs to update.
+ mPingHostnameResultV4 = getResources().getString(R.string.radioInfo_unknown);
+ mPingHostnameResultV6 = getResources().getString(R.string.radioInfo_unknown);
+ mHttpClientTestResult = getResources().getString(R.string.radioInfo_unknown);
+
+ mPingHostnameV4.setText(mPingHostnameResultV4);
+ mPingHostnameV6.setText(mPingHostnameResultV6);
+ mHttpClientTest.setText(mHttpClientTestResult);
+
+ final Runnable updatePingResults = new Runnable() {
+ public void run() {
+ mPingHostnameV4.setText(mPingHostnameResultV4);
+ mPingHostnameV6.setText(mPingHostnameResultV6);
+ mHttpClientTest.setText(mHttpClientTestResult);
+ }
+ };
+
+ Thread hostname = new Thread() {
+ @Override
+ public void run() {
+ pingHostname();
+ mHandler.post(updatePingResults);
+ }
+ };
+ hostname.start();
+
+ Thread httpClient = new Thread() {
+ @Override
+ public void run() {
+ httpClientTest();
+ mHandler.post(updatePingResults);
+ }
+ };
+ httpClient.start();
+ }
+
+ private MenuItem.OnMenuItemClickListener mViewADNCallback =
+ new MenuItem.OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ // XXX We need to specify the component here because if we don't
+ // the activity manager will try to resolve the type by calling
+ // the content provider, which causes it to be loaded in a process
+ // other than the Dialer process, which causes a lot of stuff to
+ // break.
+ intent.setClassName("com.android.phone", "com.android.phone.SimContacts");
+ startActivity(intent);
+ return true;
+ }
+ };
+
+ private MenuItem.OnMenuItemClickListener mViewFDNCallback =
+ new MenuItem.OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ // XXX We need to specify the component here because if we don't
+ // the activity manager will try to resolve the type by calling
+ // the content provider, which causes it to be loaded in a process
+ // other than the Dialer process, which causes a lot of stuff to
+ // break.
+ intent.setClassName("com.android.phone", "com.android.phone.settings.fdn.FdnList");
+ startActivity(intent);
+ return true;
+ }
+ };
+
+ private MenuItem.OnMenuItemClickListener mViewSDNCallback =
+ new MenuItem.OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ Intent intent = new Intent(
+ Intent.ACTION_VIEW, Uri.parse("content://icc/sdn"));
+ // XXX We need to specify the component here because if we don't
+ // the activity manager will try to resolve the type by calling
+ // the content provider, which causes it to be loaded in a process
+ // other than the Dialer process, which causes a lot of stuff to
+ // break.
+ intent.setClassName("com.android.phone", "com.android.phone.ADNList");
+ startActivity(intent);
+ return true;
+ }
+ };
+
+ private MenuItem.OnMenuItemClickListener mGetImsStatus =
+ new MenuItem.OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ boolean isImsRegistered = mPhone.isImsRegistered();
+ boolean availableVolte = mPhone.isVolteEnabled();
+ boolean availableWfc = mPhone.isWifiCallingEnabled();
+ boolean availableVt = mPhone.isVideoEnabled();
+ boolean availableUt = mPhone.isUtEnabled();
+
+ final String imsRegString = isImsRegistered
+ ? getString(R.string.radio_info_ims_reg_status_registered)
+ : getString(R.string.radio_info_ims_reg_status_not_registered);
+
+ final String available = getString(R.string.radio_info_ims_feature_status_available);
+ final String unavailable = getString(
+ R.string.radio_info_ims_feature_status_unavailable);
+
+ String imsStatus = getString(R.string.radio_info_ims_reg_status,
+ imsRegString,
+ availableVolte ? available : unavailable,
+ availableWfc ? available : unavailable,
+ availableVt ? available : unavailable,
+ availableUt ? available : unavailable);
+
+ AlertDialog imsDialog = new AlertDialog.Builder(RadioInfo.this)
+ .setMessage(imsStatus)
+ .setTitle(getString(R.string.radio_info_ims_reg_status_title))
+ .create();
+
+ imsDialog.show();
+
+ return true;
+ }
+ };
+
+ private MenuItem.OnMenuItemClickListener mSelectBandCallback =
+ new MenuItem.OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ Intent intent = new Intent();
+ intent.setClass(RadioInfo.this, BandMode.class);
+ startActivity(intent);
+ return true;
+ }
+ };
+
+ private MenuItem.OnMenuItemClickListener mToggleData =
+ new MenuItem.OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ int state = mTelephonyManager.getDataState();
+ switch (state) {
+ case TelephonyManager.DATA_CONNECTED:
+ mTelephonyManager.setDataEnabled(false);
+ break;
+ case TelephonyManager.DATA_DISCONNECTED:
+ mTelephonyManager.setDataEnabled(true);
+ break;
+ default:
+ // do nothing
+ break;
+ }
+ return true;
+ }
+ };
+
+ private boolean isRadioOn() {
+ //FIXME: Replace with a TelephonyManager call
+ return mPhone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
+ }
+
+ private void updateRadioPowerState() {
+ //delightful hack to prevent on-checked-changed calls from
+ //actually forcing the radio preference to its transient/current value.
+ mRadioPowerOnSwitch.setOnCheckedChangeListener(null);
+ mRadioPowerOnSwitch.setChecked(isRadioOn());
+ mRadioPowerOnSwitch.setOnCheckedChangeListener(mRadioPowerOnChangeListener);
+ }
+
+ void setImsVolteProvisionedState(boolean state) {
+ Log.d(TAG, "setImsVolteProvisioned state: " + ((state) ? "on" : "off"));
+ setImsConfigProvisionedState(IMS_VOLTE_PROVISIONED_CONFIG_ID, state);
+ }
+
+ void setImsVtProvisionedState(boolean state) {
+ Log.d(TAG, "setImsVtProvisioned() state: " + ((state) ? "on" : "off"));
+ setImsConfigProvisionedState(IMS_VT_PROVISIONED_CONFIG_ID, state);
+ }
+
+ void setImsWfcProvisionedState(boolean state) {
+ Log.d(TAG, "setImsWfcProvisioned() state: " + ((state) ? "on" : "off"));
+ setImsConfigProvisionedState(IMS_WFC_PROVISIONED_CONFIG_ID, state);
+ }
+
+ void setEabProvisionedState(boolean state) {
+ Log.d(TAG, "setEabProvisioned() state: " + ((state) ? "on" : "off"));
+ setImsConfigProvisionedState(EAB_PROVISIONED_CONFIG_ID, state);
+ }
+
+ void setImsConfigProvisionedState(int configItem, boolean state) {
+ if (mPhone != null && mImsManager != null) {
+ mQueuedWork.execute(new Runnable() {
+ public void run() {
+ try {
+ mImsManager.getConfigInterface().setProvisionedValue(
+ configItem, state ? 1 : 0);
+ } catch (ImsException e) {
+ Log.e(TAG, "setImsConfigProvisioned() exception:", e);
+ }
+ }
+ });
+ }
+ }
+
+ OnCheckedChangeListener mRadioPowerOnChangeListener = new OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ log("toggle radio power: currently " + (isRadioOn() ? "on" : "off"));
+ mPhone.setRadioPower(isChecked);
+ }
+ };
+
+ private boolean isImsVolteProvisioned() {
+ if (mPhone != null && mImsManager != null) {
+ return mImsManager.isVolteEnabledByPlatform(mPhone.getContext())
+ && mImsManager.isVolteProvisionedOnDevice(mPhone.getContext());
+ }
+ return false;
+ }
+
+ OnCheckedChangeListener mImsVolteCheckedChangeListener = new OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ setImsVolteProvisionedState(isChecked);
+ }
+ };
+
+ private boolean isImsVtProvisioned() {
+ if (mPhone != null && mImsManager != null) {
+ return mImsManager.isVtEnabledByPlatform(mPhone.getContext())
+ && mImsManager.isVtProvisionedOnDevice(mPhone.getContext());
+ }
+ return false;
+ }
+
+ OnCheckedChangeListener mImsVtCheckedChangeListener = new OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ setImsVtProvisionedState(isChecked);
+ }
+ };
+
+ private boolean isImsWfcProvisioned() {
+ if (mPhone != null && mImsManager != null) {
+ return mImsManager.isWfcEnabledByPlatform(mPhone.getContext())
+ && mImsManager.isWfcProvisionedOnDevice(mPhone.getContext());
+ }
+ return false;
+ }
+
+ OnCheckedChangeListener mImsWfcCheckedChangeListener = new OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ setImsWfcProvisionedState(isChecked);
+ }
+ };
+
+ private boolean isEabProvisioned() {
+ return isFeatureProvisioned(EAB_PROVISIONED_CONFIG_ID, false);
+ }
+
+ OnCheckedChangeListener mEabCheckedChangeListener = new OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ setEabProvisionedState(isChecked);
+ }
+ };
+
+ private boolean isFeatureProvisioned(int featureId, boolean defaultValue) {
+ boolean provisioned = defaultValue;
+ if (mImsManager != null) {
+ try {
+ ImsConfig imsConfig = mImsManager.getConfigInterface();
+ if (imsConfig != null) {
+ provisioned =
+ (imsConfig.getProvisionedValue(featureId)
+ == ImsConfig.FeatureValueConstants.ON);
+ }
+ } catch (ImsException ex) {
+ Log.e(TAG, "isFeatureProvisioned() exception:", ex);
+ }
+ }
+
+ log("isFeatureProvisioned() featureId=" + featureId + " provisioned=" + provisioned);
+ return provisioned;
+ }
+
+ private static boolean isEabEnabledByPlatform(Context context) {
+ if (context != null) {
+ CarrierConfigManager configManager = (CarrierConfigManager)
+ context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ if (configManager != null && configManager.getConfig().getBoolean(
+ CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void updateImsProvisionedState() {
+ if (!ImsManager.isImsSupportedOnDevice(mPhone.getContext())) {
+ return;
+ }
+ log("updateImsProvisionedState isImsVolteProvisioned()=" + isImsVolteProvisioned());
+ //delightful hack to prevent on-checked-changed calls from
+ //actually forcing the ims provisioning to its transient/current value.
+ mImsVolteProvisionedSwitch.setOnCheckedChangeListener(null);
+ mImsVolteProvisionedSwitch.setChecked(isImsVolteProvisioned());
+ mImsVolteProvisionedSwitch.setOnCheckedChangeListener(mImsVolteCheckedChangeListener);
+ mImsVolteProvisionedSwitch.setEnabled(!IS_USER_BUILD
+ && mImsManager.isVolteEnabledByPlatform(mPhone.getContext()));
+
+ mImsVtProvisionedSwitch.setOnCheckedChangeListener(null);
+ mImsVtProvisionedSwitch.setChecked(isImsVtProvisioned());
+ mImsVtProvisionedSwitch.setOnCheckedChangeListener(mImsVtCheckedChangeListener);
+ mImsVtProvisionedSwitch.setEnabled(!IS_USER_BUILD
+ && mImsManager.isVtEnabledByPlatform(mPhone.getContext()));
+
+ mImsWfcProvisionedSwitch.setOnCheckedChangeListener(null);
+ mImsWfcProvisionedSwitch.setChecked(isImsWfcProvisioned());
+ mImsWfcProvisionedSwitch.setOnCheckedChangeListener(mImsWfcCheckedChangeListener);
+ mImsWfcProvisionedSwitch.setEnabled(!IS_USER_BUILD
+ && mImsManager.isWfcEnabledByPlatform(mPhone.getContext()));
+
+ mEabProvisionedSwitch.setOnCheckedChangeListener(null);
+ mEabProvisionedSwitch.setChecked(isEabProvisioned());
+ mEabProvisionedSwitch.setOnCheckedChangeListener(mEabCheckedChangeListener);
+ mEabProvisionedSwitch.setEnabled(!IS_USER_BUILD
+ && isEabEnabledByPlatform(mPhone.getContext()));
+ }
+
+ OnClickListener mDnsCheckButtonHandler = new OnClickListener() {
+ public void onClick(View v) {
+ //FIXME: Replace with a TelephonyManager call
+ mPhone.disableDnsCheck(!mPhone.isDnsCheckDisabled());
+ updateDnsCheckState();
+ }
+ };
+
+ OnClickListener mOemInfoButtonHandler = new OnClickListener() {
+ public void onClick(View v) {
+ Intent intent = new Intent(OEM_RADIO_INFO_INTENT);
+ try {
+ startActivity(intent);
+ } catch (android.content.ActivityNotFoundException ex) {
+ log("OEM-specific Info/Settings Activity Not Found : " + ex);
+ // If the activity does not exist, there are no OEM
+ // settings, and so we can just do nothing...
+ }
+ }
+ };
+
+ OnClickListener mPingButtonHandler = new OnClickListener() {
+ public void onClick(View v) {
+ updatePingState();
+ }
+ };
+
+ OnClickListener mUpdateSmscButtonHandler = new OnClickListener() {
+ public void onClick(View v) {
+ mUpdateSmscButton.setEnabled(false);
+ mQueuedWork.execute(new Runnable() {
+ public void run() {
+ mPhone.setSmscAddress(mSmsc.getText().toString(),
+ mHandler.obtainMessage(EVENT_UPDATE_SMSC_DONE));
+ }
+ });
+ }
+ };
+
+ OnClickListener mRefreshSmscButtonHandler = new OnClickListener() {
+ public void onClick(View v) {
+ refreshSmsc();
+ }
+ };
+
+ OnClickListener mCarrierProvisioningButtonHandler = new OnClickListener() {
+ public void onClick(View v) {
+ final Intent intent = new Intent("com.android.settings.CARRIER_PROVISIONING");
+ final ComponentName serviceComponent = ComponentName.unflattenFromString(
+ "com.android.omadm.service/.DMIntentReceiver");
+ intent.setComponent(serviceComponent);
+ sendBroadcast(intent);
+ }
+ };
+
+ OnClickListener mTriggerCarrierProvisioningButtonHandler = new OnClickListener() {
+ public void onClick(View v) {
+ final Intent intent = new Intent("com.android.settings.TRIGGER_CARRIER_PROVISIONING");
+ final ComponentName serviceComponent = ComponentName.unflattenFromString(
+ "com.android.omadm.service/.DMIntentReceiver");
+ intent.setComponent(serviceComponent);
+ sendBroadcast(intent);
+ }
+ };
+
+ AdapterView.OnItemSelectedListener mPreferredNetworkHandler =
+ new AdapterView.OnItemSelectedListener() {
+
+ public void onItemSelected(AdapterView parent, View v, int pos, long id) {
+ if (mPreferredNetworkTypeResult != pos && pos >= 0
+ && pos <= PREFERRED_NETWORK_LABELS.length - 2) {
+ mPreferredNetworkTypeResult = pos;
+
+ // TODO: Possibly migrate this to TelephonyManager.setPreferredNetworkType()
+ // which today still has some issues (mostly that the "set" is conditional
+ // on a successful modem call, which is not what we want). Instead we always
+ // want this setting to be set, so that if the radio hiccups and this setting
+ // is for some reason unsuccessful, future calls to the radio will reflect
+ // the users's preference which is set here.
+ final int subId = mPhone.getSubId();
+ if (SubscriptionManager.isUsableSubIdValue(subId)) {
+ Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+ PREFERRED_NETWORK_MODE + subId, mPreferredNetworkTypeResult);
+ }
+ log("Calling setPreferredNetworkType(" + mPreferredNetworkTypeResult + ")");
+ Message msg = mHandler.obtainMessage(EVENT_SET_PREFERRED_TYPE_DONE);
+ mPhone.setPreferredNetworkType(mPreferredNetworkTypeResult, msg);
+ }
+ }
+
+ public void onNothingSelected(AdapterView parent) {
+ }
+ };
+
+ AdapterView.OnItemSelectedListener mSelectPhoneIndexHandler =
+ new AdapterView.OnItemSelectedListener() {
+
+ public void onItemSelected(AdapterView parent, View v, int pos, long id) {
+ if (pos >= 0 && pos <= sPhoneIndexLabels.length - 1) {
+ // the array position is equal to the phone index
+ int phoneIndex = pos;
+ Phone[] phones = PhoneFactory.getPhones();
+ if (phones == null || phones.length <= phoneIndex) {
+ return;
+ }
+ // getSubId says it takes a slotIndex, but it actually takes a phone index
+ int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ int[] subIds = SubscriptionManager.getSubId(phoneIndex);
+ if (subIds != null && subIds.length > 0) {
+ subId = subIds[0];
+ }
+ mSelectedPhoneIndex = phoneIndex;
+
+ updatePhoneIndex(phoneIndex, subId);
+ }
+ }
+
+ public void onNothingSelected(AdapterView parent) {
+ }
+ };
+
+ AdapterView.OnItemSelectedListener mCellInfoRefreshRateHandler =
+ new AdapterView.OnItemSelectedListener() {
+
+ public void onItemSelected(AdapterView parent, View v, int pos, long id) {
+ mCellInfoRefreshRateIndex = pos;
+ mTelephonyManager.setCellInfoListRate(CELL_INFO_REFRESH_RATES[pos]);
+ updateAllCellInfo();
+ }
+
+ public void onNothingSelected(AdapterView parent) {
+ }
+ };
+
+ boolean isCbrsSupported() {
+ return getResources().getBoolean(
+ com.android.internal.R.bool.config_cbrs_supported);
+ }
+
+ void updateCbrsDataState(boolean state) {
+ Log.d(TAG, "setCbrsDataSwitchState() state:" + ((state) ? "on" : "off"));
+ if (mTelephonyManager != null) {
+ mQueuedWork.execute(new Runnable() {
+ public void run() {
+ mTelephonyManager.setOpportunisticNetworkState(state);
+ mCbrsDataSwitch.setChecked(getCbrsDataState());
+ }
+ });
+ }
+ }
+
+ boolean getCbrsDataState() {
+ boolean state = false;
+ if (mTelephonyManager != null) {
+ state = mTelephonyManager.isOpportunisticNetworkEnabled();
+ }
+ Log.d(TAG, "getCbrsDataState() state:" + ((state) ? "on" : "off"));
+ return state;
+ }
+
+ OnCheckedChangeListener mCbrsDataSwitchChangeListener = new OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ updateCbrsDataState(isChecked);
+ }
+ };
+
+ private void showDsdsChangeDialog() {
+ final AlertDialog confirmDialog = new Builder(RadioInfo.this)
+ .setTitle(R.string.dsds_dialog_title)
+ .setMessage(R.string.dsds_dialog_message)
+ .setPositiveButton(R.string.dsds_dialog_confirm, mOnDsdsDialogConfirmedListener)
+ .setNegativeButton(R.string.dsds_dialog_cancel, mOnDsdsDialogConfirmedListener)
+ .create();
+ confirmDialog.show();
+ }
+
+ private static boolean isDsdsSupported() {
+ return (TelephonyManager.getDefault().isMultiSimSupported()
+ == TelephonyManager.MULTISIM_ALLOWED);
+ }
+
+ private static boolean isDsdsEnabled() {
+ return TelephonyManager.getDefault().getPhoneCount() > 1;
+ }
+
+ private void performDsdsSwitch() {
+ mTelephonyManager.switchMultiSimConfig(mDsdsSwitch.isChecked() ? 2 : 1);
+ }
+
+ /**
+ * @return {@code True} if the device is only supported dsds mode.
+ */
+ private boolean dsdsModeOnly() {
+ String dsdsMode = SystemProperties.get(DSDS_MODE_PROPERTY);
+ return !TextUtils.isEmpty(dsdsMode) && Integer.parseInt(dsdsMode) == ALWAYS_ON_DSDS_MODE;
+ }
+
+ DialogInterface.OnClickListener mOnDsdsDialogConfirmedListener =
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (which == DialogInterface.BUTTON_POSITIVE) {
+ mDsdsSwitch.toggle();
+ performDsdsSwitch();
+ }
+ }
+ };
+}