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