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:
jackqdyulei
2018-10-03 13:54:53 -07:00
parent 4b2a053bed
commit bff33e170c
18 changed files with 4855 additions and 0 deletions

View File

@@ -1133,4 +1133,186 @@
<item>4</item> <!-- AutofillManager.FLAG_ADD_CLIENT_VERBOSE -->
</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>

View File

@@ -136,4 +136,8 @@
<!-- Whether or not TopLevelSettings should force rounded icon for injected tiles -->
<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>

View File

@@ -10112,4 +10112,151 @@
<!-- Message informs the user that has no SIM card in personalized Settings [CHAR LIMIT=30] -->
<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">Couldnt 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>

54
res/xml/cdma_options.xml Normal file
View 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>

View 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>

View 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>

View File

@@ -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);
}
}

View 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);
}
}

View File

@@ -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");
}
});
}
}

View File

@@ -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();
});
}
}

View File

@@ -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());
}
}

View 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);
}
}

View 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];
}
};
}
}

File diff suppressed because it is too large Load Diff

View 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);
}
}

View 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()))));
}
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}