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.UiccSlot; 23 import com.android.telephony.Rlog; 24 25 /** Snapshots and stores the current SIM state. */ 26 public class SimSlotState { 27 private static final String TAG = SimSlotState.class.getSimpleName(); 28 29 public final int numActiveSlots; 30 public final int numActiveSims; 31 public final int numActiveEsims; 32 33 /** Returns the current SIM state. */ getCurrentState()34 public static SimSlotState getCurrentState() { 35 int numActiveSlots = 0; 36 int numActiveSims = 0; 37 int numActiveEsims = 0; 38 UiccController uiccController = UiccController.getInstance(); 39 // since we cannot hold lock insider UiccController, using getUiccSlots() for length only 40 for (int i = 0; i < uiccController.getUiccSlots().length; i++) { 41 UiccSlot slot = uiccController.getUiccSlot(i); 42 if (slot != null && slot.isActive()) { 43 numActiveSlots++; 44 // avoid CardState.isCardPresent() since this should not include restricted cards 45 if (slot.getCardState() == CardState.CARDSTATE_PRESENT) { 46 if (slot.isEuicc()) { 47 // need to check active profiles besides the presence of eSIM cards 48 UiccCard card = slot.getUiccCard(); 49 if (card != null && card.getNumApplications() > 0) { 50 numActiveSims++; 51 numActiveEsims++; 52 } 53 } else { 54 // physical SIMs do not always have non-null card 55 numActiveSims++; 56 } 57 } 58 } 59 } 60 return new SimSlotState(numActiveSlots, numActiveSims, numActiveEsims); 61 } 62 SimSlotState(int numActiveSlots, int numActiveSims, int numActiveEsims)63 private SimSlotState(int numActiveSlots, int numActiveSims, int numActiveEsims) { 64 this.numActiveSlots = numActiveSlots; 65 this.numActiveSims = numActiveSims; 66 this.numActiveEsims = numActiveEsims; 67 } 68 69 /** Returns whether the given phone is using a eSIM. */ isEsim(int phoneId)70 public static boolean isEsim(int phoneId) { 71 UiccSlot slot = UiccController.getInstance().getUiccSlotForPhone(phoneId); 72 if (slot != null) { 73 return slot.isEuicc(); 74 } else { 75 // should not happen, but assume we are not using eSIM 76 Rlog.e(TAG, "isEsim: slot=null for phone " + phoneId); 77 return false; 78 } 79 } 80 81 /** Returns whether the device has multiple active SIM profiles. */ isMultiSim()82 public static boolean isMultiSim() { 83 return (getCurrentState().numActiveSims > 1); 84 } 85 } 86