Copy MobileNetworkSettings to settings app
This is a CL to copy most components from telephony to settings app with following changes to pass the preupload check: 1. Add [CHAR LIMIT]/comments for strings that miss them This CL cannot build and future CL will fix the broken part. Bug: 114749736 Test: Build Change-Id: I744d537610eeeb7f2fb801defdd0ce47ef6088b6
This commit is contained in:
@@ -1133,4 +1133,186 @@
|
|||||||
<item>4</item> <!-- AutofillManager.FLAG_ADD_CLIENT_VERBOSE -->
|
<item>4</item> <!-- AutofillManager.FLAG_ADD_CLIENT_VERBOSE -->
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="enabled_networks_choices" translatable="false">
|
||||||
|
<item>@string/network_lte</item>
|
||||||
|
<item>@string/network_3G</item>
|
||||||
|
<item>@string/network_2G</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="enabled_networks_4g_choices" translatable="false">
|
||||||
|
<item>@string/network_4G</item>
|
||||||
|
<item>@string/network_3G</item>
|
||||||
|
<item>@string/network_2G</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="enabled_networks_values" translatable="false">
|
||||||
|
<item>"9"</item>
|
||||||
|
<item>"0"</item>
|
||||||
|
<item>"1"</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="cdma_system_select_choices">
|
||||||
|
<!-- System select dialog screen, setting option name -->
|
||||||
|
<item>Home only</item>
|
||||||
|
<!-- Remove the following option "Affiliated Networks" from the option list -->
|
||||||
|
<!-- <item>Affiliated Networks</item> -->
|
||||||
|
<!-- System select dialog screen, setting option name -->
|
||||||
|
<item>Automatic</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="cdma_system_select_values" translatable="false">
|
||||||
|
<!-- Do not translate. -->
|
||||||
|
<item>"0"</item>
|
||||||
|
<!-- Remove the following value "1" which corresponds to "Affiliated Networks" above -->
|
||||||
|
<!-- <item>"1"</item> -->
|
||||||
|
<!-- Do not translate. -->
|
||||||
|
<item>"2"</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<!-- The preferred network modes in Mobile network settings -->
|
||||||
|
<string-array name="preferred_network_mode_choices">
|
||||||
|
<item>GSM/WCDMA preferred</item>
|
||||||
|
<item>GSM only</item>
|
||||||
|
<item>WCDMA only</item>
|
||||||
|
<item>GSM/WCDMA auto</item>
|
||||||
|
<item>CDMA/EvDo auto</item>
|
||||||
|
<item>CDMA w/o EvDo</item>
|
||||||
|
<item>EvDo only</item>
|
||||||
|
<item>CDMA/EvDo/GSM/WCDMA</item>
|
||||||
|
<item>CDMA + LTE/EvDo</item>
|
||||||
|
<item>GSM/WCDMA/LTE</item>
|
||||||
|
<item>Global</item>
|
||||||
|
<item>LTE</item>
|
||||||
|
<item>LTE / WCDMA</item>
|
||||||
|
<item>TDSCDMA only</item>
|
||||||
|
<item>TDSCDMA/WCDMA</item>
|
||||||
|
<item>LTE/TDSCDMA</item>
|
||||||
|
<item>TDSCDMA/GSM</item>
|
||||||
|
<item>LTE/TDSCDMA/GSM</item>
|
||||||
|
<item>TDSCDMA/GSM/WCDMA</item>
|
||||||
|
<item>LTE/TDSCDMA/WCDMA</item>
|
||||||
|
<item>LTE/TDSCDMA/GSM/WCDMA</item>
|
||||||
|
<item>TDSCDMA/CDMA/EVDO/GSM/WCDMA </item>
|
||||||
|
<item>LTE/TDSCDMA/CDMA/EVDO/GSM/WCDMA</item>
|
||||||
|
</string-array>
|
||||||
|
<!-- The preferred network modes RIL constants, in order of the modes above,
|
||||||
|
e.g. the choice "GSM/WCDMA preferred" has the corresponding value "0" -->
|
||||||
|
<string-array name="preferred_network_mode_values" translatable="false">
|
||||||
|
<item>"0"</item>
|
||||||
|
<item>"1"</item>
|
||||||
|
<item>"2"</item>
|
||||||
|
<item>"3"</item>
|
||||||
|
<item>"4"</item>
|
||||||
|
<item>"5"</item>
|
||||||
|
<item>"6"</item>
|
||||||
|
<item>"7"</item>
|
||||||
|
<item>"8"</item>
|
||||||
|
<item>"9"</item>
|
||||||
|
<item>"10"</item>
|
||||||
|
<item>"11"</item>
|
||||||
|
<item>"12"</item>
|
||||||
|
<item>"13"</item>
|
||||||
|
<item>"14"</item>
|
||||||
|
<item>"15"</item>
|
||||||
|
<item>"16"</item>
|
||||||
|
<item>"17"</item>
|
||||||
|
<item>"18"</item>
|
||||||
|
<item>"19"</item>
|
||||||
|
<item>"20"</item>
|
||||||
|
<item>"21"</item>
|
||||||
|
<item>"22"</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<!-- Choices for CDMA subscription-->
|
||||||
|
<string-array name="cdma_subscription_choices">
|
||||||
|
<item>RUIM/SIM</item>
|
||||||
|
<item>NV</item>
|
||||||
|
</string-array>
|
||||||
|
<!-- Values for CDMA subscription-->
|
||||||
|
<string-array name="cdma_subscription_values">
|
||||||
|
<item>"0"</item>
|
||||||
|
<item>"1"</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="enabled_networks_except_gsm_choices" translatable="false">
|
||||||
|
<item>@string/network_lte</item>
|
||||||
|
<item>@string/network_3G</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="enabled_networks_except_gsm_4g_choices" translatable="false">
|
||||||
|
<item>@string/network_4G</item>
|
||||||
|
<item>@string/network_3G</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="enabled_networks_except_gsm_values" translatable="false">
|
||||||
|
<item>"9"</item>
|
||||||
|
<item>"0"</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="enabled_networks_except_lte_choices" translatable="false">
|
||||||
|
<item>@string/network_3G</item>
|
||||||
|
<item>@string/network_2G</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="enabled_networks_except_lte_values" translatable="false">
|
||||||
|
<item>"0"</item>
|
||||||
|
<item>"1"</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="enabled_networks_except_gsm_lte_choices" translatable="false">
|
||||||
|
<item>@string/network_3G</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="enabled_networks_except_gsm_lte_values" translatable="false">
|
||||||
|
<item>"0"</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="enabled_networks_cdma_choices" translatable="false">
|
||||||
|
<item>@string/network_lte</item>
|
||||||
|
<item>@string/network_3G</item>
|
||||||
|
<item>@string/network_1x</item>
|
||||||
|
<item>@string/network_global</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="enabled_networks_cdma_values" translatable="false">
|
||||||
|
<item>"8"</item>
|
||||||
|
<item>"4"</item>
|
||||||
|
<item>"5"</item>
|
||||||
|
<item>"10"</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="enabled_networks_cdma_no_lte_choices" translatable="false">
|
||||||
|
<item>@string/network_3G</item>
|
||||||
|
<item>@string/network_1x</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="enabled_networks_cdma_no_lte_values" translatable="false">
|
||||||
|
<item>"4"</item>
|
||||||
|
<item>"5"</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="enabled_networks_cdma_only_lte_choices" translatable="false">
|
||||||
|
<item>@string/network_lte</item>
|
||||||
|
<item>@string/network_global</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="enabled_networks_cdma_only_lte_values" translatable="false">
|
||||||
|
<item>"8"</item>
|
||||||
|
<item>"10"</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="enabled_networks_tdscdma_choices" translatable="false">
|
||||||
|
<item>@string/network_lte</item>
|
||||||
|
<item>@string/network_3G</item>
|
||||||
|
<item>@string/network_2G</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="enabled_networks_tdscdma_values" translatable="false">
|
||||||
|
<item>"22"</item>
|
||||||
|
<item>"18"</item>
|
||||||
|
<item>"1"</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<!--String arrays for World preferred netwrok modes -->
|
||||||
|
<string-array name="preferred_network_mode_choices_world_mode">
|
||||||
|
<item>Global</item>
|
||||||
|
<item>LTE / CDMA</item>
|
||||||
|
<item>LTE / GSM / UMTS</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="preferred_network_mode_values_world_mode">
|
||||||
|
<item>"10"</item>
|
||||||
|
<item>"8"</item>
|
||||||
|
<item>"9"</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@@ -136,4 +136,8 @@
|
|||||||
|
|
||||||
<!-- Whether or not TopLevelSettings should force rounded icon for injected tiles -->
|
<!-- Whether or not TopLevelSettings should force rounded icon for injected tiles -->
|
||||||
<bool name="config_force_rounded_icon_TopLevelSettings">true</bool>
|
<bool name="config_force_rounded_icon_TopLevelSettings">true</bool>
|
||||||
|
|
||||||
|
<!-- TODO(b/114749736): migrate override for config value -->
|
||||||
|
<!-- Show enabled lte option for lte device -->
|
||||||
|
<bool name="config_enabled_lte" translatable="false">false</bool>
|
||||||
</resources>
|
</resources>
|
||||||
|
@@ -10112,4 +10112,151 @@
|
|||||||
|
|
||||||
<!-- Message informs the user that has no SIM card in personalized Settings [CHAR LIMIT=30] -->
|
<!-- Message informs the user that has no SIM card in personalized Settings [CHAR LIMIT=30] -->
|
||||||
<string name="no_sim_card">No SIM card</string>
|
<string name="no_sim_card">No SIM card</string>
|
||||||
|
|
||||||
|
<!-- Carrier variant of Enhaced 4G LTE Mode title. [CHAR LIMIT=50] -->
|
||||||
|
<string name="enhanced_4g_lte_mode_title_variant">Advanced Calling</string>
|
||||||
|
<!-- The following strings are summaries for preferred network modes in Mobile network settings,
|
||||||
|
and have a character limit of 100 -->
|
||||||
|
<!-- WCDMA preferred [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_wcdma_perf_summary">Preferred network mode: WCDMA preferred</string>
|
||||||
|
<!-- GSM only [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_gsm_only_summary">Preferred network mode: GSM only</string>
|
||||||
|
<!-- WCDMA only [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_wcdma_only_summary">Preferred network mode: WCDMA only</string>
|
||||||
|
<!-- GSM / WCDMA [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_gsm_wcdma_summary">Preferred network mode: GSM / WCDMA</string>
|
||||||
|
<!-- CDMA [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_cdma_summary">Preferred network mode: CDMA</string>
|
||||||
|
<!-- CDMA / EvDo [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_cdma_evdo_summary">Preferred network mode: CDMA / EvDo</string>
|
||||||
|
<!-- CDMA only [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_cdma_only_summary">Preferred network mode: CDMA only</string>
|
||||||
|
<!-- EvDo only [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_evdo_only_summary">Preferred network mode: EvDo only</string>
|
||||||
|
<!-- CDMA/EvDo/GSM/WCDMA [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_cdma_evdo_gsm_wcdma_summary">Preferred network mode: CDMA/EvDo/GSM/WCDMA</string>
|
||||||
|
<!-- LTE [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_lte_summary">Preferred network mode: LTE </string>
|
||||||
|
<!-- GSM/WCDMA/LTE [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_lte_gsm_wcdma_summary">Preferred network mode: GSM/WCDMA/LTE</string>
|
||||||
|
<!-- CDMA+LTE/EVDO [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_lte_cdma_evdo_summary">Preferred network mode: CDMA+LTE/EVDO</string>
|
||||||
|
<!-- Global [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_global_summary">Preferred network mode: Global</string>
|
||||||
|
<!-- LTE / WCDMA [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_lte_wcdma_summary">Preferred network mode: LTE / WCDMA</string>
|
||||||
|
<!-- LTE / GSM / UMTS [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_lte_gsm_umts_summary">Preferred network mode: LTE / GSM / UMTS</string>
|
||||||
|
<!-- LTE / CDMA [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_lte_cdma_summary">Preferred network mode: LTE / CDMA</string>
|
||||||
|
<!-- TDSCDMA [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_tdscdma_summary">Preferred network mode: TDSCDMA</string>
|
||||||
|
<!-- TDSCDMA / WCDMA [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_tdscdma_wcdma_summary">Preferred network mode: TDSCDMA / WCDMA</string>
|
||||||
|
<!-- LTE / TDSCDMA [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_lte_tdscdma_summary">Preferred network mode: LTE / TDSCDMA</string>
|
||||||
|
<!-- TDSCDMA / GSM [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_tdscdma_gsm_summary">Preferred network mode: TDSCDMA / GSM</string>
|
||||||
|
<!-- LTE/GSM/TDSCDMA [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_lte_tdscdma_gsm_summary">Preferred network mode: LTE/GSM/TDSCDMA</string>
|
||||||
|
<!-- TDSCDMA/GSM/WCDMA [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_tdscdma_gsm_wcdma_summary">Preferred network mode: TDSCDMA/GSM/WCDMA</string>
|
||||||
|
<!-- LTE/TDSCDMA/WCDMA [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_lte_tdscdma_wcdma_summary">Preferred network mode: LTE/TDSCDMA/WCDMA</string>
|
||||||
|
<!-- LTE/TDSCDMA/GSM/WCDMA [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_lte_tdscdma_gsm_wcdma_summary">Preferred network mode: LTE/TDSCDMA/GSM/WCDMA</string>
|
||||||
|
<!-- TDSCDMA/CDMA/EvDo/GSM/WCDMA [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_tdscdma_cdma_evdo_gsm_wcdma_summary">Preferred network mode: TDSCDMA/CDMA/EvDo/GSM/WCDMA</string>
|
||||||
|
<!-- LTE/TDSCDMA/CDMA/EvDo/GSM/WCDMA [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_lte_tdscdma_cdma_evdo_gsm_wcdma_summary">Preferred network mode: LTE/TDSCDMA/CDMA/EvDo/GSM/WCDMA</string>
|
||||||
|
|
||||||
|
<!-- Text for Network lte [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="network_lte">LTE (recommended)</string>
|
||||||
|
<!-- Text for Network 4g [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="network_4G">4G (recommended)</string>
|
||||||
|
<!-- Text for Network 3g [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="network_3G" translatable="false">3G</string>
|
||||||
|
<!-- Text for Network 2g [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="network_2G" translatable="false">2G</string>
|
||||||
|
<!-- Text for Network 1x [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="network_1x" translatable="false">1x</string>
|
||||||
|
<!-- Text for Network global [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="network_global">Global</string>
|
||||||
|
|
||||||
|
<!-- Configuration setting for world mode Format is <true;GID if any to be checked> [CHAR LIMIT=NONE] -->
|
||||||
|
<string translatable="false" name="config_world_mode"/>
|
||||||
|
|
||||||
|
<!-- Available networks screen, text when no networks connected [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="network_disconnected">Disconnected</string>
|
||||||
|
<!-- Available networks screen, text when network connected [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="network_connected">Connected</string>
|
||||||
|
<!-- Available networks screen, text when a network is connecting [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="network_connecting">Connecting\u2026</string>
|
||||||
|
<!-- Available networks screen, text when a network cannot be connected [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="network_could_not_connect">Couldn’t connect</string>
|
||||||
|
|
||||||
|
<!-- Available networks screen title/heading [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="label_available">Available networks</string>
|
||||||
|
<!-- Mobile network settings screen, toast when searching for available networks [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="load_networks_progress">Searching\u2026</string>
|
||||||
|
<!-- Available networks screen, text when no networks are found [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="empty_networks_list">No networks found.</string>
|
||||||
|
<!-- Available networks screen, toast when an error is encountered when searching for networks [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="network_query_error">Couldn\u2019t find networks. Try again.</string>
|
||||||
|
<!-- Available networks screen, toast when registering on a specific network [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="register_on_network">Registering on <xliff:g id="network" example="Verizon">%s</xliff:g>\u2026</string>
|
||||||
|
<!-- Available networks screen, toast when SIM card isn't allowed on a network [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="not_allowed">Your SIM card doesn\u2019t allow a connection to this network.</string>
|
||||||
|
<!-- Available networks screen, toast when unable to connect to a network temporarily [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="connect_later">Can\u2019t connect to this network right now. Try again later.</string>
|
||||||
|
<!-- Available networks screen, toast when registered on a specific network [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="registration_done">Registered on network.</string>
|
||||||
|
|
||||||
|
<!-- Available networks screen, name of switch button for whether to select network automatically [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="select_automatically">Automatically select network</string>
|
||||||
|
|
||||||
|
<!-- Available networks screen, name of button when user wants to select network manually [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="choose_network_title">Choose network</string>
|
||||||
|
<!-- A menu item in "Mobile network settings" that allows the user to update the phone
|
||||||
|
with mobile operator specific settings. [CHAR LIMIT=25] -->
|
||||||
|
<string name="carrier_settings_title">Carrier settings</string>
|
||||||
|
<!-- Preference title for launching an account manager page for prepaid LTE [CHAR LIMIT=30] -->
|
||||||
|
<string name="cdma_lte_data_service">Set up data service</string>
|
||||||
|
<!-- Mobile network settings screen, title of Mobile Data switch preference [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="mobile_data_settings_title">Mobile data</string>
|
||||||
|
<!-- Mobile network settings screen, title of Mobile data switch preference [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="mobile_data_settings_summary">Access data using mobile network</string>
|
||||||
|
|
||||||
|
<!-- Title for preferred network type [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_title">Preferred network type</string>
|
||||||
|
<!-- Summary for preferred network type [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_summary">Change the network operating mode</string>
|
||||||
|
<!-- Dialog title for preferred network type [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="preferred_network_mode_dialogtitle">Preferred network type</string>
|
||||||
|
<!-- Mobile network settings screen, name of the option to manage carrier profiles on devices which support embedded carrier profiles [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="carrier_settings_euicc">Carrier</string>
|
||||||
|
|
||||||
|
<!-- Mobile network settings screen, name for call settings category [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="call_category">Calling</string>
|
||||||
|
<!-- Mobile network settings screen, title of Video calling setting [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="video_calling_settings_title">Carrier video calling</string>
|
||||||
|
|
||||||
|
<!-- Mobile network settings screen, setting option name [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="cdma_system_select_title">System select</string>
|
||||||
|
<!-- Mobile network settings screen, setting summary text [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="cdma_system_select_summary">Change the CDMA roaming mode</string>
|
||||||
|
<!-- System select settings screen title [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="cdma_system_select_dialogtitle">System select</string>
|
||||||
|
|
||||||
|
<!-- Mobile network settings screen, name for network operator category [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="network_operator_category">Network</string>
|
||||||
|
<!-- Available networks screen, name of button when user wants to select network manually [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="network_select_title">Network</string>
|
||||||
|
|
||||||
|
<!-- Title for CDMA subscription [CHAR LIMIT=50] -->
|
||||||
|
<string name="cdma_subscription_title">CDMA subscription</string>
|
||||||
|
<!-- Summary for CDMA subscription [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="cdma_subscription_summary">Change between RUIM/SIM and NV</string>
|
||||||
|
<!-- Dialog title for CDMA subscription [CHAR LIMIT=30] -->
|
||||||
|
<string name="cdma_subscription_dialogtitle">subscription</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
54
res/xml/cdma_options.xml
Normal file
54
res/xml/cdma_options.xml
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2008 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<com.android.phone.CdmaSystemSelectListPreference
|
||||||
|
android:key="cdma_system_select_key"
|
||||||
|
android:title="@string/cdma_system_select_title"
|
||||||
|
android:summary="@string/cdma_system_select_summary"
|
||||||
|
android:entries="@array/cdma_system_select_choices"
|
||||||
|
android:entryValues="@array/cdma_system_select_values"
|
||||||
|
android:dialogTitle="@string/cdma_system_select_dialogtitle" />
|
||||||
|
|
||||||
|
<com.android.phone.CdmaSubscriptionListPreference
|
||||||
|
android:key="cdma_subscription_key"
|
||||||
|
android:title="@string/cdma_subscription_title"
|
||||||
|
android:summary="@string/cdma_subscription_summary"
|
||||||
|
android:entries="@array/cdma_subscription_choices"
|
||||||
|
android:entryValues="@array/cdma_subscription_values"
|
||||||
|
android:dialogTitle="@string/cdma_subscription_dialogtitle" />
|
||||||
|
|
||||||
|
<!--We want separate APN setting from reset of settings because-->
|
||||||
|
<!--we want user to change it with caution.-->
|
||||||
|
<PreferenceCategory
|
||||||
|
android:key="category_cdma_apn_key">
|
||||||
|
<!-- The launching Intent will be defined thru code as we need to pass some Extra -->
|
||||||
|
<com.android.phone.RestrictedPreference
|
||||||
|
android:key="button_cdma_apn_key"
|
||||||
|
android:title="@string/apn_settings"
|
||||||
|
android:persistent="false"/>
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="carrier_settings_key"
|
||||||
|
android:title="@string/carrier_settings_title">
|
||||||
|
<intent android:action="android.intent.action.MAIN"
|
||||||
|
android:targetPackage="@string/carrier_settings"
|
||||||
|
android:targetClass="@string/carrier_settings_menu" />
|
||||||
|
</Preference>
|
||||||
|
|
||||||
|
</PreferenceScreen>
|
60
res/xml/gsm_umts_options.xml
Normal file
60
res/xml/gsm_umts_options.xml
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2008 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<com.android.phone.NetworkOperators
|
||||||
|
android:key="network_operators_category_key"
|
||||||
|
android:title="@string/network_operator_category"
|
||||||
|
android:persistent="false">
|
||||||
|
|
||||||
|
<SwitchPreference
|
||||||
|
android:key="button_auto_select_key"
|
||||||
|
android:title="@string/select_automatically"
|
||||||
|
android:persistent="false"/>
|
||||||
|
|
||||||
|
<com.android.phone.NetworkSelectListPreference
|
||||||
|
android:key="button_network_select_key"
|
||||||
|
android:title="@string/network_select_title"
|
||||||
|
android:persistent="false"/>
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="button_choose_network_key"
|
||||||
|
android:title="@string/choose_network_title"
|
||||||
|
android:fragment="com.android.phone.NetworkSelectSetting" />
|
||||||
|
</com.android.phone.NetworkOperators>
|
||||||
|
|
||||||
|
<!--We want separate APN setting from reset of settings because-->
|
||||||
|
<!--we want user to change it with caution.-->
|
||||||
|
<PreferenceCategory
|
||||||
|
android:key="category_gsm_apn_key"
|
||||||
|
android:layout="@layout/preference_category_no_label">
|
||||||
|
|
||||||
|
<com.android.phone.RestrictedPreference
|
||||||
|
android:key="button_gsm_apn_key"
|
||||||
|
android:title="@string/apn_settings"
|
||||||
|
android:persistent="false" />
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
<PreferenceScreen
|
||||||
|
android:key="carrier_settings_key"
|
||||||
|
android:title="@string/carrier_settings_title">
|
||||||
|
<intent android:action="android.intent.action.MAIN"
|
||||||
|
android:targetPackage="@string/carrier_settings"
|
||||||
|
android:targetClass="@string/carrier_settings_menu" />
|
||||||
|
</PreferenceScreen>
|
||||||
|
|
||||||
|
</PreferenceScreen>
|
91
res/xml/network_setting_fragment.xml
Normal file
91
res/xml/network_setting_fragment.xml
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2008 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<PreferenceScreen
|
||||||
|
android:key="cdma_lte_data_service_key"
|
||||||
|
android:title="@string/cdma_lte_data_service">
|
||||||
|
</PreferenceScreen>
|
||||||
|
|
||||||
|
<com.android.phone.MobileDataPreference
|
||||||
|
android:key="mobile_data_enable"
|
||||||
|
android:title="@string/mobile_data_settings_title"
|
||||||
|
android:summary="@string/mobile_data_settings_summary"/>
|
||||||
|
|
||||||
|
<com.android.phone.RestrictedSwitchPreference
|
||||||
|
android:key="button_roaming_key"
|
||||||
|
android:title="@string/roaming"
|
||||||
|
android:persistent="false"
|
||||||
|
android:summaryOn="@string/roaming_enable"
|
||||||
|
android:summaryOff="@string/roaming_disable"/>
|
||||||
|
|
||||||
|
<com.android.phone.DataUsagePreference
|
||||||
|
android:key="data_usage_summary"
|
||||||
|
android:title="@string/data_usage_title" />
|
||||||
|
|
||||||
|
<com.android.phone.AdvancedOptionsPreference
|
||||||
|
android:key="advanced_options"/>
|
||||||
|
|
||||||
|
<SwitchPreference
|
||||||
|
android:key="enhanced_4g_lte"
|
||||||
|
android:title="@string/enhanced_4g_lte_mode_title"
|
||||||
|
android:persistent="false"
|
||||||
|
android:summary="@string/enhanced_4g_lte_mode_summary"/>
|
||||||
|
|
||||||
|
<ListPreference
|
||||||
|
android:key="preferred_network_mode_key"
|
||||||
|
android:title="@string/preferred_network_mode_title"
|
||||||
|
android:summary="@string/preferred_network_mode_summary"
|
||||||
|
android:entries="@array/preferred_network_mode_choices"
|
||||||
|
android:entryValues="@array/preferred_network_mode_values"
|
||||||
|
android:dialogTitle="@string/preferred_network_mode_dialogtitle" />
|
||||||
|
|
||||||
|
<ListPreference
|
||||||
|
android:key="enabled_networks_key"
|
||||||
|
android:title="@string/preferred_network_mode_title"
|
||||||
|
android:summary="@string/preferred_network_mode_summary"
|
||||||
|
android:entries="@array/enabled_networks_choices"
|
||||||
|
android:entryValues="@array/enabled_networks_values"
|
||||||
|
android:dialogTitle="@string/preferred_network_mode_dialogtitle" />
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="carrier_settings_euicc_key"
|
||||||
|
android:title="@string/carrier_settings_euicc" />
|
||||||
|
|
||||||
|
<PreferenceCategory
|
||||||
|
android:key="calling"
|
||||||
|
android:title="@string/call_category">
|
||||||
|
|
||||||
|
<PreferenceScreen
|
||||||
|
android:key="wifi_calling_key"
|
||||||
|
android:title="@string/wifi_calling_settings_title">
|
||||||
|
|
||||||
|
<intent android:action="android.intent.action.MAIN"
|
||||||
|
android:targetPackage="com.android.settings"
|
||||||
|
android:targetClass="com.android.settings.Settings$WifiCallingSettingsActivity">
|
||||||
|
<extra android:name="show_drawer_menu" android:value="true" />
|
||||||
|
</intent>
|
||||||
|
|
||||||
|
</PreferenceScreen>
|
||||||
|
|
||||||
|
<SwitchPreference
|
||||||
|
android:key="video_calling_key"
|
||||||
|
android:title="@string/video_calling_settings_title"
|
||||||
|
android:persistent="true"/>
|
||||||
|
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
</PreferenceScreen>
|
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.android.settings.mobilenetwork;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.preference.Preference;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Customized preference class representing the "Advanced" button that expands to fields that
|
||||||
|
* are hidden by default.
|
||||||
|
*/
|
||||||
|
public class AdvancedOptionsPreference extends Preference {
|
||||||
|
public AdvancedOptionsPreference(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onBindView(View view) {
|
||||||
|
super.onBindView(view);
|
||||||
|
|
||||||
|
setIcon(R.drawable.ic_expand_more);
|
||||||
|
setTitle(R.string.advanced_options_title);
|
||||||
|
TextView summary = view.findViewById(android.R.id.summary);
|
||||||
|
summary.setMaxLines(1);
|
||||||
|
}
|
||||||
|
}
|
203
src/com/android/settings/mobilenetwork/CdmaOptions.java
Normal file
203
src/com/android/settings/mobilenetwork/CdmaOptions.java
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.mobilenetwork;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.PersistableBundle;
|
||||||
|
import android.os.SystemProperties;
|
||||||
|
import android.preference.Preference;
|
||||||
|
import android.preference.PreferenceFragment;
|
||||||
|
import android.preference.PreferenceScreen;
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.telephony.CarrierConfigManager;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
import com.android.internal.logging.MetricsLogger;
|
||||||
|
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
|
import com.android.internal.telephony.PhoneConstants;
|
||||||
|
import com.android.phone.MobileNetworkSettings;
|
||||||
|
import com.android.phone.RestrictedPreference;
|
||||||
|
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of Phone-specific settings screens.
|
||||||
|
*/
|
||||||
|
public class CdmaOptions {
|
||||||
|
private static final String LOG_TAG = "CdmaOptions";
|
||||||
|
|
||||||
|
private CarrierConfigManager mCarrierConfigManager;
|
||||||
|
private CdmaSystemSelectListPreference mButtonCdmaSystemSelect;
|
||||||
|
private CdmaSubscriptionListPreference mButtonCdmaSubscription;
|
||||||
|
private RestrictedPreference mButtonAPNExpand;
|
||||||
|
private Preference mCategoryAPNExpand;
|
||||||
|
private Preference mButtonCarrierSettings;
|
||||||
|
|
||||||
|
private static final String BUTTON_CDMA_SYSTEM_SELECT_KEY = "cdma_system_select_key";
|
||||||
|
private static final String BUTTON_CDMA_SUBSCRIPTION_KEY = "cdma_subscription_key";
|
||||||
|
private static final String BUTTON_CARRIER_SETTINGS_KEY = "carrier_settings_key";
|
||||||
|
private static final String BUTTON_APN_EXPAND_KEY = "button_cdma_apn_key";
|
||||||
|
private static final String CATEGORY_APN_EXPAND_KEY = "category_cdma_apn_key";
|
||||||
|
|
||||||
|
private PreferenceFragment mPrefFragment;
|
||||||
|
private PreferenceScreen mPrefScreen;
|
||||||
|
private int mSubId;
|
||||||
|
|
||||||
|
public CdmaOptions(PreferenceFragment prefFragment, PreferenceScreen prefScreen, int subId) {
|
||||||
|
mPrefFragment = prefFragment;
|
||||||
|
mPrefScreen = prefScreen;
|
||||||
|
mPrefFragment.addPreferencesFromResource(R.xml.cdma_options);
|
||||||
|
mCarrierConfigManager = new CarrierConfigManager(prefFragment.getContext());
|
||||||
|
|
||||||
|
// Initialize preferences.
|
||||||
|
mButtonCdmaSystemSelect = (CdmaSystemSelectListPreference) mPrefScreen
|
||||||
|
.findPreference(BUTTON_CDMA_SYSTEM_SELECT_KEY);
|
||||||
|
mButtonCdmaSubscription = (CdmaSubscriptionListPreference) mPrefScreen
|
||||||
|
.findPreference(BUTTON_CDMA_SUBSCRIPTION_KEY);
|
||||||
|
mButtonCarrierSettings = mPrefScreen.findPreference(BUTTON_CARRIER_SETTINGS_KEY);
|
||||||
|
mButtonAPNExpand = (RestrictedPreference) mPrefScreen.findPreference(BUTTON_APN_EXPAND_KEY);
|
||||||
|
mCategoryAPNExpand = mPrefScreen.findPreference(CATEGORY_APN_EXPAND_KEY);
|
||||||
|
|
||||||
|
updateSubscriptionId(subId);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateSubscriptionId(int subId) {
|
||||||
|
mSubId = subId;
|
||||||
|
int phoneType = TelephonyManager.from(mPrefFragment.getContext())
|
||||||
|
.createForSubscriptionId(mSubId).getPhoneType();
|
||||||
|
|
||||||
|
PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
|
||||||
|
// Some CDMA carriers want the APN settings.
|
||||||
|
boolean addAPNExpand = shouldAddApnExpandPreference(phoneType, carrierConfig);
|
||||||
|
boolean addCdmaSubscription =
|
||||||
|
deviceSupportsNvAndRuim();
|
||||||
|
// Read platform settings for carrier settings
|
||||||
|
boolean addCarrierSettings =
|
||||||
|
carrierConfig.getBoolean(CarrierConfigManager.KEY_CARRIER_SETTINGS_ENABLE_BOOL);
|
||||||
|
|
||||||
|
mPrefScreen.addPreference(mButtonCdmaSystemSelect);
|
||||||
|
mButtonCdmaSystemSelect.setEnabled(true);
|
||||||
|
|
||||||
|
// Making no assumptions of whether they are added or removed at this point.
|
||||||
|
// Calling add or remove explicitly to make sure they are updated.
|
||||||
|
|
||||||
|
if (addAPNExpand) {
|
||||||
|
log("update: addAPNExpand");
|
||||||
|
mButtonAPNExpand.setDisabledByAdmin(
|
||||||
|
MobileNetworkSettings.isDpcApnEnforced(mButtonAPNExpand.getContext())
|
||||||
|
? RestrictedLockUtilsInternal.getDeviceOwner(
|
||||||
|
mButtonAPNExpand.getContext())
|
||||||
|
: null);
|
||||||
|
mButtonAPNExpand.setOnPreferenceClickListener(
|
||||||
|
new Preference.OnPreferenceClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceClick(Preference preference) {
|
||||||
|
MetricsLogger.action(mButtonAPNExpand.getContext(),
|
||||||
|
MetricsEvent.ACTION_MOBILE_NETWORK_APN_SETTINGS);
|
||||||
|
// We need to build the Intent by hand as the Preference Framework
|
||||||
|
// does not allow to add an Intent with some extras into a Preference
|
||||||
|
// XML file
|
||||||
|
final Intent intent = new Intent(Settings.ACTION_APN_SETTINGS);
|
||||||
|
// This will setup the Home and Search affordance
|
||||||
|
intent.putExtra(":settings:show_fragment_as_subsetting", true);
|
||||||
|
intent.putExtra("sub_id", mSubId);
|
||||||
|
mPrefFragment.startActivity(intent);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mPrefScreen.addPreference(mCategoryAPNExpand);
|
||||||
|
} else {
|
||||||
|
mPrefScreen.removePreference(mCategoryAPNExpand);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addCdmaSubscription) {
|
||||||
|
log("Both NV and Ruim supported, ENABLE subscription type selection");
|
||||||
|
mPrefScreen.addPreference(mButtonCdmaSubscription);
|
||||||
|
mButtonCdmaSubscription.setEnabled(true);
|
||||||
|
} else {
|
||||||
|
log("Both NV and Ruim NOT supported, REMOVE subscription type selection");
|
||||||
|
mPrefScreen.removePreference(mButtonCdmaSubscription);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addCarrierSettings) {
|
||||||
|
mPrefScreen.addPreference(mButtonCarrierSettings);
|
||||||
|
} else {
|
||||||
|
mPrefScreen.removePreference(mButtonCarrierSettings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether we should add the APN expandable preference based on the phone type and
|
||||||
|
* carrier config
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
public static boolean shouldAddApnExpandPreference(int phoneType, PersistableBundle config) {
|
||||||
|
return phoneType == PhoneConstants.PHONE_TYPE_CDMA
|
||||||
|
&& config.getBoolean(CarrierConfigManager.KEY_SHOW_APN_SETTING_CDMA_BOOL);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean deviceSupportsNvAndRuim() {
|
||||||
|
// retrieve the list of subscription types supported by device.
|
||||||
|
String subscriptionsSupported = SystemProperties.get("ril.subscription.types");
|
||||||
|
boolean nvSupported = false;
|
||||||
|
boolean ruimSupported = false;
|
||||||
|
|
||||||
|
log("deviceSupportsnvAnRum: prop=" + subscriptionsSupported);
|
||||||
|
if (!TextUtils.isEmpty(subscriptionsSupported)) {
|
||||||
|
// Searches through the comma-separated list for a match for "NV"
|
||||||
|
// and "RUIM" to update nvSupported and ruimSupported.
|
||||||
|
for (String subscriptionType : subscriptionsSupported.split(",")) {
|
||||||
|
subscriptionType = subscriptionType.trim();
|
||||||
|
if (subscriptionType.equalsIgnoreCase("NV")) {
|
||||||
|
nvSupported = true;
|
||||||
|
}
|
||||||
|
if (subscriptionType.equalsIgnoreCase("RUIM")) {
|
||||||
|
ruimSupported = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log("deviceSupportsnvAnRum: nvSupported=" + nvSupported +
|
||||||
|
" ruimSupported=" + ruimSupported);
|
||||||
|
return (nvSupported && ruimSupported);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean preferenceTreeClick(Preference preference) {
|
||||||
|
if (preference.getKey().equals(BUTTON_CDMA_SYSTEM_SELECT_KEY)) {
|
||||||
|
log("preferenceTreeClick: return BUTTON_CDMA_ROAMING_KEY true");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (preference.getKey().equals(BUTTON_CDMA_SUBSCRIPTION_KEY)) {
|
||||||
|
log("preferenceTreeClick: return CDMA_SUBSCRIPTION_KEY true");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showDialog(Preference preference) {
|
||||||
|
if (preference.getKey().equals(BUTTON_CDMA_SYSTEM_SELECT_KEY)) {
|
||||||
|
mButtonCdmaSystemSelect.showDialog(null);
|
||||||
|
} else if (preference.getKey().equals(BUTTON_CDMA_SUBSCRIPTION_KEY)) {
|
||||||
|
mButtonCdmaSubscription.showDialog(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void log(String s) {
|
||||||
|
android.util.Log.d(LOG_TAG, s);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.mobilenetwork;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.preference.ListPreference;
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.internal.telephony.Phone;
|
||||||
|
import com.android.settingslib.utils.ThreadUtils;
|
||||||
|
|
||||||
|
public class CdmaSubscriptionListPreference extends ListPreference {
|
||||||
|
|
||||||
|
private static final String LOG_TAG = "CdmaSubscriptionListPreference";
|
||||||
|
|
||||||
|
// Used for CDMA subscription mode
|
||||||
|
private static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0;
|
||||||
|
private static final int CDMA_SUBSCRIPTION_NV = 1;
|
||||||
|
|
||||||
|
//preferredSubscriptionMode 0 - RUIM/SIM, preferred
|
||||||
|
// 1 - NV
|
||||||
|
static final int preferredSubscriptionMode = Phone.PREFERRED_CDMA_SUBSCRIPTION;
|
||||||
|
|
||||||
|
private TelephonyManager mTelephonyManager;
|
||||||
|
|
||||||
|
public CdmaSubscriptionListPreference(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
|
||||||
|
mTelephonyManager = TelephonyManager.from(context);
|
||||||
|
setCurrentCdmaSubscriptionModeValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setCurrentCdmaSubscriptionModeValue() {
|
||||||
|
int cdmaSubscriptionMode = Settings.Global.getInt(getContext().getContentResolver(),
|
||||||
|
Settings.Global.CDMA_SUBSCRIPTION_MODE, preferredSubscriptionMode);
|
||||||
|
setValue(Integer.toString(cdmaSubscriptionMode));
|
||||||
|
}
|
||||||
|
|
||||||
|
public CdmaSubscriptionListPreference(Context context) {
|
||||||
|
this(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the subscription id associated with this preference.
|
||||||
|
*
|
||||||
|
* @param subId the subscription id.
|
||||||
|
*/
|
||||||
|
public void setSubscriptionId(int subId) {
|
||||||
|
mTelephonyManager = TelephonyManager.from(getContext()).createForSubscriptionId(subId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void showDialog(Bundle state) {
|
||||||
|
setCurrentCdmaSubscriptionModeValue();
|
||||||
|
|
||||||
|
super.showDialog(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDialogClosed(boolean positiveResult) {
|
||||||
|
super.onDialogClosed(positiveResult);
|
||||||
|
|
||||||
|
if (!positiveResult) {
|
||||||
|
//The button was dismissed - no need to set new value
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int buttonCdmaSubscriptionMode = Integer.parseInt(getValue());
|
||||||
|
Log.d(LOG_TAG, "Setting new value " + buttonCdmaSubscriptionMode);
|
||||||
|
int statusCdmaSubscriptionMode;
|
||||||
|
switch(buttonCdmaSubscriptionMode) {
|
||||||
|
case CDMA_SUBSCRIPTION_NV:
|
||||||
|
statusCdmaSubscriptionMode = Phone.CDMA_SUBSCRIPTION_NV;
|
||||||
|
break;
|
||||||
|
case CDMA_SUBSCRIPTION_RUIM_SIM:
|
||||||
|
statusCdmaSubscriptionMode = Phone.CDMA_SUBSCRIPTION_RUIM_SIM;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
statusCdmaSubscriptionMode = Phone.PREFERRED_CDMA_SUBSCRIPTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the CDMA subscription mode, when mode has been successfully changed, update the
|
||||||
|
// mode to the global setting.
|
||||||
|
ThreadUtils.postOnBackgroundThread(() -> {
|
||||||
|
// The subscription mode selected by user.
|
||||||
|
int cdmaSubscriptionMode = Integer.parseInt(getValue());
|
||||||
|
|
||||||
|
boolean isSuccessed = mTelephonyManager.setCdmaSubscriptionMode(
|
||||||
|
statusCdmaSubscriptionMode);
|
||||||
|
|
||||||
|
// Update the global settings if successed.
|
||||||
|
if (isSuccessed) {
|
||||||
|
Settings.Global.putInt(getContext().getContentResolver(),
|
||||||
|
Settings.Global.CDMA_SUBSCRIPTION_MODE,
|
||||||
|
cdmaSubscriptionMode);
|
||||||
|
} else {
|
||||||
|
Log.e(LOG_TAG, "Setting Cdma subscription source failed");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,187 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.mobilenetwork;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.preference.ListPreference;
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.settingslib.utils.ThreadUtils;
|
||||||
|
|
||||||
|
public class CdmaSystemSelectListPreference extends ListPreference {
|
||||||
|
|
||||||
|
private static final String LOG_TAG = "CdmaRoamingListPreference";
|
||||||
|
private static final boolean DBG = false;
|
||||||
|
|
||||||
|
private TelephonyManager mTelephonyManager;
|
||||||
|
private MyHandler mHandler = new MyHandler();
|
||||||
|
|
||||||
|
public CdmaSystemSelectListPreference(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
|
||||||
|
mHandler = new MyHandler();
|
||||||
|
mTelephonyManager = TelephonyManager.from(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CdmaSystemSelectListPreference(Context context) {
|
||||||
|
this(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the subscription id associated with this preference.
|
||||||
|
*
|
||||||
|
* @param subId the subscription id.
|
||||||
|
*/
|
||||||
|
public void setSubscriptionId(int subId) {
|
||||||
|
mTelephonyManager = TelephonyManager.from(getContext()).createForSubscriptionId(subId);
|
||||||
|
queryCdmaRoamingMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void showDialog(Bundle state) {
|
||||||
|
if (!mTelephonyManager.getEmergencyCallbackMode()) {
|
||||||
|
super.showDialog(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDialogClosed(boolean positiveResult) {
|
||||||
|
super.onDialogClosed(positiveResult);
|
||||||
|
|
||||||
|
if (positiveResult && (getValue() != null)) {
|
||||||
|
int buttonCdmaRoamingMode = Integer.parseInt(getValue());
|
||||||
|
int settingsCdmaRoamingMode = Settings.Global.getInt(
|
||||||
|
getContext().getContentResolver(),
|
||||||
|
Settings.Global.CDMA_ROAMING_MODE,
|
||||||
|
TelephonyManager.CDMA_ROAMING_MODE_HOME);
|
||||||
|
if (buttonCdmaRoamingMode != settingsCdmaRoamingMode) {
|
||||||
|
int cdmaRoamingMode = TelephonyManager.CDMA_ROAMING_MODE_ANY;
|
||||||
|
if (buttonCdmaRoamingMode != TelephonyManager.CDMA_ROAMING_MODE_ANY) {
|
||||||
|
cdmaRoamingMode = TelephonyManager.CDMA_ROAMING_MODE_HOME;
|
||||||
|
}
|
||||||
|
//Set the Settings.Secure network mode
|
||||||
|
Settings.Global.putInt(
|
||||||
|
getContext().getContentResolver(),
|
||||||
|
Settings.Global.CDMA_ROAMING_MODE,
|
||||||
|
buttonCdmaRoamingMode);
|
||||||
|
//Set the roaming preference mode
|
||||||
|
setCdmaRoamingMode(cdmaRoamingMode);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.d(LOG_TAG, String.format("onDialogClosed: positiveResult=%b value=%s -- do nothing",
|
||||||
|
positiveResult, getValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class MyHandler extends Handler {
|
||||||
|
|
||||||
|
static final int MESSAGE_GET_ROAMING_PREFERENCE = 0;
|
||||||
|
static final int MESSAGE_SET_ROAMING_PREFERENCE = 1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
switch (msg.what) {
|
||||||
|
case MESSAGE_GET_ROAMING_PREFERENCE:
|
||||||
|
handleQueryCdmaRoamingPreference(msg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MESSAGE_SET_ROAMING_PREFERENCE:
|
||||||
|
handleSetCdmaRoamingPreference(msg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleQueryCdmaRoamingPreference(Message msg) {
|
||||||
|
int cdmaRoamingMode = msg.arg1;
|
||||||
|
|
||||||
|
if (cdmaRoamingMode != TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT) {
|
||||||
|
int settingsRoamingMode = Settings.Global.getInt(
|
||||||
|
getContext().getContentResolver(),
|
||||||
|
Settings.Global.CDMA_ROAMING_MODE,
|
||||||
|
TelephonyManager.CDMA_ROAMING_MODE_HOME);
|
||||||
|
|
||||||
|
//check that statusCdmaRoamingMode is from an accepted value
|
||||||
|
if (cdmaRoamingMode == TelephonyManager.CDMA_ROAMING_MODE_HOME
|
||||||
|
|| cdmaRoamingMode == TelephonyManager.CDMA_ROAMING_MODE_ANY) {
|
||||||
|
//check changes in statusCdmaRoamingMode and updates settingsRoamingMode
|
||||||
|
if (cdmaRoamingMode != settingsRoamingMode) {
|
||||||
|
settingsRoamingMode = cdmaRoamingMode;
|
||||||
|
//changes the Settings.Secure accordingly to statusCdmaRoamingMode
|
||||||
|
Settings.Global.putInt(
|
||||||
|
getContext().getContentResolver(),
|
||||||
|
Settings.Global.CDMA_ROAMING_MODE,
|
||||||
|
settingsRoamingMode);
|
||||||
|
}
|
||||||
|
//changes the mButtonPreferredNetworkMode accordingly to modemNetworkMode
|
||||||
|
setValue(Integer.toString(cdmaRoamingMode));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(DBG) Log.i(LOG_TAG, "reset cdma roaming mode to default" );
|
||||||
|
resetCdmaRoamingModeToDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleSetCdmaRoamingPreference(Message msg) {
|
||||||
|
boolean isSuccessed = (boolean) msg.obj;
|
||||||
|
|
||||||
|
if (isSuccessed && (getValue() != null)) {
|
||||||
|
int cdmaRoamingMode = Integer.parseInt(getValue());
|
||||||
|
Settings.Global.putInt(
|
||||||
|
getContext().getContentResolver(),
|
||||||
|
Settings.Global.CDMA_ROAMING_MODE,
|
||||||
|
cdmaRoamingMode );
|
||||||
|
} else {
|
||||||
|
queryCdmaRoamingMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetCdmaRoamingModeToDefault() {
|
||||||
|
//set the mButtonCdmaRoam
|
||||||
|
setValue(Integer.toString(TelephonyManager.CDMA_ROAMING_MODE_ANY));
|
||||||
|
//set the Settings.System
|
||||||
|
Settings.Global.putInt(
|
||||||
|
getContext().getContentResolver(),
|
||||||
|
Settings.Global.CDMA_ROAMING_MODE,
|
||||||
|
TelephonyManager.CDMA_ROAMING_MODE_ANY);
|
||||||
|
//Set the Status
|
||||||
|
setCdmaRoamingMode(TelephonyManager.CDMA_ROAMING_MODE_ANY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void queryCdmaRoamingMode() {
|
||||||
|
ThreadUtils.postOnBackgroundThread(() -> {
|
||||||
|
Message msg = mHandler.obtainMessage(MyHandler.MESSAGE_GET_ROAMING_PREFERENCE);
|
||||||
|
msg.arg1 = mTelephonyManager.getCdmaRoamingMode();
|
||||||
|
msg.sendToTarget();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setCdmaRoamingMode(int mode) {
|
||||||
|
ThreadUtils.postOnBackgroundThread(() -> {
|
||||||
|
Message msg = mHandler.obtainMessage(MyHandler.MESSAGE_SET_ROAMING_PREFERENCE);
|
||||||
|
msg.obj = mTelephonyManager.setCdmaRoamingMode(mode);
|
||||||
|
msg.sendToTarget();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.mobilenetwork;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.NetworkTemplate;
|
||||||
|
import android.preference.Preference;
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
|
import android.text.format.Formatter;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
|
import com.android.settingslib.net.DataUsageController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The preference that shows mobile data usage summary and
|
||||||
|
* leads to mobile data usage list page.
|
||||||
|
*/
|
||||||
|
public class DataUsagePreference extends Preference {
|
||||||
|
|
||||||
|
private NetworkTemplate mTemplate;
|
||||||
|
private int mSubId;
|
||||||
|
|
||||||
|
public DataUsagePreference(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* After creating this preference, this functions needs to be called to
|
||||||
|
* initialize which subID it connects to.
|
||||||
|
*/
|
||||||
|
public void initialize(int subId) {
|
||||||
|
Activity activity = (Activity) getContext();
|
||||||
|
|
||||||
|
mSubId = subId;
|
||||||
|
mTemplate = getNetworkTemplate(activity, subId);
|
||||||
|
|
||||||
|
DataUsageController controller = new DataUsageController(activity);
|
||||||
|
|
||||||
|
DataUsageController.DataUsageInfo usageInfo = controller.getDataUsageInfo(mTemplate);
|
||||||
|
setSummary(activity.getString(R.string.data_usage_template,
|
||||||
|
Formatter.formatFileSize(activity, usageInfo.usageLevel), usageInfo.period));
|
||||||
|
setIntent(getIntent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Intent getIntent() {
|
||||||
|
Intent intent = new Intent(Settings.ACTION_MOBILE_DATA_USAGE);
|
||||||
|
|
||||||
|
intent.putExtra(Settings.EXTRA_NETWORK_TEMPLATE, mTemplate);
|
||||||
|
intent.putExtra(Settings.EXTRA_SUB_ID, mSubId);
|
||||||
|
|
||||||
|
return intent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private NetworkTemplate getNetworkTemplate(Activity activity, int subId) {
|
||||||
|
TelephonyManager tm = (TelephonyManager) activity
|
||||||
|
.getSystemService(Context.TELEPHONY_SERVICE);
|
||||||
|
NetworkTemplate mobileAll = NetworkTemplate.buildTemplateMobileAll(
|
||||||
|
tm.getSubscriberId(subId));
|
||||||
|
return NetworkTemplate.normalize(mobileAll,
|
||||||
|
tm.getMergedSubscriberIds());
|
||||||
|
}
|
||||||
|
}
|
179
src/com/android/settings/mobilenetwork/GsmUmtsOptions.java
Normal file
179
src/com/android/settings/mobilenetwork/GsmUmtsOptions.java
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.mobilenetwork;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.PersistableBundle;
|
||||||
|
import android.preference.Preference;
|
||||||
|
import android.preference.PreferenceFragment;
|
||||||
|
import android.preference.PreferenceScreen;
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.telephony.CarrierConfigManager;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
|
|
||||||
|
import com.android.internal.logging.MetricsLogger;
|
||||||
|
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
|
import com.android.internal.telephony.Phone;
|
||||||
|
import com.android.internal.telephony.PhoneConstants;
|
||||||
|
import com.android.phone.INetworkQueryService;
|
||||||
|
import com.android.phone.MobileNetworkSettings;
|
||||||
|
import com.android.phone.PhoneGlobals;
|
||||||
|
import com.android.phone.RestrictedPreference;
|
||||||
|
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of Network-specific settings screens.
|
||||||
|
*/
|
||||||
|
public class GsmUmtsOptions {
|
||||||
|
private static final String LOG_TAG = "GsmUmtsOptions";
|
||||||
|
|
||||||
|
private CarrierConfigManager mCarrierConfigManager;
|
||||||
|
private RestrictedPreference mButtonAPNExpand;
|
||||||
|
private Preference mCategoryAPNExpand;
|
||||||
|
Preference mCarrierSettingPref;
|
||||||
|
|
||||||
|
private NetworkOperators mNetworkOperator;
|
||||||
|
|
||||||
|
private static final String BUTTON_APN_EXPAND_KEY = "button_gsm_apn_key";
|
||||||
|
private static final String CATEGORY_APN_EXPAND_KEY = "category_gsm_apn_key";
|
||||||
|
private static final String BUTTON_CARRIER_SETTINGS_KEY = "carrier_settings_key";
|
||||||
|
|
||||||
|
public static final String EXTRA_SUB_ID = "sub_id";
|
||||||
|
private PreferenceFragment mPrefFragment;
|
||||||
|
private PreferenceScreen mPrefScreen;
|
||||||
|
|
||||||
|
public GsmUmtsOptions(PreferenceFragment prefFragment, PreferenceScreen prefScreen,
|
||||||
|
final int subId, INetworkQueryService queryService) {
|
||||||
|
final Context context = prefFragment.getContext();
|
||||||
|
mPrefFragment = prefFragment;
|
||||||
|
mPrefScreen = prefScreen;
|
||||||
|
mCarrierConfigManager = new CarrierConfigManager(context);
|
||||||
|
mPrefFragment.addPreferencesFromResource(R.xml.gsm_umts_options);
|
||||||
|
mButtonAPNExpand = (RestrictedPreference) mPrefScreen.findPreference(BUTTON_APN_EXPAND_KEY);
|
||||||
|
mCategoryAPNExpand = mPrefScreen.findPreference(CATEGORY_APN_EXPAND_KEY);
|
||||||
|
mNetworkOperator = (NetworkOperators) mPrefScreen
|
||||||
|
.findPreference(NetworkOperators.CATEGORY_NETWORK_OPERATORS_KEY);
|
||||||
|
mCarrierSettingPref = mPrefScreen.findPreference(BUTTON_CARRIER_SETTINGS_KEY);
|
||||||
|
|
||||||
|
mNetworkOperator.initialize();
|
||||||
|
|
||||||
|
update(subId, queryService);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unlike mPrefFragment or mPrefScreen, subId or queryService may change during lifecycle of
|
||||||
|
// GsmUmtsOptions. When that happens, we update GsmUmtsOptions with new parameters.
|
||||||
|
protected void update(final int subId, INetworkQueryService queryService) {
|
||||||
|
boolean addAPNExpand = true;
|
||||||
|
boolean addNetworkOperatorsCategory = true;
|
||||||
|
boolean addCarrierSettings = true;
|
||||||
|
final TelephonyManager telephonyManager = TelephonyManager.from(mPrefFragment.getContext())
|
||||||
|
.createForSubscriptionId(subId);
|
||||||
|
Phone phone = PhoneGlobals.getPhone(subId);
|
||||||
|
if (phone == null) return;
|
||||||
|
if (telephonyManager.getPhoneType() != PhoneConstants.PHONE_TYPE_GSM) {
|
||||||
|
log("Not a GSM phone");
|
||||||
|
addAPNExpand = false;
|
||||||
|
mNetworkOperator.setEnabled(false);
|
||||||
|
} else {
|
||||||
|
log("Not a CDMA phone");
|
||||||
|
PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId);
|
||||||
|
|
||||||
|
// Determine which options to display. For GSM these are defaulted to true in
|
||||||
|
// CarrierConfigManager, but they maybe overriden by DefaultCarrierConfigService or a
|
||||||
|
// carrier app.
|
||||||
|
// Note: these settings used to be controlled with overlays in
|
||||||
|
// Telephony/res/values/config.xml
|
||||||
|
if (!carrierConfig.getBoolean(CarrierConfigManager.KEY_APN_EXPAND_BOOL)
|
||||||
|
&& mCategoryAPNExpand != null) {
|
||||||
|
addAPNExpand = false;
|
||||||
|
}
|
||||||
|
if (!carrierConfig.getBoolean(
|
||||||
|
CarrierConfigManager.KEY_OPERATOR_SELECTION_EXPAND_BOOL)) {
|
||||||
|
addNetworkOperatorsCategory = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (carrierConfig.getBoolean(CarrierConfigManager.KEY_CSP_ENABLED_BOOL)) {
|
||||||
|
if (phone.isCspPlmnEnabled()) {
|
||||||
|
log("[CSP] Enabling Operator Selection menu.");
|
||||||
|
mNetworkOperator.setEnabled(true);
|
||||||
|
} else {
|
||||||
|
log("[CSP] Disabling Operator Selection menu.");
|
||||||
|
addNetworkOperatorsCategory = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read platform settings for carrier settings
|
||||||
|
addCarrierSettings = carrierConfig.getBoolean(
|
||||||
|
CarrierConfigManager.KEY_CARRIER_SETTINGS_ENABLE_BOOL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Making no assumptions of whether they are added or removed at this point.
|
||||||
|
// Calling add or remove explicitly to make sure they are updated.
|
||||||
|
|
||||||
|
if (addAPNExpand) {
|
||||||
|
log("update: addAPNExpand");
|
||||||
|
mButtonAPNExpand.setDisabledByAdmin(
|
||||||
|
MobileNetworkSettings.isDpcApnEnforced(mButtonAPNExpand.getContext())
|
||||||
|
? RestrictedLockUtilsInternal.getDeviceOwner(
|
||||||
|
mButtonAPNExpand.getContext())
|
||||||
|
: null);
|
||||||
|
mButtonAPNExpand.setOnPreferenceClickListener(
|
||||||
|
new Preference.OnPreferenceClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceClick(Preference preference) {
|
||||||
|
MetricsLogger.action(mButtonAPNExpand.getContext(),
|
||||||
|
MetricsEvent.ACTION_MOBILE_NETWORK_APN_SETTINGS);
|
||||||
|
// We need to build the Intent by hand as the Preference Framework
|
||||||
|
// does not allow to add an Intent with some extras into a Preference
|
||||||
|
// XML file
|
||||||
|
final Intent intent = new Intent(Settings.ACTION_APN_SETTINGS);
|
||||||
|
// This will setup the Home and Search affordance
|
||||||
|
intent.putExtra(":settings:show_fragment_as_subsetting", true);
|
||||||
|
intent.putExtra(EXTRA_SUB_ID, subId);
|
||||||
|
mPrefFragment.startActivity(intent);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mPrefScreen.addPreference(mCategoryAPNExpand);
|
||||||
|
} else {
|
||||||
|
mPrefScreen.removePreference(mCategoryAPNExpand);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addNetworkOperatorsCategory) {
|
||||||
|
mPrefScreen.addPreference(mNetworkOperator);
|
||||||
|
mNetworkOperator.update(subId, queryService);
|
||||||
|
} else {
|
||||||
|
mPrefScreen.removePreference(mNetworkOperator);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addCarrierSettings) {
|
||||||
|
mPrefScreen.addPreference(mCarrierSettingPref);
|
||||||
|
} else {
|
||||||
|
mPrefScreen.removePreference(mCarrierSettingPref);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean preferenceTreeClick(Preference preference) {
|
||||||
|
return mNetworkOperator.preferenceTreeClick(preference);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void log(String s) {
|
||||||
|
android.util.Log.d(LOG_TAG, s);
|
||||||
|
}
|
||||||
|
}
|
320
src/com/android/settings/mobilenetwork/MobileDataPreference.java
Normal file
320
src/com/android/settings/mobilenetwork/MobileDataPreference.java
Normal file
@@ -0,0 +1,320 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.mobilenetwork;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.database.ContentObserver;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.preference.DialogPreference;
|
||||||
|
import android.preference.PreferenceScreen;
|
||||||
|
import android.provider.Settings.Global;
|
||||||
|
import android.telephony.SubscriptionInfo;
|
||||||
|
import android.telephony.SubscriptionManager;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Checkable;
|
||||||
|
|
||||||
|
import com.android.internal.logging.MetricsLogger;
|
||||||
|
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Customized Preference to enable / disable mobile data.
|
||||||
|
* Basically copy of with com.android.settings.CellDataPreference.
|
||||||
|
*/
|
||||||
|
public class MobileDataPreference extends DialogPreference {
|
||||||
|
|
||||||
|
private static final boolean DBG = false;
|
||||||
|
private static final String TAG = "MobileDataPreference";
|
||||||
|
|
||||||
|
public int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||||
|
public boolean mChecked;
|
||||||
|
// Whether to show the dialog to ask switching default data subscription.
|
||||||
|
// Should be true only when a multi-sim phone only supports data connection on a single phone,
|
||||||
|
// and user is enabling data on the non-default phone.
|
||||||
|
public boolean mMultiSimDialog;
|
||||||
|
private TelephonyManager mTelephonyManager;
|
||||||
|
private SubscriptionManager mSubscriptionManager;
|
||||||
|
|
||||||
|
public MobileDataPreference(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs, com.android.internal.R.attr.switchPreferenceStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must be called to avoid binder leakage.
|
||||||
|
void dispose() {
|
||||||
|
mListener.setListener(false, mSubId, getContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onRestoreInstanceState(Parcelable s) {
|
||||||
|
CellDataState state = (CellDataState) s;
|
||||||
|
super.onRestoreInstanceState(state.getSuperState());
|
||||||
|
mTelephonyManager = TelephonyManager.from(getContext());
|
||||||
|
mChecked = state.mChecked;
|
||||||
|
mMultiSimDialog = state.mMultiSimDialog;
|
||||||
|
if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
||||||
|
mSubId = state.mSubId;
|
||||||
|
setKey(getKey() + mSubId);
|
||||||
|
}
|
||||||
|
notifyChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Parcelable onSaveInstanceState() {
|
||||||
|
CellDataState state = new CellDataState(super.onSaveInstanceState());
|
||||||
|
state.mChecked = mChecked;
|
||||||
|
state.mMultiSimDialog = mMultiSimDialog;
|
||||||
|
state.mSubId = mSubId;
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onAttachedToActivity() {
|
||||||
|
super.onAttachedToActivity();
|
||||||
|
mListener.setListener(true, mSubId, getContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPrepareForRemoval() {
|
||||||
|
mListener.setListener(false, mSubId, getContext());
|
||||||
|
super.onPrepareForRemoval();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize this preference with subId.
|
||||||
|
*/
|
||||||
|
public void initialize(int subId) {
|
||||||
|
if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
||||||
|
throw new IllegalArgumentException("MobileDataPreference needs a SubscriptionInfo");
|
||||||
|
}
|
||||||
|
mSubscriptionManager = SubscriptionManager.from(getContext());
|
||||||
|
mTelephonyManager = TelephonyManager.from(getContext());
|
||||||
|
if (mSubId != subId) {
|
||||||
|
mSubId = subId;
|
||||||
|
setKey(getKey() + subId);
|
||||||
|
}
|
||||||
|
updateChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateChecked() {
|
||||||
|
setChecked(mTelephonyManager.getDataEnabled(mSubId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void performClick(PreferenceScreen preferenceScreen) {
|
||||||
|
if (!isEnabled() || !SubscriptionManager.isValidSubscriptionId(mSubId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final SubscriptionInfo currentSir = mSubscriptionManager.getActiveSubscriptionInfo(
|
||||||
|
mSubId);
|
||||||
|
final SubscriptionInfo nextSir = mSubscriptionManager.getDefaultDataSubscriptionInfo();
|
||||||
|
final boolean isMultiSim = (mTelephonyManager.getSimCount() > 1);
|
||||||
|
final boolean isMultipleDataOnCapable =
|
||||||
|
(mTelephonyManager.getNumberOfModemsWithSimultaneousDataConnections() > 1);
|
||||||
|
final boolean isDefaultDataSubscription = (nextSir != null && currentSir != null
|
||||||
|
&& currentSir.getSubscriptionId() == nextSir.getSubscriptionId());
|
||||||
|
if (mChecked) {
|
||||||
|
if (!isMultiSim) {
|
||||||
|
// disabling data; show confirmation dialog which eventually
|
||||||
|
// calls setMobileDataEnabled() once user confirms.
|
||||||
|
mMultiSimDialog = false;
|
||||||
|
super.performClick(preferenceScreen);
|
||||||
|
} else {
|
||||||
|
// Don't show any dialog.
|
||||||
|
setMobileDataEnabled(false /* enabled */, false /* disableOtherSubscriptions */);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isMultiSim && !isMultipleDataOnCapable && !isDefaultDataSubscription) {
|
||||||
|
// enabling data and setting to default; show confirmation dialog which eventually
|
||||||
|
// calls setMobileDataEnabled() once user confirms.
|
||||||
|
mMultiSimDialog = true;
|
||||||
|
super.performClick(preferenceScreen);
|
||||||
|
} else {
|
||||||
|
// Don't show any dialog.
|
||||||
|
setMobileDataEnabled(true /* enabled */, false /* disableOtherSubscriptions */);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setMobileDataEnabled(boolean enabled, boolean disableOtherSubscriptions) {
|
||||||
|
if (DBG) Log.d(TAG, "setMobileDataEnabled(" + enabled + "," + mSubId + ")");
|
||||||
|
|
||||||
|
MetricsLogger.action(getContext(), MetricsEvent.ACTION_MOBILE_NETWORK_MOBILE_DATA_TOGGLE,
|
||||||
|
enabled);
|
||||||
|
|
||||||
|
mTelephonyManager.setDataEnabled(mSubId, enabled);
|
||||||
|
|
||||||
|
if (disableOtherSubscriptions) {
|
||||||
|
disableDataForOtherSubscriptions(mSubId);
|
||||||
|
}
|
||||||
|
|
||||||
|
setChecked(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setChecked(boolean checked) {
|
||||||
|
if (mChecked == checked) return;
|
||||||
|
mChecked = checked;
|
||||||
|
notifyChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onBindView(View view) {
|
||||||
|
super.onBindView(view);
|
||||||
|
View checkableView = view.findViewById(com.android.internal.R.id.switch_widget);
|
||||||
|
checkableView.setClickable(false);
|
||||||
|
((Checkable) checkableView).setChecked(mChecked);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
|
||||||
|
if (mMultiSimDialog) {
|
||||||
|
showMultiSimDialog(builder);
|
||||||
|
} else {
|
||||||
|
showDisableDialog(builder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showDisableDialog(AlertDialog.Builder builder) {
|
||||||
|
builder.setTitle(null)
|
||||||
|
.setMessage(R.string.data_usage_disable_mobile)
|
||||||
|
.setPositiveButton(android.R.string.ok, this)
|
||||||
|
.setNegativeButton(android.R.string.cancel, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showMultiSimDialog(AlertDialog.Builder builder) {
|
||||||
|
final SubscriptionInfo currentSir = mSubscriptionManager.getActiveSubscriptionInfo(mSubId);
|
||||||
|
final SubscriptionInfo nextSir = mSubscriptionManager.getDefaultDataSubscriptionInfo();
|
||||||
|
|
||||||
|
final String previousName = (nextSir == null)
|
||||||
|
? getContext().getResources().getString(R.string.sim_selection_required_pref)
|
||||||
|
: nextSir.getDisplayName().toString();
|
||||||
|
|
||||||
|
builder.setTitle(R.string.sim_change_data_title);
|
||||||
|
builder.setMessage(getContext().getString(R.string.sim_change_data_message,
|
||||||
|
String.valueOf(currentSir != null ? currentSir.getDisplayName() : null),
|
||||||
|
previousName));
|
||||||
|
|
||||||
|
builder.setPositiveButton(R.string.ok, this);
|
||||||
|
builder.setNegativeButton(R.string.cancel, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void disableDataForOtherSubscriptions(int subId) {
|
||||||
|
List<SubscriptionInfo> subInfoList = mSubscriptionManager.getActiveSubscriptionInfoList();
|
||||||
|
if (subInfoList != null) {
|
||||||
|
for (SubscriptionInfo subInfo : subInfoList) {
|
||||||
|
if (subInfo.getSubscriptionId() != subId) {
|
||||||
|
mTelephonyManager.setDataEnabled(subInfo.getSubscriptionId(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
if (which != DialogInterface.BUTTON_POSITIVE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mMultiSimDialog) {
|
||||||
|
mSubscriptionManager.setDefaultDataSubId(mSubId);
|
||||||
|
setMobileDataEnabled(true /* enabled */, true /* disableOtherSubscriptions */);
|
||||||
|
} else {
|
||||||
|
// TODO: extend to modify policy enabled flag.
|
||||||
|
setMobileDataEnabled(false /* enabled */, false /* disableOtherSubscriptions */);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final DataStateListener mListener = new DataStateListener() {
|
||||||
|
@Override
|
||||||
|
public void onChange(boolean selfChange) {
|
||||||
|
updateChecked();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener that listens mobile data state change.
|
||||||
|
*/
|
||||||
|
public abstract static class DataStateListener extends ContentObserver {
|
||||||
|
public DataStateListener() {
|
||||||
|
super(new Handler(Looper.getMainLooper()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set / Unset data state listening, specifying subId.
|
||||||
|
*/
|
||||||
|
public void setListener(boolean listening, int subId, Context context) {
|
||||||
|
if (listening) {
|
||||||
|
Uri uri = Global.getUriFor(Global.MOBILE_DATA);
|
||||||
|
if (TelephonyManager.getDefault().getSimCount() != 1) {
|
||||||
|
uri = Global.getUriFor(Global.MOBILE_DATA + subId);
|
||||||
|
}
|
||||||
|
context.getContentResolver().registerContentObserver(uri, false, this);
|
||||||
|
} else {
|
||||||
|
context.getContentResolver().unregisterContentObserver(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class that represents state of mobile data state.
|
||||||
|
* Used by onSaveInstanceState and onRestoreInstanceState.
|
||||||
|
*/
|
||||||
|
public static class CellDataState extends BaseSavedState {
|
||||||
|
public int mSubId;
|
||||||
|
public boolean mChecked;
|
||||||
|
public boolean mMultiSimDialog;
|
||||||
|
|
||||||
|
public CellDataState(Parcelable base) {
|
||||||
|
super(base);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CellDataState(Parcel source) {
|
||||||
|
super(source);
|
||||||
|
mChecked = source.readByte() != 0;
|
||||||
|
mMultiSimDialog = source.readByte() != 0;
|
||||||
|
mSubId = source.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
super.writeToParcel(dest, flags);
|
||||||
|
dest.writeByte((byte) (mChecked ? 1 : 0));
|
||||||
|
dest.writeByte((byte) (mMultiSimDialog ? 1 : 0));
|
||||||
|
dest.writeInt(mSubId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<CellDataState> CREATOR = new Creator<CellDataState>() {
|
||||||
|
@Override
|
||||||
|
public CellDataState createFromParcel(Parcel source) {
|
||||||
|
return new CellDataState(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CellDataState[] newArray(int size) {
|
||||||
|
return new CellDataState[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
2003
src/com/android/settings/mobilenetwork/MobileNetworkFragment.java
Normal file
2003
src/com/android/settings/mobilenetwork/MobileNetworkFragment.java
Normal file
File diff suppressed because it is too large
Load Diff
299
src/com/android/settings/mobilenetwork/NetworkOperators.java
Normal file
299
src/com/android/settings/mobilenetwork/NetworkOperators.java
Normal file
@@ -0,0 +1,299 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.mobilenetwork;
|
||||||
|
|
||||||
|
import android.app.ProgressDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.preference.Preference;
|
||||||
|
import android.preference.PreferenceCategory;
|
||||||
|
import android.preference.TwoStatePreference;
|
||||||
|
import android.telephony.ServiceState;
|
||||||
|
import android.telephony.SubscriptionManager;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.android.internal.logging.MetricsLogger;
|
||||||
|
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
|
import com.android.phone.NetworkSelectSettingActivity;
|
||||||
|
import com.android.settingslib.utils.ThreadUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "Networks" settings UI for the Phone app.
|
||||||
|
*/
|
||||||
|
public class NetworkOperators extends PreferenceCategory
|
||||||
|
implements Preference.OnPreferenceChangeListener {
|
||||||
|
|
||||||
|
private static final String LOG_TAG = "NetworkOperators";
|
||||||
|
private static final boolean DBG = true;
|
||||||
|
|
||||||
|
private static final int EVENT_AUTO_SELECT_DONE = 100;
|
||||||
|
private static final int EVENT_GET_NETWORK_SELECTION_MODE_DONE = 200;
|
||||||
|
|
||||||
|
//String keys for preference lookup
|
||||||
|
public static final String BUTTON_NETWORK_SELECT_KEY = "button_network_select_key";
|
||||||
|
public static final String BUTTON_AUTO_SELECT_KEY = "button_auto_select_key";
|
||||||
|
public static final String BUTTON_CHOOSE_NETWORK_KEY = "button_choose_network_key";
|
||||||
|
public static final String CATEGORY_NETWORK_OPERATORS_KEY = "network_operators_category_key";
|
||||||
|
|
||||||
|
//preference objects
|
||||||
|
private NetworkSelectListPreference mNetworkSelect;
|
||||||
|
private TwoStatePreference mAutoSelect;
|
||||||
|
private Preference mChooseNetwork;
|
||||||
|
private ProgressDialog mProgressDialog;
|
||||||
|
|
||||||
|
private int mSubId;
|
||||||
|
private TelephonyManager mTelephonyManager;
|
||||||
|
|
||||||
|
// There's two sets of Auto-Select UI in this class.
|
||||||
|
// If {@code com.android.internal.R.bool.config_enableNewAutoSelectNetworkUI} set as true
|
||||||
|
// {@link mChooseNetwork} will be used, otherwise {@link mNetworkSelect} will be used.
|
||||||
|
boolean mEnableNewManualSelectNetworkUI;
|
||||||
|
|
||||||
|
public NetworkOperators(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NetworkOperators(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize NetworkOperators instance.
|
||||||
|
*/
|
||||||
|
public void initialize() {
|
||||||
|
mEnableNewManualSelectNetworkUI = getContext().getResources().getBoolean(
|
||||||
|
com.android.internal.R.bool.config_enableNewAutoSelectNetworkUI);
|
||||||
|
mAutoSelect = (TwoStatePreference) findPreference(BUTTON_AUTO_SELECT_KEY);
|
||||||
|
mChooseNetwork = findPreference(BUTTON_CHOOSE_NETWORK_KEY);
|
||||||
|
mNetworkSelect = (NetworkSelectListPreference) findPreference(BUTTON_NETWORK_SELECT_KEY);
|
||||||
|
if (mEnableNewManualSelectNetworkUI) {
|
||||||
|
removePreference(mNetworkSelect);
|
||||||
|
} else {
|
||||||
|
removePreference(mChooseNetwork);
|
||||||
|
}
|
||||||
|
mProgressDialog = new ProgressDialog(getContext());
|
||||||
|
mTelephonyManager = TelephonyManager.from(getContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update NetworkOperators instance if like subId is updated.
|
||||||
|
*
|
||||||
|
* @param subId Corresponding subscription ID of this network.
|
||||||
|
*/
|
||||||
|
protected void update(final int subId) {
|
||||||
|
mSubId = subId;
|
||||||
|
mTelephonyManager = TelephonyManager.from(getContext()).createForSubscriptionId(mSubId);
|
||||||
|
|
||||||
|
if (mAutoSelect != null) {
|
||||||
|
mAutoSelect.setOnPreferenceChangeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mEnableNewManualSelectNetworkUI) {
|
||||||
|
if (mChooseNetwork != null) {
|
||||||
|
ServiceState ss = mTelephonyManager.getServiceState();
|
||||||
|
if (ss != null && ss.getState() == ServiceState.STATE_IN_SERVICE) {
|
||||||
|
mChooseNetwork.setSummary(mTelephonyManager.getNetworkOperatorName());
|
||||||
|
} else {
|
||||||
|
mChooseNetwork.setSummary(R.string.network_disconnected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (mNetworkSelect != null) {
|
||||||
|
mNetworkSelect.initialize(mSubId, this, mProgressDialog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getNetworkSelectionMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implemented to support onPreferenceChangeListener to look for preference
|
||||||
|
* changes specifically on auto select button.
|
||||||
|
*
|
||||||
|
* @param preference is the preference to be changed, should be auto select button.
|
||||||
|
* @param newValue should be the value of whether autoSelect is checked.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
|
if (preference == mAutoSelect) {
|
||||||
|
boolean autoSelect = (Boolean) newValue;
|
||||||
|
if (DBG) logd("onPreferenceChange autoSelect: " + String.valueOf(autoSelect));
|
||||||
|
selectNetworkAutomatic(autoSelect);
|
||||||
|
MetricsLogger.action(getContext(),
|
||||||
|
MetricsEvent.ACTION_MOBILE_NETWORK_AUTO_SELECT_NETWORK_TOGGLE, autoSelect);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Handler mHandler = new Handler() {
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
switch (msg.what) {
|
||||||
|
case EVENT_AUTO_SELECT_DONE:
|
||||||
|
mAutoSelect.setEnabled(true);
|
||||||
|
dismissProgressBar();
|
||||||
|
|
||||||
|
boolean isSuccessed = (boolean) msg.obj;
|
||||||
|
|
||||||
|
if (isSuccessed) {
|
||||||
|
if (DBG) logd("automatic network selection: succeeded!");
|
||||||
|
displayNetworkSelectionSucceeded();
|
||||||
|
} else {
|
||||||
|
if (DBG) logd("automatic network selection: failed!");
|
||||||
|
displayNetworkSelectionFailed();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
|
||||||
|
int networkSelectionMode = msg.arg1;
|
||||||
|
if (networkSelectionMode == TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN) {
|
||||||
|
if (DBG) logd("get network selection mode: failed!");
|
||||||
|
} else {
|
||||||
|
boolean autoSelect = networkSelectionMode
|
||||||
|
== TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
|
||||||
|
if (DBG) {
|
||||||
|
logd("get network selection mode: "
|
||||||
|
+ (autoSelect ? "auto" : "manual") + " selection");
|
||||||
|
}
|
||||||
|
if (mAutoSelect != null) {
|
||||||
|
mAutoSelect.setChecked(autoSelect);
|
||||||
|
}
|
||||||
|
if (mEnableNewManualSelectNetworkUI) {
|
||||||
|
if (mChooseNetwork != null) {
|
||||||
|
mChooseNetwork.setEnabled(!autoSelect);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (mNetworkSelect != null) {
|
||||||
|
mNetworkSelect.setEnabled(!autoSelect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Used by both mAutoSelect and mNetworkSelect buttons.
|
||||||
|
protected void displayNetworkSelectionFailed() {
|
||||||
|
Toast.makeText(getContext(), R.string.connect_later, Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used by both mAutoSelect and mNetworkSelect buttons.
|
||||||
|
protected void displayNetworkSelectionSucceeded() {
|
||||||
|
Toast.makeText(getContext(), R.string.registration_done, Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void selectNetworkAutomatic(boolean autoSelect) {
|
||||||
|
if (DBG) logd("selectNetworkAutomatic: " + String.valueOf(autoSelect));
|
||||||
|
|
||||||
|
if (autoSelect) {
|
||||||
|
if (mEnableNewManualSelectNetworkUI) {
|
||||||
|
if (mChooseNetwork != null) {
|
||||||
|
mChooseNetwork.setEnabled(!autoSelect);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (mNetworkSelect != null) {
|
||||||
|
mNetworkSelect.setEnabled(!autoSelect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (DBG) logd("select network automatically...");
|
||||||
|
showAutoSelectProgressBar();
|
||||||
|
mAutoSelect.setEnabled(false);
|
||||||
|
if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
|
||||||
|
ThreadUtils.postOnBackgroundThread(() -> {
|
||||||
|
mTelephonyManager.setNetworkSelectionModeAutomatic();
|
||||||
|
// Because TelephonyManager#setNetworkSelectionModeAutomatic doesn't have a
|
||||||
|
// return value, we query the current network selection mode to tell if the
|
||||||
|
// TelephonyManager#setNetworkSelectionModeAutomatic is successed.
|
||||||
|
int networkSelectionMode = mTelephonyManager.getNetworkSelectionMode();
|
||||||
|
Message msg = mHandler.obtainMessage(EVENT_AUTO_SELECT_DONE);
|
||||||
|
msg.obj = networkSelectionMode == TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
|
||||||
|
msg.sendToTarget();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (mEnableNewManualSelectNetworkUI) {
|
||||||
|
if (mChooseNetwork != null) {
|
||||||
|
// Open the choose Network page automatically when user turn off the auto-select
|
||||||
|
openChooseNetworkPage();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (mNetworkSelect != null) {
|
||||||
|
mNetworkSelect.onClick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void getNetworkSelectionMode() {
|
||||||
|
if (DBG) logd("getting network selection mode...");
|
||||||
|
ThreadUtils.postOnBackgroundThread(() -> {
|
||||||
|
int networkSelectionMode = mTelephonyManager.getNetworkSelectionMode();
|
||||||
|
Message msg = mHandler.obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE);
|
||||||
|
msg.arg1 = networkSelectionMode;
|
||||||
|
msg.sendToTarget();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dismissProgressBar() {
|
||||||
|
if (mProgressDialog != null && mProgressDialog.isShowing()) {
|
||||||
|
mProgressDialog.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showAutoSelectProgressBar() {
|
||||||
|
mProgressDialog.setMessage(
|
||||||
|
getContext().getResources().getString(R.string.register_automatically));
|
||||||
|
mProgressDialog.setCanceledOnTouchOutside(false);
|
||||||
|
mProgressDialog.setCancelable(false);
|
||||||
|
mProgressDialog.setIndeterminate(true);
|
||||||
|
mProgressDialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open the Choose network page via {@alink NetworkSelectSettingActivity}
|
||||||
|
*/
|
||||||
|
public void openChooseNetworkPage() {
|
||||||
|
Intent intent = NetworkSelectSettingActivity.getIntent(getContext(), mSubId);
|
||||||
|
getContext().startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean preferenceTreeClick(Preference preference) {
|
||||||
|
if (mEnableNewManualSelectNetworkUI) {
|
||||||
|
if (DBG) logd("enable New AutoSelectNetwork UI");
|
||||||
|
if (preference == mChooseNetwork) {
|
||||||
|
openChooseNetworkPage();
|
||||||
|
}
|
||||||
|
return (preference == mAutoSelect || preference == mChooseNetwork);
|
||||||
|
} else {
|
||||||
|
return (preference == mAutoSelect || preference == mNetworkSelect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logd(String msg) {
|
||||||
|
Log.d(LOG_TAG, "[NetworksList] " + msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loge(String msg) {
|
||||||
|
Log.e(LOG_TAG, "[NetworksList] " + msg);
|
||||||
|
}
|
||||||
|
}
|
287
src/com/android/settings/mobilenetwork/NetworkScanHelper.java
Normal file
287
src/com/android/settings/mobilenetwork/NetworkScanHelper.java
Normal file
@@ -0,0 +1,287 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.mobilenetwork;
|
||||||
|
|
||||||
|
import android.annotation.IntDef;
|
||||||
|
import android.telephony.AccessNetworkConstants.AccessNetworkType;
|
||||||
|
import android.telephony.CellInfo;
|
||||||
|
import android.telephony.NetworkScan;
|
||||||
|
import android.telephony.NetworkScanRequest;
|
||||||
|
import android.telephony.RadioAccessSpecifier;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
|
import android.telephony.TelephonyScanManager;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.internal.telephony.CellNetworkScanResult;
|
||||||
|
import com.android.phone.CellInfoUtil;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.FutureCallback;
|
||||||
|
import com.google.common.util.concurrent.Futures;
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
import com.google.common.util.concurrent.SettableFuture;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper class that builds the common interface and performs the network scan for two different
|
||||||
|
* network scan APIs.
|
||||||
|
*/
|
||||||
|
public class NetworkScanHelper {
|
||||||
|
public static final String TAG = "NetworkScanHelper";
|
||||||
|
private static final boolean DBG = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callbacks interface to inform the network scan results.
|
||||||
|
*/
|
||||||
|
public interface NetworkScanCallback {
|
||||||
|
/**
|
||||||
|
* Called when the results is returned from {@link TelephonyManager}. This method will be
|
||||||
|
* called at least one time if there is no error occurred during the network scan.
|
||||||
|
*
|
||||||
|
* <p> This method can be called multiple times in one network scan, until
|
||||||
|
* {@link #onComplete()} or {@link #onError(int)} is called.
|
||||||
|
*
|
||||||
|
* @param results
|
||||||
|
*/
|
||||||
|
void onResults(List<CellInfo> results);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the current network scan process is finished. No more
|
||||||
|
* {@link #onResults(List)} will be called for the current network scan after this method is
|
||||||
|
* called.
|
||||||
|
*/
|
||||||
|
void onComplete();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when an error occurred during the network scan process.
|
||||||
|
*
|
||||||
|
* <p> There is no more result returned from {@link TelephonyManager} if an error occurred.
|
||||||
|
*
|
||||||
|
* <p> {@link #onComplete()} will not be called if an error occurred.
|
||||||
|
*
|
||||||
|
* @see {@link NetworkScan.ScanErrorCode}
|
||||||
|
*/
|
||||||
|
void onError(int errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@IntDef({NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS, NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS})
|
||||||
|
public @interface NetworkQueryType {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the network scan using {@link TelephonyManager#getAvailableNetworks()}. The network
|
||||||
|
* scan results won't be returned to the caller until the network scan is completed.
|
||||||
|
*
|
||||||
|
* <p> This is typically used when the modem doesn't support the new network scan api
|
||||||
|
* {@link TelephonyManager#requestNetworkScan(
|
||||||
|
* NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)}.
|
||||||
|
*/
|
||||||
|
public static final int NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the network scan using {@link TelephonyManager#requestNetworkScan(
|
||||||
|
* NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)} The network scan
|
||||||
|
* results will be returned to the caller periodically in a small time window until the network
|
||||||
|
* scan is completed. The complete results should be returned in the last called of
|
||||||
|
* {@link NetworkScanCallback#onResults(List)}.
|
||||||
|
*
|
||||||
|
* <p> This is recommended to be used if modem supports the new network scan api
|
||||||
|
* {@link TelephonyManager#requestNetworkScan(
|
||||||
|
* NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)}
|
||||||
|
*/
|
||||||
|
public static final int NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS = 2;
|
||||||
|
|
||||||
|
/** The constants below are used in the async network scan. */
|
||||||
|
private static final boolean INCREMENTAL_RESULTS = true;
|
||||||
|
private static final int SEARCH_PERIODICITY_SEC = 5;
|
||||||
|
private static final int MAX_SEARCH_TIME_SEC = 300;
|
||||||
|
private static final int INCREMENTAL_RESULTS_PERIODICITY_SEC = 3;
|
||||||
|
|
||||||
|
private static final NetworkScanRequest NETWORK_SCAN_REQUEST =
|
||||||
|
new NetworkScanRequest(
|
||||||
|
NetworkScanRequest.SCAN_TYPE_ONE_SHOT,
|
||||||
|
new RadioAccessSpecifier[]{
|
||||||
|
// GSM
|
||||||
|
new RadioAccessSpecifier(
|
||||||
|
AccessNetworkType.GERAN,
|
||||||
|
null /* bands */,
|
||||||
|
null /* channels */),
|
||||||
|
// LTE
|
||||||
|
new RadioAccessSpecifier(
|
||||||
|
AccessNetworkType.EUTRAN,
|
||||||
|
null /* bands */,
|
||||||
|
null /* channels */),
|
||||||
|
// WCDMA
|
||||||
|
new RadioAccessSpecifier(
|
||||||
|
AccessNetworkType.UTRAN,
|
||||||
|
null /* bands */,
|
||||||
|
null /* channels */)
|
||||||
|
},
|
||||||
|
SEARCH_PERIODICITY_SEC,
|
||||||
|
MAX_SEARCH_TIME_SEC,
|
||||||
|
INCREMENTAL_RESULTS,
|
||||||
|
INCREMENTAL_RESULTS_PERIODICITY_SEC,
|
||||||
|
null /* List of PLMN ids (MCC-MNC) */);
|
||||||
|
|
||||||
|
private final NetworkScanCallback mNetworkScanCallback;
|
||||||
|
private final TelephonyManager mTelephonyManager;
|
||||||
|
private final TelephonyScanManager.NetworkScanCallback mInternalNetworkScanCallback;
|
||||||
|
private final Executor mExecutor;
|
||||||
|
|
||||||
|
private NetworkScan mNetworkScanRequester;
|
||||||
|
|
||||||
|
/** Callbacks for sync network scan */
|
||||||
|
private ListenableFuture<List<CellInfo>> mNetworkScanFuture;
|
||||||
|
|
||||||
|
public NetworkScanHelper(TelephonyManager tm, NetworkScanCallback callback, Executor executor) {
|
||||||
|
mTelephonyManager = tm;
|
||||||
|
mNetworkScanCallback = callback;
|
||||||
|
mInternalNetworkScanCallback = new NetworkScanCallbackImpl();
|
||||||
|
mExecutor = executor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a network scan for the given type {@code type}.
|
||||||
|
* {@link #NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS} is recommended if modem supports
|
||||||
|
* {@link TelephonyManager#requestNetworkScan(
|
||||||
|
* NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)}.
|
||||||
|
*
|
||||||
|
* @param type used to tell which network scan API should be used.
|
||||||
|
*/
|
||||||
|
public void startNetworkScan(@NetworkQueryType int type) {
|
||||||
|
if (type == NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS) {
|
||||||
|
mNetworkScanFuture = SettableFuture.create();
|
||||||
|
Futures.addCallback(mNetworkScanFuture, new FutureCallback<List<CellInfo>>() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(List<CellInfo> result) {
|
||||||
|
onResults(result);
|
||||||
|
onComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Throwable t) {
|
||||||
|
int errCode = Integer.parseInt(t.getMessage());
|
||||||
|
onError(errCode);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mExecutor.execute(new NetworkScanSyncTask(
|
||||||
|
mTelephonyManager, (SettableFuture) mNetworkScanFuture));
|
||||||
|
} else if (type == NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS) {
|
||||||
|
if (DBG) Log.d(TAG, "start network scan async");
|
||||||
|
mNetworkScanRequester = mTelephonyManager.requestNetworkScan(
|
||||||
|
NETWORK_SCAN_REQUEST,
|
||||||
|
mExecutor,
|
||||||
|
mInternalNetworkScanCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The network scan of type {@link #NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS} can't be stopped,
|
||||||
|
* however, the result of the current network scan won't be returned to the callback after
|
||||||
|
* calling this method.
|
||||||
|
*/
|
||||||
|
public void stopNetworkQuery() {
|
||||||
|
if (mNetworkScanRequester != null) {
|
||||||
|
mNetworkScanRequester.stopScan();
|
||||||
|
mNetworkScanFuture = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mNetworkScanFuture != null) {
|
||||||
|
mNetworkScanFuture.cancel(true /* mayInterruptIfRunning */);
|
||||||
|
mNetworkScanFuture = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onResults(List<CellInfo> cellInfos) {
|
||||||
|
mNetworkScanCallback.onResults(cellInfos);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onComplete() {
|
||||||
|
mNetworkScanCallback.onComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onError(int errCode) {
|
||||||
|
mNetworkScanCallback.onError(errCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the status code of {@link CellNetworkScanResult} to one of the
|
||||||
|
* {@link NetworkScan.ScanErrorCode}.
|
||||||
|
* @param errCode status code from {@link CellNetworkScanResult}.
|
||||||
|
*
|
||||||
|
* @return one of the scan error code from {@link NetworkScan.ScanErrorCode}.
|
||||||
|
*/
|
||||||
|
private static int convertToScanErrorCode(int errCode) {
|
||||||
|
switch (errCode) {
|
||||||
|
case CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE:
|
||||||
|
return NetworkScan.ERROR_RADIO_INTERFACE_ERROR;
|
||||||
|
case CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE:
|
||||||
|
default:
|
||||||
|
return NetworkScan.ERROR_MODEM_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class NetworkScanCallbackImpl extends TelephonyScanManager.NetworkScanCallback {
|
||||||
|
public void onResults(List<CellInfo> results) {
|
||||||
|
if (DBG) Log.d(TAG, "async scan onResults() results = " + results);
|
||||||
|
NetworkScanHelper.this.onResults(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onComplete() {
|
||||||
|
if (DBG) Log.d(TAG, "async scan onComplete()");
|
||||||
|
NetworkScanHelper.this.onComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onError(@NetworkScan.ScanErrorCode int errCode) {
|
||||||
|
if (DBG) Log.d(TAG, "async scan onError() errorCode = " + errCode);
|
||||||
|
NetworkScanHelper.this.onError(errCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class NetworkScanSyncTask implements Runnable {
|
||||||
|
private final SettableFuture<List<CellInfo>> mCallback;
|
||||||
|
private final TelephonyManager mTelephonyManager;
|
||||||
|
|
||||||
|
NetworkScanSyncTask(
|
||||||
|
TelephonyManager telephonyManager, SettableFuture<List<CellInfo>> callback) {
|
||||||
|
mTelephonyManager = telephonyManager;
|
||||||
|
mCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (DBG) Log.d(TAG, "sync scan start");
|
||||||
|
CellNetworkScanResult result = mTelephonyManager.getAvailableNetworks();
|
||||||
|
if (result.getStatus() == CellNetworkScanResult.STATUS_SUCCESS) {
|
||||||
|
List<CellInfo> cellInfos = result.getOperators()
|
||||||
|
.stream()
|
||||||
|
.map(operatorInfo
|
||||||
|
-> CellInfoUtil.convertOperatorInfoToCellInfo(operatorInfo))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (DBG) Log.d(TAG, "sync scan complete");
|
||||||
|
mCallback.set(cellInfos);
|
||||||
|
} else {
|
||||||
|
mCallback.setException(new Throwable(
|
||||||
|
Integer.toString(convertToScanErrorCode(result.getStatus()))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,505 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.phone;
|
||||||
|
|
||||||
|
import android.app.ProgressDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.preference.ListPreference;
|
||||||
|
import android.preference.Preference;
|
||||||
|
import android.telephony.CellInfo;
|
||||||
|
import android.telephony.CellInfoCdma;
|
||||||
|
import android.telephony.CellInfoGsm;
|
||||||
|
import android.telephony.CellInfoLte;
|
||||||
|
import android.telephony.CellInfoWcdma;
|
||||||
|
import android.telephony.SubscriptionManager;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
|
import android.text.BidiFormatter;
|
||||||
|
import android.text.TextDirectionHeuristics;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.android.internal.logging.MetricsLogger;
|
||||||
|
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
|
import com.android.internal.telephony.OperatorInfo;
|
||||||
|
import com.android.phone.NetworkScanHelper.NetworkScanCallback;
|
||||||
|
import com.android.settingslib.utils.ThreadUtils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "Networks" preference in "Mobile network" settings UI for the Phone app.
|
||||||
|
* It's used to manually search and choose mobile network. Enabled only when
|
||||||
|
* autoSelect preference is turned off.
|
||||||
|
*/
|
||||||
|
public class NetworkSelectListPreference extends ListPreference
|
||||||
|
implements DialogInterface.OnCancelListener,
|
||||||
|
Preference.OnPreferenceChangeListener{
|
||||||
|
|
||||||
|
private static final String LOG_TAG = "networkSelect";
|
||||||
|
private static final boolean DBG = true;
|
||||||
|
|
||||||
|
private static final int EVENT_MANUALLY_NETWORK_SELECTION_DONE = 1;
|
||||||
|
private static final int EVENT_NETWORK_SCAN_RESULTS = 2;
|
||||||
|
private static final int EVENT_NETWORK_SCAN_COMPLETED = 3;
|
||||||
|
private static final int EVENT_NETWORK_SCAN_ERROR = 4;
|
||||||
|
|
||||||
|
//dialog ids
|
||||||
|
private static final int DIALOG_NETWORK_SELECTION = 100;
|
||||||
|
private static final int DIALOG_NETWORK_LIST_LOAD = 200;
|
||||||
|
|
||||||
|
private final ExecutorService mNetworkScanExecutor = Executors.newFixedThreadPool(1);
|
||||||
|
|
||||||
|
private List<CellInfo> mCellInfoList;
|
||||||
|
private CellInfo mCellInfo;
|
||||||
|
|
||||||
|
private int mSubId;
|
||||||
|
private TelephonyManager mTelephonyManager;
|
||||||
|
private NetworkScanHelper mNetworkScanHelper;
|
||||||
|
private NetworkOperators mNetworkOperators;
|
||||||
|
private List<String> mForbiddenPlmns;
|
||||||
|
|
||||||
|
private ProgressDialog mProgressDialog;
|
||||||
|
public NetworkSelectListPreference(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NetworkSelectListPreference(Context context, AttributeSet attrs, int defStyleAttr,
|
||||||
|
int defStyleRes) {
|
||||||
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onClick() {
|
||||||
|
showProgressDialog(DIALOG_NETWORK_LIST_LOAD);
|
||||||
|
TelephonyManager telephonyManager = (TelephonyManager)
|
||||||
|
getContext().getSystemService(Context.TELEPHONY_SERVICE);
|
||||||
|
new AsyncTask<Void, Void, List<String>>() {
|
||||||
|
@Override
|
||||||
|
protected List<String> doInBackground(Void... voids) {
|
||||||
|
String[] forbiddenPlmns = telephonyManager.getForbiddenPlmns();
|
||||||
|
return forbiddenPlmns != null ? Arrays.asList(forbiddenPlmns) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(List<String> result) {
|
||||||
|
mForbiddenPlmns = result;
|
||||||
|
loadNetworksList();
|
||||||
|
}
|
||||||
|
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Handler mHandler = new Handler() {
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
switch (msg.what) {
|
||||||
|
case EVENT_MANUALLY_NETWORK_SELECTION_DONE:
|
||||||
|
if (DBG) logd("hideProgressPanel");
|
||||||
|
dismissProgressDialog();
|
||||||
|
|
||||||
|
boolean isSuccessed = (boolean) msg.obj;
|
||||||
|
if (isSuccessed) {
|
||||||
|
if (DBG) {
|
||||||
|
logd("manual network selection: succeeded! "
|
||||||
|
+ getNetworkTitle(mCellInfo));
|
||||||
|
}
|
||||||
|
mNetworkOperators.displayNetworkSelectionSucceeded();
|
||||||
|
} else {
|
||||||
|
if (DBG) logd("manual network selection: failed!");
|
||||||
|
mNetworkOperators.displayNetworkSelectionFailed();
|
||||||
|
}
|
||||||
|
mNetworkOperators.getNetworkSelectionMode();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EVENT_NETWORK_SCAN_RESULTS:
|
||||||
|
List<CellInfo> results = (List<CellInfo>) msg.obj;
|
||||||
|
results.removeIf(cellInfo -> cellInfo == null);
|
||||||
|
mCellInfoList = new ArrayList<>(results);
|
||||||
|
if (DBG) logd("CALLBACK_SCAN_RESULTS" + mCellInfoList.toString());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EVENT_NETWORK_SCAN_COMPLETED:
|
||||||
|
if (DBG) logd("scan complete, load the cellInfosList");
|
||||||
|
dismissProgressDialog();
|
||||||
|
networksListLoaded();
|
||||||
|
break;
|
||||||
|
case EVENT_NETWORK_SCAN_ERROR:
|
||||||
|
dismissProgressDialog();
|
||||||
|
displayNetworkQueryFailed();
|
||||||
|
mNetworkOperators.getNetworkSelectionMode();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final NetworkScanHelper.NetworkScanCallback mCallback = new NetworkScanCallback() {
|
||||||
|
public void onResults(List<CellInfo> results) {
|
||||||
|
if (DBG) logd("get scan results: " + results.toString());
|
||||||
|
Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_RESULTS, results);
|
||||||
|
msg.sendToTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onComplete() {
|
||||||
|
if (DBG) logd("network scan completed.");
|
||||||
|
Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_COMPLETED);
|
||||||
|
msg.sendToTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onError(int error) {
|
||||||
|
if (DBG) logd("network scan error.");
|
||||||
|
Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_ERROR);
|
||||||
|
msg.sendToTarget();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
//implemented for DialogInterface.OnCancelListener
|
||||||
|
public void onCancel(DialogInterface dialog) {
|
||||||
|
if (DBG) logd("user manually close the dialog");
|
||||||
|
mNetworkScanHelper.stopNetworkQuery();
|
||||||
|
|
||||||
|
// If cancelled, we query NetworkSelectMode and update states of AutoSelect button.
|
||||||
|
mNetworkOperators.getNetworkSelectionMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDialogClosed(boolean positiveResult) {
|
||||||
|
super.onDialogClosed(positiveResult);
|
||||||
|
// If dismissed, we query NetworkSelectMode and update states of AutoSelect button.
|
||||||
|
if (!positiveResult) {
|
||||||
|
mNetworkOperators.getNetworkSelectionMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This initialize method needs to be called for this preference to work properly.
|
||||||
|
protected void initialize(int subId, NetworkOperators networkOperators,
|
||||||
|
ProgressDialog progressDialog) {
|
||||||
|
mSubId = subId;
|
||||||
|
mNetworkOperators = networkOperators;
|
||||||
|
// This preference should share the same progressDialog with networkOperators category.
|
||||||
|
mProgressDialog = progressDialog;
|
||||||
|
|
||||||
|
mTelephonyManager = TelephonyManager.from(getContext()).createForSubscriptionId(mSubId);
|
||||||
|
mNetworkScanHelper = new NetworkScanHelper(
|
||||||
|
mTelephonyManager, mCallback, mNetworkScanExecutor);
|
||||||
|
|
||||||
|
setSummary(mTelephonyManager.getNetworkOperatorName());
|
||||||
|
|
||||||
|
setOnPreferenceChangeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPrepareForRemoval() {
|
||||||
|
destroy();
|
||||||
|
super.onPrepareForRemoval();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void destroy() {
|
||||||
|
dismissProgressDialog();
|
||||||
|
|
||||||
|
if (mNetworkScanHelper != null) {
|
||||||
|
mNetworkScanHelper.stopNetworkQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
mNetworkScanExecutor.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void displayEmptyNetworkList() {
|
||||||
|
Toast.makeText(getContext(), R.string.empty_networks_list, Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void displayNetworkQueryFailed() {
|
||||||
|
Toast.makeText(getContext(), R.string.network_query_error, Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadNetworksList() {
|
||||||
|
if (DBG) logd("load networks list...");
|
||||||
|
mNetworkScanHelper.startNetworkScan(
|
||||||
|
NetworkScanHelper.NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void networksListLoaded() {
|
||||||
|
if (DBG) logd("networks list loaded");
|
||||||
|
|
||||||
|
mNetworkOperators.getNetworkSelectionMode();
|
||||||
|
if (mCellInfoList != null) {
|
||||||
|
// create a preference for each item in the list.
|
||||||
|
// just use the operator name instead of the mildly
|
||||||
|
// confusing mcc/mnc.
|
||||||
|
List<CharSequence> networkEntriesList = new ArrayList<>();
|
||||||
|
List<CharSequence> networkEntryValuesList = new ArrayList<>();
|
||||||
|
for (CellInfo cellInfo: mCellInfoList) {
|
||||||
|
// Display each operator name only once.
|
||||||
|
String networkTitle = getNetworkTitle(cellInfo);
|
||||||
|
if (CellInfoUtil.isForbidden(cellInfo, mForbiddenPlmns)) {
|
||||||
|
networkTitle += " "
|
||||||
|
+ getContext().getResources().getString(R.string.forbidden_network);
|
||||||
|
}
|
||||||
|
networkEntriesList.add(networkTitle);
|
||||||
|
networkEntryValuesList.add(getOperatorNumeric(cellInfo));
|
||||||
|
}
|
||||||
|
setEntries(networkEntriesList.toArray(new CharSequence[networkEntriesList.size()]));
|
||||||
|
setEntryValues(networkEntryValuesList.toArray(
|
||||||
|
new CharSequence[networkEntryValuesList.size()]));
|
||||||
|
|
||||||
|
super.onClick();
|
||||||
|
} else {
|
||||||
|
displayEmptyNetworkList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dismissProgressDialog() {
|
||||||
|
if (mProgressDialog != null && mProgressDialog.isShowing()) {
|
||||||
|
try {
|
||||||
|
mProgressDialog.dismiss();
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
loge("Can't close the progress dialog " + ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showProgressDialog(int id) {
|
||||||
|
if (mProgressDialog == null) {
|
||||||
|
mProgressDialog = new ProgressDialog(getContext());
|
||||||
|
} else {
|
||||||
|
// Dismiss progress bar if it's showing now.
|
||||||
|
dismissProgressDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (id) {
|
||||||
|
case DIALOG_NETWORK_SELECTION:
|
||||||
|
final String networkSelectMsg = getContext().getResources()
|
||||||
|
.getString(R.string.register_on_network,
|
||||||
|
getNetworkTitle(mCellInfo));
|
||||||
|
mProgressDialog.setMessage(networkSelectMsg);
|
||||||
|
mProgressDialog.setCanceledOnTouchOutside(false);
|
||||||
|
mProgressDialog.setCancelable(false);
|
||||||
|
mProgressDialog.setIndeterminate(true);
|
||||||
|
break;
|
||||||
|
case DIALOG_NETWORK_LIST_LOAD:
|
||||||
|
mProgressDialog.setMessage(
|
||||||
|
getContext().getResources().getString(R.string.load_networks_progress));
|
||||||
|
mProgressDialog.setCanceledOnTouchOutside(false);
|
||||||
|
mProgressDialog.setCancelable(true);
|
||||||
|
mProgressDialog.setIndeterminate(false);
|
||||||
|
mProgressDialog.setOnCancelListener(this);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
mProgressDialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implemented to support onPreferenceChangeListener to look for preference
|
||||||
|
* changes specifically on this button.
|
||||||
|
*
|
||||||
|
* @param preference is the preference to be changed, should be network select button.
|
||||||
|
* @param newValue should be the value of the selection as index of operators.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
|
int operatorIndex = findIndexOfValue((String) newValue);
|
||||||
|
mCellInfo = mCellInfoList.get(operatorIndex);
|
||||||
|
if (DBG) logd("selected network: " + mCellInfo.toString());
|
||||||
|
|
||||||
|
MetricsLogger.action(getContext(),
|
||||||
|
MetricsEvent.ACTION_MOBILE_NETWORK_MANUAL_SELECT_NETWORK);
|
||||||
|
|
||||||
|
if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
|
||||||
|
ThreadUtils.postOnBackgroundThread(() -> {
|
||||||
|
final OperatorInfo operatorInfo = getOperatorInfoFromCellInfo(mCellInfo);
|
||||||
|
if (DBG) logd("manually selected network: " + operatorInfo.toString());
|
||||||
|
boolean isSuccessed = mTelephonyManager.setNetworkSelectionModeManual(
|
||||||
|
operatorInfo, true /* persistSelection */);
|
||||||
|
Message msg = mHandler.obtainMessage(EVENT_MANUALLY_NETWORK_SELECTION_DONE);
|
||||||
|
msg.obj = isSuccessed;
|
||||||
|
msg.sendToTarget();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
loge("Error selecting network, subscription Id is invalid " + mSubId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the title of the network obtained in the manual search.
|
||||||
|
*
|
||||||
|
* @param cellInfo contains the information of the network.
|
||||||
|
* @return Long Name if not null/empty, otherwise Short Name if not null/empty,
|
||||||
|
* else MCCMNC string.
|
||||||
|
*/
|
||||||
|
private String getNetworkTitle(CellInfo cellInfo) {
|
||||||
|
OperatorInfo ni = getOperatorInfoFromCellInfo(cellInfo);
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(ni.getOperatorAlphaLong())) {
|
||||||
|
return ni.getOperatorAlphaLong();
|
||||||
|
} else if (!TextUtils.isEmpty(ni.getOperatorAlphaShort())) {
|
||||||
|
return ni.getOperatorAlphaShort();
|
||||||
|
} else {
|
||||||
|
BidiFormatter bidiFormatter = BidiFormatter.getInstance();
|
||||||
|
return bidiFormatter.unicodeWrap(ni.getOperatorNumeric(), TextDirectionHeuristics.LTR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the operator numeric (MCCMNC) obtained in the manual search.
|
||||||
|
*
|
||||||
|
* @param cellInfo contains the information of the network.
|
||||||
|
* @return MCCMNC string.
|
||||||
|
*/
|
||||||
|
private String getOperatorNumeric(CellInfo cellInfo) {
|
||||||
|
return getOperatorInfoFromCellInfo(cellInfo).getOperatorNumeric();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap a cell info into an operator info.
|
||||||
|
*/
|
||||||
|
private OperatorInfo getOperatorInfoFromCellInfo(CellInfo cellInfo) {
|
||||||
|
OperatorInfo oi;
|
||||||
|
if (cellInfo instanceof CellInfoLte) {
|
||||||
|
CellInfoLte lte = (CellInfoLte) cellInfo;
|
||||||
|
oi = new OperatorInfo(
|
||||||
|
(String) lte.getCellIdentity().getOperatorAlphaLong(),
|
||||||
|
(String) lte.getCellIdentity().getOperatorAlphaShort(),
|
||||||
|
lte.getCellIdentity().getMobileNetworkOperator());
|
||||||
|
} else if (cellInfo instanceof CellInfoWcdma) {
|
||||||
|
CellInfoWcdma wcdma = (CellInfoWcdma) cellInfo;
|
||||||
|
oi = new OperatorInfo(
|
||||||
|
(String) wcdma.getCellIdentity().getOperatorAlphaLong(),
|
||||||
|
(String) wcdma.getCellIdentity().getOperatorAlphaShort(),
|
||||||
|
wcdma.getCellIdentity().getMobileNetworkOperator());
|
||||||
|
} else if (cellInfo instanceof CellInfoGsm) {
|
||||||
|
CellInfoGsm gsm = (CellInfoGsm) cellInfo;
|
||||||
|
oi = new OperatorInfo(
|
||||||
|
(String) gsm.getCellIdentity().getOperatorAlphaLong(),
|
||||||
|
(String) gsm.getCellIdentity().getOperatorAlphaShort(),
|
||||||
|
gsm.getCellIdentity().getMobileNetworkOperator());
|
||||||
|
} else if (cellInfo instanceof CellInfoCdma) {
|
||||||
|
CellInfoCdma cdma = (CellInfoCdma) cellInfo;
|
||||||
|
oi = new OperatorInfo(
|
||||||
|
(String) cdma.getCellIdentity().getOperatorAlphaLong(),
|
||||||
|
(String) cdma.getCellIdentity().getOperatorAlphaShort(),
|
||||||
|
"" /* operator numeric */);
|
||||||
|
} else {
|
||||||
|
oi = new OperatorInfo("", "", "");
|
||||||
|
}
|
||||||
|
return oi;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Parcelable onSaveInstanceState() {
|
||||||
|
final Parcelable superState = super.onSaveInstanceState();
|
||||||
|
if (isPersistent()) {
|
||||||
|
// No need to save instance state since it's persistent
|
||||||
|
return superState;
|
||||||
|
}
|
||||||
|
|
||||||
|
final SavedState myState = new SavedState(superState);
|
||||||
|
myState.mDialogListEntries = getEntries();
|
||||||
|
myState.mDialogListEntryValues = getEntryValues();
|
||||||
|
myState.mCellInfoList = mCellInfoList;
|
||||||
|
return myState;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onRestoreInstanceState(Parcelable state) {
|
||||||
|
if (state == null || !state.getClass().equals(SavedState.class)) {
|
||||||
|
// Didn't save state for us in onSaveInstanceState
|
||||||
|
super.onRestoreInstanceState(state);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SavedState myState = (SavedState) state;
|
||||||
|
|
||||||
|
if (getEntries() == null && myState.mDialogListEntries != null) {
|
||||||
|
setEntries(myState.mDialogListEntries);
|
||||||
|
}
|
||||||
|
if (getEntryValues() == null && myState.mDialogListEntryValues != null) {
|
||||||
|
setEntryValues(myState.mDialogListEntryValues);
|
||||||
|
}
|
||||||
|
if (mCellInfoList == null && myState.mCellInfoList != null) {
|
||||||
|
mCellInfoList = myState.mCellInfoList;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.onRestoreInstanceState(myState.getSuperState());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We save entries, entryValues and operatorInfoList into bundle.
|
||||||
|
* At onCreate of fragment, dialog will be restored if it was open. In this case,
|
||||||
|
* we need to restore entries, entryValues and operatorInfoList. Without those information,
|
||||||
|
* onPreferenceChange will fail if user select network from the dialog.
|
||||||
|
*/
|
||||||
|
private static class SavedState extends BaseSavedState {
|
||||||
|
CharSequence[] mDialogListEntries;
|
||||||
|
CharSequence[] mDialogListEntryValues;
|
||||||
|
List<CellInfo> mCellInfoList;
|
||||||
|
|
||||||
|
SavedState(Parcel source) {
|
||||||
|
super(source);
|
||||||
|
final ClassLoader boot = Object.class.getClassLoader();
|
||||||
|
mDialogListEntries = source.readCharSequenceArray();
|
||||||
|
mDialogListEntryValues = source.readCharSequenceArray();
|
||||||
|
mCellInfoList = source.readParcelableList(mCellInfoList, boot);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
super.writeToParcel(dest, flags);
|
||||||
|
dest.writeCharSequenceArray(mDialogListEntries);
|
||||||
|
dest.writeCharSequenceArray(mDialogListEntryValues);
|
||||||
|
dest.writeParcelableList(mCellInfoList, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
SavedState(Parcelable superState) {
|
||||||
|
super(superState);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Parcelable.Creator<SavedState> CREATOR =
|
||||||
|
new Parcelable.Creator<SavedState>() {
|
||||||
|
public SavedState createFromParcel(Parcel in) {
|
||||||
|
return new SavedState(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SavedState[] newArray(int size) {
|
||||||
|
return new SavedState[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logd(String msg) {
|
||||||
|
Log.d(LOG_TAG, "[NetworksList] " + msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loge(String msg) {
|
||||||
|
Log.e(LOG_TAG, "[NetworksList] " + msg);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.android.settings.mobilenetwork;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.app.DialogFragment;
|
||||||
|
import android.app.Fragment;
|
||||||
|
import android.app.FragmentManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.DialogInterface.OnClickListener;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.PersistableBundle;
|
||||||
|
import android.telephony.CarrierConfigManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A dialog fragment that asks the user if they are sure they want to turn on data roaming
|
||||||
|
* to avoid accidental charges.
|
||||||
|
*/
|
||||||
|
public class RoamingDialogFragment extends DialogFragment implements OnClickListener {
|
||||||
|
|
||||||
|
public static final String SUB_ID_KEY = "sub_id_key";
|
||||||
|
|
||||||
|
private CarrierConfigManager mCarrierConfigManager;
|
||||||
|
private int mSubId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The interface we expect a host activity to implement.
|
||||||
|
*/
|
||||||
|
public interface RoamingDialogListener {
|
||||||
|
void onPositiveButtonClick(DialogFragment dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
// the host activity which implements the listening interface
|
||||||
|
private RoamingDialogListener mListener;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
Bundle args = getArguments();
|
||||||
|
mSubId = args.getInt(SUB_ID_KEY);
|
||||||
|
mCarrierConfigManager = new CarrierConfigManager(context);
|
||||||
|
|
||||||
|
// Verify host activity implemented callback interface
|
||||||
|
FragmentManager fragmentManager = getFragmentManager();
|
||||||
|
Fragment fragment = fragmentManager.findFragmentById(R.id.network_setting_content);
|
||||||
|
try {
|
||||||
|
mListener = (RoamingDialogListener) fragment;
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
throw new ClassCastException(fragment.toString() +
|
||||||
|
"must implement RoamingDialogListener");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||||
|
int title = R.string.roaming_alert_title;
|
||||||
|
PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
|
||||||
|
if (carrierConfig != null && carrierConfig.getBoolean(
|
||||||
|
CarrierConfigManager.KEY_CHECK_PRICING_WITH_CARRIER_FOR_DATA_ROAMING_BOOL)) {
|
||||||
|
title = R.string.roaming_check_price_warning;
|
||||||
|
}
|
||||||
|
builder.setMessage(getResources().getString(R.string.roaming_warning))
|
||||||
|
.setTitle(title)
|
||||||
|
.setIconAttribute(android.R.attr.alertDialogIcon)
|
||||||
|
.setPositiveButton(android.R.string.yes, this)
|
||||||
|
.setNegativeButton(android.R.string.no, this);
|
||||||
|
return builder.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
// let the host know that the positive button has been clicked
|
||||||
|
if (which == dialog.BUTTON_POSITIVE) {
|
||||||
|
mListener.onPositiveButtonClick(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user