• 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 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