From bae147bab3ebf9f3e582a91c71e18c335065a5c3 Mon Sep 17 00:00:00 2001 From: Chaohui Wang Date: Sun, 7 Apr 2024 15:16:03 +0800 Subject: [PATCH] Close ApnSettings when subscription not enabled Including the case that physical sim is removed. Fix: 332885481 Test: manual - on ApnSettings Change-Id: I9bc77f995b6c1e98046a84fafb05f9b61d71ce70 --- .../network/apn/ApnEditPageProvider.kt | 14 +++++++ .../settings/network/apn/ApnSettings.java | 39 ++++++++++--------- .../telephony/SubscriptionRepository.kt | 15 ++++++- 3 files changed, 49 insertions(+), 19 deletions(-) diff --git a/src/com/android/settings/network/apn/ApnEditPageProvider.kt b/src/com/android/settings/network/apn/ApnEditPageProvider.kt index a287b848474..71fe4d6f981 100644 --- a/src/com/android/settings/network/apn/ApnEditPageProvider.kt +++ b/src/com/android/settings/network/apn/ApnEditPageProvider.kt @@ -27,6 +27,7 @@ import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -39,6 +40,7 @@ import androidx.compose.ui.res.stringResource import androidx.navigation.NavType import androidx.navigation.navArgument import com.android.settings.R +import com.android.settings.network.telephony.SubscriptionRepository import com.android.settingslib.spa.framework.common.SettingsPageProvider import com.android.settingslib.spa.framework.compose.LocalNavController import com.android.settingslib.spa.framework.theme.SettingsDimension @@ -78,6 +80,18 @@ object ApnEditPageProvider : SettingsPageProvider { mutableStateOf(apnDataInit) } ApnPage(apnDataInit, apnDataCur, uriInit) + SubscriptionNotEnabledEffect(subId) + } + + @Composable + private fun SubscriptionNotEnabledEffect(subId: Int) { + val context = LocalContext.current + val navController = LocalNavController.current + LaunchedEffect(subId) { + SubscriptionRepository(context).isSubscriptionEnabledFlow(subId).collect { isEnabled -> + if (!isEnabled) navController.navigateBack() + } + } } fun getRoute( diff --git a/src/com/android/settings/network/apn/ApnSettings.java b/src/com/android/settings/network/apn/ApnSettings.java index be906536dd6..80239cb0d0e 100644 --- a/src/com/android/settings/network/apn/ApnSettings.java +++ b/src/com/android/settings/network/apn/ApnSettings.java @@ -52,8 +52,11 @@ import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.MotionEvent; +import android.view.View; import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.preference.Preference; import androidx.preference.PreferenceGroup; @@ -61,9 +64,12 @@ import com.android.settings.R; import com.android.settings.RestrictedSettingsFragment; import com.android.settings.flags.Flags; import com.android.settings.network.SubscriptionUtil; +import com.android.settings.network.telephony.SubscriptionRepository; import com.android.settings.spa.SpaActivity; import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; +import kotlin.Unit; + import java.util.ArrayList; /** Handle each different apn setting. */ @@ -92,13 +98,6 @@ public class ApnSettings extends RestrictedSettingsFragment Telephony.Carriers.EDITED_STATUS, }; - /** Copied from {@code com.android.internal.telephony.TelephonyIntents} */ - private static final String ACTION_SIM_STATE_CHANGED = - "android.intent.action.SIM_STATE_CHANGED"; - /** Copied from {@code com.android.internal.telephony.IccCardConstants} */ - public static final String INTENT_KEY_ICC_STATE = "ss"; - public static final String INTENT_VALUE_ICC_ABSENT = "ABSENT"; - private static final int ID_INDEX = 0; private static final int NAME_INDEX = 1; private static final int APN_INDEX = 2; @@ -162,16 +161,7 @@ public class ApnSettings extends RestrictedSettingsFragment private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (ACTION_SIM_STATE_CHANGED.equals(action) - && intent.getStringExtra(INTENT_KEY_ICC_STATE) - .equals(INTENT_VALUE_ICC_ABSENT)) { - final SubscriptionManager sm = context.getSystemService(SubscriptionManager.class); - if (sm != null && !sm.isActiveSubscriptionId(mSubId)) { - Log.d(TAG, "Due to SIM absent, closes APN settings page"); - finish(); - } - } else if (intent.getAction().equals( + if (intent.getAction().equals( TelephonyManager.ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED)) { if (mRestoreDefaultApnMode) { return; @@ -223,7 +213,6 @@ public class ApnSettings extends RestrictedSettingsFragment mPhoneId = SubscriptionUtil.getPhoneId(activity, mSubId); mIntentFilter = new IntentFilter(); mIntentFilter.addAction(TelephonyManager.ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED); - mIntentFilter.addAction(ACTION_SIM_STATE_CHANGED); setIfOnlyAvailableForAdmins(true); @@ -263,6 +252,20 @@ public class ApnSettings extends RestrictedSettingsFragment addPreferencesFromResource(R.xml.apn_settings); } + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + new SubscriptionRepository(requireContext()) + .collectSubscriptionEnabled(mSubId, getViewLifecycleOwner(), (isEnabled) -> { + if (!isEnabled) { + Log.d(TAG, "Due to subscription not enabled, closes APN settings page"); + finish(); + } + return Unit.INSTANCE; + }); + } + @Override public void onResume() { super.onResume(); diff --git a/src/com/android/settings/network/telephony/SubscriptionRepository.kt b/src/com/android/settings/network/telephony/SubscriptionRepository.kt index b0a39ec2616..938f4d8ef22 100644 --- a/src/com/android/settings/network/telephony/SubscriptionRepository.kt +++ b/src/com/android/settings/network/telephony/SubscriptionRepository.kt @@ -20,7 +20,9 @@ import android.content.Context import android.telephony.SubscriptionInfo import android.telephony.SubscriptionManager import android.util.Log +import androidx.lifecycle.LifecycleOwner import com.android.settings.network.SubscriptionUtil +import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.asExecutor import kotlinx.coroutines.channels.awaitClose @@ -43,6 +45,16 @@ class SubscriptionRepository(private val context: Context) { context.getSelectableSubscriptionInfoList() fun isSubscriptionEnabledFlow(subId: Int) = context.isSubscriptionEnabledFlow(subId) + + /** TODO: Move this to UI layer, when UI layer migrated to Kotlin. */ + fun collectSubscriptionEnabled( + subId: Int, + lifecycleOwner: LifecycleOwner, + action: (Boolean) -> Unit, + ) { + isSubscriptionEnabledFlow(subId).collectLatestWithLifecycle(lifecycleOwner, action = action) + } + } val Context.subscriptionManager: SubscriptionManager? @@ -52,7 +64,8 @@ fun Context.requireSubscriptionManager(): SubscriptionManager = subscriptionMana fun Context.isSubscriptionEnabledFlow(subId: Int) = subscriptionsChangedFlow().map { subscriptionManager?.isSubscriptionEnabled(subId) ?: false -}.flowOn(Dispatchers.Default) +}.conflate().onEach { Log.d(TAG, "[$subId] isSubscriptionEnabledFlow: $it") } + .flowOn(Dispatchers.Default) fun Context.phoneNumberFlow(subscriptionInfo: SubscriptionInfo) = subscriptionsChangedFlow().map { SubscriptionUtil.getFormattedPhoneNumber(this, subscriptionInfo)