From d94ac1219018a187eaa13786b063134e7882706e Mon Sep 17 00:00:00 2001 From: SongFerngWang Date: Thu, 6 Jul 2023 19:55:33 +0800 Subject: [PATCH] To fix waiting too long issue when psim -> esim if the user swithes slot from psim to esim, then the settings need to wait the simSlotMapping completed and it has a timer to avoid UI stay here too long. Since the framework did not sned the carrier config changed with vaild subId in MEP + psim->esim case, it cause the settings does not know the simSlotMapping completed and it stay here until timeout. For MEP case, changing this condition as SimSlotStatusChanged Bug: 273813956 Test: atest UiccSlotUtilTest Change-Id: Ic09dbcb3629fe13770f3ad301c0a396d6745969f --- .../settings/network/UiccSlotUtil.java | 51 +++++++++++++++++-- .../settings/network/UiccSlotUtilTest.java | 23 +++++++++ 2 files changed, 70 insertions(+), 4 deletions(-) diff --git a/src/com/android/settings/network/UiccSlotUtil.java b/src/com/android/settings/network/UiccSlotUtil.java index 95a0e4d5f2a..49a1a852ff1 100644 --- a/src/com/android/settings/network/UiccSlotUtil.java +++ b/src/com/android/settings/network/UiccSlotUtil.java @@ -17,7 +17,10 @@ package com.android.settings.network; import android.annotation.IntDef; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; import android.provider.Settings; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; @@ -54,6 +57,28 @@ public class UiccSlotUtil { public static final int INVALID_PHYSICAL_SLOT_ID = -1; public static final int INVALID_PORT_ID = -1; + @VisibleForTesting + static class SimSlotChangeReceiver extends BroadcastReceiver{ + private final CountDownLatch mLatch; + SimSlotChangeReceiver(CountDownLatch latch) { + mLatch = latch; + } + + public void registerOn(Context context) { + context.registerReceiver(this, + new IntentFilter(TelephonyManager.ACTION_SIM_SLOT_STATUS_CHANGED), + Context.RECEIVER_EXPORTED/*UNAUDITED*/); + } + + @Override + public void onReceive(Context context, Intent intent) { + Log.i(TAG, "Action: " + intent.getAction()); + if (TelephonyManager.ACTION_SIM_SLOT_STATUS_CHANGED.equals(intent.getAction())) { + mLatch.countDown(); + } + } + } + /** * Mode for switching to eSIM slot which decides whether there is cleanup process, e.g. * disabling test profile, after eSIM slot is activated and whether we will wait it finished. @@ -229,19 +254,27 @@ public class UiccSlotUtil { && uiccSlotMapping.getPortIndex() == port); } - private static void performSwitchToSlot(TelephonyManager telMgr, + @VisibleForTesting + static void performSwitchToSlot(TelephonyManager telMgr, Collection uiccSlotMappings, Context context) throws UiccSlotsException { - CarrierConfigChangedReceiver receiver = null; + BroadcastReceiver receiver = null; long waitingTimeMillis = Settings.Global.getLong( context.getContentResolver(), Settings.Global.EUICC_SWITCH_SLOT_TIMEOUT_MILLIS, DEFAULT_WAIT_AFTER_SWITCH_TIMEOUT_MILLIS); + Log.d(TAG, "Set waitingTime as " + waitingTimeMillis); + try { CountDownLatch latch = new CountDownLatch(1); - receiver = new CarrierConfigChangedReceiver(latch); - receiver.registerOn(context); + if (isMultipleEnabledProfilesSupported(telMgr)) { + receiver = new SimSlotChangeReceiver(latch); + ((SimSlotChangeReceiver) receiver).registerOn(context); + } else { + receiver = new CarrierConfigChangedReceiver(latch); + ((CarrierConfigChangedReceiver) receiver).registerOn(context); + } telMgr.setSimSlotMapping(uiccSlotMappings); latch.await(waitingTimeMillis, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { @@ -435,4 +468,14 @@ public class UiccSlotUtil { Log.i(TAG, "isRemovableSimEnabled: " + isRemovableSimEnabled); return isRemovableSimEnabled; } + + private static boolean isMultipleEnabledProfilesSupported(TelephonyManager telMgr) { + List cardInfos = telMgr.getUiccCardsInfo(); + if (cardInfos == null) { + Log.w(TAG, "UICC cards info list is empty."); + return false; + } + return cardInfos.stream().anyMatch( + cardInfo -> cardInfo.isMultipleEnabledProfilesSupported()); + } } diff --git a/tests/unit/src/com/android/settings/network/UiccSlotUtilTest.java b/tests/unit/src/com/android/settings/network/UiccSlotUtilTest.java index 9a2c61167cb..2e17fb271cd 100644 --- a/tests/unit/src/com/android/settings/network/UiccSlotUtilTest.java +++ b/tests/unit/src/com/android/settings/network/UiccSlotUtilTest.java @@ -20,10 +20,13 @@ import static android.telephony.UiccSlotInfo.CARD_STATE_INFO_PRESENT; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; +import android.content.Intent; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; @@ -49,6 +52,7 @@ import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.concurrent.CountDownLatch; @RunWith(AndroidJUnit4.class) public class UiccSlotUtilTest { @@ -738,6 +742,25 @@ public class UiccSlotUtilTest { assertThat(testSlot).isFalse(); } + @Test + public void performSwitchToSlot_setSimSlotMapping() throws UiccSlotsException { + Collection uiccSlotMappings = createUiccSlotMappingDualPortsBNoOrding(); + + UiccSlotUtil.performSwitchToSlot(mTelephonyManager, uiccSlotMappings, mContext); + + verify(mTelephonyManager).setSimSlotMapping(any()); + } + + @Test + public void onReceiveSimSlotChangeReceiver_receiveAction_timerCountDown() { + CountDownLatch latch = spy(new CountDownLatch(1)); + UiccSlotUtil.SimSlotChangeReceiver receive = new UiccSlotUtil.SimSlotChangeReceiver(latch); + + receive.onReceive(mContext, new Intent(TelephonyManager.ACTION_SIM_SLOT_STATUS_CHANGED)); + + verify(latch).countDown(); + } + private void compareTwoUiccSlotMappings(Collection testUiccSlotMappings, Collection verifyUiccSlotMappings) { assertThat(testUiccSlotMappings.size()).isEqualTo(verifyUiccSlotMappings.size());