1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.telephony.metrics; 18 19 import com.android.internal.telephony.uicc.IccCardStatus.CardState; 20 import com.android.internal.telephony.uicc.UiccCard; 21 import com.android.internal.telephony.uicc.UiccController; 22 import com.android.internal.telephony.uicc.UiccPort; 23 import com.android.internal.telephony.uicc.UiccSlot; 24 import com.android.telephony.Rlog; 25 26 import java.util.Arrays; 27 import java.util.Objects; 28 29 /** Snapshots and stores the current SIM state. */ 30 public class SimSlotState { 31 private static final String TAG = SimSlotState.class.getSimpleName(); 32 33 public final int numActiveSlots; 34 public final int numActiveSims; 35 public final int numActiveEsims; 36 public final int numActiveEsimSlots; 37 public final int numActiveMepSlots; 38 39 /** Returns the current SIM state. */ getCurrentState()40 public static SimSlotState getCurrentState() { 41 int numActiveSlots = 0; 42 int numActiveSims = 0; 43 int numActiveEsims = 0; 44 int numActiveEsimSlots = 0; 45 int numActiveMepSlots = 0; 46 UiccController uiccController = UiccController.getInstance(); 47 // since we cannot hold lock insider UiccController, using getUiccSlots() for length only 48 for (int i = 0; i < uiccController.getUiccSlots().length; i++) { 49 UiccSlot slot = uiccController.getUiccSlot(i); 50 if (slot != null && slot.isActive()) { 51 numActiveSlots++; 52 if (slot.isEuicc()) { 53 numActiveEsimSlots++; 54 } 55 // avoid CardState.isCardPresent() since this should not include restricted cards 56 if (slot.getCardState() == CardState.CARDSTATE_PRESENT) { 57 if (slot.isEuicc()) { 58 // need to check active profiles besides the presence of eSIM cards 59 UiccCard card = slot.getUiccCard(); 60 if (card != null) { 61 int numActiveProfiles = (int) Arrays.stream(card.getUiccPortList()) 62 .filter(Objects::nonNull) 63 .map(UiccPort::getUiccProfile) 64 .filter(Objects::nonNull) 65 .filter(profile -> profile.getNumApplications() > 0) 66 .count(); 67 numActiveSims += numActiveProfiles; 68 numActiveEsims += numActiveProfiles; 69 if (numActiveProfiles > 1) { 70 numActiveMepSlots++; 71 } 72 } 73 } else { 74 // physical SIMs do not always have non-null card 75 numActiveSims++; 76 } 77 } 78 } 79 } 80 return new SimSlotState( 81 numActiveSlots, 82 numActiveSims, 83 numActiveEsims, 84 numActiveEsimSlots, 85 numActiveMepSlots); 86 } 87 SimSlotState( int numActiveSlots, int numActiveSims, int numActiveEsims, int numActiveEsimSlots, int numActiveMepSlots)88 private SimSlotState( 89 int numActiveSlots, 90 int numActiveSims, 91 int numActiveEsims, 92 int numActiveEsimSlots, 93 int numActiveMepSlots) { 94 this.numActiveSlots = numActiveSlots; 95 this.numActiveSims = numActiveSims; 96 this.numActiveEsims = numActiveEsims; 97 this.numActiveEsimSlots = numActiveEsimSlots; 98 this.numActiveMepSlots = numActiveMepSlots; 99 } 100 101 /** Returns whether the given phone is using a eSIM. */ isEsim(int phoneId)102 public static boolean isEsim(int phoneId) { 103 UiccSlot slot = UiccController.getInstance().getUiccSlotForPhone(phoneId); 104 if (slot != null) { 105 return slot.isEuicc(); 106 } else { 107 // should not happen, but assume we are not using eSIM 108 Rlog.e(TAG, "isEsim: slot=null for phone " + phoneId); 109 return false; 110 } 111 } 112 113 /** Returns whether the device has multiple active SIM profiles. */ isMultiSim()114 public static boolean isMultiSim() { 115 return (getCurrentState().numActiveSims > 1); 116 } 117 } 118