[MEP]The Esim's PhysicalSlotIndex is wrong am: d3f3730721
am: f795e9b6d0
Original change: https://android-review.googlesource.com/c/platform/packages/apps/Settings/+/2063560 Change-Id: Ib78e2038d2cb8bc2e9e7bdb78c90bd515f8b306d Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -37,7 +37,6 @@ public class SwitchToEuiccSubscriptionSidecar extends EuiccOperationSidecar {
|
||||
private static final String TAG = "SwitchToEuiccSidecar";
|
||||
private static final String ACTION_SWITCH_TO_SUBSCRIPTION =
|
||||
"com.android.settings.network.SWITCH_TO_SUBSCRIPTION";
|
||||
private static final int ESIM_SLOT_ID = 1;
|
||||
|
||||
private PendingIntent mCallbackIntent;
|
||||
private int mSubId;
|
||||
@@ -92,11 +91,20 @@ public class SwitchToEuiccSubscriptionSidecar extends EuiccOperationSidecar {
|
||||
setState(State.RUNNING, Substate.UNUSED);
|
||||
mCallbackIntent = createCallbackIntent();
|
||||
mSubId = subscriptionId;
|
||||
int targetSlot = getTargetSlot();
|
||||
if (targetSlot < 0) {
|
||||
Log.d(TAG, "There is no esim, the TargetSlot is " + targetSlot);
|
||||
setState(State.ERROR, Substate.UNUSED);
|
||||
return;
|
||||
}
|
||||
|
||||
// To check whether the esim slot's port is active. If yes, skip setSlotMapping. If no,
|
||||
// set this slot+port into setSimSlotMapping.
|
||||
mPort = (port < 0) ? getTargetPortId(removedSubInfo) : port;
|
||||
mPort = (port < 0) ? getTargetPortId(removedSubInfo, targetSlot) : port;
|
||||
mRemovedSubInfo = removedSubInfo;
|
||||
Log.i(TAG, "The SubId is " + mSubId + ". The port is " + mPort);
|
||||
Log.d(TAG,
|
||||
String.format("set esim into the Slot%d SubId%d:Port%d",
|
||||
targetSlot, mSubId, mPort));
|
||||
|
||||
if (mTelephonyManager.isMultiSimEnabled() && removedSubInfo != null
|
||||
&& removedSubInfo.isEmbedded()) {
|
||||
@@ -108,11 +116,11 @@ public class SwitchToEuiccSubscriptionSidecar extends EuiccOperationSidecar {
|
||||
mEuiccManager.switchToSubscription(SubscriptionManager.INVALID_SUBSCRIPTION_ID, mPort,
|
||||
mCallbackIntent);
|
||||
} else {
|
||||
mSwitchSlotSidecar.runSwitchToEuiccSlot(getTargetSlot(), mPort, removedSubInfo);
|
||||
mSwitchSlotSidecar.runSwitchToEuiccSlot(targetSlot, mPort, removedSubInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private int getTargetPortId(SubscriptionInfo removedSubInfo) {
|
||||
private int getTargetPortId(SubscriptionInfo removedSubInfo, int targetSlot) {
|
||||
if (!mTelephonyManager.isMultiSimEnabled() || !isMultipleEnabledProfilesSupported()) {
|
||||
// In the 'SS mode' or 'DSDS+no MEP', the port is 0.
|
||||
return 0;
|
||||
@@ -124,16 +132,19 @@ public class SwitchToEuiccSubscriptionSidecar extends EuiccOperationSidecar {
|
||||
return removedSubInfo.getPortIndex();
|
||||
}
|
||||
|
||||
// In DSDS+MEP mode, the removedSubInfo is psim or is null, it means the this esim need
|
||||
// In DSDS+MEP mode, the removedSubInfo is psim or is null, it means this esim needs
|
||||
// another port in the esim slot.
|
||||
// To find another esim's port and value is from 0;
|
||||
// To find another esim's port and value is from 0.
|
||||
// For example:
|
||||
// 1) If there is no enabled esim and the user add new esim. This new esim's port is 0.
|
||||
// 2) If there is one enabled esim and the user add new esim. This new esim's port is 1.
|
||||
int port = 0;
|
||||
Collection<UiccSlotMapping> uiccSlotMappings = mTelephonyManager.getSimSlotMapping();
|
||||
for (UiccSlotMapping uiccSlotMapping :
|
||||
uiccSlotMappings.stream()
|
||||
.filter(
|
||||
uiccSlotMapping -> uiccSlotMapping.getPhysicalSlotIndex()
|
||||
== getTargetSlot())
|
||||
== targetSlot)
|
||||
.collect(Collectors.toList())) {
|
||||
if (uiccSlotMapping.getPortIndex() == port) {
|
||||
port++;
|
||||
@@ -143,7 +154,7 @@ public class SwitchToEuiccSubscriptionSidecar extends EuiccOperationSidecar {
|
||||
}
|
||||
|
||||
private int getTargetSlot() {
|
||||
return ESIM_SLOT_ID;
|
||||
return UiccSlotUtil.getEsimSlotId(getContext());
|
||||
}
|
||||
|
||||
private void onSwitchSlotSidecarStateChange() {
|
||||
|
@@ -36,6 +36,7 @@ import java.util.Collection;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
// ToDo: to do the refactor for renaming
|
||||
public class UiccSlotUtil {
|
||||
@@ -174,6 +175,28 @@ public class UiccSlotUtil {
|
||||
performSwitchToSlot(telMgr, newUiccSlotMappings, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context the application context.
|
||||
* @return the esim slot. If the value is -1, there is not the esim.
|
||||
*/
|
||||
public static int getEsimSlotId(Context context) {
|
||||
TelephonyManager telMgr = context.getSystemService(TelephonyManager.class);
|
||||
ImmutableList<UiccSlotInfo> slotInfos = UiccSlotUtil.getSlotInfos(telMgr);
|
||||
int firstEsimSlot = IntStream.range(0, slotInfos.size())
|
||||
.filter(
|
||||
index -> {
|
||||
UiccSlotInfo slotInfo = slotInfos.get(index);
|
||||
if (slotInfo == null) {
|
||||
return false;
|
||||
}
|
||||
return !slotInfo.isRemovable();
|
||||
})
|
||||
.findFirst().orElse(-1);
|
||||
|
||||
Log.i(TAG, "firstEsimSlot: " + firstEsimSlot);
|
||||
return firstEsimSlot;
|
||||
}
|
||||
|
||||
private static boolean isTargetSlotActive(Collection<UiccSlotMapping> uiccSlotMappings,
|
||||
int slotId, int port) {
|
||||
return uiccSlotMappings.stream()
|
||||
|
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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 static android.telephony.UiccSlotInfo.CARD_STATE_INFO_PRESENT;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.telephony.UiccPortInfo;
|
||||
import android.telephony.UiccSlotInfo;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class UiccSlotUtilTest {
|
||||
private Context mContext;
|
||||
@Mock
|
||||
private TelephonyManager mTelephonyManager;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSlotInfos_oneSimSlotDevice_returnTheCorrectSlotInfoList() {
|
||||
when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(oneSimSlotDevice_ActivePsim());
|
||||
ImmutableList<UiccSlotInfo> testUiccSlotInfos =
|
||||
UiccSlotUtil.getSlotInfos(mTelephonyManager);
|
||||
|
||||
assertThat(testUiccSlotInfos.size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSlotInfos_twoSimSlotsDevice_returnTheCorrectSlotInfoList() {
|
||||
when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(
|
||||
twoSimSlotsDevice_ActivePsimActiveEsim());
|
||||
ImmutableList<UiccSlotInfo> testUiccSlotInfos =
|
||||
UiccSlotUtil.getSlotInfos(mTelephonyManager);
|
||||
|
||||
assertThat(testUiccSlotInfos.size()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEsimSlotId_twoSimSlotsDeviceAndEsimIsSlot0_returnTheCorrectEsimSlot() {
|
||||
when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(
|
||||
twoSimSlotsDevice_ActiveEsimActivePsim());
|
||||
int testSlot = UiccSlotUtil.getEsimSlotId(mContext);
|
||||
|
||||
assertThat(testSlot).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEsimSlotId_twoSimSlotsDeviceAndEsimIsSlot1_returnTheCorrectEsimSlot() {
|
||||
when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(
|
||||
twoSimSlotsDevice_ActivePsimActiveEsim());
|
||||
int testSlot = UiccSlotUtil.getEsimSlotId(mContext);
|
||||
|
||||
assertThat(testSlot).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEsimSlotId_noEimSlotDevice_returnTheCorrectEsimSlot() {
|
||||
when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(
|
||||
oneSimSlotDevice_ActivePsim());
|
||||
int testSlot = UiccSlotUtil.getEsimSlotId(mContext);
|
||||
|
||||
assertThat(testSlot).isEqualTo(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* The "oneSimSlotDevice" has below cases
|
||||
* 1) The device is one psim slot and no esim slot
|
||||
* 2) The device is no psim slot and one esim slot. like the watch.
|
||||
*
|
||||
* The "twoSimsSlotDevice" has below cases
|
||||
* 1) The device is one psim slot and one esim slot
|
||||
* 2) The device is two psim slots
|
||||
*/
|
||||
|
||||
private UiccSlotInfo[] oneSimSlotDevice_ActivePsim() {
|
||||
return new UiccSlotInfo[]{createUiccSlotInfo(false, true, 0, true)};
|
||||
}
|
||||
|
||||
private UiccSlotInfo[] oneSimSlotDevice_ActiveEsim() {
|
||||
return new UiccSlotInfo[]{createUiccSlotInfo(true, false, 1, true)};
|
||||
}
|
||||
|
||||
private UiccSlotInfo[] twoSimSlotsDevice_ActivePsimActiveEsim() {
|
||||
return new UiccSlotInfo[]{
|
||||
createUiccSlotInfo(false, true, 0, true),
|
||||
createUiccSlotInfo(true, false, 1, true)};
|
||||
}
|
||||
|
||||
private UiccSlotInfo[] twoSimSlotsDevice_ActiveEsimActivePsim() {
|
||||
return new UiccSlotInfo[]{
|
||||
createUiccSlotInfo(true, false, 0, true),
|
||||
createUiccSlotInfo(false, true, 1, true)};
|
||||
}
|
||||
|
||||
private UiccSlotInfo[] twoSimSlotsDevice_twoActiveEsims() {
|
||||
// device supports MEP, so device can enable two esims.
|
||||
// If device has psim slot, the UiccSlotInfo of psim always be in UiccSlotInfo[].
|
||||
return new UiccSlotInfo[]{
|
||||
createUiccSlotInfo(false, true, -1, true),
|
||||
createUiccSlotInfoForEsimMep(0, true, 1, true)};
|
||||
}
|
||||
|
||||
private UiccSlotInfo[] twoSimSlotsDevice_ActivePsimInactiveEsim() {
|
||||
return new UiccSlotInfo[]{
|
||||
createUiccSlotInfo(false, true, 0, true),
|
||||
createUiccSlotInfo(true, false, -1, false)};
|
||||
}
|
||||
|
||||
private UiccSlotInfo[] twoSimSlotsDevice_InactivePsimActiveEsim() {
|
||||
return new UiccSlotInfo[]{
|
||||
createUiccSlotInfo(false, true, 0, false),
|
||||
createUiccSlotInfo(true, false, 1, true)};
|
||||
}
|
||||
|
||||
private UiccSlotInfo[] twoSimSlotsDevice_NoInsertPsimActiveEsim() {
|
||||
return new UiccSlotInfo[]{
|
||||
createUiccSlotInfo(false, true, -1, false),
|
||||
createUiccSlotInfo(true, false, 1, true)};
|
||||
}
|
||||
//ToDo: add more cases.
|
||||
|
||||
private UiccSlotInfo createUiccSlotInfo(boolean isEuicc, boolean isRemovable,
|
||||
int logicalSlotIdx, boolean isActive) {
|
||||
return new UiccSlotInfo(
|
||||
isEuicc, /* isEuicc */
|
||||
"123", /* cardId */
|
||||
CARD_STATE_INFO_PRESENT, /* cardStateInfo */
|
||||
true, /* isExtendApduSupported */
|
||||
isRemovable, /* isRemovable */
|
||||
Collections.singletonList(
|
||||
new UiccPortInfo("" /* iccId */, 0 /* portIdx */,
|
||||
logicalSlotIdx /* logicalSlotIdx */, isActive /* isActive */))
|
||||
);
|
||||
}
|
||||
|
||||
private UiccSlotInfo createUiccSlotInfoForEsimMep(int logicalSlotIdx1, boolean isActiveEsim1,
|
||||
int logicalSlotIdx2, boolean isActiveEsim2) {
|
||||
return new UiccSlotInfo(
|
||||
true, /* isEuicc */
|
||||
"123", /* cardId */
|
||||
CARD_STATE_INFO_PRESENT, /* cardStateInfo */
|
||||
true, /* isExtendApduSupported */
|
||||
false, /* isRemovable */
|
||||
Arrays.asList(
|
||||
new UiccPortInfo("" /* iccId */, 0 /* portIdx */,
|
||||
logicalSlotIdx1 /* logicalSlotIdx */, isActiveEsim1 /* isActive */),
|
||||
new UiccPortInfo("" /* iccId */, 1 /* portIdx */,
|
||||
logicalSlotIdx2 /* logicalSlotIdx */,
|
||||
isActiveEsim2 /* isActive */)));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user