Merge 25Q1 (ab/12770256) to aosp-main-future
Bug: 385190204 Merged-In: Iaee6792d1a27be8fa4b443f783a47a3715b6d3a1 Change-Id: I0ac29cecfec526a38cf4a120b8ef704ee7bc01b3
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.network
|
||||
|
||||
import android.content.Context
|
||||
import com.android.settings.R
|
||||
import com.android.settings.flags.Flags
|
||||
import com.android.settingslib.metadata.ProvidePreferenceScreen
|
||||
import com.android.settingslib.metadata.preferenceHierarchy
|
||||
import com.android.settingslib.preference.PreferenceScreenCreator
|
||||
|
||||
@ProvidePreferenceScreen
|
||||
class AdaptiveConnectivityScreen : PreferenceScreenCreator {
|
||||
override val key
|
||||
get() = KEY
|
||||
|
||||
override val title
|
||||
get() = R.string.adaptive_connectivity_title
|
||||
|
||||
override fun isFlagEnabled(context: Context) = Flags.catalystAdaptiveConnectivity()
|
||||
|
||||
override fun fragmentClass() = AdaptiveConnectivitySettings::class.java
|
||||
|
||||
override fun getPreferenceHierarchy(context: Context) = preferenceHierarchy(this) {
|
||||
+AdaptiveConnectivityTogglePreference()
|
||||
}
|
||||
|
||||
override fun hasCompleteHierarchy() = false
|
||||
|
||||
companion object {
|
||||
const val KEY = "adaptive_connectivity"
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,10 @@
|
||||
package com.android.settings.network;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
@@ -30,8 +34,6 @@ public class AdaptiveConnectivitySettings extends DashboardFragment {
|
||||
|
||||
private static final String TAG = "AdaptiveConnectivitySettings";
|
||||
|
||||
private static final String KEY_ADAPTIVE_CONNECTIVITY_PREFERENCE = "adaptive_connectivity";
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return SettingsEnums.ADAPTIVE_CONNECTIVITY_CATEGORY;
|
||||
@@ -49,4 +51,9 @@ public class AdaptiveConnectivitySettings extends DashboardFragment {
|
||||
|
||||
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||
new BaseSearchIndexProvider(R.xml.adaptive_connectivity_settings);
|
||||
|
||||
@Override
|
||||
public @Nullable String getPreferenceScreenBindingKey(@NonNull Context context) {
|
||||
return AdaptiveConnectivityScreen.KEY;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.network
|
||||
|
||||
import android.content.Context
|
||||
import android.net.wifi.WifiManager
|
||||
import android.provider.Settings.Secure.ADAPTIVE_CONNECTIVITY_ENABLED
|
||||
import com.android.settings.R
|
||||
import com.android.settingslib.datastore.KeyValueStore
|
||||
import com.android.settingslib.datastore.KeyedObservableDelegate
|
||||
import com.android.settingslib.datastore.SettingsSecureStore
|
||||
import com.android.settingslib.datastore.SettingsStore
|
||||
import com.android.settingslib.metadata.MainSwitchPreference
|
||||
import com.android.settingslib.metadata.ReadWritePermit
|
||||
import com.android.settingslib.metadata.SensitivityLevel
|
||||
|
||||
// LINT.IfChange
|
||||
class AdaptiveConnectivityTogglePreference :
|
||||
MainSwitchPreference(KEY, R.string.adaptive_connectivity_main_switch_title) {
|
||||
|
||||
override fun storage(context: Context): KeyValueStore =
|
||||
AdaptiveConnectivityToggleStorage(context, SettingsSecureStore.get(context))
|
||||
|
||||
override fun getReadPermit(context: Context, myUid: Int, callingUid: Int) =
|
||||
ReadWritePermit.ALLOW
|
||||
|
||||
override fun getWritePermit(context: Context, value: Boolean?, myUid: Int, callingUid: Int) =
|
||||
ReadWritePermit.ALLOW
|
||||
|
||||
override val sensitivityLevel
|
||||
get() = SensitivityLevel.NO_SENSITIVITY
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private class AdaptiveConnectivityToggleStorage(
|
||||
private val context: Context,
|
||||
private val settingsStore: SettingsStore,
|
||||
) : KeyedObservableDelegate<String>(settingsStore), KeyValueStore {
|
||||
|
||||
override fun contains(key: String) = settingsStore.contains(KEY)
|
||||
|
||||
override fun <T : Any> getDefaultValue(key: String, valueType: Class<T>) =
|
||||
DEFAULT_VALUE as T
|
||||
|
||||
override fun <T : Any> getValue(key: String, valueType: Class<T>) =
|
||||
(settingsStore.getBoolean(key) ?: DEFAULT_VALUE) as T
|
||||
|
||||
override fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?) {
|
||||
settingsStore.setBoolean(key, value as Boolean)
|
||||
context.getSystemService(WifiManager::class.java)?.setWifiScoringEnabled(value)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val KEY = ADAPTIVE_CONNECTIVITY_ENABLED
|
||||
const val DEFAULT_VALUE = true
|
||||
}
|
||||
}
|
||||
// LINT.ThenChange(AdaptiveConnectivityTogglePreferenceController.java)
|
||||
@@ -29,6 +29,7 @@ import com.android.settings.widget.SettingsMainSwitchPreferenceController;
|
||||
* {@link SettingsMainSwitchPreferenceController}
|
||||
* that controls whether Adaptive connectivity option is enabled.
|
||||
*/
|
||||
// LINT.IfChange
|
||||
public class AdaptiveConnectivityTogglePreferenceController extends
|
||||
SettingsMainSwitchPreferenceController {
|
||||
|
||||
@@ -69,3 +70,4 @@ public class AdaptiveConnectivityTogglePreferenceController extends
|
||||
return R.string.menu_key_network;
|
||||
}
|
||||
}
|
||||
// LINT.ThenChange(AdaptiveConnectivityTogglePreference.kt)
|
||||
|
||||
203
src/com/android/settings/network/AirplaneModePreference.kt
Normal file
203
src/com/android/settings/network/AirplaneModePreference.kt
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.network
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Looper
|
||||
import android.os.UserHandle
|
||||
import android.os.UserManager
|
||||
import android.provider.Settings
|
||||
import android.telephony.PhoneStateListener
|
||||
import android.telephony.TelephonyManager
|
||||
import android.util.Log
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.preference.Preference
|
||||
import com.android.settings.AirplaneModeEnabler
|
||||
import com.android.settings.PreferenceRestrictionMixin
|
||||
import com.android.settings.R
|
||||
import com.android.settings.Utils
|
||||
import com.android.settingslib.RestrictedSwitchPreference
|
||||
import com.android.settingslib.datastore.AbstractKeyedDataObservable
|
||||
import com.android.settingslib.datastore.DataChangeReason
|
||||
import com.android.settingslib.datastore.KeyValueStore
|
||||
import com.android.settingslib.datastore.SettingsGlobalStore
|
||||
import com.android.settingslib.datastore.SettingsStore
|
||||
import com.android.settingslib.metadata.PreferenceAvailabilityProvider
|
||||
import com.android.settingslib.metadata.PreferenceLifecycleContext
|
||||
import com.android.settingslib.metadata.PreferenceLifecycleProvider
|
||||
import com.android.settingslib.metadata.ReadWritePermit
|
||||
import com.android.settingslib.metadata.SensitivityLevel
|
||||
import com.android.settingslib.metadata.SwitchPreference
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
// LINT.IfChange
|
||||
class AirplaneModePreference :
|
||||
SwitchPreference(KEY, R.string.airplane_mode),
|
||||
PreferenceAvailabilityProvider,
|
||||
PreferenceLifecycleProvider,
|
||||
PreferenceRestrictionMixin {
|
||||
|
||||
override val icon: Int
|
||||
@DrawableRes get() = R.drawable.ic_airplanemode_active
|
||||
|
||||
override fun isAvailable(context: Context) =
|
||||
(context.resources.getBoolean(R.bool.config_show_toggle_airplane) &&
|
||||
!context.packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK))
|
||||
|
||||
override fun isEnabled(context: Context) = super<PreferenceRestrictionMixin>.isEnabled(context)
|
||||
|
||||
override val restrictionKeys
|
||||
get() = arrayOf(UserManager.DISALLOW_AIRPLANE_MODE)
|
||||
|
||||
override fun getReadPermit(context: Context, myUid: Int, callingUid: Int) =
|
||||
ReadWritePermit.ALLOW
|
||||
|
||||
override fun getWritePermit(context: Context, value: Boolean?, myUid: Int, callingUid: Int) =
|
||||
when {
|
||||
isSatelliteOn(context) || isInEcmMode(context) -> ReadWritePermit.DISALLOW
|
||||
else -> ReadWritePermit.ALLOW
|
||||
}
|
||||
|
||||
override val sensitivityLevel
|
||||
get() = SensitivityLevel.HIGH_SENSITIVITY
|
||||
|
||||
override fun storage(context: Context): KeyValueStore =
|
||||
AirplaneModeStorage(context, SettingsGlobalStore.get(context))
|
||||
|
||||
@Suppress("DEPRECATION", "MissingPermission", "UNCHECKED_CAST")
|
||||
private class AirplaneModeStorage(
|
||||
private val context: Context,
|
||||
private val settingsStore: SettingsStore,
|
||||
) : AbstractKeyedDataObservable<String>(), KeyValueStore {
|
||||
private var phoneStateListener: PhoneStateListener? = null
|
||||
|
||||
override fun contains(key: String) =
|
||||
settingsStore.contains(KEY) &&
|
||||
context.getSystemService(TelephonyManager::class.java) != null
|
||||
|
||||
override fun <T : Any> getDefaultValue(key: String, valueType: Class<T>) =
|
||||
DEFAULT_VALUE as T
|
||||
|
||||
override fun <T : Any> getValue(key: String, valueType: Class<T>): T =
|
||||
(settingsStore.getBoolean(key) ?: DEFAULT_VALUE) as T
|
||||
|
||||
override fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?) {
|
||||
if (value is Boolean) {
|
||||
settingsStore.setBoolean(key, value)
|
||||
|
||||
val intent = Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED)
|
||||
intent.putExtra("state", value)
|
||||
context.sendBroadcastAsUser(intent, UserHandle.ALL)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFirstObserverAdded() {
|
||||
context.getSystemService(TelephonyManager::class.java)?.let {
|
||||
phoneStateListener =
|
||||
object : PhoneStateListener(Looper.getMainLooper()) {
|
||||
@Deprecated("Deprecated in Java")
|
||||
override fun onRadioPowerStateChanged(state: Int) {
|
||||
Log.d(TAG, "onRadioPowerStateChanged(), state=$state")
|
||||
notifyChange(KEY, DataChangeReason.UPDATE)
|
||||
}
|
||||
}
|
||||
it.listen(phoneStateListener, PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onLastObserverRemoved() {
|
||||
context
|
||||
.getSystemService(TelephonyManager::class.java)
|
||||
?.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(context: PreferenceLifecycleContext) {
|
||||
context.requirePreference<RestrictedSwitchPreference>(KEY).onPreferenceChangeListener =
|
||||
Preference.OnPreferenceChangeListener { _: Preference, _: Any ->
|
||||
if (isInEcmMode(context)) {
|
||||
showEcmDialog(context)
|
||||
return@OnPreferenceChangeListener false
|
||||
}
|
||||
if (isSatelliteOn(context)) {
|
||||
showSatelliteDialog(context)
|
||||
return@OnPreferenceChangeListener false
|
||||
}
|
||||
return@OnPreferenceChangeListener true
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(
|
||||
context: PreferenceLifecycleContext,
|
||||
requestCode: Int,
|
||||
resultCode: Int,
|
||||
data: Intent?,
|
||||
): Boolean {
|
||||
if (requestCode == REQUEST_CODE_EXIT_ECM && resultCode == Activity.RESULT_OK) {
|
||||
context.getKeyValueStore(KEY)?.setBoolean(KEY, true)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun isInEcmMode(context: Context) =
|
||||
AirplaneModeEnabler.isInEcmMode(
|
||||
context,
|
||||
context.getSystemService(TelephonyManager::class.java),
|
||||
)
|
||||
|
||||
private fun isSatelliteOn(context: Context): Boolean {
|
||||
try {
|
||||
return SatelliteRepository(context)
|
||||
.requestIsSessionStarted(Executors.newSingleThreadExecutor())
|
||||
.get(2000, TimeUnit.MILLISECONDS)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error to get satellite status : $e")
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun showEcmDialog(context: PreferenceLifecycleContext) {
|
||||
val intent =
|
||||
Intent(TelephonyManager.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null)
|
||||
.setPackage(Utils.PHONE_PACKAGE_NAME)
|
||||
context.startActivityForResult(intent, REQUEST_CODE_EXIT_ECM, null)
|
||||
}
|
||||
|
||||
private fun showSatelliteDialog(context: PreferenceLifecycleContext) {
|
||||
val intent =
|
||||
Intent(context, SatelliteWarningDialogActivity::class.java)
|
||||
.putExtra(
|
||||
SatelliteWarningDialogActivity.EXTRA_TYPE_OF_SATELLITE_WARNING_DIALOG,
|
||||
SatelliteWarningDialogActivity.TYPE_IS_AIRPLANE_MODE,
|
||||
)
|
||||
context.startActivity(intent)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TAG = "AirplaneModePreference"
|
||||
const val KEY = Settings.Global.AIRPLANE_MODE_ON
|
||||
const val DEFAULT_VALUE = false
|
||||
const val REQUEST_CODE_EXIT_ECM = 1
|
||||
|
||||
fun Context.isAirplaneModeOn() = SettingsGlobalStore.get(this).getBoolean(KEY) == true
|
||||
}
|
||||
}
|
||||
// LINT.ThenChange(AirplaneModePreferenceController.java)
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package com.android.settings.network;
|
||||
|
||||
import static android.provider.SettingsSlicesContract.KEY_AIRPLANE_MODE;
|
||||
|
||||
import static com.android.settings.network.SatelliteWarningDialogActivity.EXTRA_TYPE_OF_SATELLITE_WARNING_DIALOG;
|
||||
import static com.android.settings.network.SatelliteWarningDialogActivity.TYPE_IS_AIRPLANE_MODE;
|
||||
|
||||
@@ -52,6 +50,7 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
// LINT.IfChange
|
||||
public class AirplaneModePreferenceController extends TogglePreferenceController
|
||||
implements LifecycleObserver, OnStart, OnResume, OnStop, OnDestroy,
|
||||
AirplaneModeEnabler.OnAirplaneModeChangedListener {
|
||||
@@ -94,7 +93,7 @@ public class AirplaneModePreferenceController extends TogglePreferenceController
|
||||
|
||||
@Override
|
||||
public boolean handlePreferenceTreeClick(Preference preference) {
|
||||
if (KEY_AIRPLANE_MODE.equals(preference.getKey()) && isAvailable()) {
|
||||
if (AirplaneModePreference.KEY.equals(preference.getKey()) && isAvailable()) {
|
||||
// In ECM mode launch ECM app dialog
|
||||
if (mAirplaneModeEnabler.isInEcmMode()) {
|
||||
if (mFragment != null) {
|
||||
@@ -217,3 +216,4 @@ public class AirplaneModePreferenceController extends TogglePreferenceController
|
||||
}
|
||||
}
|
||||
}
|
||||
// LINT.ThenChange(AirplaneModePreference.kt)
|
||||
|
||||
@@ -88,10 +88,10 @@ public class CellularSecurityPreferenceController extends BasePreferenceControll
|
||||
} catch (UnsupportedOperationException e) {
|
||||
Log.i(LOG_TAG, "Null cipher enablement is unsupported, hiding divider: "
|
||||
+ e.getMessage());
|
||||
} catch (Exception e) {
|
||||
} catch (IllegalStateException e) {
|
||||
Log.e(LOG_TAG,
|
||||
"Failed isNullCipherAndIntegrityEnabled. Setting availability to "
|
||||
+ "CONDITIONALLY_UNAVAILABLE. Exception: "
|
||||
+ "UNSUPPORTED_ON_DEVICE. Exception: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
|
||||
@@ -104,6 +104,12 @@ public class CellularSecurityPreferenceController extends BasePreferenceControll
|
||||
} catch (UnsupportedOperationException e) {
|
||||
Log.i(LOG_TAG, "Cellular security notifications are unsupported, hiding divider: "
|
||||
+ e.getMessage());
|
||||
} catch (IllegalStateException e) {
|
||||
Log.e(LOG_TAG,
|
||||
"Failed isNullCipherNotificationsEnabled, "
|
||||
+ "isCellularIdentifierDisclosureNotificationsEnabled. "
|
||||
+ "Setting availability to UNSUPPORTED_ON_DEVICE. Exception: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
|
||||
if (isNullCipherDisablementAvailable || areCellSecNotificationsAvailable) {
|
||||
@@ -119,7 +125,7 @@ public class CellularSecurityPreferenceController extends BasePreferenceControll
|
||||
return super.handlePreferenceTreeClick(preference);
|
||||
}
|
||||
boolean isSafetyCenterSupported = isSafetyCenterSupported();
|
||||
if (isSafetyCenterSupported) {
|
||||
if (isSafetyCenterSupported && areNotificationsEnabled()) {
|
||||
Intent safetyCenterIntent = new Intent(Intent.ACTION_SAFETY_CENTER);
|
||||
safetyCenterIntent.putExtra(SafetyCenterManager.EXTRA_SAFETY_SOURCES_GROUP_ID,
|
||||
"AndroidCellularNetworkSecuritySources");
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.android.settings.network;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
@@ -27,13 +26,14 @@ import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
import com.android.settings.system.ResetDashboardFragment;
|
||||
import com.android.settings.network.telephony.MobileNetworkUtils;
|
||||
import com.android.settings.system.ResetDashboardFragment;
|
||||
|
||||
public class EraseEuiccDataDialogFragment extends InstrumentedDialogFragment implements
|
||||
DialogInterface.OnClickListener {
|
||||
|
||||
78
src/com/android/settings/network/MobileDataPreference.kt
Normal file
78
src/com/android/settings/network/MobileDataPreference.kt
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.network
|
||||
|
||||
import android.content.Context
|
||||
import android.telephony.SubscriptionManager
|
||||
import com.android.settings.R
|
||||
import com.android.settings.network.telephony.MobileDataRepository
|
||||
import com.android.settings.network.telephony.SubscriptionRepository
|
||||
import com.android.settingslib.datastore.KeyValueStore
|
||||
import com.android.settingslib.datastore.NoOpKeyedObservable
|
||||
import com.android.settingslib.metadata.PreferenceAvailabilityProvider
|
||||
import com.android.settingslib.metadata.ReadWritePermit
|
||||
import com.android.settingslib.metadata.SensitivityLevel
|
||||
import com.android.settingslib.metadata.SwitchPreference
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
class MobileDataPreference :
|
||||
SwitchPreference(
|
||||
KEY,
|
||||
R.string.mobile_data_settings_title,
|
||||
R.string.mobile_data_settings_summary,
|
||||
),
|
||||
PreferenceAvailabilityProvider {
|
||||
|
||||
override fun isAvailable(context: Context) =
|
||||
SubscriptionRepository(context).getSelectableSubscriptionInfoList().any {
|
||||
it.simSlotIndex > -1
|
||||
}
|
||||
|
||||
override fun storage(context: Context): KeyValueStore = MobileDataStorage(context)
|
||||
|
||||
override fun getReadPermit(context: Context, myUid: Int, callingUid: Int) =
|
||||
ReadWritePermit.ALLOW
|
||||
|
||||
override fun getWritePermit(context: Context, value: Boolean?, myUid: Int, callingUid: Int) =
|
||||
ReadWritePermit.ALLOW
|
||||
|
||||
override val sensitivityLevel
|
||||
get() = SensitivityLevel.LOW_SENSITIVITY
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private class MobileDataStorage(private val context: Context) :
|
||||
NoOpKeyedObservable<String>(), KeyValueStore {
|
||||
|
||||
override fun contains(key: String) = key == KEY
|
||||
|
||||
override fun <T : Any> getValue(key: String, valueType: Class<T>): T {
|
||||
val subId = SubscriptionManager.getDefaultDataSubscriptionId()
|
||||
val flow = MobileDataRepository(context).isMobileDataEnabledFlow(subId)
|
||||
return runBlocking { flow.first() } as T
|
||||
}
|
||||
|
||||
override fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?) {
|
||||
val subId = SubscriptionManager.getDefaultDataSubscriptionId()
|
||||
MobileDataRepository(context).setMobileDataEnabled(subId, value as Boolean)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val KEY = "mobile_data"
|
||||
}
|
||||
}
|
||||
@@ -92,4 +92,6 @@ class MobileNetworkListFragment : DashboardFragment() {
|
||||
simRepositoryFactory(context).canEnterMobileNetworkPage()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getPreferenceScreenBindingKey(context: Context) = MobileNetworkListScreen.KEY
|
||||
}
|
||||
|
||||
168
src/com/android/settings/network/MobileNetworkListScreen.kt
Normal file
168
src/com/android/settings/network/MobileNetworkListScreen.kt
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.network
|
||||
|
||||
import android.content.Context
|
||||
import android.os.UserManager
|
||||
import android.telephony.SubscriptionInfo
|
||||
import android.telephony.SubscriptionManager
|
||||
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.Preference.OnPreferenceClickListener
|
||||
import com.android.settings.PreferenceRestrictionMixin
|
||||
import com.android.settings.R
|
||||
import com.android.settings.flags.Flags
|
||||
import com.android.settings.network.AirplaneModePreference.Companion.isAirplaneModeOn
|
||||
import com.android.settings.network.SubscriptionUtil.getUniqueSubscriptionDisplayName
|
||||
import com.android.settings.network.telephony.SimRepository
|
||||
import com.android.settings.network.telephony.SubscriptionRepository
|
||||
import com.android.settings.network.telephony.euicc.EuiccRepository
|
||||
import com.android.settings.spa.network.getAddSimIntent
|
||||
import com.android.settings.spa.network.startAddSimFlow
|
||||
import com.android.settingslib.RestrictedPreference
|
||||
import com.android.settingslib.datastore.HandlerExecutor
|
||||
import com.android.settingslib.datastore.KeyedObserver
|
||||
import com.android.settingslib.datastore.SettingsGlobalStore
|
||||
import com.android.settingslib.metadata.PreferenceAvailabilityProvider
|
||||
import com.android.settingslib.metadata.PreferenceLifecycleContext
|
||||
import com.android.settingslib.metadata.PreferenceLifecycleProvider
|
||||
import com.android.settingslib.metadata.PreferenceMetadata
|
||||
import com.android.settingslib.metadata.PreferenceSummaryProvider
|
||||
import com.android.settingslib.metadata.ProvidePreferenceScreen
|
||||
import com.android.settingslib.metadata.preferenceHierarchy
|
||||
import com.android.settingslib.preference.PreferenceScreenBinding
|
||||
import com.android.settingslib.preference.PreferenceScreenCreator
|
||||
|
||||
@ProvidePreferenceScreen
|
||||
class MobileNetworkListScreen :
|
||||
PreferenceScreenCreator,
|
||||
PreferenceScreenBinding,
|
||||
PreferenceAvailabilityProvider,
|
||||
PreferenceSummaryProvider,
|
||||
PreferenceLifecycleProvider,
|
||||
PreferenceRestrictionMixin,
|
||||
OnPreferenceClickListener {
|
||||
|
||||
private var airplaneModeObserver: KeyedObserver<String>? = null
|
||||
private var subscriptionInfoList: List<SubscriptionInfo>? = null
|
||||
private var onSubscriptionsChangedListener: OnSubscriptionsChangedListener? = null
|
||||
|
||||
override val key: String
|
||||
get() = KEY
|
||||
|
||||
override val title: Int
|
||||
get() = R.string.provider_network_settings_title
|
||||
|
||||
override val icon: Int
|
||||
get() = R.drawable.ic_sim_card
|
||||
|
||||
override val keywords: Int
|
||||
get() = R.string.keywords_more_mobile_networks
|
||||
|
||||
override fun intent(context: Context) = getAddSimIntent()
|
||||
|
||||
override fun getSummary(context: Context): CharSequence? {
|
||||
val list = getSelectableSubscriptionInfoList(context)
|
||||
return when {
|
||||
list.isNotEmpty() ->
|
||||
list
|
||||
.map { getUniqueSubscriptionDisplayName(it, context).toString() }
|
||||
.distinct()
|
||||
.joinToString(", ")
|
||||
EuiccRepository(context).showEuiccSettings() ->
|
||||
context.getString(R.string.mobile_network_summary_add_a_network)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
override fun isAvailable(context: Context) =
|
||||
SimRepository(context).showMobileNetworkPageEntrance()
|
||||
|
||||
override fun isEnabled(context: Context) =
|
||||
super<PreferenceRestrictionMixin>.isEnabled(context) &&
|
||||
!context.isAirplaneModeOn() &&
|
||||
(getSelectableSubscriptionInfoList(context).isNotEmpty() ||
|
||||
EuiccRepository(context).showEuiccSettings())
|
||||
|
||||
private fun getSelectableSubscriptionInfoList(context: Context): List<SubscriptionInfo> =
|
||||
subscriptionInfoList
|
||||
?: SubscriptionRepository(context).getSelectableSubscriptionInfoList().also {
|
||||
subscriptionInfoList = it
|
||||
}
|
||||
|
||||
override val restrictionKeys
|
||||
get() = arrayOf(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)
|
||||
|
||||
override val useAdminDisabledSummary
|
||||
get() = true
|
||||
|
||||
override fun createWidget(context: Context) = RestrictedPreference(context)
|
||||
|
||||
override fun bind(preference: Preference, metadata: PreferenceMetadata) {
|
||||
super.bind(preference, metadata)
|
||||
preference.onPreferenceClickListener = this
|
||||
}
|
||||
|
||||
override fun onPreferenceClick(preference: Preference): Boolean {
|
||||
val summary = preference.summary ?: return true // no-op
|
||||
val context = preference.context
|
||||
if (summary == context.getString(R.string.mobile_network_summary_add_a_network)) {
|
||||
startAddSimFlow(context) // start intent
|
||||
return true
|
||||
}
|
||||
return false // start fragment
|
||||
}
|
||||
|
||||
override fun onCreate(context: PreferenceLifecycleContext) {
|
||||
val executor = HandlerExecutor.main
|
||||
val observer = KeyedObserver<String> { _, _ -> context.notifyPreferenceChange(KEY) }
|
||||
airplaneModeObserver = observer
|
||||
SettingsGlobalStore.get(context).addObserver(AirplaneModePreference.KEY, observer, executor)
|
||||
context.getSystemService(SubscriptionManager::class.java)?.let {
|
||||
val listener =
|
||||
object : OnSubscriptionsChangedListener() {
|
||||
override fun onSubscriptionsChanged() {
|
||||
subscriptionInfoList = null // invalid cache
|
||||
context.notifyPreferenceChange(KEY)
|
||||
}
|
||||
}
|
||||
it.addOnSubscriptionsChangedListener(executor, listener)
|
||||
onSubscriptionsChangedListener = listener
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy(context: PreferenceLifecycleContext) {
|
||||
airplaneModeObserver?.let {
|
||||
SettingsGlobalStore.get(context).removeObserver(AirplaneModePreference.KEY, it)
|
||||
}
|
||||
context.getSystemService(SubscriptionManager::class.java)?.apply {
|
||||
onSubscriptionsChangedListener?.let { removeOnSubscriptionsChangedListener(it) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun isFlagEnabled(context: Context) = Flags.catalystMobileNetworkList()
|
||||
|
||||
override fun hasCompleteHierarchy() = false
|
||||
|
||||
override fun fragmentClass() = MobileNetworkListFragment::class.java
|
||||
|
||||
override fun getPreferenceHierarchy(context: Context) =
|
||||
preferenceHierarchy(this) { +MobileDataPreference() }
|
||||
|
||||
companion object {
|
||||
const val KEY = "mobile_network_list"
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,7 @@ import kotlinx.coroutines.flow.Flow
|
||||
* - Has subscriptions: click action takes you to a page listing the subscriptions, and the summary
|
||||
* text gives the count of SIMs
|
||||
*/
|
||||
// LINT.IfChange
|
||||
class MobileNetworkSummaryController
|
||||
@JvmOverloads
|
||||
constructor(
|
||||
@@ -119,3 +120,4 @@ constructor(
|
||||
)
|
||||
}
|
||||
}
|
||||
// LINT.ThenChange(MobileNetworkListScreen.kt)
|
||||
|
||||
@@ -19,6 +19,7 @@ import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.settings.R;
|
||||
@@ -58,7 +59,9 @@ public class NetworkDashboardFragment extends DashboardFragment implements
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
|
||||
use(AirplaneModePreferenceController.class).setFragment(this);
|
||||
if (isCatalystEnabled()) {
|
||||
use(AirplaneModePreferenceController.class).setFragment(this);
|
||||
}
|
||||
use(NetworkProviderCallsSmsController.class).init(this);
|
||||
}
|
||||
|
||||
@@ -101,8 +104,10 @@ public class NetworkDashboardFragment extends DashboardFragment implements
|
||||
|
||||
switch (requestCode) {
|
||||
case AirplaneModePreferenceController.REQUEST_CODE_EXIT_ECM:
|
||||
use(AirplaneModePreferenceController.class)
|
||||
.onActivityResult(requestCode, resultCode, data);
|
||||
if (isCatalystEnabled()) {
|
||||
use(AirplaneModePreferenceController.class)
|
||||
.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -115,4 +120,9 @@ public class NetworkDashboardFragment extends DashboardFragment implements
|
||||
return buildPreferenceControllers(context, null /* lifecycle */);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public @Nullable String getPreferenceScreenBindingKey(@NonNull Context context) {
|
||||
return NetworkDashboardScreen.KEY;
|
||||
}
|
||||
}
|
||||
|
||||
57
src/com/android/settings/network/NetworkDashboardScreen.kt
Normal file
57
src/com/android/settings/network/NetworkDashboardScreen.kt
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.network
|
||||
|
||||
import android.content.Context
|
||||
import com.android.settings.R
|
||||
import com.android.settings.datausage.DataSaverScreen
|
||||
import com.android.settings.flags.Flags
|
||||
import com.android.settingslib.metadata.PreferenceIconProvider
|
||||
import com.android.settingslib.metadata.ProvidePreferenceScreen
|
||||
import com.android.settingslib.metadata.preferenceHierarchy
|
||||
import com.android.settingslib.preference.PreferenceScreenCreator
|
||||
|
||||
@ProvidePreferenceScreen
|
||||
class NetworkDashboardScreen : PreferenceScreenCreator, PreferenceIconProvider {
|
||||
override val key: String
|
||||
get() = KEY
|
||||
|
||||
override val title: Int
|
||||
get() = R.string.network_dashboard_title
|
||||
|
||||
override fun getIcon(context: Context) =
|
||||
when {
|
||||
Flags.homepageRevamp() -> R.drawable.ic_settings_wireless_filled
|
||||
else -> R.drawable.ic_settings_wireless
|
||||
}
|
||||
|
||||
override fun isFlagEnabled(context: Context) = Flags.catalystNetworkProviderAndInternetScreen()
|
||||
|
||||
override fun hasCompleteHierarchy() = false
|
||||
|
||||
override fun fragmentClass() = NetworkDashboardFragment::class.java
|
||||
|
||||
override fun getPreferenceHierarchy(context: Context) =
|
||||
preferenceHierarchy(this) {
|
||||
+MobileNetworkListScreen.KEY order -15
|
||||
+AirplaneModePreference() order -5
|
||||
+DataSaverScreen.KEY order 10
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val KEY = "network_provider_and_internet_screen"
|
||||
}
|
||||
}
|
||||
65
src/com/android/settings/network/NetworkProviderScreen.kt
Normal file
65
src/com/android/settings/network/NetworkProviderScreen.kt
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.network
|
||||
|
||||
import android.content.Context
|
||||
import android.os.UserManager
|
||||
import com.android.settings.PreferenceRestrictionMixin
|
||||
import com.android.settings.R
|
||||
import com.android.settings.flags.Flags
|
||||
import com.android.settings.wifi.WifiSwitchPreference
|
||||
import com.android.settingslib.metadata.PreferenceAvailabilityProvider
|
||||
import com.android.settingslib.metadata.ProvidePreferenceScreen
|
||||
import com.android.settingslib.metadata.preferenceHierarchy
|
||||
import com.android.settingslib.preference.PreferenceScreenCreator
|
||||
|
||||
@ProvidePreferenceScreen
|
||||
class NetworkProviderScreen :
|
||||
PreferenceScreenCreator, PreferenceAvailabilityProvider, PreferenceRestrictionMixin {
|
||||
override val key: String
|
||||
get() = KEY
|
||||
|
||||
override val title: Int
|
||||
get() = R.string.provider_internet_settings
|
||||
|
||||
override val icon: Int
|
||||
get() = R.drawable.ic_settings_wireless
|
||||
|
||||
override val keywords: Int
|
||||
get() = R.string.keywords_internet
|
||||
|
||||
override fun isAvailable(context: Context) =
|
||||
context.resources.getBoolean(R.bool.config_show_internet_settings)
|
||||
|
||||
override fun isEnabled(context: Context) = super<PreferenceRestrictionMixin>.isEnabled(context)
|
||||
|
||||
override val restrictionKeys
|
||||
get() = arrayOf(UserManager.DISALLOW_CONFIG_WIFI)
|
||||
|
||||
override fun isFlagEnabled(context: Context) = Flags.catalystInternetSettings()
|
||||
|
||||
override fun hasCompleteHierarchy() = false
|
||||
|
||||
override fun fragmentClass() = NetworkProviderSettings::class.java
|
||||
|
||||
override fun getPreferenceHierarchy(context: Context) = preferenceHierarchy(this) {
|
||||
+WifiSwitchPreference()
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val KEY = "internet_settings"
|
||||
}
|
||||
}
|
||||
@@ -64,8 +64,8 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.android.settings.AirplaneModeEnabler;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.RestrictedSettingsFragment;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.dashboard.RestrictedDashboardFragment;
|
||||
import com.android.settings.datausage.DataUsagePreference;
|
||||
import com.android.settings.datausage.DataUsageUtils;
|
||||
import com.android.settings.location.WifiScanningFragment;
|
||||
@@ -104,7 +104,7 @@ import java.util.Optional;
|
||||
* UI for Mobile network and Wi-Fi network settings.
|
||||
*/
|
||||
@SearchIndexable
|
||||
public class NetworkProviderSettings extends RestrictedSettingsFragment
|
||||
public class NetworkProviderSettings extends RestrictedDashboardFragment
|
||||
implements Indexable, WifiPickerTracker.WifiPickerTrackerCallback,
|
||||
WifiDialog2.WifiDialog2Listener, DialogInterface.OnDismissListener,
|
||||
AirplaneModeEnabler.OnAirplaneModeChangedListener, InternetUpdater.InternetChangeListener {
|
||||
@@ -356,9 +356,17 @@ public class NetworkProviderSettings extends RestrictedSettingsFragment
|
||||
mIsGuest = userManager.isGuestUser();
|
||||
}
|
||||
|
||||
private void addPreferences() {
|
||||
addPreferencesFromResource(R.xml.network_provider_settings);
|
||||
@Override
|
||||
protected String getLogTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceScreenResId() {
|
||||
return R.xml.network_provider_settings;
|
||||
}
|
||||
|
||||
private void addPreferences() {
|
||||
mAirplaneModeMsgPreference = findPreference(PREF_KEY_AIRPLANE_MODE_MSG);
|
||||
updateAirplaneModeMsgPreference(mAirplaneModeEnabler.isAirplaneModeOn() /* visible */);
|
||||
mConnectedWifiEntryPreferenceCategory = findPreference(PREF_KEY_CONNECTED_ACCESS_POINTS);
|
||||
@@ -421,6 +429,10 @@ public class NetworkProviderSettings extends RestrictedSettingsFragment
|
||||
}
|
||||
|
||||
private void addWifiSwitchPreferenceController() {
|
||||
if (isCatalystEnabled()) {
|
||||
Log.i(TAG, "WifiSwitchPreferenceController bypassed since Catalyst is enabled!");
|
||||
return;
|
||||
}
|
||||
if (!hasWifiManager()) return;
|
||||
if (mWifiSwitchPreferenceController == null) {
|
||||
mWifiSwitchPreferenceController =
|
||||
@@ -1500,4 +1512,9 @@ public class NetworkProviderSettings extends RestrictedSettingsFragment
|
||||
return android.R.attr.colorControlNormal;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String getPreferenceScreenBindingKey(@NonNull Context context) {
|
||||
return NetworkProviderScreen.KEY;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.settings.network
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings
|
||||
import android.telephony.SubscriptionManager
|
||||
import android.util.Log
|
||||
@@ -55,6 +56,7 @@ import com.android.settings.R
|
||||
import com.android.settings.SidecarFragment
|
||||
import com.android.settings.network.telephony.SimRepository
|
||||
import com.android.settings.network.telephony.SubscriptionActionDialogActivity
|
||||
import com.android.settings.network.telephony.SubscriptionRepository
|
||||
import com.android.settings.network.telephony.ToggleSubscriptionDialogActivity
|
||||
import com.android.settings.network.telephony.requireSubscriptionManager
|
||||
import com.android.settings.spa.SpaActivity.Companion.startSpaActivity
|
||||
@@ -78,8 +80,10 @@ import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.conflate
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.coroutines.withTimeoutOrNull
|
||||
|
||||
class SimOnboardingActivity : SpaBaseDialogActivity() {
|
||||
lateinit var scope: CoroutineScope
|
||||
@@ -105,6 +109,12 @@ class SimOnboardingActivity : SpaBaseDialogActivity() {
|
||||
}
|
||||
|
||||
var targetSubId = intent.getIntExtra(SUB_ID,SubscriptionManager.INVALID_SUBSCRIPTION_ID)
|
||||
if (targetSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
||||
targetSubId = intent.getIntExtra(
|
||||
Settings.EXTRA_SUB_ID,
|
||||
SubscriptionManager.INVALID_SUBSCRIPTION_ID
|
||||
)
|
||||
}
|
||||
initServiceData(this, targetSubId, callbackListener)
|
||||
if (!onboardingService.isUsableTargetSubscriptionId) {
|
||||
Log.e(TAG, "The subscription id is not usable.")
|
||||
@@ -489,31 +499,25 @@ class SimOnboardingActivity : SpaBaseDialogActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun checkSimIsReadyAndGoNext() {
|
||||
private suspend fun checkSimIsReadyAndGoNext() {
|
||||
withContext(Dispatchers.Default) {
|
||||
val isEnabled = context.requireSubscriptionManager()
|
||||
.isSubscriptionEnabled(onboardingService.targetSubId)
|
||||
if (!isEnabled) {
|
||||
val latch = CountDownLatch(1)
|
||||
val receiver = CarrierConfigChangedReceiver(latch)
|
||||
try {
|
||||
val waitingTimeMillis =
|
||||
Settings.Global.getLong(
|
||||
context.contentResolver,
|
||||
Settings.Global.EUICC_SWITCH_SLOT_TIMEOUT_MILLIS,
|
||||
UiccSlotUtil.DEFAULT_WAIT_AFTER_SWITCH_TIMEOUT_MILLIS
|
||||
)
|
||||
receiver.registerOn(context)
|
||||
Log.d(TAG, "Start waiting, waitingTime is $waitingTimeMillis")
|
||||
latch.await(waitingTimeMillis, TimeUnit.MILLISECONDS)
|
||||
} catch (e: InterruptedException) {
|
||||
Thread.currentThread().interrupt()
|
||||
Log.e(TAG, "Failed switching to physical slot.", e)
|
||||
} finally {
|
||||
context.unregisterReceiver(receiver)
|
||||
}
|
||||
}
|
||||
Log.d(TAG, "Sim is ready then go to next")
|
||||
val waitingTimeMillis =
|
||||
Settings.Global.getLong(
|
||||
context.contentResolver,
|
||||
Settings.Global.EUICC_SWITCH_SLOT_TIMEOUT_MILLIS,
|
||||
UiccSlotUtil.DEFAULT_WAIT_AFTER_SWITCH_TIMEOUT_MILLIS,
|
||||
)
|
||||
Log.d(TAG, "Start waiting, waitingTime is $waitingTimeMillis")
|
||||
val isTimeout =
|
||||
withTimeoutOrNull(waitingTimeMillis) {
|
||||
SubscriptionRepository(context)
|
||||
.isSubscriptionEnabledFlow(onboardingService.targetSubId)
|
||||
.firstOrNull { it }
|
||||
} == null
|
||||
Log.d(
|
||||
TAG,
|
||||
if (isTimeout) "Sim is not ready after timeout" else "Sim is ready then go to next",
|
||||
)
|
||||
callbackListener(CallbackType.CALLBACK_SETUP_NAME)
|
||||
}
|
||||
}
|
||||
@@ -588,7 +592,7 @@ class SimOnboardingActivity : SpaBaseDialogActivity() {
|
||||
setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
}
|
||||
}
|
||||
context.startActivity(intent)
|
||||
context.startActivityAsUser(intent, UserHandle.CURRENT)
|
||||
}
|
||||
|
||||
var onboardingService:SimOnboardingService = SimOnboardingService()
|
||||
@@ -610,4 +614,4 @@ class SimOnboardingActivity : SpaBaseDialogActivity() {
|
||||
CALLBACK_FINISH(5)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,8 +74,11 @@ class SimOnboardingService {
|
||||
}
|
||||
var isEsimProfileEnabled: Boolean = false
|
||||
get() {
|
||||
activeSubInfoList.stream().anyMatch { it.isEmbedded }
|
||||
return false
|
||||
return activeSubInfoList.stream().anyMatch { it.isEmbedded }
|
||||
}
|
||||
var isRemovableSimProfileEnabled: Boolean = false
|
||||
get() {
|
||||
return activeSubInfoList.stream().anyMatch { !it.isEmbedded }
|
||||
}
|
||||
var doesTargetSimActive = false
|
||||
get() {
|
||||
@@ -288,8 +291,8 @@ class SimOnboardingService {
|
||||
Log.d(TAG, "Hardware does not support DSDS.")
|
||||
return false
|
||||
}
|
||||
val isActiveSim = activeSubInfoList.isNotEmpty()
|
||||
if (isMultipleEnabledProfilesSupported && isActiveSim) {
|
||||
val anyActiveSim = activeSubInfoList.isNotEmpty()
|
||||
if (isMultipleEnabledProfilesSupported && anyActiveSim) {
|
||||
Log.d(TAG,
|
||||
"Device supports MEP and eSIM operation and eSIM profile is enabled."
|
||||
+ " DSDS condition satisfied."
|
||||
@@ -297,15 +300,13 @@ class SimOnboardingService {
|
||||
return true
|
||||
}
|
||||
|
||||
if (doesTargetSimHaveEsimOperation) {
|
||||
if (UiccSlotRepository(telephonyManager).anyRemovablePhysicalSimEnabled()) {
|
||||
Log.d(
|
||||
TAG,
|
||||
"eSIM operation and removable PSIM is enabled. DSDS condition satisfied."
|
||||
)
|
||||
return true
|
||||
}
|
||||
} else if (isEsimProfileEnabled) {
|
||||
if (doesTargetSimHaveEsimOperation && isRemovableSimProfileEnabled) {
|
||||
Log.d(TAG,
|
||||
"eSIM operation and removable PSIM is enabled. DSDS condition satisfied."
|
||||
)
|
||||
return true
|
||||
}
|
||||
if (!doesTargetSimHaveEsimOperation && isEsimProfileEnabled) {
|
||||
Log.d(TAG,
|
||||
"Removable SIM operation and eSIM profile is enabled. DSDS condition"
|
||||
+ " satisfied."
|
||||
|
||||
@@ -35,19 +35,35 @@ import com.android.settingslib.TetherUtil
|
||||
import com.android.settingslib.Utils
|
||||
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.conflate
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class TetherPreferenceController(context: Context, key: String) :
|
||||
BasePreferenceController(context, key) {
|
||||
class TetherPreferenceController(
|
||||
context: Context,
|
||||
key: String,
|
||||
private val tetheredRepository: TetheredRepository = TetheredRepository(context),
|
||||
) : BasePreferenceController(context, key) {
|
||||
|
||||
private val tetheredRepository = TetheredRepository(context)
|
||||
private val tetheringManager = mContext.getSystemService(TetheringManager::class.java)!!
|
||||
|
||||
private var preference: Preference? = null
|
||||
|
||||
override fun getAvailabilityStatus() =
|
||||
if (TetherUtil.isTetherAvailable(mContext)) AVAILABLE else CONDITIONALLY_UNAVAILABLE
|
||||
private val isTetherAvailableFlow =
|
||||
flow { emit(TetherUtil.isTetherAvailable(mContext)) }
|
||||
.distinctUntilChanged()
|
||||
.conflate()
|
||||
.flowOn(Dispatchers.Default)
|
||||
|
||||
/**
|
||||
* Always returns available here to avoid ANR.
|
||||
* - Actual UI visibility is handled in [onViewCreated].
|
||||
* - Search visibility is handled in [updateNonIndexableKeys].
|
||||
*/
|
||||
override fun getAvailabilityStatus() = AVAILABLE
|
||||
|
||||
override fun displayPreference(screen: PreferenceScreen) {
|
||||
super.displayPreference(screen)
|
||||
@@ -55,6 +71,9 @@ class TetherPreferenceController(context: Context, key: String) :
|
||||
}
|
||||
|
||||
override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) {
|
||||
isTetherAvailableFlow.collectLatestWithLifecycle(viewLifecycleOwner) {
|
||||
preference?.isVisible = it
|
||||
}
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||
getTitleResId()?.let { preference?.setTitle(it) }
|
||||
@@ -84,6 +103,12 @@ class TetherPreferenceController(context: Context, key: String) :
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateNonIndexableKeys(keys: MutableList<String>) {
|
||||
if (!TetherUtil.isTetherAvailable(mContext)) {
|
||||
keys += preferenceKey
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun isTetherConfigDisallowed(context: Context?): Boolean =
|
||||
|
||||
@@ -26,7 +26,6 @@ import android.net.VpnManager;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.provider.SettingsSlicesContract;
|
||||
import android.security.Credentials;
|
||||
import android.security.LegacyVpnProfileStore;
|
||||
import android.util.Log;
|
||||
@@ -39,7 +38,6 @@ import com.android.internal.net.LegacyVpnInfo;
|
||||
import com.android.internal.net.VpnConfig;
|
||||
import com.android.internal.net.VpnProfile;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settings.vpn2.VpnInfoPreference;
|
||||
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||
@@ -50,7 +48,6 @@ import com.android.settingslib.core.lifecycle.events.OnResume;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class VpnPreferenceController extends AbstractPreferenceController
|
||||
@@ -87,7 +84,7 @@ public class VpnPreferenceController extends AbstractPreferenceController
|
||||
Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS);
|
||||
// Manually set dependencies for Wifi when not toggleable.
|
||||
if (toggleable == null || !toggleable.contains(Settings.Global.RADIO_WIFI)) {
|
||||
preference.setDependency(SettingsSlicesContract.KEY_AIRPLANE_MODE);
|
||||
preference.setDependency(Settings.Global.AIRPLANE_MODE_ON);
|
||||
}
|
||||
return preference;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ import com.google.common.annotations.VisibleForTesting;
|
||||
/**
|
||||
* This controller helps to manage the state of wifi switch preference.
|
||||
*/
|
||||
// LINT.IfChange
|
||||
public class WifiSwitchPreferenceController extends AbstractPreferenceController implements
|
||||
LifecycleObserver {
|
||||
|
||||
@@ -125,3 +126,4 @@ public class WifiSwitchPreferenceController extends AbstractPreferenceController
|
||||
return wifiManager.isWifiEnabled();
|
||||
}
|
||||
}
|
||||
// LINT.ThenChange(WifiSwitchPreference.kt)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,7 +23,6 @@ import android.app.Dialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
@@ -34,7 +33,6 @@ import android.provider.Telephony;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.data.ApnSetting;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
@@ -51,7 +49,6 @@ import androidx.preference.PreferenceGroup;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.RestrictedSettingsFragment;
|
||||
import com.android.settings.flags.Flags;
|
||||
import com.android.settings.network.telephony.SubscriptionRepository;
|
||||
import com.android.settings.spa.SpaActivity;
|
||||
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
@@ -59,6 +56,7 @@ import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
import kotlin.Unit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** Handle each different apn setting. */
|
||||
public class ApnSettings extends RestrictedSettingsFragment
|
||||
@@ -68,16 +66,12 @@ public class ApnSettings extends RestrictedSettingsFragment
|
||||
public static final String APN_ID = "apn_id";
|
||||
public static final String APN_LIST = "apn_list";
|
||||
public static final String SUB_ID = "sub_id";
|
||||
public static final String MVNO_TYPE = "mvno_type";
|
||||
public static final String MVNO_MATCH_DATA = "mvno_match_data";
|
||||
|
||||
private static final String[] CARRIERS_PROJECTION = new String[] {
|
||||
Telephony.Carriers._ID,
|
||||
Telephony.Carriers.NAME,
|
||||
Telephony.Carriers.APN,
|
||||
Telephony.Carriers.TYPE,
|
||||
Telephony.Carriers.MVNO_TYPE,
|
||||
Telephony.Carriers.MVNO_MATCH_DATA,
|
||||
Telephony.Carriers.EDITED_STATUS,
|
||||
};
|
||||
|
||||
@@ -85,9 +79,7 @@ public class ApnSettings extends RestrictedSettingsFragment
|
||||
private static final int NAME_INDEX = 1;
|
||||
private static final int APN_INDEX = 2;
|
||||
private static final int TYPES_INDEX = 3;
|
||||
private static final int MVNO_TYPE_INDEX = 4;
|
||||
private static final int MVNO_MATCH_DATA_INDEX = 5;
|
||||
private static final int EDITED_INDEX = 6;
|
||||
private static final int EDITED_INDEX = 4;
|
||||
|
||||
private static final int MENU_NEW = Menu.FIRST;
|
||||
private static final int MENU_RESTORE = Menu.FIRST + 1;
|
||||
@@ -101,8 +93,6 @@ public class ApnSettings extends RestrictedSettingsFragment
|
||||
private PreferredApnRepository mPreferredApnRepository;
|
||||
@Nullable
|
||||
private String mPreferredApnKey;
|
||||
private String mMvnoType;
|
||||
private String mMvnoMatchData;
|
||||
|
||||
private boolean mUnavailable;
|
||||
|
||||
@@ -135,10 +125,9 @@ public class ApnSettings extends RestrictedSettingsFragment
|
||||
mHideImsApn = b.getBoolean(CarrierConfigManager.KEY_HIDE_IMS_APN_BOOL);
|
||||
mAllowAddingApns = b.getBoolean(CarrierConfigManager.KEY_ALLOW_ADDING_APNS_BOOL);
|
||||
if (mAllowAddingApns) {
|
||||
final String[] readOnlyApnTypes = b.getStringArray(
|
||||
CarrierConfigManager.KEY_READ_ONLY_APN_TYPES_STRING_ARRAY);
|
||||
final List<String> readOnlyApnTypes = ApnTypes.getReadOnlyApnTypes(b);
|
||||
// if no apn type can be edited, do not allow adding APNs
|
||||
if (ApnEditor.hasAllApns(readOnlyApnTypes)) {
|
||||
if (ApnTypes.hasAllApnTypes(readOnlyApnTypes)) {
|
||||
Log.d(TAG, "not allowing adding APN because all APN types are read only");
|
||||
mAllowAddingApns = false;
|
||||
}
|
||||
@@ -242,8 +231,6 @@ public class ApnSettings extends RestrictedSettingsFragment
|
||||
final String key = cursor.getString(ID_INDEX);
|
||||
final String type = cursor.getString(TYPES_INDEX);
|
||||
final int edited = cursor.getInt(EDITED_INDEX);
|
||||
mMvnoType = cursor.getString(MVNO_TYPE_INDEX);
|
||||
mMvnoMatchData = cursor.getString(MVNO_MATCH_DATA_INDEX);
|
||||
|
||||
final ApnPreference pref = new ApnPreference(getPrefContext());
|
||||
|
||||
@@ -311,20 +298,9 @@ public class ApnSettings extends RestrictedSettingsFragment
|
||||
}
|
||||
|
||||
private void addNewApn() {
|
||||
if (Flags.newApnPageEnabled()) {
|
||||
String route = ApnEditPageProvider.INSTANCE.getRoute(
|
||||
INSERT_URL, Telephony.Carriers.CONTENT_URI, mSubId);
|
||||
SpaActivity.startSpaActivity(getContext(), route);
|
||||
} else {
|
||||
final Intent intent = new Intent(Intent.ACTION_INSERT, Telephony.Carriers.CONTENT_URI);
|
||||
intent.putExtra(SUB_ID, mSubId);
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
if (!TextUtils.isEmpty(mMvnoType) && !TextUtils.isEmpty(mMvnoMatchData)) {
|
||||
intent.putExtra(MVNO_TYPE, mMvnoType);
|
||||
intent.putExtra(MVNO_MATCH_DATA, mMvnoMatchData);
|
||||
}
|
||||
startActivity(intent);
|
||||
}
|
||||
String route = ApnEditPageProvider.INSTANCE.getRoute(
|
||||
INSERT_URL, Telephony.Carriers.CONTENT_URI, mSubId);
|
||||
SpaActivity.startSpaActivity(getContext(), route);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.telephony.CarrierConfigManager
|
||||
import android.util.Log
|
||||
import com.android.settings.R
|
||||
import com.android.settings.network.apn.ApnTypes.getPreSelectedApnType
|
||||
import com.android.settings.network.apn.ApnTypes.getReadOnlyApnTypes
|
||||
|
||||
private const val TAG = "ApnStatus"
|
||||
|
||||
@@ -204,9 +205,7 @@ fun getCarrierCustomizedConfig(
|
||||
CarrierConfigManager.KEY_ALLOW_ADDING_APNS_BOOL
|
||||
)
|
||||
val customizedConfig = CustomizedConfig(
|
||||
readOnlyApnTypes = b.getStringArray(
|
||||
CarrierConfigManager.KEY_READ_ONLY_APN_TYPES_STRING_ARRAY
|
||||
)?.toList() ?: emptyList(),
|
||||
readOnlyApnTypes = b.getReadOnlyApnTypes(),
|
||||
readOnlyApnFields = b.getStringArray(
|
||||
CarrierConfigManager.KEY_READ_ONLY_APN_FIELDS_STRING_ARRAY
|
||||
)?.toList() ?: emptyList(),
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package com.android.settings.network.apn
|
||||
|
||||
import android.content.Context
|
||||
import android.os.PersistableBundle
|
||||
import android.telephony.CarrierConfigManager
|
||||
import android.telephony.data.ApnSetting
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
@@ -45,13 +47,13 @@ object ApnTypes {
|
||||
ApnSetting.TYPE_VSIM_STRING,
|
||||
ApnSetting.TYPE_BIP_STRING,
|
||||
ApnSetting.TYPE_ENTERPRISE_STRING,
|
||||
ApnSetting.TYPE_OEM_PAID_STRING,
|
||||
ApnSetting.TYPE_OEM_PRIVATE_STRING,
|
||||
)
|
||||
|
||||
private fun splitToList(apnType: String): List<String> {
|
||||
val types = apnType.split(',').map { it.trim().toLowerCase(Locale.current) }
|
||||
if (ApnSetting.TYPE_ALL_STRING in types || APN_TYPES.all { it in types }) {
|
||||
return listOf(ApnSetting.TYPE_ALL_STRING)
|
||||
}
|
||||
if (hasAllApnTypes(types)) return listOf(ApnSetting.TYPE_ALL_STRING)
|
||||
return APN_TYPES.filter { it in types }
|
||||
}
|
||||
|
||||
@@ -130,4 +132,32 @@ object ApnTypes {
|
||||
private fun defaultPreSelectedApnTypes(readOnlyApnTypes: List<String>) =
|
||||
if (ApnSetting.TYPE_ALL_STRING in readOnlyApnTypes) emptyList()
|
||||
else PreSelectedTypes.filterNot { it in readOnlyApnTypes }
|
||||
|
||||
/** Array of APN types that are never user-editable */
|
||||
private val ALWAYS_READ_ONLY_APN_TYPES =
|
||||
arrayOf(ApnSetting.TYPE_OEM_PAID_STRING, ApnSetting.TYPE_OEM_PRIVATE_STRING)
|
||||
|
||||
/**
|
||||
* Fetch complete list of read only APN types.
|
||||
*
|
||||
* The list primarily comes from carrier config, but is also supplied by APN types which are
|
||||
* always read only.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun PersistableBundle.getReadOnlyApnTypes(): List<String> {
|
||||
val carrierReadOnlyApnTypes =
|
||||
getStringArray(CarrierConfigManager.KEY_READ_ONLY_APN_TYPES_STRING_ARRAY)?.toList()
|
||||
?: emptyList()
|
||||
return carrierReadOnlyApnTypes + ALWAYS_READ_ONLY_APN_TYPES
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if passed in array of APN types indicates all APN types
|
||||
*
|
||||
* @param apnTypes array of APN types. "*" indicates all types.
|
||||
* @return true if all apn types are included in the array, false otherwise
|
||||
*/
|
||||
@JvmStatic
|
||||
fun hasAllApnTypes(apnTypes: List<String>): Boolean =
|
||||
ApnSetting.TYPE_ALL_STRING in apnTypes || APN_TYPES.all { it in apnTypes }
|
||||
}
|
||||
|
||||
@@ -224,7 +224,10 @@ class CarrierConfigRepository(private val context: Context) {
|
||||
}
|
||||
|
||||
private val BooleanKeysWhichNotFollowingsNamingConventions =
|
||||
listOf(CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS)
|
||||
listOf(
|
||||
CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS,
|
||||
CarrierConfigManager.KEY_MMS_MMS_ENABLED_BOOL,
|
||||
)
|
||||
|
||||
private fun checkBooleanKey(key: String) {
|
||||
check(key.endsWith("_bool") || key in BooleanKeysWhichNotFollowingsNamingConventions) {
|
||||
|
||||
@@ -16,29 +16,31 @@
|
||||
|
||||
package com.android.settings.network.telephony;
|
||||
|
||||
import static androidx.lifecycle.Lifecycle.Event.ON_START;
|
||||
import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
|
||||
|
||||
import static com.android.settings.network.telephony.EnabledNetworkModePreferenceControllerHelperKt.getNetworkModePreferenceType;
|
||||
import static com.android.settings.network.telephony.EnabledNetworkModePreferenceControllerHelperKt.setAllowedNetworkTypes;
|
||||
import static com.android.settings.network.telephony.mode.NetworkModes.addNrToLteNetworkMode;
|
||||
import static com.android.settings.network.telephony.mode.NetworkModes.reduceNrToLteNetworkMode;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.os.PersistableBundle;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.RadioAccessFamily;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyCallback;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.telephony.satellite.SatelliteManager;
|
||||
import android.telephony.satellite.SatelliteModemStateCallback;
|
||||
import android.telephony.satellite.SelectedNbIotSatelliteSubscriptionCallback;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.lifecycle.LifecycleObserver;
|
||||
import androidx.lifecycle.DefaultLifecycleObserver;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.OnLifecycleEvent;
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.ListPreferenceDialogFragmentCompat;
|
||||
import androidx.preference.Preference;
|
||||
@@ -52,7 +54,6 @@ import com.android.settings.network.CarrierConfigCache;
|
||||
import com.android.settings.network.SubscriptionsChangeListener;
|
||||
import com.android.settings.network.telephony.NetworkModeChoicesProto.EnabledNetworks;
|
||||
import com.android.settings.network.telephony.NetworkModeChoicesProto.UiOptions;
|
||||
import com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -65,7 +66,7 @@ import java.util.stream.Stream;
|
||||
*/
|
||||
public class EnabledNetworkModePreferenceController extends
|
||||
BasePreferenceController implements
|
||||
ListPreference.OnPreferenceChangeListener, LifecycleObserver,
|
||||
ListPreference.OnPreferenceChangeListener, DefaultLifecycleObserver,
|
||||
SubscriptionsChangeListener.SubscriptionsChangeListenerClient {
|
||||
|
||||
private static final String LOG_TAG = "EnabledNetworkMode";
|
||||
@@ -81,6 +82,43 @@ public class EnabledNetworkModePreferenceController extends
|
||||
private PhoneCallStateTelephonyCallback mTelephonyCallback;
|
||||
private FragmentManager mFragmentManager;
|
||||
private LifecycleOwner mViewLifecycleOwner;
|
||||
private SatelliteManager mSatelliteManager;
|
||||
private boolean mIsSatelliteSessionStarted = false;
|
||||
private boolean mIsCurrentSubscriptionForSatellite = false;
|
||||
|
||||
@VisibleForTesting
|
||||
final SelectedNbIotSatelliteSubscriptionCallback mSelectedNbIotSatelliteSubscriptionCallback =
|
||||
new SelectedNbIotSatelliteSubscriptionCallback() {
|
||||
@Override
|
||||
public void onSelectedNbIotSatelliteSubscriptionChanged(int selectedSubId) {
|
||||
mIsCurrentSubscriptionForSatellite = selectedSubId == mSubId;
|
||||
updatePreference();
|
||||
}
|
||||
};
|
||||
|
||||
@VisibleForTesting
|
||||
final SatelliteModemStateCallback mSatelliteModemStateCallback =
|
||||
new SatelliteModemStateCallback() {
|
||||
@Override
|
||||
public void onSatelliteModemStateChanged(int state) {
|
||||
switch (state) {
|
||||
case SatelliteManager.SATELLITE_MODEM_STATE_OFF:
|
||||
case SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE:
|
||||
case SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN:
|
||||
if (mIsSatelliteSessionStarted) {
|
||||
mIsSatelliteSessionStarted = false;
|
||||
updatePreference();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (!mIsSatelliteSessionStarted) {
|
||||
mIsSatelliteSessionStarted = true;
|
||||
updatePreference();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public EnabledNetworkModePreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
@@ -88,6 +126,7 @@ public class EnabledNetworkModePreferenceController extends
|
||||
if (mTelephonyCallback == null) {
|
||||
mTelephonyCallback = new PhoneCallStateTelephonyCallback();
|
||||
}
|
||||
mSatelliteManager = context.getSystemService(SatelliteManager.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -101,8 +140,22 @@ public class EnabledNetworkModePreferenceController extends
|
||||
return mCallState == TelephonyManager.CALL_STATE_IDLE;
|
||||
}
|
||||
|
||||
@OnLifecycleEvent(ON_START)
|
||||
public void onStart() {
|
||||
@Override
|
||||
public void onStart(@NonNull LifecycleOwner owner) {
|
||||
if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) {
|
||||
if (mSatelliteManager != null) {
|
||||
try {
|
||||
mSatelliteManager.registerForModemStateChanged(
|
||||
mContext.getMainExecutor(), mSatelliteModemStateCallback);
|
||||
mSatelliteManager.registerForSelectedNbIotSatelliteSubscriptionChanged(
|
||||
mContext.getMainExecutor(),
|
||||
mSelectedNbIotSatelliteSubscriptionCallback);
|
||||
} catch (IllegalStateException e) {
|
||||
Log.w(LOG_TAG, "IllegalStateException : " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mSubscriptionsListener.start();
|
||||
if (mAllowedNetworkTypesListener == null || mTelephonyCallback == null) {
|
||||
return;
|
||||
@@ -111,9 +164,21 @@ public class EnabledNetworkModePreferenceController extends
|
||||
mTelephonyCallback.register(mTelephonyManager, mSubId);
|
||||
}
|
||||
|
||||
@OnLifecycleEvent(ON_STOP)
|
||||
public void onStop() {
|
||||
@Override
|
||||
public void onStop(@NonNull LifecycleOwner owner) {
|
||||
mSubscriptionsListener.stop();
|
||||
if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) {
|
||||
if (mSatelliteManager != null) {
|
||||
try {
|
||||
mSatelliteManager.unregisterForModemStateChanged(mSatelliteModemStateCallback);
|
||||
mSatelliteManager.unregisterForSelectedNbIotSatelliteSubscriptionChanged(
|
||||
mSelectedNbIotSatelliteSubscriptionCallback);
|
||||
} catch (IllegalStateException e) {
|
||||
Log.w(LOG_TAG, "IllegalStateException : " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mAllowedNetworkTypesListener == null || mTelephonyCallback == null) {
|
||||
return;
|
||||
}
|
||||
@@ -145,7 +210,7 @@ public class EnabledNetworkModePreferenceController extends
|
||||
listPreference.setEntryValues(mBuilder.getEntryValues());
|
||||
listPreference.setValue(Integer.toString(mBuilder.getSelectedEntryValue()));
|
||||
listPreference.setSummary(mBuilder.getSummary());
|
||||
boolean listPreferenceEnabled = isCallStateIdle();
|
||||
boolean listPreferenceEnabled = isPreferenceShallEnabled();
|
||||
listPreference.setEnabled(listPreferenceEnabled);
|
||||
if (!listPreferenceEnabled) {
|
||||
// If dialog is already opened when ListPreference disabled, dismiss them.
|
||||
@@ -201,6 +266,14 @@ public class EnabledNetworkModePreferenceController extends
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPreferenceShallEnabled() {
|
||||
Log.d(LOG_TAG, "isPreferenceShallEnabled, mIsSatelliteSessionStarted : "
|
||||
+ mIsSatelliteSessionStarted + " / mIsCurrentSubscriptionForSatellite : "
|
||||
+ mIsCurrentSubscriptionForSatellite);
|
||||
return isCallStateIdle()
|
||||
&& !(mIsSatelliteSessionStarted && mIsCurrentSubscriptionForSatellite);
|
||||
}
|
||||
|
||||
private final class PreferenceEntriesBuilder {
|
||||
private CarrierConfigCache mCarrierConfigCache;
|
||||
private Context mContext;
|
||||
@@ -252,7 +325,7 @@ public class EnabledNetworkModePreferenceController extends
|
||||
|
||||
if (flagHidePrefer3gItem) {
|
||||
mDisplay3gOptions = carrierConfig.getBoolean(
|
||||
CarrierConfigManager.KEY_PREFER_3G_VISIBILITY_BOOL);
|
||||
CarrierConfigManager.KEY_PREFER_3G_VISIBILITY_BOOL);
|
||||
} else {
|
||||
mDisplay3gOptions = getResourcesForSubId().getBoolean(
|
||||
R.bool.config_display_network_mode_3g_option);
|
||||
@@ -428,14 +501,14 @@ public class EnabledNetworkModePreferenceController extends
|
||||
addLteEntry(entryValuesInt[entryIndex]);
|
||||
break;
|
||||
case add5gEntry:
|
||||
add5gEntry(addNrToLteNetworkType(entryValuesInt[entryIndex]));
|
||||
add5gEntry(addNrToLteNetworkMode(entryValuesInt[entryIndex]));
|
||||
break;
|
||||
case add5gAnd4gEntry:
|
||||
add5gEntry(addNrToLteNetworkType(entryValuesInt[entryIndex]));
|
||||
add5gEntry(addNrToLteNetworkMode(entryValuesInt[entryIndex]));
|
||||
add4gEntry(entryValuesInt[entryIndex]);
|
||||
break;
|
||||
case add5gAndLteEntry:
|
||||
add5gEntry(addNrToLteNetworkType(entryValuesInt[entryIndex]));
|
||||
add5gEntry(addNrToLteNetworkMode(entryValuesInt[entryIndex]));
|
||||
addLteEntry(entryValuesInt[entryIndex]);
|
||||
break;
|
||||
default:
|
||||
@@ -445,12 +518,12 @@ public class EnabledNetworkModePreferenceController extends
|
||||
}
|
||||
|
||||
private int getPreferredNetworkMode() {
|
||||
int networkMode = MobileNetworkUtils.getNetworkTypeFromRaf(
|
||||
int networkMode = RadioAccessFamily.getNetworkTypeFromRaf(
|
||||
(int) mTelephonyManager.getAllowedNetworkTypesForReason(
|
||||
TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER));
|
||||
if (!showNrList()) {
|
||||
Log.d(LOG_TAG, "Network mode :" + networkMode + " reduce NR");
|
||||
networkMode = reduceNrToLteNetworkType(networkMode);
|
||||
networkMode = reduceNrToLteNetworkMode(networkMode);
|
||||
}
|
||||
Log.d(LOG_TAG, "getPreferredNetworkMode: " + networkMode);
|
||||
return networkMode;
|
||||
@@ -471,16 +544,16 @@ public class EnabledNetworkModePreferenceController extends
|
||||
enabledNetworkType = EnabledNetworks.ENABLED_NETWORKS_CDMA_CHOICES;
|
||||
} else {
|
||||
switch (settingsNetworkMode) {
|
||||
case TelephonyManagerConstants.NETWORK_MODE_CDMA_EVDO:
|
||||
case TelephonyManagerConstants.NETWORK_MODE_CDMA_NO_EVDO:
|
||||
case TelephonyManagerConstants.NETWORK_MODE_EVDO_NO_CDMA:
|
||||
case TelephonyManager.NETWORK_MODE_CDMA_EVDO:
|
||||
case TelephonyManager.NETWORK_MODE_CDMA_NO_EVDO:
|
||||
case TelephonyManager.NETWORK_MODE_EVDO_NO_CDMA:
|
||||
enabledNetworkType =
|
||||
EnabledNetworks.ENABLED_NETWORKS_CDMA_NO_LTE_CHOICES;
|
||||
break;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_GLOBAL:
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO:
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_ONLY:
|
||||
case TelephonyManager.NETWORK_MODE_GLOBAL:
|
||||
case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO:
|
||||
case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_LTE_ONLY:
|
||||
enabledNetworkType =
|
||||
EnabledNetworks.ENABLED_NETWORKS_CDMA_ONLY_LTE_CHOICES;
|
||||
break;
|
||||
@@ -538,46 +611,42 @@ public class EnabledNetworkModePreferenceController extends
|
||||
void setPreferenceValueAndSummary(int networkMode) {
|
||||
setSelectedEntry(networkMode);
|
||||
switch (networkMode) {
|
||||
case TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_WCDMA:
|
||||
case TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA:
|
||||
case TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_GSM:
|
||||
setSelectedEntry(
|
||||
TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA);
|
||||
case TelephonyManager.NETWORK_MODE_TDSCDMA_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_TDSCDMA_GSM_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_TDSCDMA_GSM:
|
||||
setSelectedEntry(TelephonyManager.NETWORK_MODE_TDSCDMA_GSM_WCDMA);
|
||||
setSummary(R.string.network_3G);
|
||||
break;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_WCDMA_ONLY:
|
||||
case TelephonyManagerConstants.NETWORK_MODE_GSM_UMTS:
|
||||
case TelephonyManagerConstants.NETWORK_MODE_WCDMA_PREF:
|
||||
case TelephonyManager.NETWORK_MODE_WCDMA_ONLY:
|
||||
case TelephonyManager.NETWORK_MODE_GSM_UMTS:
|
||||
case TelephonyManager.NETWORK_MODE_WCDMA_PREF:
|
||||
if (!mIsGlobalCdma) {
|
||||
setSelectedEntry(TelephonyManagerConstants.NETWORK_MODE_WCDMA_PREF);
|
||||
setSelectedEntry(TelephonyManager.NETWORK_MODE_WCDMA_PREF);
|
||||
setSummary(R.string.network_3G);
|
||||
} else {
|
||||
setSelectedEntry(
|
||||
TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA);
|
||||
setSelectedEntry(TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA);
|
||||
setSummary(R.string.network_global);
|
||||
}
|
||||
break;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_GSM_ONLY:
|
||||
case TelephonyManager.NETWORK_MODE_GSM_ONLY:
|
||||
if (!mIsGlobalCdma) {
|
||||
setSelectedEntry(TelephonyManagerConstants.NETWORK_MODE_GSM_ONLY);
|
||||
setSelectedEntry(TelephonyManager.NETWORK_MODE_GSM_ONLY);
|
||||
setSummary(R.string.network_2G);
|
||||
} else {
|
||||
setSelectedEntry(
|
||||
TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA);
|
||||
setSelectedEntry(TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA);
|
||||
setSummary(R.string.network_global);
|
||||
}
|
||||
break;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_GSM_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA:
|
||||
if (MobileNetworkUtils.isWorldMode(mContext, mSubId)) {
|
||||
setSummary(
|
||||
R.string.preferred_network_mode_lte_gsm_umts_summary);
|
||||
break;
|
||||
}
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_ONLY:
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_LTE_ONLY:
|
||||
case TelephonyManager.NETWORK_MODE_LTE_WCDMA:
|
||||
if (!mIsGlobalCdma) {
|
||||
setSelectedEntry(
|
||||
TelephonyManagerConstants.NETWORK_MODE_LTE_GSM_WCDMA);
|
||||
setSelectedEntry(TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA);
|
||||
if (is5gEntryDisplayed()) {
|
||||
setSummary(mShow4gForLTE
|
||||
? R.string.network_4G_pure : R.string.network_lte_pure);
|
||||
@@ -586,55 +655,52 @@ public class EnabledNetworkModePreferenceController extends
|
||||
? R.string.network_4G : R.string.network_lte);
|
||||
}
|
||||
} else {
|
||||
setSelectedEntry(
|
||||
TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA);
|
||||
setSelectedEntry(TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA);
|
||||
setSummary(R.string.network_global);
|
||||
}
|
||||
break;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO:
|
||||
case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO:
|
||||
if (MobileNetworkUtils.isWorldMode(mContext, mSubId)) {
|
||||
setSummary(
|
||||
R.string.preferred_network_mode_lte_cdma_summary);
|
||||
} else {
|
||||
setSelectedEntry(
|
||||
TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO);
|
||||
setSelectedEntry(TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO);
|
||||
setSummary(is5gEntryDisplayed()
|
||||
? R.string.network_lte_pure : R.string.network_lte);
|
||||
}
|
||||
break;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
|
||||
setSelectedEntry(
|
||||
TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA);
|
||||
case TelephonyManager.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
|
||||
setSelectedEntry(TelephonyManager.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA);
|
||||
setSummary(R.string.network_3G);
|
||||
break;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_CDMA_EVDO:
|
||||
case TelephonyManagerConstants.NETWORK_MODE_EVDO_NO_CDMA:
|
||||
case TelephonyManagerConstants.NETWORK_MODE_GLOBAL:
|
||||
setSelectedEntry(TelephonyManagerConstants.NETWORK_MODE_CDMA_EVDO);
|
||||
case TelephonyManager.NETWORK_MODE_CDMA_EVDO:
|
||||
case TelephonyManager.NETWORK_MODE_EVDO_NO_CDMA:
|
||||
case TelephonyManager.NETWORK_MODE_GLOBAL:
|
||||
setSelectedEntry(TelephonyManager.NETWORK_MODE_CDMA_EVDO);
|
||||
setSummary(R.string.network_3G);
|
||||
break;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_CDMA_NO_EVDO:
|
||||
setSelectedEntry(TelephonyManagerConstants.NETWORK_MODE_CDMA_NO_EVDO);
|
||||
case TelephonyManager.NETWORK_MODE_CDMA_NO_EVDO:
|
||||
setSelectedEntry(TelephonyManager.NETWORK_MODE_CDMA_NO_EVDO);
|
||||
setSummary(R.string.network_1x);
|
||||
break;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_ONLY:
|
||||
setSelectedEntry(TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_ONLY);
|
||||
case TelephonyManager.NETWORK_MODE_TDSCDMA_ONLY:
|
||||
setSelectedEntry(TelephonyManager.NETWORK_MODE_TDSCDMA_ONLY);
|
||||
setSummary(R.string.network_3G);
|
||||
break;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM:
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA:
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA:
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA:
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM:
|
||||
case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
|
||||
if (MobileNetworkUtils.isTdscdmaSupported(mContext, mSubId)) {
|
||||
setSelectedEntry(TelephonyManagerConstants
|
||||
.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA);
|
||||
setSelectedEntry(
|
||||
TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA);
|
||||
setSummary(is5gEntryDisplayed()
|
||||
? R.string.network_lte_pure : R.string.network_lte);
|
||||
} else {
|
||||
setSelectedEntry(
|
||||
TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA);
|
||||
TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA);
|
||||
if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA
|
||||
|| mIsGlobalCdma
|
||||
|| MobileNetworkUtils.isWorldMode(mContext, mSubId)) {
|
||||
@@ -651,30 +717,28 @@ public class EnabledNetworkModePreferenceController extends
|
||||
}
|
||||
break;
|
||||
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_ONLY:
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE:
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA:
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_NR_ONLY:
|
||||
case TelephonyManager.NETWORK_MODE_NR_LTE:
|
||||
case TelephonyManager.NETWORK_MODE_NR_LTE_GSM_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_NR_LTE_WCDMA:
|
||||
setSelectedEntry(TelephonyManager.NETWORK_MODE_NR_LTE_GSM_WCDMA);
|
||||
setSummary(getResourcesForSubId().getString(R.string.network_5G_recommended));
|
||||
break;
|
||||
case TelephonyManager.NETWORK_MODE_NR_LTE_TDSCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_NR_LTE_TDSCDMA_GSM:
|
||||
case TelephonyManager.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
|
||||
setSelectedEntry(
|
||||
TelephonyManagerConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA);
|
||||
TelephonyManager.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA);
|
||||
setSummary(getResourcesForSubId().getString(R.string.network_5G_recommended));
|
||||
break;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA:
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM:
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA:
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA:
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
|
||||
setSelectedEntry(TelephonyManagerConstants
|
||||
.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA);
|
||||
case TelephonyManager.NETWORK_MODE_NR_LTE_CDMA_EVDO:
|
||||
setSelectedEntry(TelephonyManager.NETWORK_MODE_NR_LTE_CDMA_EVDO);
|
||||
setSummary(getResourcesForSubId().getString(R.string.network_5G_recommended));
|
||||
break;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO:
|
||||
setSelectedEntry(TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO);
|
||||
setSummary(getResourcesForSubId().getString(R.string.network_5G_recommended));
|
||||
break;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA:
|
||||
setSelectedEntry(
|
||||
TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA);
|
||||
case TelephonyManager.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA:
|
||||
setSelectedEntry(TelephonyManager.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA);
|
||||
if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA
|
||||
|| mIsGlobalCdma
|
||||
|| MobileNetworkUtils.isWorldMode(mContext, mSubId)) {
|
||||
@@ -691,74 +755,6 @@ public class EnabledNetworkModePreferenceController extends
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform LTE network mode to 5G network mode.
|
||||
*
|
||||
* @param networkType an LTE network mode without 5G.
|
||||
* @return the corresponding network mode with 5G.
|
||||
*/
|
||||
private int addNrToLteNetworkType(int networkType) {
|
||||
switch (networkType) {
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_ONLY:
|
||||
return TelephonyManagerConstants.NETWORK_MODE_NR_LTE;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO:
|
||||
return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_GSM_WCDMA:
|
||||
return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
|
||||
return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_WCDMA:
|
||||
return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_WCDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA:
|
||||
return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM:
|
||||
return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA:
|
||||
return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA:
|
||||
return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
|
||||
return TelephonyManagerConstants
|
||||
.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
|
||||
default:
|
||||
return networkType; // not LTE
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform NR5G network mode to LTE network mode.
|
||||
*
|
||||
* @param networkType an 5G network mode.
|
||||
* @return the corresponding network mode without 5G.
|
||||
*/
|
||||
private int reduceNrToLteNetworkType(int networkType) {
|
||||
switch (networkType) {
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE:
|
||||
return TelephonyManagerConstants.NETWORK_MODE_LTE_ONLY;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO:
|
||||
return TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA:
|
||||
return TelephonyManagerConstants.NETWORK_MODE_LTE_GSM_WCDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA:
|
||||
return TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_WCDMA:
|
||||
return TelephonyManagerConstants.NETWORK_MODE_LTE_WCDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA:
|
||||
return TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM:
|
||||
return TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA:
|
||||
return TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA:
|
||||
return TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
|
||||
return TelephonyManagerConstants
|
||||
.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
|
||||
default:
|
||||
return networkType; // do nothing
|
||||
}
|
||||
}
|
||||
|
||||
private void setPreferenceValueAndSummary() {
|
||||
setPreferenceValueAndSummary(getPreferredNetworkMode());
|
||||
}
|
||||
@@ -771,7 +767,7 @@ public class EnabledNetworkModePreferenceController extends
|
||||
* Add 5G option. Only show the UI when device supported 5G and allowed 5G.
|
||||
*/
|
||||
private void add5gEntry(int value) {
|
||||
boolean isNRValue = value >= TelephonyManagerConstants.NETWORK_MODE_NR_ONLY;
|
||||
boolean isNRValue = value >= TelephonyManager.NETWORK_MODE_NR_ONLY;
|
||||
if (showNrList() && isNRValue) {
|
||||
mEntries.add(getResourcesForSubId().getString(R.string.network_5G_recommended));
|
||||
mEntriesValue.add(value);
|
||||
@@ -791,7 +787,7 @@ public class EnabledNetworkModePreferenceController extends
|
||||
+ " allowed5GNetworkType: " + mAllowed5gNetworkType);
|
||||
mEntries.add(getResourcesForSubId().getString(R.string.network_global));
|
||||
if (showNrList()) {
|
||||
value = addNrToLteNetworkType(value);
|
||||
value = addNrToLteNetworkMode(value);
|
||||
}
|
||||
mEntriesValue.add(value);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.settings.network.telephony
|
||||
|
||||
import android.content.Context
|
||||
import android.telephony.CarrierConfigManager
|
||||
import android.telephony.RadioAccessFamily
|
||||
import android.telephony.SubscriptionManager
|
||||
import android.telephony.TelephonyManager
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
@@ -35,7 +36,7 @@ fun TelephonyManager.setAllowedNetworkTypes(
|
||||
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Default) {
|
||||
setAllowedNetworkTypesForReason(
|
||||
TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER,
|
||||
MobileNetworkUtils.getRafFromNetworkType(newPreferredNetworkMode),
|
||||
RadioAccessFamily.getRafFromNetworkType(newPreferredNetworkMode).toLong(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.settings.network.telephony
|
||||
|
||||
import android.content.Context
|
||||
import android.telephony.CarrierConfigManager
|
||||
import android.telephony.SubscriptionManager
|
||||
import android.telephony.TelephonyManager
|
||||
import android.telephony.data.ApnSetting
|
||||
@@ -45,7 +46,7 @@ constructor(
|
||||
private var subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID
|
||||
private var telephonyManager: TelephonyManager =
|
||||
context.getSystemService(TelephonyManager::class.java)!!
|
||||
|
||||
private val carrierConfigRepository = CarrierConfigRepository(context)
|
||||
private var preferenceScreen: PreferenceScreen? = null
|
||||
|
||||
fun init(subId: Int) {
|
||||
@@ -54,7 +55,13 @@ constructor(
|
||||
}
|
||||
|
||||
override fun getAvailabilityStatus() =
|
||||
if (getAvailabilityStatus(telephonyManager, subId, getDefaultDataSubId)) AVAILABLE
|
||||
if (getAvailabilityStatus(
|
||||
telephonyManager,
|
||||
subId,
|
||||
getDefaultDataSubId,
|
||||
carrierConfigRepository
|
||||
)
|
||||
) AVAILABLE
|
||||
else CONDITIONALLY_UNAVAILABLE
|
||||
|
||||
override fun displayPreference(screen: PreferenceScreen) {
|
||||
@@ -92,11 +99,14 @@ constructor(
|
||||
telephonyManager: TelephonyManager,
|
||||
subId: Int,
|
||||
getDefaultDataSubId: () -> Int,
|
||||
carrierConfigRepository: CarrierConfigRepository,
|
||||
): Boolean {
|
||||
return SubscriptionManager.isValidSubscriptionId(subId) &&
|
||||
!telephonyManager.isDataEnabled &&
|
||||
telephonyManager.isApnMetered(ApnSetting.TYPE_MMS) &&
|
||||
!isFallbackDataEnabled(telephonyManager, subId, getDefaultDataSubId())
|
||||
!isFallbackDataEnabled(telephonyManager, subId, getDefaultDataSubId()) &&
|
||||
carrierConfigRepository.getBoolean(
|
||||
subId, CarrierConfigManager.KEY_MMS_MMS_ENABLED_BOOL)
|
||||
}
|
||||
|
||||
private fun isFallbackDataEnabled(
|
||||
@@ -118,11 +128,16 @@ constructor(
|
||||
) : MobileNetworkSettingsSearchItem {
|
||||
private var telephonyManager: TelephonyManager =
|
||||
context.getSystemService(TelephonyManager::class.java)!!
|
||||
private val carrierConfigRepository = CarrierConfigRepository(context)
|
||||
|
||||
@VisibleForTesting
|
||||
fun isAvailable(subId: Int): Boolean =
|
||||
getAvailabilityStatus(
|
||||
telephonyManager.createForSubscriptionId(subId), subId, getDefaultDataSubId)
|
||||
telephonyManager.createForSubscriptionId(subId),
|
||||
subId,
|
||||
getDefaultDataSubId,
|
||||
carrierConfigRepository
|
||||
)
|
||||
|
||||
override fun getSearchResult(subId: Int): MobileNetworkSettingsSearchResult? {
|
||||
if (!isAvailable(subId)) return null
|
||||
|
||||
@@ -277,11 +277,18 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings impleme
|
||||
if (roamingPreferenceController != null) {
|
||||
roamingPreferenceController.init(getParentFragmentManager(), mSubId);
|
||||
}
|
||||
final SatelliteSettingsPreferenceCategoryController
|
||||
satelliteSettingsPreferenceCategoryController =
|
||||
use(SatelliteSettingsPreferenceCategoryController.class);
|
||||
if (satelliteSettingsPreferenceCategoryController != null) {
|
||||
satelliteSettingsPreferenceCategoryController.init(mSubId);
|
||||
}
|
||||
final SatelliteSettingPreferenceController satelliteSettingPreferenceController = use(
|
||||
SatelliteSettingPreferenceController.class);
|
||||
if (satelliteSettingPreferenceController != null) {
|
||||
satelliteSettingPreferenceController.init(mSubId);
|
||||
}
|
||||
|
||||
use(ApnPreferenceController.class).init(mSubId);
|
||||
use(CarrierPreferenceController.class).init(mSubId);
|
||||
use(DataUsagePreferenceController.class).init(mSubId);
|
||||
@@ -327,12 +334,10 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings impleme
|
||||
convertToEsimPreferenceController.init(mSubId, mSubscriptionInfoEntity);
|
||||
}
|
||||
|
||||
List<AbstractSubscriptionPreferenceController> subscriptionPreferenceControllers =
|
||||
useAll(AbstractSubscriptionPreferenceController.class);
|
||||
for (AbstractSubscriptionPreferenceController controller :
|
||||
subscriptionPreferenceControllers) {
|
||||
controller.init(mSubId);
|
||||
}
|
||||
List<AbstractPreferenceController> subscriptionPreferenceControllers =
|
||||
useGroup(AbstractSubscriptionPreferenceController.class);
|
||||
subscriptionPreferenceControllers.forEach(
|
||||
controller -> ((AbstractSubscriptionPreferenceController) controller).init(mSubId));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -18,19 +18,6 @@ package com.android.settings.network.telephony;
|
||||
|
||||
import static android.provider.Telephony.Carriers.ENFORCE_MANAGED_URI;
|
||||
|
||||
import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.CDMA;
|
||||
import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.EVDO;
|
||||
import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.GSM;
|
||||
import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.LTE;
|
||||
import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.NR;
|
||||
import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.RAF_TD_SCDMA;
|
||||
import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.RAF_UNKNOWN;
|
||||
import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.WCDMA;
|
||||
import static com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO;
|
||||
import static com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants.NETWORK_MODE_LTE_GSM_WCDMA;
|
||||
import static com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO;
|
||||
import static com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA;
|
||||
|
||||
import android.app.KeyguardManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -56,11 +43,11 @@ import android.provider.Settings;
|
||||
import android.telecom.PhoneAccountHandle;
|
||||
import android.telecom.TelecomManager;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.RadioAccessFamily;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.telephony.euicc.EuiccManager;
|
||||
import android.telephony.ims.ImsManager;
|
||||
import android.telephony.ims.ImsRcsManager;
|
||||
import android.telephony.ims.ProvisioningManager;
|
||||
@@ -83,15 +70,12 @@ import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.network.CarrierConfigCache;
|
||||
import com.android.settings.network.SubscriptionUtil;
|
||||
import com.android.settings.network.ims.WifiCallingQueryImsState;
|
||||
import com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants;
|
||||
import com.android.settings.network.telephony.wificalling.WifiCallingRepository;
|
||||
import com.android.settingslib.core.instrumentation.Instrumentable;
|
||||
import com.android.settingslib.graph.SignalDrawable;
|
||||
import com.android.settingslib.mobile.dataservice.SubscriptionInfoEntity;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class MobileNetworkUtils {
|
||||
|
||||
@@ -334,14 +318,14 @@ public class MobileNetworkUtils {
|
||||
}
|
||||
|
||||
if (isWorldMode(context, subId)) {
|
||||
final int settingsNetworkMode = getNetworkTypeFromRaf(
|
||||
final int settingsNetworkMode = RadioAccessFamily.getNetworkTypeFromRaf(
|
||||
(int) telephonyManager.getAllowedNetworkTypesForReason(
|
||||
TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER));
|
||||
|
||||
if (settingsNetworkMode == NETWORK_MODE_LTE_GSM_WCDMA
|
||||
|| settingsNetworkMode == NETWORK_MODE_LTE_CDMA_EVDO
|
||||
|| settingsNetworkMode == NETWORK_MODE_NR_LTE_GSM_WCDMA
|
||||
|| settingsNetworkMode == NETWORK_MODE_NR_LTE_CDMA_EVDO) {
|
||||
if (settingsNetworkMode == TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA
|
||||
|| settingsNetworkMode == TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO
|
||||
|| settingsNetworkMode == TelephonyManager.NETWORK_MODE_NR_LTE_GSM_WCDMA
|
||||
|| settingsNetworkMode == TelephonyManager.NETWORK_MODE_NR_LTE_CDMA_EVDO) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -365,14 +349,14 @@ public class MobileNetworkUtils {
|
||||
}
|
||||
final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class)
|
||||
.createForSubscriptionId(subId);
|
||||
final int networkMode = getNetworkTypeFromRaf(
|
||||
final int networkMode = RadioAccessFamily.getNetworkTypeFromRaf(
|
||||
(int) telephonyManager.getAllowedNetworkTypesForReason(
|
||||
TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER));
|
||||
if (isWorldMode(context, subId)) {
|
||||
if (networkMode == NETWORK_MODE_LTE_CDMA_EVDO
|
||||
|| networkMode == NETWORK_MODE_LTE_GSM_WCDMA
|
||||
|| networkMode == NETWORK_MODE_NR_LTE_CDMA_EVDO
|
||||
|| networkMode == NETWORK_MODE_NR_LTE_GSM_WCDMA) {
|
||||
if (networkMode == TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO
|
||||
|| networkMode == TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA
|
||||
|| networkMode == TelephonyManager.NETWORK_MODE_NR_LTE_CDMA_EVDO
|
||||
|| networkMode == TelephonyManager.NETWORK_MODE_NR_LTE_GSM_WCDMA) {
|
||||
return true;
|
||||
} else if (shouldSpeciallyUpdateGsmCdma(context, subId)) {
|
||||
return true;
|
||||
@@ -433,17 +417,17 @@ public class MobileNetworkUtils {
|
||||
}
|
||||
|
||||
if (isWorldMode(context, subId)) {
|
||||
final int networkMode = getNetworkTypeFromRaf(
|
||||
final int networkMode = RadioAccessFamily.getNetworkTypeFromRaf(
|
||||
(int) telephonyManager.getAllowedNetworkTypesForReason(
|
||||
TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER));
|
||||
if (networkMode == TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO) {
|
||||
if (networkMode == TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO) {
|
||||
return false;
|
||||
}
|
||||
if (shouldSpeciallyUpdateGsmCdma(context, subId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (networkMode == TelephonyManagerConstants.NETWORK_MODE_LTE_GSM_WCDMA) {
|
||||
if (networkMode == TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -548,16 +532,16 @@ public class MobileNetworkUtils {
|
||||
}
|
||||
final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class)
|
||||
.createForSubscriptionId(subId);
|
||||
final int networkMode = getNetworkTypeFromRaf(
|
||||
final int networkMode = RadioAccessFamily.getNetworkTypeFromRaf(
|
||||
(int) telephonyManager.getAllowedNetworkTypesForReason(
|
||||
TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER));
|
||||
if (networkMode == TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM
|
||||
|| networkMode == TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA
|
||||
|| networkMode == TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA
|
||||
|| networkMode == TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA
|
||||
if (networkMode == TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM
|
||||
|| networkMode == TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA
|
||||
|| networkMode == TelephonyManager.NETWORK_MODE_LTE_TDSCDMA
|
||||
|| networkMode == TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_WCDMA
|
||||
|| networkMode
|
||||
== TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA
|
||||
|| networkMode == TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA) {
|
||||
== TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA
|
||||
|| networkMode == TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA) {
|
||||
if (!isTdscdmaSupported(context, subId)) {
|
||||
return true;
|
||||
}
|
||||
@@ -610,12 +594,8 @@ public class MobileNetworkUtils {
|
||||
}
|
||||
|
||||
public static CharSequence getCurrentCarrierNameForDisplay(Context context) {
|
||||
final SubscriptionInfo subInfo = getSubscriptionInfo(context,
|
||||
return getCurrentCarrierNameForDisplay(context,
|
||||
SubscriptionManager.getDefaultSubscriptionId());
|
||||
if (subInfo != null) {
|
||||
return subInfo.getCarrierName();
|
||||
}
|
||||
return getOperatorNameFromTelephonyManager(context);
|
||||
}
|
||||
|
||||
private static @Nullable SubscriptionInfo getSubscriptionInfo(Context context, int subId) {
|
||||
@@ -651,197 +631,6 @@ public class MobileNetworkUtils {
|
||||
return activeSubIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loop through all the device logical slots to check whether the user's current country
|
||||
* supports eSIM.
|
||||
*/
|
||||
private static boolean isCurrentCountrySupported(Context context) {
|
||||
final EuiccManager em = (EuiccManager) context.getSystemService(EuiccManager.class);
|
||||
final TelephonyManager tm =
|
||||
(TelephonyManager) context.getSystemService(TelephonyManager.class);
|
||||
|
||||
Set<String> countrySet = new HashSet<>();
|
||||
for (int i = 0; i < tm.getPhoneCount(); i++) {
|
||||
String countryCode = tm.getNetworkCountryIso(i);
|
||||
if (!TextUtils.isEmpty(countryCode)) {
|
||||
countrySet.add(countryCode);
|
||||
}
|
||||
}
|
||||
boolean isSupported = countrySet.stream().anyMatch(em::isSupportedCountry);
|
||||
Log.i(TAG, "isCurrentCountrySupported countryCodes: " + countrySet
|
||||
+ " eSIMSupported: " + isSupported);
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
/**
|
||||
* Imported from {@link android.telephony.RadioAccessFamily}
|
||||
*/
|
||||
public static long getRafFromNetworkType(int type) {
|
||||
switch (type) {
|
||||
case TelephonyManagerConstants.NETWORK_MODE_WCDMA_PREF:
|
||||
return GSM | WCDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_GSM_ONLY:
|
||||
return GSM;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_WCDMA_ONLY:
|
||||
return WCDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_GSM_UMTS:
|
||||
return GSM | WCDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_CDMA_EVDO:
|
||||
return CDMA | EVDO;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO:
|
||||
return LTE | CDMA | EVDO;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_GSM_WCDMA:
|
||||
return LTE | GSM | WCDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
|
||||
return LTE | CDMA | EVDO | GSM | WCDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_ONLY:
|
||||
return LTE;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_WCDMA:
|
||||
return LTE | WCDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_CDMA_NO_EVDO:
|
||||
return CDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_EVDO_NO_CDMA:
|
||||
return EVDO;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_GLOBAL:
|
||||
return GSM | WCDMA | CDMA | EVDO;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_ONLY:
|
||||
return RAF_TD_SCDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_WCDMA:
|
||||
return RAF_TD_SCDMA | WCDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA:
|
||||
return LTE | RAF_TD_SCDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_GSM:
|
||||
return RAF_TD_SCDMA | GSM;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM:
|
||||
return LTE | RAF_TD_SCDMA | GSM;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA:
|
||||
return RAF_TD_SCDMA | GSM | WCDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA:
|
||||
return LTE | RAF_TD_SCDMA | WCDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA:
|
||||
return LTE | RAF_TD_SCDMA | GSM | WCDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
|
||||
return RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
|
||||
return LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA;
|
||||
case (TelephonyManagerConstants.NETWORK_MODE_NR_ONLY):
|
||||
return NR;
|
||||
case (TelephonyManagerConstants.NETWORK_MODE_NR_LTE):
|
||||
return NR | LTE;
|
||||
case (TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO):
|
||||
return NR | LTE | CDMA | EVDO;
|
||||
case (TelephonyManagerConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA):
|
||||
return NR | LTE | GSM | WCDMA;
|
||||
case (TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA):
|
||||
return NR | LTE | CDMA | EVDO | GSM | WCDMA;
|
||||
case (TelephonyManagerConstants.NETWORK_MODE_NR_LTE_WCDMA):
|
||||
return NR | LTE | WCDMA;
|
||||
case (TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA):
|
||||
return NR | LTE | RAF_TD_SCDMA;
|
||||
case (TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM):
|
||||
return NR | LTE | RAF_TD_SCDMA | GSM;
|
||||
case (TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA):
|
||||
return NR | LTE | RAF_TD_SCDMA | WCDMA;
|
||||
case (TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA):
|
||||
return NR | LTE | RAF_TD_SCDMA | GSM | WCDMA;
|
||||
case (TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA):
|
||||
return NR | LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA;
|
||||
default:
|
||||
return RAF_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Imported from {@link android.telephony.RadioAccessFamily}
|
||||
*/
|
||||
public static int getNetworkTypeFromRaf(int raf) {
|
||||
raf = getAdjustedRaf(raf);
|
||||
|
||||
switch (raf) {
|
||||
case (GSM | WCDMA):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_WCDMA_PREF;
|
||||
case GSM:
|
||||
return TelephonyManagerConstants.NETWORK_MODE_GSM_ONLY;
|
||||
case WCDMA:
|
||||
return TelephonyManagerConstants.NETWORK_MODE_WCDMA_ONLY;
|
||||
case (CDMA | EVDO):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_CDMA_EVDO;
|
||||
case (LTE | CDMA | EVDO):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO;
|
||||
case (LTE | GSM | WCDMA):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_LTE_GSM_WCDMA;
|
||||
case (LTE | CDMA | EVDO | GSM | WCDMA):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA;
|
||||
case LTE:
|
||||
return TelephonyManagerConstants.NETWORK_MODE_LTE_ONLY;
|
||||
case (LTE | WCDMA):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_LTE_WCDMA;
|
||||
case CDMA:
|
||||
return TelephonyManagerConstants.NETWORK_MODE_CDMA_NO_EVDO;
|
||||
case EVDO:
|
||||
return TelephonyManagerConstants.NETWORK_MODE_EVDO_NO_CDMA;
|
||||
case (GSM | WCDMA | CDMA | EVDO):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_GLOBAL;
|
||||
case RAF_TD_SCDMA:
|
||||
return TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_ONLY;
|
||||
case (RAF_TD_SCDMA | WCDMA):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_WCDMA;
|
||||
case (LTE | RAF_TD_SCDMA):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA;
|
||||
case (RAF_TD_SCDMA | GSM):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_GSM;
|
||||
case (LTE | RAF_TD_SCDMA | GSM):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM;
|
||||
case (RAF_TD_SCDMA | GSM | WCDMA):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA;
|
||||
case (LTE | RAF_TD_SCDMA | WCDMA):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA;
|
||||
case (LTE | RAF_TD_SCDMA | GSM | WCDMA):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA;
|
||||
case (RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
|
||||
case (LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
|
||||
case (NR):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_NR_ONLY;
|
||||
case (NR | LTE):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_NR_LTE;
|
||||
case (NR | LTE | CDMA | EVDO):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO;
|
||||
case (NR | LTE | GSM | WCDMA):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA;
|
||||
case (NR | LTE | CDMA | EVDO | GSM | WCDMA):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA;
|
||||
case (NR | LTE | WCDMA):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_WCDMA;
|
||||
case (NR | LTE | RAF_TD_SCDMA):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA;
|
||||
case (NR | LTE | RAF_TD_SCDMA | GSM):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM;
|
||||
case (NR | LTE | RAF_TD_SCDMA | WCDMA):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA;
|
||||
case (NR | LTE | RAF_TD_SCDMA | GSM | WCDMA):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA;
|
||||
case (NR | LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA):
|
||||
return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
|
||||
default:
|
||||
return TelephonyManagerConstants.NETWORK_MODE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Imported from {@link android.telephony.RadioAccessFamily}
|
||||
*/
|
||||
private static int getAdjustedRaf(int raf) {
|
||||
raf = ((GSM & raf) > 0) ? (GSM | raf) : raf;
|
||||
raf = ((WCDMA & raf) > 0) ? (WCDMA | raf) : raf;
|
||||
raf = ((CDMA & raf) > 0) ? (CDMA | raf) : raf;
|
||||
raf = ((EVDO & raf) > 0) ? (EVDO | raf) : raf;
|
||||
raf = ((LTE & raf) > 0) ? (LTE | raf) : raf;
|
||||
raf = ((NR & raf) > 0) ? (NR | raf) : raf;
|
||||
return raf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copied from SubscriptionsPreferenceController#activeNetworkIsCellular()
|
||||
*/
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.telephony.CarrierConfigManager
|
||||
import android.telephony.NetworkRegistrationInfo
|
||||
import android.telephony.TelephonyManager
|
||||
import android.telephony.satellite.SatelliteManager
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
@@ -92,6 +93,11 @@ class NetworkSelectRepository(context: Context, private val subId: Int) {
|
||||
* Update satellite PLMNs from the satellite framework.
|
||||
*/
|
||||
private fun getSatellitePlmns(): List<String> {
|
||||
if (satelliteManager == null) {
|
||||
Log.d(TAG, "SatelliteManager is null")
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
val config = carrierConfigManager.getConfigForSubId(
|
||||
subId,
|
||||
CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL
|
||||
@@ -104,7 +110,11 @@ class NetworkSelectRepository(context: Context, private val subId: Int) {
|
||||
return if (shouldFilter) {
|
||||
satelliteManager.getSatellitePlmnsForCarrier(subId)
|
||||
} else {
|
||||
emptyList();
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
private companion object {
|
||||
private const val TAG = "NetworkSelectRepository"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,33 +21,81 @@ import static com.android.settings.network.telephony.EnabledNetworkModePreferenc
|
||||
import android.content.Context;
|
||||
import android.os.PersistableBundle;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.RadioAccessFamily;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.telephony.satellite.SatelliteManager;
|
||||
import android.telephony.satellite.SatelliteModemStateCallback;
|
||||
import android.telephony.satellite.SelectedNbIotSatelliteSubscriptionCallback;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.lifecycle.DefaultLifecycleObserver;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.network.CarrierConfigCache;
|
||||
import com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants;
|
||||
import com.android.settings.network.telephony.mode.NetworkModes;
|
||||
|
||||
/**
|
||||
* Preference controller for "Preferred network mode"
|
||||
*/
|
||||
public class PreferredNetworkModePreferenceController extends BasePreferenceController
|
||||
implements ListPreference.OnPreferenceChangeListener {
|
||||
implements ListPreference.OnPreferenceChangeListener, DefaultLifecycleObserver {
|
||||
private static final String TAG = "PrefNetworkModeCtrl";
|
||||
|
||||
private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
private CarrierConfigCache mCarrierConfigCache;
|
||||
private TelephonyManager mTelephonyManager;
|
||||
private boolean mIsGlobalCdma;
|
||||
private SatelliteManager mSatelliteManager;
|
||||
private Preference mPreference;
|
||||
private boolean mIsSatelliteSessionStarted = false;
|
||||
private boolean mIsCurrentSubscriptionForSatellite = false;
|
||||
|
||||
@VisibleForTesting
|
||||
final SelectedNbIotSatelliteSubscriptionCallback mSelectedNbIotSatelliteSubscriptionCallback =
|
||||
new SelectedNbIotSatelliteSubscriptionCallback() {
|
||||
@Override
|
||||
public void onSelectedNbIotSatelliteSubscriptionChanged(int selectedSubId) {
|
||||
mIsCurrentSubscriptionForSatellite = selectedSubId == mSubId;
|
||||
updateState(mPreference);
|
||||
}
|
||||
};
|
||||
|
||||
@VisibleForTesting
|
||||
final SatelliteModemStateCallback mSatelliteModemStateCallback =
|
||||
new SatelliteModemStateCallback() {
|
||||
@Override
|
||||
public void onSatelliteModemStateChanged(int state) {
|
||||
switch (state) {
|
||||
case SatelliteManager.SATELLITE_MODEM_STATE_OFF:
|
||||
case SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE:
|
||||
case SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN:
|
||||
if (mIsSatelliteSessionStarted) {
|
||||
mIsSatelliteSessionStarted = false;
|
||||
updateState(mPreference);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (!mIsSatelliteSessionStarted) {
|
||||
mIsSatelliteSessionStarted = true;
|
||||
updateState(mPreference);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public PreferredNetworkModePreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
mCarrierConfigCache = CarrierConfigCache.getInstance(context);
|
||||
mSatelliteManager = context.getSystemService(SatelliteManager.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -57,9 +105,19 @@ public class PreferredNetworkModePreferenceController extends BasePreferenceCont
|
||||
? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreference = screen.findPreference(getPreferenceKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
if (preference == null) {
|
||||
return;
|
||||
}
|
||||
super.updateState(preference);
|
||||
preference.setEnabled(!(mIsCurrentSubscriptionForSatellite && mIsSatelliteSessionStarted));
|
||||
final ListPreference listPreference = (ListPreference) preference;
|
||||
final int networkMode = getPreferredNetworkMode();
|
||||
listPreference.setValue(Integer.toString(networkMode));
|
||||
@@ -72,11 +130,11 @@ public class PreferredNetworkModePreferenceController extends BasePreferenceCont
|
||||
|
||||
mTelephonyManager.setAllowedNetworkTypesForReason(
|
||||
TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER,
|
||||
MobileNetworkUtils.getRafFromNetworkType(newPreferredNetworkMode));
|
||||
RadioAccessFamily.getRafFromNetworkType(newPreferredNetworkMode));
|
||||
|
||||
final ListPreference listPreference = (ListPreference) preference;
|
||||
listPreference.setSummary(getPreferredNetworkModeSummaryResId(newPreferredNetworkMode));
|
||||
return true;
|
||||
final ListPreference listPreference = (ListPreference) preference;
|
||||
listPreference.setSummary(getPreferredNetworkModeSummaryResId(newPreferredNetworkMode));
|
||||
return true;
|
||||
}
|
||||
|
||||
public void init(int subId) {
|
||||
@@ -89,57 +147,89 @@ public class PreferredNetworkModePreferenceController extends BasePreferenceCont
|
||||
&& carrierConfig.getBoolean(CarrierConfigManager.KEY_SHOW_CDMA_CHOICES_BOOL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(@NonNull LifecycleOwner owner) {
|
||||
if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) {
|
||||
if (mSatelliteManager != null) {
|
||||
try {
|
||||
mSatelliteManager.registerForModemStateChanged(
|
||||
mContext.getMainExecutor(), mSatelliteModemStateCallback);
|
||||
mSatelliteManager.registerForSelectedNbIotSatelliteSubscriptionChanged(
|
||||
mContext.getMainExecutor(),
|
||||
mSelectedNbIotSatelliteSubscriptionCallback);
|
||||
} catch (IllegalStateException e) {
|
||||
Log.w(TAG, "IllegalStateException : " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop(@NonNull LifecycleOwner owner) {
|
||||
if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) {
|
||||
if (mSatelliteManager != null) {
|
||||
try {
|
||||
mSatelliteManager.unregisterForModemStateChanged(mSatelliteModemStateCallback);
|
||||
mSatelliteManager.unregisterForSelectedNbIotSatelliteSubscriptionChanged(
|
||||
mSelectedNbIotSatelliteSubscriptionCallback);
|
||||
} catch (IllegalStateException e) {
|
||||
Log.w(TAG, "IllegalStateException : " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int getPreferredNetworkMode() {
|
||||
if (mTelephonyManager == null) {
|
||||
Log.w(TAG, "TelephonyManager is null");
|
||||
return TelephonyManagerConstants.NETWORK_MODE_UNKNOWN;
|
||||
return NetworkModes.NETWORK_MODE_UNKNOWN;
|
||||
}
|
||||
return MobileNetworkUtils.getNetworkTypeFromRaf(
|
||||
return RadioAccessFamily.getNetworkTypeFromRaf(
|
||||
(int) mTelephonyManager.getAllowedNetworkTypesForReason(
|
||||
TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER));
|
||||
}
|
||||
|
||||
private int getPreferredNetworkModeSummaryResId(int NetworkMode) {
|
||||
switch (NetworkMode) {
|
||||
case TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA:
|
||||
private int getPreferredNetworkModeSummaryResId(int networkMode) {
|
||||
switch (networkMode) {
|
||||
case TelephonyManager.NETWORK_MODE_TDSCDMA_GSM_WCDMA:
|
||||
return R.string.preferred_network_mode_tdscdma_gsm_wcdma_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_GSM:
|
||||
case TelephonyManager.NETWORK_MODE_TDSCDMA_GSM:
|
||||
return R.string.preferred_network_mode_tdscdma_gsm_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_WCDMA_PREF:
|
||||
case TelephonyManager.NETWORK_MODE_WCDMA_PREF:
|
||||
return R.string.preferred_network_mode_wcdma_perf_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_GSM_ONLY:
|
||||
case TelephonyManager.NETWORK_MODE_GSM_ONLY:
|
||||
return R.string.preferred_network_mode_gsm_only_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_TDSCDMA_WCDMA:
|
||||
return R.string.preferred_network_mode_tdscdma_wcdma_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_WCDMA_ONLY:
|
||||
case TelephonyManager.NETWORK_MODE_WCDMA_ONLY:
|
||||
return R.string.preferred_network_mode_wcdma_only_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_GSM_UMTS:
|
||||
case TelephonyManager.NETWORK_MODE_GSM_UMTS:
|
||||
return R.string.preferred_network_mode_gsm_wcdma_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_CDMA_EVDO:
|
||||
case TelephonyManager.NETWORK_MODE_CDMA_EVDO:
|
||||
return mTelephonyManager.isLteCdmaEvdoGsmWcdmaEnabled()
|
||||
? R.string.preferred_network_mode_cdma_summary
|
||||
: R.string.preferred_network_mode_cdma_evdo_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_CDMA_NO_EVDO:
|
||||
case TelephonyManager.NETWORK_MODE_CDMA_NO_EVDO:
|
||||
return R.string.preferred_network_mode_cdma_only_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_EVDO_NO_CDMA:
|
||||
case TelephonyManager.NETWORK_MODE_EVDO_NO_CDMA:
|
||||
return R.string.preferred_network_mode_evdo_only_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA:
|
||||
return R.string.preferred_network_mode_lte_tdscdma_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_ONLY:
|
||||
case TelephonyManager.NETWORK_MODE_LTE_ONLY:
|
||||
return R.string.preferred_network_mode_lte_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM:
|
||||
case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM:
|
||||
return R.string.preferred_network_mode_lte_tdscdma_gsm_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA:
|
||||
return R.string.preferred_network_mode_lte_tdscdma_gsm_wcdma_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_GSM_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA:
|
||||
return R.string.preferred_network_mode_lte_gsm_wcdma_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO:
|
||||
case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO:
|
||||
return R.string.preferred_network_mode_lte_cdma_evdo_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_ONLY:
|
||||
case TelephonyManager.NETWORK_MODE_TDSCDMA_ONLY:
|
||||
return R.string.preferred_network_mode_tdscdma_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
|
||||
return R.string.preferred_network_mode_lte_tdscdma_cdma_evdo_gsm_wcdma_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
|
||||
if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA
|
||||
|| mIsGlobalCdma
|
||||
|| MobileNetworkUtils.isWorldMode(mContext, mSubId)) {
|
||||
@@ -147,35 +237,35 @@ public class PreferredNetworkModePreferenceController extends BasePreferenceCont
|
||||
} else {
|
||||
return R.string.preferred_network_mode_lte_summary;
|
||||
}
|
||||
case TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
|
||||
return R.string.preferred_network_mode_tdscdma_cdma_evdo_gsm_wcdma_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_GLOBAL:
|
||||
case TelephonyManager.NETWORK_MODE_GLOBAL:
|
||||
return R.string.preferred_network_mode_cdma_evdo_gsm_wcdma_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_WCDMA:
|
||||
return R.string.preferred_network_mode_lte_tdscdma_wcdma_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_LTE_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_LTE_WCDMA:
|
||||
return R.string.preferred_network_mode_lte_wcdma_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_ONLY:
|
||||
case TelephonyManager.NETWORK_MODE_NR_ONLY:
|
||||
return R.string.preferred_network_mode_nr_only_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE:
|
||||
case TelephonyManager.NETWORK_MODE_NR_LTE:
|
||||
return R.string.preferred_network_mode_nr_lte_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO:
|
||||
case TelephonyManager.NETWORK_MODE_NR_LTE_CDMA_EVDO:
|
||||
return R.string.preferred_network_mode_nr_lte_cdma_evdo_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_NR_LTE_GSM_WCDMA:
|
||||
return R.string.preferred_network_mode_nr_lte_gsm_wcdma_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA:
|
||||
return R.string.preferred_network_mode_global_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_NR_LTE_WCDMA:
|
||||
return R.string.preferred_network_mode_nr_lte_wcdma_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_NR_LTE_TDSCDMA:
|
||||
return R.string.preferred_network_mode_nr_lte_tdscdma_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM:
|
||||
case TelephonyManager.NETWORK_MODE_NR_LTE_TDSCDMA_GSM:
|
||||
return R.string.preferred_network_mode_nr_lte_tdscdma_gsm_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA:
|
||||
return R.string.preferred_network_mode_nr_lte_tdscdma_wcdma_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA:
|
||||
return R.string.preferred_network_mode_nr_lte_tdscdma_gsm_wcdma_summary;
|
||||
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
|
||||
case TelephonyManager.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
|
||||
return R.string.preferred_network_mode_nr_lte_tdscdma_cdma_evdo_gsm_wcdma_summary;
|
||||
default:
|
||||
return R.string.preferred_network_mode_global_summary;
|
||||
|
||||
@@ -56,20 +56,26 @@ import java.util.Set;
|
||||
/** Handle Satellite Setting Preference Layout. */
|
||||
public class SatelliteSetting extends RestrictedDashboardFragment {
|
||||
private static final String TAG = "SatelliteSetting";
|
||||
public static final String PREF_KEY_ABOUT_SATELLITE_MESSAGING = "key_about_satellite_messaging";
|
||||
public static final String PREF_KEY_CATEGORY_YOUR_SATELLITE_PLAN =
|
||||
private static final String PREF_KEY_ABOUT_SATELLITE_MESSAGING =
|
||||
"key_about_satellite_messaging";
|
||||
private static final String PREF_KEY_CATEGORY_YOUR_SATELLITE_PLAN =
|
||||
"key_category_your_satellite_plan";
|
||||
public static final String PREF_KEY_YOUR_SATELLITE_PLAN = "key_your_satellite_plan";
|
||||
public static final String PREF_KEY_CATEGORY_HOW_IT_WORKS = "key_category_how_it_works";
|
||||
private static final String PREF_KEY_YOUR_SATELLITE_PLAN = "key_your_satellite_plan";
|
||||
private static final String PREF_KEY_CATEGORY_HOW_IT_WORKS = "key_category_how_it_works";
|
||||
private static final String PREF_KEY_YOUR_SATELLITE_DATA_PLAN = "key_your_satellite_data_plan";
|
||||
private static final String PREF_KEY_CATEGORY_ABOUT_SATELLITE = "key_category_about_satellite";
|
||||
private static final String KEY_FOOTER_PREFERENCE = "satellite_setting_extra_info_footer_pref";
|
||||
public static final String SUB_ID = "sub_id";
|
||||
|
||||
static final String SUB_ID = "sub_id";
|
||||
static final String EXTRA_IS_SERVICE_DATA_TYPE = "is_service_data_type";
|
||||
|
||||
private Activity mActivity;
|
||||
private TelephonyManager mTelephonymanager;
|
||||
private CarrierConfigManager mCarrierConfigManager;
|
||||
private SatelliteManager mSatelliteManager;
|
||||
private PersistableBundle mConfigBundle;
|
||||
private int mSubId;
|
||||
private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
private String mSimOperatorName = "";
|
||||
private boolean mIsServiceDataType = false;
|
||||
|
||||
public SatelliteSetting() {
|
||||
super(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
|
||||
@@ -111,13 +117,19 @@ public class SatelliteSetting extends RestrictedDashboardFragment {
|
||||
return;
|
||||
}
|
||||
|
||||
mTelephonymanager = mActivity.getSystemService(TelephonyManager.class);
|
||||
mIsServiceDataType = getIntent().getBooleanExtra(EXTRA_IS_SERVICE_DATA_TYPE, false);
|
||||
mSimOperatorName = getSystemService(TelephonyManager.class).getSimOperatorName(mSubId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
updateDynamicPreferenceViews();
|
||||
boolean isSatelliteEligible = isSatelliteEligible();
|
||||
updateTitle();
|
||||
updateAboutSatelliteContent();
|
||||
updateMobilePlan(isSatelliteEligible);
|
||||
updateHowItWorksContent(isSatelliteEligible);
|
||||
updateFooterContent();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -130,31 +142,45 @@ public class SatelliteSetting extends RestrictedDashboardFragment {
|
||||
return R.xml.satellite_setting;
|
||||
}
|
||||
|
||||
private void updateDynamicPreferenceViews() {
|
||||
String operatorName = mTelephonymanager.getSimOperatorName(mSubId);
|
||||
boolean isSatelliteEligible = isSatelliteEligible();
|
||||
private void updateTitle() {
|
||||
getActivity().setTitle(getSubjectString());
|
||||
}
|
||||
|
||||
// About satellite content
|
||||
private void updateAboutSatelliteContent() {
|
||||
Preference categoryTitle = findPreference(PREF_KEY_CATEGORY_ABOUT_SATELLITE);
|
||||
categoryTitle.setTitle(
|
||||
getString(R.string.category_name_about_satellite_messaging,
|
||||
getDescriptionString()));
|
||||
|
||||
// About satellite messaging
|
||||
Preference preference = findPreference(PREF_KEY_ABOUT_SATELLITE_MESSAGING);
|
||||
preference.setTitle(
|
||||
getResources().getString(R.string.title_about_satellite_setting, operatorName));
|
||||
getResources().getString(R.string.title_about_satellite_setting, mSimOperatorName));
|
||||
}
|
||||
|
||||
private void updateMobilePlan(boolean isSatelliteEligible) {
|
||||
// Your mobile plan
|
||||
PreferenceCategory prefCategory = findPreference(PREF_KEY_CATEGORY_YOUR_SATELLITE_PLAN);
|
||||
prefCategory.setTitle(getResources().getString(R.string.category_title_your_satellite_plan,
|
||||
operatorName));
|
||||
mSimOperatorName));
|
||||
Preference messagingPreference = findPreference(PREF_KEY_YOUR_SATELLITE_PLAN);
|
||||
|
||||
preference = findPreference(PREF_KEY_YOUR_SATELLITE_PLAN);
|
||||
Drawable icon;
|
||||
Drawable icon = getContext().getDrawable(R.drawable.ic_check_circle_24px);
|
||||
if (isSatelliteEligible) {
|
||||
/* In case satellite is allowed by carrier's entitlement server, the page will show
|
||||
the check icon with guidance that satellite is included in user's mobile plan */
|
||||
preference.setTitle(R.string.title_have_satellite_plan);
|
||||
icon = getContext().getDrawable(R.drawable.ic_check_circle_24px);
|
||||
messagingPreference.setTitle(R.string.title_have_satellite_plan);
|
||||
if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) {
|
||||
Preference connectivityPreference = findPreference(
|
||||
PREF_KEY_YOUR_SATELLITE_DATA_PLAN);
|
||||
connectivityPreference.setTitle(R.string.title_have_satellite_data_plan);
|
||||
connectivityPreference.setIcon(icon);
|
||||
connectivityPreference.setVisible(true);
|
||||
}
|
||||
} else {
|
||||
/* Or, it will show the blocked icon with the guidance that satellite is not included
|
||||
in user's mobile plan */
|
||||
preference.setTitle(R.string.title_no_satellite_plan);
|
||||
messagingPreference.setTitle(R.string.title_no_satellite_plan);
|
||||
/* And, the link url provides more information via web page will be shown */
|
||||
SpannableString spannable = new SpannableString(
|
||||
getResources().getString(R.string.summary_add_satellite_setting));
|
||||
@@ -162,9 +188,9 @@ public class SatelliteSetting extends RestrictedDashboardFragment {
|
||||
Spanned.SPAN_INCLUSIVE_INCLUSIVE);
|
||||
spannable.setSpan(new StyleSpan(Typeface.BOLD), 0, spannable.length(),
|
||||
Spanned.SPAN_INCLUSIVE_INCLUSIVE);
|
||||
preference.setSummary(spannable);
|
||||
messagingPreference.setSummary(spannable);
|
||||
/* The link will lead users to a guide page */
|
||||
preference.setOnPreferenceClickListener(pref -> {
|
||||
messagingPreference.setOnPreferenceClickListener(pref -> {
|
||||
String url = readSatelliteMoreInfoString(mSubId);
|
||||
if (!url.isEmpty()) {
|
||||
Uri uri = Uri.parse(url);
|
||||
@@ -173,11 +199,13 @@ public class SatelliteSetting extends RestrictedDashboardFragment {
|
||||
}
|
||||
return true;
|
||||
});
|
||||
icon = getResources().getDrawable(R.drawable.ic_block_24px);
|
||||
icon = getResources().getDrawable(R.drawable.ic_block_24px, null);
|
||||
}
|
||||
icon.setTintList(Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary));
|
||||
preference.setIcon(icon);
|
||||
messagingPreference.setIcon(icon);
|
||||
}
|
||||
|
||||
private void updateHowItWorksContent(boolean isSatelliteEligible) {
|
||||
/* Composes "How it works" section, which guides how users can use satellite messaging, when
|
||||
satellite messaging is included in user's mobile plan, or it'll will be grey out. */
|
||||
if (!isSatelliteEligible) {
|
||||
@@ -185,29 +213,32 @@ public class SatelliteSetting extends RestrictedDashboardFragment {
|
||||
category.setEnabled(false);
|
||||
category.setShouldDisableView(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateFooterContent() {
|
||||
// More about satellite messaging
|
||||
FooterPreference footerPreference = findPreference(KEY_FOOTER_PREFERENCE);
|
||||
if (footerPreference != null) {
|
||||
footerPreference.setSummary(
|
||||
getResources().getString(R.string.satellite_setting_summary_more_information,
|
||||
operatorName));
|
||||
getSubjectString(), mSimOperatorName));
|
||||
|
||||
final String[] link = new String[1];
|
||||
link[0] = readSatelliteMoreInfoString(mSubId);
|
||||
footerPreference.setLearnMoreAction(view -> {
|
||||
if (!link[0].isEmpty()) {
|
||||
Intent helpIntent = HelpUtils.getHelpIntent(mActivity, link[0],
|
||||
this.getClass().getName());
|
||||
if (helpIntent != null) {
|
||||
mActivity.startActivityForResult(helpIntent, /*requestCode=*/ 0);
|
||||
if (link[0] != null && !link[0].isEmpty()) {
|
||||
footerPreference.setLearnMoreAction(view -> {
|
||||
if (!link[0].isEmpty()) {
|
||||
Intent helpIntent = HelpUtils.getHelpIntent(mActivity, link[0],
|
||||
this.getClass().getName());
|
||||
if (helpIntent != null) {
|
||||
mActivity.startActivityForResult(helpIntent, /*requestCode=*/ 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
footerPreference.setLearnMoreText(
|
||||
getResources().getString(R.string.more_about_satellite_messaging));
|
||||
});
|
||||
|
||||
// TODO : b/320467418 add rounded rectangle border line to footer preference.
|
||||
footerPreference.setLearnMoreText(
|
||||
getString(R.string.more_about_satellite_messaging, getDescriptionString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,6 +276,32 @@ public class SatelliteSetting extends RestrictedDashboardFragment {
|
||||
return bundle.getBoolean(KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, false);
|
||||
}
|
||||
|
||||
// This is for a word which first letter is uppercase. e.g. Satellite messaging.
|
||||
private String getSubjectString() {
|
||||
int result;
|
||||
if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) {
|
||||
result = mIsServiceDataType
|
||||
? R.string.title_satellite_setting_connectivity
|
||||
: R.string.satellite_setting_title;
|
||||
} else {
|
||||
result = R.string.satellite_setting_title;
|
||||
}
|
||||
return getString(result);
|
||||
}
|
||||
|
||||
// This is for a word without uppercase letter. e.g. satellite messaging.
|
||||
private String getDescriptionString() {
|
||||
int result;
|
||||
if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) {
|
||||
result = mIsServiceDataType
|
||||
? R.string.description_satellite_setting_connectivity
|
||||
: R.string.description_satellite_setting_messaging;
|
||||
} else {
|
||||
result = R.string.satellite_setting_title;
|
||||
}
|
||||
return getString(result);
|
||||
}
|
||||
|
||||
private static void loge(String message) {
|
||||
Log.e(TAG, message);
|
||||
}
|
||||
|
||||
@@ -16,16 +16,25 @@
|
||||
|
||||
package com.android.settings.network.telephony;
|
||||
|
||||
import static android.telephony.NetworkRegistrationInfo.SERVICE_TYPE_DATA;
|
||||
import static android.telephony.NetworkRegistrationInfo.SERVICE_TYPE_SMS;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.PersistableBundle;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.TelephonyCallback;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.telephony.satellite.NtnSignalStrength;
|
||||
import android.telephony.satellite.SatelliteManager;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.lifecycle.DefaultLifecycleObserver;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
@@ -33,28 +42,34 @@ import com.android.internal.telephony.flags.Flags;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.network.CarrierConfigCache;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnStart;
|
||||
import com.android.settingslib.core.lifecycle.events.OnStop;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Preference controller for "Satellite Setting"
|
||||
*/
|
||||
public class SatelliteSettingPreferenceController extends
|
||||
TelephonyBasePreferenceController implements LifecycleObserver, OnStart, OnStop {
|
||||
|
||||
TelephonyBasePreferenceController implements DefaultLifecycleObserver {
|
||||
private static final String TAG = "SatelliteSettingPreferenceController";
|
||||
|
||||
CarrierConfigCache mCarrierConfigCache;
|
||||
SatelliteManager mSatelliteManager;
|
||||
@Nullable private Boolean mIsSatelliteEligible = null;
|
||||
private TelephonyManager mTelephonyManager = null;
|
||||
@VisibleForTesting
|
||||
final CarrierRoamingNtnModeCallback mCarrierRoamingNtnModeCallback =
|
||||
new CarrierRoamingNtnModeCallback();
|
||||
|
||||
@Nullable
|
||||
private Boolean mIsSatelliteEligible = null;
|
||||
private boolean mIsServiceDataType = false;
|
||||
|
||||
public SatelliteSettingPreferenceController(@NonNull Context context, @NonNull String key) {
|
||||
super(context, key);
|
||||
mCarrierConfigCache = CarrierConfigCache.getInstance(context);
|
||||
mSatelliteManager = context.getSystemService(SatelliteManager.class);
|
||||
mTelephonyManager = context.getSystemService(TelephonyManager.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -76,22 +91,31 @@ public class SatelliteSettingPreferenceController extends
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
public void onResume(@NonNull LifecycleOwner owner) {
|
||||
if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) {
|
||||
mTelephonyManager.registerTelephonyCallback(mContext.getMainExecutor(),
|
||||
mCarrierRoamingNtnModeCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
public void onPause(@NonNull LifecycleOwner owner) {
|
||||
if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) {
|
||||
mTelephonyManager.unregisterTelephonyCallback(mCarrierRoamingNtnModeCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(@NonNull PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
updateState(screen.findPreference(getPreferenceKey()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(@Nullable Preference preference) {
|
||||
super.updateState(preference);
|
||||
if (preference != null) {
|
||||
mCarrierRoamingNtnModeCallback.mPref = preference;
|
||||
updateSummary(preference);
|
||||
}
|
||||
}
|
||||
@@ -105,6 +129,7 @@ public class SatelliteSettingPreferenceController extends
|
||||
// This will setup the Home and Search affordance
|
||||
intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_AS_SUBSETTING, true);
|
||||
intent.putExtra(SatelliteSetting.SUB_ID, mSubId);
|
||||
intent.putExtra(SatelliteSetting.EXTRA_IS_SERVICE_DATA_TYPE, mIsServiceDataType);
|
||||
mContext.startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
@@ -114,14 +139,20 @@ public class SatelliteSettingPreferenceController extends
|
||||
|
||||
/**
|
||||
* Set subId for Satellite Settings page.
|
||||
*
|
||||
* @param subId subscription ID.
|
||||
*/
|
||||
public void init(int subId) {
|
||||
logd("init(), subId=" + subId);
|
||||
mSubId = subId;
|
||||
mTelephonyManager = mTelephonyManager.createForSubscriptionId(subId);
|
||||
}
|
||||
|
||||
private void updateSummary(Preference preference) {
|
||||
if (mSatelliteManager == null) {
|
||||
logd("updateSummary - no SatelliteManager");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Set<Integer> restrictionReason =
|
||||
mSatelliteManager.getAttachRestrictionReasonsForCarrier(mSubId);
|
||||
@@ -147,4 +178,46 @@ public class SatelliteSettingPreferenceController extends
|
||||
private static void loge(String message) {
|
||||
Log.e(TAG, message);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
class CarrierRoamingNtnModeCallback extends TelephonyCallback implements
|
||||
TelephonyCallback.CarrierRoamingNtnModeListener {
|
||||
Preference mPref = null;
|
||||
|
||||
@Override
|
||||
public void onCarrierRoamingNtnAvailableServicesChanged(int[] availableServices) {
|
||||
CarrierRoamingNtnModeListener.super.onCarrierRoamingNtnAvailableServicesChanged(
|
||||
availableServices);
|
||||
List<Integer> availableServicesList = Arrays.stream(availableServices).boxed().toList();
|
||||
boolean isSmsAvailable = availableServicesList.contains(SERVICE_TYPE_SMS);
|
||||
boolean isDataAvailable = availableServicesList.contains(SERVICE_TYPE_DATA);
|
||||
logd("isSmsAvailable : " + isSmsAvailable
|
||||
+ " / isDataAvailable " + isDataAvailable);
|
||||
if (mPref == null) {
|
||||
logd("Satellite preference is not initialized yet");
|
||||
return;
|
||||
}
|
||||
if (isDataAvailable) {
|
||||
mIsServiceDataType = true;
|
||||
mPref.setTitle(R.string.title_satellite_setting_connectivity);
|
||||
} else if (isSmsAvailable) {
|
||||
mPref.setTitle(R.string.satellite_setting_title);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCarrierRoamingNtnEligibleStateChanged(boolean eligible) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCarrierRoamingNtnModeChanged(boolean active) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCarrierRoamingNtnSignalStrengthChanged(NtnSignalStrength ntnSignalStrength) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.network.telephony;
|
||||
|
||||
import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL;
|
||||
import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ESOS_SUPPORTED_BOOL;
|
||||
import static android.telephony.NetworkRegistrationInfo.SERVICE_TYPE_DATA;
|
||||
import static android.telephony.NetworkRegistrationInfo.SERVICE_TYPE_SMS;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.PersistableBundle;
|
||||
import android.telephony.TelephonyCallback;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.telephony.satellite.NtnSignalStrength;
|
||||
import android.telephony.satellite.SatelliteManager;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.lifecycle.DefaultLifecycleObserver;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.flags.Flags;
|
||||
import com.android.settings.network.CarrierConfigCache;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/** Preference controller for Satellite functions in mobile network settings. */
|
||||
public class SatelliteSettingsPreferenceCategoryController
|
||||
extends TelephonyBasePreferenceController implements DefaultLifecycleObserver {
|
||||
private static final String TAG = "SatelliteSettingsPrefCategoryCon";
|
||||
|
||||
private CarrierConfigCache mCarrierConfigCache;
|
||||
private SatelliteManager mSatelliteManager;
|
||||
private PreferenceCategory mPreferenceCategory;
|
||||
private TelephonyManager mTelephonyManager;
|
||||
|
||||
@VisibleForTesting
|
||||
final CarrierRoamingNtnModeCallback mCarrierRoamingNtnModeCallback =
|
||||
new CarrierRoamingNtnModeCallback();
|
||||
|
||||
public SatelliteSettingsPreferenceCategoryController(Context context, String key) {
|
||||
super(context, key);
|
||||
mCarrierConfigCache = CarrierConfigCache.getInstance(context);
|
||||
mSatelliteManager = context.getSystemService(SatelliteManager.class);
|
||||
mTelephonyManager = context.getSystemService(TelephonyManager.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set subId for Satellite Settings category .
|
||||
*
|
||||
* @param subId subscription ID.
|
||||
*/
|
||||
public void init(int subId) {
|
||||
Log.d(TAG, "init(), subId=" + subId);
|
||||
mSubId = subId;
|
||||
mTelephonyManager = mTelephonyManager.createForSubscriptionId(subId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreferenceCategory = screen.findPreference(getPreferenceKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus(int subId) {
|
||||
if (!com.android.internal.telephony.flags.Flags.carrierEnabledSatelliteFlag()) {
|
||||
return UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
|
||||
if (mSatelliteManager == null) {
|
||||
return UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
|
||||
final PersistableBundle carrierConfig = mCarrierConfigCache.getConfigForSubId(subId);
|
||||
final boolean isSatelliteAttachSupported = carrierConfig.getBoolean(
|
||||
KEY_SATELLITE_ATTACH_SUPPORTED_BOOL);
|
||||
boolean isSatelliteSosSupported = false;
|
||||
if (Flags.satelliteOemSettingsUxMigration()) {
|
||||
isSatelliteSosSupported = carrierConfig.getBoolean(
|
||||
KEY_SATELLITE_ESOS_SUPPORTED_BOOL);
|
||||
}
|
||||
|
||||
return (isSatelliteAttachSupported || isSatelliteSosSupported)
|
||||
? AVAILABLE_UNSEARCHABLE : UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume(@NonNull LifecycleOwner owner) {
|
||||
if (Flags.satelliteOemSettingsUxMigration()) {
|
||||
mTelephonyManager.registerTelephonyCallback(mContext.getMainExecutor(),
|
||||
mCarrierRoamingNtnModeCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause(@NonNull LifecycleOwner owner) {
|
||||
if (Flags.satelliteOemSettingsUxMigration()) {
|
||||
mTelephonyManager.unregisterTelephonyCallback(mCarrierRoamingNtnModeCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
class CarrierRoamingNtnModeCallback extends TelephonyCallback implements
|
||||
TelephonyCallback.CarrierRoamingNtnModeListener {
|
||||
@Override
|
||||
public void onCarrierRoamingNtnAvailableServicesChanged(int[] availableServices) {
|
||||
CarrierRoamingNtnModeListener.super.onCarrierRoamingNtnAvailableServicesChanged(
|
||||
availableServices);
|
||||
List<Integer> availableServicesList = Arrays.stream(availableServices).boxed().toList();
|
||||
boolean isSmsAvailable = availableServicesList.contains(SERVICE_TYPE_SMS);
|
||||
boolean isDataAvailable = availableServicesList.contains(SERVICE_TYPE_DATA);
|
||||
Log.i(TAG, "isSmsAvailable : " + isSmsAvailable
|
||||
+ " / isDataAvailable " + isDataAvailable);
|
||||
if (mPreferenceCategory == null) {
|
||||
Log.d(TAG, "Satellite preference category is not initialized yet");
|
||||
return;
|
||||
}
|
||||
if (isDataAvailable) {
|
||||
mPreferenceCategory.setTitle(R.string.category_title_satellite_connectivity);
|
||||
} else if (isSmsAvailable) {
|
||||
mPreferenceCategory.setTitle(R.string.satellite_setting_title);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCarrierRoamingNtnEligibleStateChanged(boolean eligible) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCarrierRoamingNtnModeChanged(boolean active) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCarrierRoamingNtnSignalStrengthChanged(NtnSignalStrength ntnSignalStrength) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,188 +23,6 @@ import android.telephony.TelephonyManager;
|
||||
*/
|
||||
public class TelephonyConstants {
|
||||
|
||||
/**
|
||||
* Copied from {@link android.telephony.TelephonyManager}
|
||||
*/
|
||||
public static class TelephonyManagerConstants {
|
||||
|
||||
// Network modes are in turn copied from RILConstants
|
||||
// with one difference: NETWORK_MODE_CDMA is named NETWORK_MODE_CDMA_EVDO
|
||||
|
||||
public static final int NETWORK_MODE_UNKNOWN = -1;
|
||||
|
||||
/**
|
||||
* GSM, WCDMA (WCDMA preferred)
|
||||
*/
|
||||
public static final int NETWORK_MODE_WCDMA_PREF = 0;
|
||||
|
||||
/**
|
||||
* GSM only
|
||||
*/
|
||||
public static final int NETWORK_MODE_GSM_ONLY = 1;
|
||||
|
||||
/**
|
||||
* WCDMA only
|
||||
*/
|
||||
public static final int NETWORK_MODE_WCDMA_ONLY = 2;
|
||||
|
||||
/**
|
||||
* GSM, WCDMA (auto mode, according to PRL)
|
||||
*/
|
||||
public static final int NETWORK_MODE_GSM_UMTS = 3;
|
||||
|
||||
/**
|
||||
* CDMA and EvDo (auto mode, according to PRL)
|
||||
* this is NETWORK_MODE_CDMA in RILConstants.java
|
||||
*/
|
||||
public static final int NETWORK_MODE_CDMA_EVDO = 4;
|
||||
|
||||
/**
|
||||
* CDMA only
|
||||
*/
|
||||
public static final int NETWORK_MODE_CDMA_NO_EVDO = 5;
|
||||
|
||||
/**
|
||||
* EvDo only
|
||||
*/
|
||||
public static final int NETWORK_MODE_EVDO_NO_CDMA = 6;
|
||||
|
||||
/**
|
||||
* GSM, WCDMA, CDMA, and EvDo (auto mode, according to PRL)
|
||||
*/
|
||||
public static final int NETWORK_MODE_GLOBAL = 7;
|
||||
|
||||
/**
|
||||
* LTE, CDMA and EvDo
|
||||
*/
|
||||
public static final int NETWORK_MODE_LTE_CDMA_EVDO = 8;
|
||||
|
||||
/**
|
||||
* LTE, GSM and WCDMA
|
||||
*/
|
||||
public static final int NETWORK_MODE_LTE_GSM_WCDMA = 9;
|
||||
|
||||
/**
|
||||
* LTE, CDMA, EvDo, GSM, and WCDMA
|
||||
*/
|
||||
public static final int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA = 10;
|
||||
|
||||
/**
|
||||
* LTE only mode.
|
||||
*/
|
||||
public static final int NETWORK_MODE_LTE_ONLY = 11;
|
||||
|
||||
/**
|
||||
* LTE and WCDMA
|
||||
*/
|
||||
public static final int NETWORK_MODE_LTE_WCDMA = 12;
|
||||
|
||||
/**
|
||||
* TD-SCDMA only
|
||||
*/
|
||||
public static final int NETWORK_MODE_TDSCDMA_ONLY = 13;
|
||||
|
||||
/**
|
||||
* TD-SCDMA and WCDMA
|
||||
*/
|
||||
public static final int NETWORK_MODE_TDSCDMA_WCDMA = 14;
|
||||
|
||||
/**
|
||||
* LTE and TD-SCDMA
|
||||
*/
|
||||
public static final int NETWORK_MODE_LTE_TDSCDMA = 15;
|
||||
|
||||
/**
|
||||
* TD-SCDMA and GSM
|
||||
*/
|
||||
public static final int NETWORK_MODE_TDSCDMA_GSM = 16;
|
||||
|
||||
/**
|
||||
* TD-SCDMA, GSM and LTE
|
||||
*/
|
||||
public static final int NETWORK_MODE_LTE_TDSCDMA_GSM = 17;
|
||||
|
||||
/**
|
||||
* TD-SCDMA, GSM and WCDMA
|
||||
*/
|
||||
public static final int NETWORK_MODE_TDSCDMA_GSM_WCDMA = 18;
|
||||
|
||||
/**
|
||||
* LTE, TD-SCDMA and WCDMA
|
||||
*/
|
||||
public static final int NETWORK_MODE_LTE_TDSCDMA_WCDMA = 19;
|
||||
|
||||
/**
|
||||
* LTE, TD-SCDMA, GSM, and WCDMA
|
||||
*/
|
||||
public static final int NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA = 20;
|
||||
|
||||
/**
|
||||
* TD-SCDMA, CDMA, EVDO, GSM and WCDMA
|
||||
*/
|
||||
public static final int NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 21;
|
||||
|
||||
/**
|
||||
* LTE, TDCSDMA, CDMA, EVDO, GSM and WCDMA
|
||||
*/
|
||||
public static final int NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 22;
|
||||
|
||||
/**
|
||||
* NR 5G only mode
|
||||
*/
|
||||
public static final int NETWORK_MODE_NR_ONLY = 23;
|
||||
|
||||
/**
|
||||
* NR 5G, LTE
|
||||
*/
|
||||
public static final int NETWORK_MODE_NR_LTE = 24;
|
||||
|
||||
/**
|
||||
* NR 5G, LTE, CDMA and EvDo
|
||||
*/
|
||||
public static final int NETWORK_MODE_NR_LTE_CDMA_EVDO = 25;
|
||||
|
||||
/**
|
||||
* NR 5G, LTE, GSM and WCDMA
|
||||
*/
|
||||
public static final int NETWORK_MODE_NR_LTE_GSM_WCDMA = 26;
|
||||
|
||||
/**
|
||||
* NR 5G, LTE, CDMA, EvDo, GSM and WCDMA
|
||||
*/
|
||||
public static final int NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA = 27;
|
||||
|
||||
/**
|
||||
* NR 5G, LTE and WCDMA
|
||||
*/
|
||||
public static final int NETWORK_MODE_NR_LTE_WCDMA = 28;
|
||||
|
||||
/**
|
||||
* NR 5G, LTE and TDSCDMA
|
||||
*/
|
||||
public static final int NETWORK_MODE_NR_LTE_TDSCDMA = 29;
|
||||
|
||||
/**
|
||||
* NR 5G, LTE, TD-SCDMA and GSM
|
||||
*/
|
||||
public static final int NETWORK_MODE_NR_LTE_TDSCDMA_GSM = 30;
|
||||
|
||||
/**
|
||||
* NR 5G, LTE, TD-SCDMA, WCDMA
|
||||
*/
|
||||
public static final int NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA = 31;
|
||||
|
||||
/**
|
||||
* NR 5G, LTE, TD-SCDMA, GSM and WCDMA
|
||||
*/
|
||||
public static final int NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA = 32;
|
||||
|
||||
/**
|
||||
* NR 5G, LTE, TD-SCDMA, CDMA, EVDO, GSM and WCDMA
|
||||
*/
|
||||
public static final int NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 33;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copied from {@link android.telephony.RadioAccessFamily}
|
||||
*/
|
||||
|
||||
@@ -557,15 +557,17 @@ public class ToggleSubscriptionDialogActivity extends SubscriptionActionDialogAc
|
||||
Log.d(TAG, "Hardware does not support DSDS.");
|
||||
return false;
|
||||
}
|
||||
boolean isActiveSim = SubscriptionUtil.getActiveSubscriptions(
|
||||
boolean anyActiveSim = SubscriptionUtil.getActiveSubscriptions(
|
||||
mSubscriptionManager).size() > 0;
|
||||
if (isMultipleEnabledProfilesSupported() && isActiveSim) {
|
||||
if (isMultipleEnabledProfilesSupported() && anyActiveSim) {
|
||||
Log.d(TAG,
|
||||
"Device supports MEP and eSIM operation and eSIM profile is enabled."
|
||||
+ " DSDS condition satisfied.");
|
||||
return true;
|
||||
}
|
||||
boolean isRemovableSimEnabled = isRemovableSimEnabled();
|
||||
boolean isRemovableSimEnabled =
|
||||
SubscriptionUtil.getActiveSubscriptions(mSubscriptionManager).stream()
|
||||
.anyMatch(subInfo-> !subInfo.isEmbedded());
|
||||
if (mIsEsimOperation && isRemovableSimEnabled) {
|
||||
Log.d(TAG, "eSIM operation and removable SIM is enabled. DSDS condition satisfied.");
|
||||
return true;
|
||||
@@ -583,7 +585,7 @@ public class ToggleSubscriptionDialogActivity extends SubscriptionActionDialogAc
|
||||
}
|
||||
|
||||
private boolean isRemovableSimEnabled() {
|
||||
return new UiccSlotRepository(mTelMgr).anyRemovablePhysicalSimEnabled();
|
||||
return new UiccSlotRepository(mTelMgr).anyRemovablePhysicalSimSlotActiveAndInserted();
|
||||
}
|
||||
|
||||
private boolean isMultipleEnabledProfilesSupported() {
|
||||
|
||||
@@ -22,17 +22,17 @@ import android.util.Log
|
||||
|
||||
class UiccSlotRepository(private val telephonyManager: TelephonyManager?) {
|
||||
|
||||
/** Returns whether any removable physical sim is enabled. */
|
||||
fun anyRemovablePhysicalSimEnabled(): Boolean {
|
||||
/** Returns whether any removable physical sim slot is active and the sim is inserted. */
|
||||
fun anyRemovablePhysicalSimSlotActiveAndInserted(): Boolean {
|
||||
val result =
|
||||
telephonyManager?.uiccSlotsInfo?.any { uiccSlotInfo: UiccSlotInfo? ->
|
||||
uiccSlotInfo.isRemovablePhysicalSimEnabled()
|
||||
uiccSlotInfo.isRemovablePhysicalSimSlotActiveAndInserted()
|
||||
} ?: false
|
||||
Log.i(TAG, "anyRemovablePhysicalSimEnabled: $result")
|
||||
return result
|
||||
}
|
||||
|
||||
private fun UiccSlotInfo?.isRemovablePhysicalSimEnabled(): Boolean {
|
||||
private fun UiccSlotInfo?.isRemovablePhysicalSimSlotActiveAndInserted(): Boolean {
|
||||
return this != null &&
|
||||
isRemovable &&
|
||||
!isEuicc &&
|
||||
|
||||
@@ -44,12 +44,12 @@ constructor(
|
||||
context: Context,
|
||||
key: String,
|
||||
private val callStateRepository: CallStateRepository = CallStateRepository(context),
|
||||
private val videoCallingRepository: VideoCallingRepository = VideoCallingRepository(context),
|
||||
) : TogglePreferenceController(context, key), On4gLteUpdateListener {
|
||||
|
||||
private var subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID
|
||||
private var preference: TwoStatePreference? = null
|
||||
private var callingPreferenceCategoryController: CallingPreferenceCategoryController? = null
|
||||
private val repository = VideoCallingRepository(context)
|
||||
|
||||
private var videoCallEditable = false
|
||||
private var isInCall = false
|
||||
@@ -71,14 +71,18 @@ constructor(
|
||||
override fun displayPreference(screen: PreferenceScreen) {
|
||||
super.displayPreference(screen)
|
||||
preference = screen.findPreference(preferenceKey)
|
||||
Log.d(TAG, "init ui")
|
||||
preference?.isVisible = false
|
||||
callingPreferenceCategoryController?.updateChildVisible(preferenceKey, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) {
|
||||
repository.isVideoCallReadyFlow(subId).collectLatestWithLifecycle(viewLifecycleOwner) {
|
||||
isReady ->
|
||||
preference?.isVisible = isReady
|
||||
callingPreferenceCategoryController?.updateChildVisible(preferenceKey, isReady)
|
||||
}
|
||||
videoCallingRepository.isVideoCallReadyFlow(subId)
|
||||
.collectLatestWithLifecycle(viewLifecycleOwner) { isReady ->
|
||||
Log.d(TAG, "isVideoCallReadyFlow: update visible")
|
||||
preference?.isVisible = isReady
|
||||
callingPreferenceCategoryController?.updateChildVisible(preferenceKey, isReady)
|
||||
}
|
||||
callStateRepository.callStateFlow(subId).collectLatestWithLifecycle(viewLifecycleOwner) {
|
||||
callState ->
|
||||
isInCall = callState != TelephonyManager.CALL_STATE_IDLE
|
||||
@@ -129,10 +133,10 @@ constructor(
|
||||
|
||||
class VideoCallingSearchItem(private val context: Context) :
|
||||
MobileNetworkSettingsSearchItem {
|
||||
private val repository = VideoCallingRepository(context)
|
||||
private val videoCallingRepository = VideoCallingRepository(context)
|
||||
|
||||
private fun isAvailable(subId: Int): Boolean = runBlocking {
|
||||
repository.isVideoCallReadyFlow(subId).first()
|
||||
videoCallingRepository.isVideoCallReadyFlow(subId).first()
|
||||
}
|
||||
|
||||
override fun getSearchResult(subId: Int): MobileNetworkSettingsSearchResult? {
|
||||
|
||||
@@ -16,20 +16,20 @@
|
||||
|
||||
package com.android.settings.network.telephony.cdma;
|
||||
|
||||
import static com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants.NETWORK_MODE_LTE_GSM_WCDMA;
|
||||
import static com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA;
|
||||
import static com.android.settings.network.telephony.TelephonyConstants.TelephonyManagerConstants.NETWORK_MODE_UNKNOWN;
|
||||
import static android.telephony.TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA;
|
||||
import static android.telephony.TelephonyManager.NETWORK_MODE_NR_LTE_GSM_WCDMA;
|
||||
|
||||
import static com.android.settings.network.telephony.mode.NetworkModes.NETWORK_MODE_UNKNOWN;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.RadioAccessFamily;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.network.telephony.MobileNetworkUtils;
|
||||
|
||||
/**
|
||||
* Preference controller for "System Select"
|
||||
*/
|
||||
@@ -65,7 +65,7 @@ public class CdmaSystemSelectPreferenceController extends CdmaBasePreferenceCont
|
||||
}
|
||||
|
||||
final int settingsNetworkMode =
|
||||
hasTelephonyMgr ? MobileNetworkUtils.getNetworkTypeFromRaf(
|
||||
hasTelephonyMgr ? RadioAccessFamily.getNetworkTypeFromRaf(
|
||||
(int) mTelephonyManager.getAllowedNetworkTypesForReason(
|
||||
TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER))
|
||||
: NETWORK_MODE_UNKNOWN;
|
||||
|
||||
@@ -25,18 +25,22 @@ import android.telephony.CarrierConfigManager
|
||||
import android.telephony.ServiceState
|
||||
import android.telephony.SubscriptionManager
|
||||
import android.telephony.TelephonyManager
|
||||
import android.telephony.satellite.SatelliteManager
|
||||
import android.telephony.satellite.SatelliteModemStateCallback
|
||||
import android.telephony.satellite.SelectedNbIotSatelliteSubscriptionCallback
|
||||
import android.util.Log
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import com.android.settings.R
|
||||
import com.android.settings.Settings.NetworkSelectActivity
|
||||
import com.android.settings.flags.Flags
|
||||
import com.android.settings.network.CarrierConfigCache
|
||||
import com.android.settings.network.telephony.MobileNetworkUtils
|
||||
import com.android.settings.network.telephony.allowedNetworkTypesFlow
|
||||
@@ -46,8 +50,6 @@ import com.android.settingslib.spa.framework.compose.OverridableFlow
|
||||
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
|
||||
import com.android.settingslib.spa.widget.preference.SwitchPreference
|
||||
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
|
||||
import kotlin.properties.Delegates.notNull
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.delay
|
||||
@@ -59,6 +61,7 @@ import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
/**
|
||||
* Preference controller for "Auto Select Network"
|
||||
@@ -73,9 +76,14 @@ class AutoSelectPreferenceController @JvmOverloads constructor(
|
||||
private val getConfigForSubId: (subId: Int) -> PersistableBundle = { subId ->
|
||||
CarrierConfigCache.getInstance(context).getConfigForSubId(subId)
|
||||
},
|
||||
) : ComposePreferenceController(context, key) {
|
||||
) : ComposePreferenceController(context, key), DefaultLifecycleObserver {
|
||||
|
||||
private var isSatelliteSessionStarted = false
|
||||
private var isSelectedSubIdForSatellite = false
|
||||
|
||||
private lateinit var telephonyManager: TelephonyManager
|
||||
private val satelliteManager: SatelliteManager? =
|
||||
context.getSystemService(SatelliteManager::class.java)
|
||||
private val listeners = mutableListOf<OnNetworkSelectModeListener>()
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -83,6 +91,21 @@ class AutoSelectPreferenceController @JvmOverloads constructor(
|
||||
|
||||
private var subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID
|
||||
|
||||
val satelliteModemStateCallback = SatelliteModemStateCallback { state ->
|
||||
isSatelliteSessionStarted = when (state) {
|
||||
SatelliteManager.SATELLITE_MODEM_STATE_OFF,
|
||||
SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE,
|
||||
SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN -> false
|
||||
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
|
||||
val selectedNbIotSatelliteSubscriptionCallback =
|
||||
SelectedNbIotSatelliteSubscriptionCallback { selectedSubId ->
|
||||
isSelectedSubIdForSatellite = selectedSubId == subId
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialization based on given subscription id.
|
||||
*/
|
||||
@@ -90,7 +113,6 @@ class AutoSelectPreferenceController @JvmOverloads constructor(
|
||||
this.subId = subId
|
||||
telephonyManager = mContext.getSystemService(TelephonyManager::class.java)!!
|
||||
.createForSubscriptionId(subId)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
@@ -117,7 +139,10 @@ class AutoSelectPreferenceController @JvmOverloads constructor(
|
||||
SwitchPreference(object : SwitchPreferenceModel {
|
||||
override val title = stringResource(R.string.select_automatically)
|
||||
override val summary = { disallowedSummary }
|
||||
override val changeable = { disallowedSummary.isEmpty() }
|
||||
override val changeable = {
|
||||
disallowedSummary.isEmpty()
|
||||
&& !(isSatelliteSessionStarted && isSelectedSubIdForSatellite)
|
||||
}
|
||||
override val checked = { isAuto }
|
||||
override val onCheckedChange: (Boolean) -> Unit = { newChecked ->
|
||||
if (newChecked) {
|
||||
@@ -132,6 +157,38 @@ class AutoSelectPreferenceController @JvmOverloads constructor(
|
||||
})
|
||||
}
|
||||
|
||||
override fun onStart(owner: LifecycleOwner) {
|
||||
if (Flags.satelliteOemSettingsUxMigration()) {
|
||||
if (satelliteManager != null) {
|
||||
try {
|
||||
satelliteManager.registerForModemStateChanged(
|
||||
mContext.mainExecutor, satelliteModemStateCallback
|
||||
)
|
||||
satelliteManager.registerForSelectedNbIotSatelliteSubscriptionChanged(
|
||||
mContext.mainExecutor, selectedNbIotSatelliteSubscriptionCallback
|
||||
)
|
||||
} catch (e: IllegalStateException) {
|
||||
Log.w(TAG, "IllegalStateException $e")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStop(owner: LifecycleOwner) {
|
||||
if (Flags.satelliteOemSettingsUxMigration()) {
|
||||
if (satelliteManager != null) {
|
||||
try {
|
||||
satelliteManager.unregisterForModemStateChanged(satelliteModemStateCallback)
|
||||
satelliteManager.unregisterForSelectedNbIotSatelliteSubscriptionChanged(
|
||||
selectedNbIotSatelliteSubscriptionCallback
|
||||
)
|
||||
} catch (e: IllegalStateException) {
|
||||
Log.w(TAG, "IllegalStateException $e")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun getDisallowedSummary(serviceState: ServiceState): String =
|
||||
withContext(Dispatchers.Default) {
|
||||
if (!serviceState.roaming && onlyAutoSelectInHome()) {
|
||||
@@ -213,6 +270,8 @@ class AutoSelectPreferenceController @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "AutoSelectPreferenceController"
|
||||
|
||||
private val MINIMUM_DIALOG_TIME = 1.seconds
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.network.telephony.mode
|
||||
|
||||
import android.telephony.TelephonyManager
|
||||
import com.google.common.collect.ImmutableBiMap
|
||||
|
||||
/** Network mode related utilities. */
|
||||
object NetworkModes {
|
||||
const val NETWORK_MODE_UNKNOWN = -1
|
||||
|
||||
private val LteToNrNetworkModeMap =
|
||||
ImmutableBiMap.builder<Int, Int>()
|
||||
.put(TelephonyManager.NETWORK_MODE_LTE_ONLY, TelephonyManager.NETWORK_MODE_NR_LTE)
|
||||
.put(
|
||||
TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO,
|
||||
TelephonyManager.NETWORK_MODE_NR_LTE_CDMA_EVDO,
|
||||
)
|
||||
.put(
|
||||
TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA,
|
||||
TelephonyManager.NETWORK_MODE_NR_LTE_GSM_WCDMA,
|
||||
)
|
||||
.put(
|
||||
TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA,
|
||||
TelephonyManager.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA,
|
||||
)
|
||||
.put(
|
||||
TelephonyManager.NETWORK_MODE_LTE_WCDMA,
|
||||
TelephonyManager.NETWORK_MODE_NR_LTE_WCDMA,
|
||||
)
|
||||
.put(
|
||||
TelephonyManager.NETWORK_MODE_LTE_TDSCDMA,
|
||||
TelephonyManager.NETWORK_MODE_NR_LTE_TDSCDMA,
|
||||
)
|
||||
.put(
|
||||
TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM,
|
||||
TelephonyManager.NETWORK_MODE_NR_LTE_TDSCDMA_GSM,
|
||||
)
|
||||
.put(
|
||||
TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_WCDMA,
|
||||
TelephonyManager.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA,
|
||||
)
|
||||
.put(
|
||||
TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA,
|
||||
TelephonyManager.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA,
|
||||
)
|
||||
.put(
|
||||
TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA,
|
||||
TelephonyManager.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA,
|
||||
)
|
||||
.build()
|
||||
|
||||
/**
|
||||
* Transforms LTE network mode to 5G network mode.
|
||||
*
|
||||
* @param networkMode an LTE network mode without 5G.
|
||||
* @return the corresponding network mode with 5G.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun addNrToLteNetworkMode(networkMode: Int): Int =
|
||||
LteToNrNetworkModeMap.getOrElse(networkMode) { networkMode }
|
||||
|
||||
/**
|
||||
* Transforms NR5G network mode to LTE network mode.
|
||||
*
|
||||
* @param networkMode an 5G network mode.
|
||||
* @return the corresponding network mode without 5G.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun reduceNrToLteNetworkMode(networkMode: Int): Int =
|
||||
LteToNrNetworkModeMap.inverse().getOrElse(networkMode) { networkMode }
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.network.tether
|
||||
|
||||
import android.bluetooth.BluetoothAdapter
|
||||
import android.bluetooth.BluetoothPan
|
||||
import android.bluetooth.BluetoothProfile
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.TetheringManager
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import com.android.settings.R
|
||||
import com.android.settings.datausage.DataSaverBackend
|
||||
import com.android.settingslib.datastore.KeyValueStore
|
||||
import com.android.settingslib.datastore.KeyedDataObservable
|
||||
import com.android.settingslib.metadata.PreferenceAvailabilityProvider
|
||||
import com.android.settingslib.metadata.PreferenceLifecycleContext
|
||||
import com.android.settingslib.metadata.PreferenceLifecycleProvider
|
||||
import com.android.settingslib.metadata.ReadWritePermit
|
||||
import com.android.settingslib.metadata.SensitivityLevel
|
||||
import com.android.settingslib.metadata.SwitchPreference
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
// LINT.IfChange
|
||||
@Suppress("DEPRECATION")
|
||||
class BluetoothTetherSwitchPreference :
|
||||
SwitchPreference(KEY, R.string.bluetooth_tether_checkbox_text),
|
||||
PreferenceAvailabilityProvider,
|
||||
PreferenceLifecycleProvider {
|
||||
|
||||
private var tetherChangeReceiver: BroadcastReceiver? = null
|
||||
|
||||
override val summary: Int
|
||||
get() = R.string.bluetooth_tethering_subtext
|
||||
|
||||
override val keywords: Int
|
||||
get() = R.string.keywords_hotspot_tethering
|
||||
|
||||
override fun storage(context: Context): KeyValueStore = BluetoothTetherStore(context)
|
||||
|
||||
override fun isAvailable(context: Context): Boolean {
|
||||
BluetoothAdapter.getDefaultAdapter() ?: return false
|
||||
val tetheringManager = context.getSystemService(TetheringManager::class.java)
|
||||
val bluetoothRegexs = tetheringManager?.tetherableBluetoothRegexs
|
||||
return bluetoothRegexs?.isNotEmpty() == true
|
||||
}
|
||||
|
||||
override fun isEnabled(context: Context): Boolean {
|
||||
val adapter = BluetoothAdapter.getDefaultAdapter() ?: return false
|
||||
val btState = adapter.state
|
||||
/* TODO: when bluetooth is off, btstate will be `state_turning_on` -> `state_off` ->
|
||||
`state_turning_on` -> `state_on`, causing preference enable status incorrect. */
|
||||
when (btState) {
|
||||
BluetoothAdapter.STATE_TURNING_OFF,
|
||||
BluetoothAdapter.STATE_TURNING_ON -> return false
|
||||
else -> {}
|
||||
}
|
||||
val dataSaverBackend = DataSaverBackend(context)
|
||||
return !dataSaverBackend.isDataSaverEnabled
|
||||
}
|
||||
|
||||
override fun getReadPermit(context: Context, myUid: Int, callingUid: Int) =
|
||||
ReadWritePermit.ALLOW
|
||||
|
||||
override fun getWritePermit(context: Context, value: Boolean?, myUid: Int, callingUid: Int) =
|
||||
ReadWritePermit.ALLOW
|
||||
|
||||
override val sensitivityLevel: Int
|
||||
get() = SensitivityLevel.LOW_SENSITIVITY
|
||||
|
||||
override fun onCreate(context: PreferenceLifecycleContext) {
|
||||
val receiver =
|
||||
object : BroadcastReceiver() {
|
||||
override fun onReceive(content: Context, intent: Intent) {
|
||||
when (intent.action) {
|
||||
TetheringManager.ACTION_TETHER_STATE_CHANGED,
|
||||
Intent.ACTION_MEDIA_SHARED,
|
||||
Intent.ACTION_MEDIA_UNSHARED,
|
||||
BluetoothAdapter.ACTION_STATE_CHANGED,
|
||||
BluetoothPan.ACTION_TETHERING_STATE_CHANGED ->
|
||||
context.notifyPreferenceChange(KEY)
|
||||
}
|
||||
}
|
||||
}
|
||||
tetherChangeReceiver = receiver
|
||||
var filter = IntentFilter(TetheringManager.ACTION_TETHER_STATE_CHANGED)
|
||||
val intent = context.registerReceiver(receiver, filter)
|
||||
|
||||
filter = IntentFilter()
|
||||
filter.addAction(Intent.ACTION_MEDIA_SHARED)
|
||||
filter.addAction(Intent.ACTION_MEDIA_UNSHARED)
|
||||
filter.addDataScheme("file")
|
||||
context.registerReceiver(receiver, filter)
|
||||
|
||||
filter = IntentFilter()
|
||||
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED)
|
||||
filter.addAction(BluetoothPan.ACTION_TETHERING_STATE_CHANGED)
|
||||
context.registerReceiver(receiver, filter)
|
||||
}
|
||||
|
||||
override fun onDestroy(context: PreferenceLifecycleContext) {
|
||||
tetherChangeReceiver?.let {
|
||||
context.unregisterReceiver(it)
|
||||
tetherChangeReceiver = null
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private class BluetoothTetherStore(private val context: Context) :
|
||||
KeyedDataObservable<String>(), KeyValueStore {
|
||||
|
||||
val bluetoothPan = AtomicReference<BluetoothPan>()
|
||||
|
||||
override fun contains(key: String) = key == KEY
|
||||
|
||||
override fun <T : Any> getValue(key: String, valueType: Class<T>): T? {
|
||||
// TODO: support async operation in background thread
|
||||
val adapter = BluetoothAdapter.getDefaultAdapter() ?: return false as T
|
||||
if (bluetoothPan.get() == null) {
|
||||
val profileServiceListener: BluetoothProfile.ServiceListener =
|
||||
object : BluetoothProfile.ServiceListener {
|
||||
override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) {
|
||||
if (bluetoothPan.get() == null) {
|
||||
bluetoothPan.set(proxy as BluetoothPan)
|
||||
notifyChange(KEY, 0)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onServiceDisconnected(profile: Int) {
|
||||
/* Do nothing */
|
||||
}
|
||||
}
|
||||
// TODO: adapter.closeProfileProxy(bluetoothPan.get())
|
||||
adapter.getProfileProxy(
|
||||
context.applicationContext,
|
||||
profileServiceListener,
|
||||
BluetoothProfile.PAN,
|
||||
)
|
||||
}
|
||||
|
||||
val btState = adapter.state
|
||||
val pan = bluetoothPan.get()
|
||||
return ((btState == BluetoothAdapter.STATE_ON ||
|
||||
btState == BluetoothAdapter.STATE_TURNING_OFF) && pan != null && pan.isTetheringOn)
|
||||
as T?
|
||||
}
|
||||
|
||||
override fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?) {
|
||||
if (value == null) return
|
||||
val connectivityManager =
|
||||
context.getSystemService(ConnectivityManager::class.java) ?: return
|
||||
if (value as Boolean) {
|
||||
val handler by lazy { Handler(Looper.getMainLooper()) }
|
||||
val startTetheringCallback = OnStartTetheringCallback()
|
||||
fun startTethering() {
|
||||
connectivityManager.startTethering(
|
||||
ConnectivityManager.TETHERING_BLUETOOTH,
|
||||
true,
|
||||
startTetheringCallback,
|
||||
handler,
|
||||
)
|
||||
}
|
||||
|
||||
val adapter = BluetoothAdapter.getDefaultAdapter()
|
||||
if (adapter.state == BluetoothAdapter.STATE_OFF) {
|
||||
adapter.enable()
|
||||
val filter = IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)
|
||||
val tetherChangeReceiver =
|
||||
object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
if (
|
||||
intent.getIntExtra(
|
||||
BluetoothAdapter.EXTRA_STATE,
|
||||
BluetoothAdapter.ERROR,
|
||||
) == BluetoothAdapter.STATE_ON
|
||||
) {
|
||||
startTethering()
|
||||
context.unregisterReceiver(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
val intent = context.registerReceiver(tetherChangeReceiver, filter)
|
||||
if (intent != null) tetherChangeReceiver.onReceive(context, intent)
|
||||
} else {
|
||||
startTethering()
|
||||
}
|
||||
} else {
|
||||
connectivityManager.stopTethering(ConnectivityManager.TETHERING_BLUETOOTH)
|
||||
}
|
||||
}
|
||||
|
||||
private inner class OnStartTetheringCallback :
|
||||
ConnectivityManager.OnStartTetheringCallback() {
|
||||
override fun onTetheringStarted() {
|
||||
notifyChange(KEY, 0)
|
||||
}
|
||||
|
||||
override fun onTetheringFailed() {
|
||||
notifyChange(KEY, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val KEY = "enable_bluetooth_tethering"
|
||||
}
|
||||
}
|
||||
// LINT.ThenChange(TetherSettings.java)
|
||||
87
src/com/android/settings/network/tether/TetherScreen.kt
Normal file
87
src/com/android/settings/network/tether/TetherScreen.kt
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.network.tether
|
||||
|
||||
import android.content.Context
|
||||
import android.net.TetheringManager
|
||||
import android.os.UserManager
|
||||
import com.android.settings.PreferenceRestrictionMixin
|
||||
import com.android.settings.R
|
||||
import com.android.settings.Settings.TetherSettingsActivity
|
||||
import com.android.settings.datausage.DataSaverMainSwitchPreference
|
||||
import com.android.settings.flags.Flags
|
||||
import com.android.settings.network.TetherPreferenceController
|
||||
import com.android.settings.utils.makeLaunchIntent
|
||||
import com.android.settings.wifi.tether.WifiHotspotSwitchPreference
|
||||
import com.android.settingslib.TetherUtil
|
||||
import com.android.settingslib.Utils
|
||||
import com.android.settingslib.metadata.PreferenceAvailabilityProvider
|
||||
import com.android.settingslib.metadata.PreferenceMetadata
|
||||
import com.android.settingslib.metadata.PreferenceTitleProvider
|
||||
import com.android.settingslib.metadata.ProvidePreferenceScreen
|
||||
import com.android.settingslib.metadata.preferenceHierarchy
|
||||
import com.android.settingslib.preference.PreferenceScreenCreator
|
||||
|
||||
@ProvidePreferenceScreen
|
||||
class TetherScreen :
|
||||
PreferenceScreenCreator,
|
||||
PreferenceTitleProvider,
|
||||
PreferenceAvailabilityProvider,
|
||||
PreferenceRestrictionMixin {
|
||||
|
||||
override val key: String
|
||||
get() = KEY
|
||||
|
||||
override val icon: Int
|
||||
get() = R.drawable.ic_wifi_tethering
|
||||
|
||||
override val keywords: Int
|
||||
get() = R.string.keywords_hotspot_tethering
|
||||
|
||||
override fun getTitle(context: Context): CharSequence? =
|
||||
if (TetherPreferenceController.isTetherConfigDisallowed(context)) {
|
||||
context.getText(R.string.tether_settings_title_all)
|
||||
} else {
|
||||
val tetheringManager = context.getSystemService(TetheringManager::class.java)!!
|
||||
context.getText(Utils.getTetheringLabel(tetheringManager))
|
||||
}
|
||||
|
||||
override fun isAvailable(context: Context) = TetherUtil.isTetherAvailable(context)
|
||||
|
||||
override fun isEnabled(context: Context) = super<PreferenceRestrictionMixin>.isEnabled(context)
|
||||
|
||||
override val restrictionKeys
|
||||
get() = arrayOf(UserManager.DISALLOW_CONFIG_TETHERING)
|
||||
|
||||
override fun isFlagEnabled(context: Context) = Flags.catalystTetherSettings()
|
||||
|
||||
override fun hasCompleteHierarchy() = false
|
||||
|
||||
override fun fragmentClass() = TetherSettings::class.java
|
||||
|
||||
override fun getLaunchIntent(context: Context, metadata: PreferenceMetadata?) =
|
||||
makeLaunchIntent(context, TetherSettingsActivity::class.java, metadata?.key)
|
||||
|
||||
override fun getPreferenceHierarchy(context: Context) =
|
||||
preferenceHierarchy(this) {
|
||||
val dataSaverStore = DataSaverMainSwitchPreference.createDataStore(context)
|
||||
+WifiHotspotSwitchPreference(context, dataSaverStore)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val KEY = "tether_settings"
|
||||
}
|
||||
}
|
||||
@@ -48,14 +48,15 @@ import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.TwoStatePreference;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.RestrictedSettingsFragment;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.dashboard.RestrictedDashboardFragment;
|
||||
import com.android.settings.datausage.DataSaverBackend;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settings.wifi.tether.WifiTetherPreferenceController;
|
||||
@@ -71,11 +72,12 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
// LINT.IfChange
|
||||
/**
|
||||
* Displays preferences for Tethering.
|
||||
*/
|
||||
@SearchIndexable
|
||||
public class TetherSettings extends RestrictedSettingsFragment
|
||||
public class TetherSettings extends RestrictedDashboardFragment
|
||||
implements DataSaverBackend.Listener {
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -143,11 +145,20 @@ public class TetherSettings extends RestrictedSettingsFragment
|
||||
super(UserManager.DISALLOW_CONFIG_TETHERING);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getLogTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceScreenResId() {
|
||||
return R.xml.tether_prefs;
|
||||
}
|
||||
|
||||
@SuppressWarnings("NullAway")
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
// Even when the UI is restricted, addPreferencesFromResource cannot be omitted.
|
||||
addPreferencesFromResource(R.xml.tether_prefs);
|
||||
setIfOnlyAvailableForAdmins(true);
|
||||
if (isUiRestricted()) {
|
||||
return;
|
||||
@@ -194,18 +205,23 @@ public class TetherSettings extends RestrictedSettingsFragment
|
||||
getPreferenceScreen().removePreference(mUsbTether);
|
||||
}
|
||||
|
||||
mWifiTetherPreferenceController.displayPreference(getPreferenceScreen());
|
||||
if (!isCatalystEnabled() && mWifiTetherPreferenceController != null) {
|
||||
mWifiTetherPreferenceController.displayPreference(getPreferenceScreen());
|
||||
}
|
||||
|
||||
if (!bluetoothAvailable) {
|
||||
getPreferenceScreen().removePreference(mBluetoothTether);
|
||||
} else {
|
||||
BluetoothPan pan = mBluetoothPan.get();
|
||||
if (pan != null && pan.isTetheringOn()) {
|
||||
mBluetoothTether.setChecked(true);
|
||||
if (!isCatalystEnabled()) {
|
||||
if (!bluetoothAvailable) {
|
||||
mBluetoothTether.setVisible(false);
|
||||
} else {
|
||||
mBluetoothTether.setChecked(false);
|
||||
BluetoothPan pan = mBluetoothPan.get();
|
||||
if (pan != null && pan.isTetheringOn()) {
|
||||
mBluetoothTether.setChecked(true);
|
||||
} else {
|
||||
mBluetoothTether.setChecked(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ethernetAvailable) getPreferenceScreen().removePreference(mEthernetTether);
|
||||
// Set initial state based on Data Saver mode.
|
||||
onDataSaverChanged(mDataSaverBackend.isDataSaverEnabled());
|
||||
@@ -214,8 +230,10 @@ public class TetherSettings extends RestrictedSettingsFragment
|
||||
@VisibleForTesting
|
||||
void setupViewModel() {
|
||||
TetheringManagerModel model = new ViewModelProvider(this).get(TetheringManagerModel.class);
|
||||
mWifiTetherPreferenceController =
|
||||
new WifiTetherPreferenceController(getContext(), getSettingsLifecycle(), model);
|
||||
if (!isCatalystEnabled()) {
|
||||
mWifiTetherPreferenceController =
|
||||
new WifiTetherPreferenceController(getContext(), getSettingsLifecycle(), model);
|
||||
}
|
||||
mTm = model.getTetheringManager();
|
||||
model.getTetheredInterfaces().observe(this, this::onTetheredInterfacesChanged);
|
||||
}
|
||||
@@ -252,9 +270,13 @@ public class TetherSettings extends RestrictedSettingsFragment
|
||||
@Override
|
||||
public void onDataSaverChanged(boolean isDataSaving) {
|
||||
mDataSaverEnabled = isDataSaving;
|
||||
mWifiTetherPreferenceController.setDataSaverEnabled(mDataSaverEnabled);
|
||||
if (!isCatalystEnabled()) {
|
||||
mWifiTetherPreferenceController.setDataSaverEnabled(mDataSaverEnabled);
|
||||
}
|
||||
mUsbTether.setEnabled(!mDataSaverEnabled);
|
||||
mBluetoothTether.setEnabled(!mDataSaverEnabled);
|
||||
if (!isCatalystEnabled()) {
|
||||
mBluetoothTether.setEnabled(!mDataSaverEnabled);
|
||||
}
|
||||
mEthernetTether.setEnabled(!mDataSaverEnabled);
|
||||
mDataSaverFooter.setVisible(mDataSaverEnabled);
|
||||
}
|
||||
@@ -504,6 +526,8 @@ public class TetherSettings extends RestrictedSettingsFragment
|
||||
}
|
||||
|
||||
private void updateBluetoothState() {
|
||||
if (isCatalystEnabled()) return;
|
||||
|
||||
final int btState = getBluetoothState();
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "updateBluetoothState() btState : " + btState);
|
||||
@@ -559,7 +583,7 @@ public class TetherSettings extends RestrictedSettingsFragment
|
||||
}
|
||||
|
||||
private void startTethering(int choice) {
|
||||
if (choice == TETHERING_BLUETOOTH) {
|
||||
if (choice == TETHERING_BLUETOOTH && !isCatalystEnabled()) {
|
||||
// Turn on Bluetooth first.
|
||||
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
||||
if (adapter.getState() == BluetoothAdapter.STATE_OFF) {
|
||||
@@ -581,7 +605,7 @@ public class TetherSettings extends RestrictedSettingsFragment
|
||||
} else {
|
||||
mCm.stopTethering(TETHERING_USB);
|
||||
}
|
||||
} else if (preference == mBluetoothTether) {
|
||||
} else if (preference == mBluetoothTether && !isCatalystEnabled()) {
|
||||
if (mBluetoothTether.isChecked()) {
|
||||
startTethering(TETHERING_BLUETOOTH);
|
||||
} else {
|
||||
@@ -723,4 +747,10 @@ public class TetherSettings extends RestrictedSettingsFragment
|
||||
}
|
||||
updateBluetoothAndEthernetState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String getPreferenceScreenBindingKey(@NonNull Context context) {
|
||||
return TetherScreen.KEY;
|
||||
}
|
||||
}
|
||||
// LINT.ThenChange(BluetoothTetherSwitchPreference.kt)
|
||||
|
||||
Reference in New Issue
Block a user