blob: 7b1309685e6737d3f340d27383b6c1cdfe36f7e6 [file] [log] [blame]
Marcus Hagerott66e8b222016-10-23 15:41:55 -07001/*
2 * Copyright (C) 2016 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 */
16package com.android.contacts.common.model;
17
18import android.os.Build;
19import android.support.annotation.RequiresApi;
Marcus Hagerott216e2972016-10-26 15:53:42 -070020import android.telephony.PhoneNumberUtils;
Marcus Hagerott66e8b222016-10-23 15:41:55 -070021import android.telephony.SubscriptionInfo;
22import android.telephony.TelephonyManager;
23import android.util.Log;
24
Marcus Hagerott2aa31982016-10-25 14:36:25 -070025import java.util.ArrayList;
Marcus Hagerott66e8b222016-10-23 15:41:55 -070026import java.util.Arrays;
Marcus Hagerott66e8b222016-10-23 15:41:55 -070027import java.util.List;
Marcus Hagerott216e2972016-10-26 15:53:42 -070028import java.util.Locale;
Marcus Hagerott66e8b222016-10-23 15:41:55 -070029import java.util.Objects;
30
31/**
32 * Holds data for a SIM card in the device.
33 */
34public class SimCard {
35
36 private static final String TAG = "SimCard";
37
38 public static final int NO_SUBSCRIPTION_ID = -1;
39
40 // This state is created from the info we get from the system
41 private final String mSimId;
42 private final int mSubscriptionId;
43 private final CharSequence mCarrierName;
44 private final CharSequence mDisplayName;
45 private final String mPhoneNumber;
46 private final String mCountryCode;
47
48 // This is our own state that we associate with SIM cards. Currently these are only used
49 // in the GoogleContacts app.
50 // Note: these are logically immutable but are not final to reduce required constructor
51 // parameters
52 private boolean mDismissed = false;
53 private boolean mImported = false;
54
55 private List<SimContact> mContacts;
56
57 public SimCard(SimCard other) {
58 mSimId = other.mSimId;
59 mSubscriptionId = other.mSubscriptionId;
60 mCarrierName = other.mCarrierName;
61 mDisplayName = other.mDisplayName;
62 mPhoneNumber = other.mPhoneNumber;
63 mCountryCode = other.mCountryCode;
64 mDismissed = other.mDismissed;
65 mImported = other.mImported;
Marcus Hagerott2aa31982016-10-25 14:36:25 -070066 if (other.mContacts != null) {
67 mContacts = new ArrayList<>(other.mContacts);
68 }
Marcus Hagerott66e8b222016-10-23 15:41:55 -070069 }
70
71 public SimCard(String simId, int subscriptionId, CharSequence carrierName,
72 CharSequence displayName, String phoneNumber, String countryCode) {
73 mSimId = simId;
74 mSubscriptionId = subscriptionId;
75 mCarrierName = carrierName;
76 mDisplayName = displayName;
77 mPhoneNumber = phoneNumber;
Marcus Hagerott216e2972016-10-26 15:53:42 -070078 mCountryCode = countryCode != null ? countryCode.toUpperCase(Locale.US) : null;
Marcus Hagerott66e8b222016-10-23 15:41:55 -070079 }
80
81 public SimCard(String simId, CharSequence carrierName,
82 CharSequence displayName, String phoneNumber, String countryCode) {
83 this(simId, NO_SUBSCRIPTION_ID, carrierName, displayName, phoneNumber, countryCode);
84 }
85
86 public String getSimId() {
87 return mSimId;
88 }
89
90 public int getSubscriptionId() {
91 return mSubscriptionId;
92 }
93
Marcus Hagerott2aa31982016-10-25 14:36:25 -070094 public boolean hasValidSubscriptionId() {
95 return mSubscriptionId != NO_SUBSCRIPTION_ID;
96 }
97
Marcus Hagerott216e2972016-10-26 15:53:42 -070098 public CharSequence getDisplayName() {
99 return mDisplayName;
100 }
101
102 public String getPhone() {
103 return mPhoneNumber;
104 }
105
106 public CharSequence getFormattedPhone() {
107 if (mPhoneNumber == null) {
108 return null;
109 }
110 return PhoneNumberUtils.formatNumber(mPhoneNumber, mCountryCode);
111 }
112
Marcus Hagerott8636d1e2016-10-27 19:14:12 -0700113 public boolean hasPhone() {
114 return mPhoneNumber != null;
115 }
116
Marcus Hagerott2aa31982016-10-25 14:36:25 -0700117 public String getCountryCode() {
118 return mCountryCode;
119 }
120
Marcus Hagerott1dd62282016-11-07 16:31:47 -0800121 /**
122 * Returns whether the contacts for this SIM card have been initialized.
123 */
124 public boolean areContactsAvailable() {
125 return mContacts != null;
126 }
127
128 /**
129 * Returns whether this SIM card has any SIM contacts.
130 *
131 * A precondition of this method is that the contacts have been initialized.
132 */
Marcus Hagerott66e8b222016-10-23 15:41:55 -0700133 public boolean hasContacts() {
134 if (mContacts == null) {
135 throw new IllegalStateException("Contacts not loaded.");
136 }
137 return !mContacts.isEmpty();
138 }
139
Marcus Hagerott1dd62282016-11-07 16:31:47 -0800140 /**
141 * Returns the number of contacts stored on this SIM card.
142 *
143 * A precondition of this method is that the contacts have been initialized.
144 */
Marcus Hagerott66e8b222016-10-23 15:41:55 -0700145 public int getContactCount() {
146 if (mContacts == null) {
147 throw new IllegalStateException("Contacts not loaded.");
148 }
149 return mContacts.size();
150 }
151
152 public boolean isDismissed() {
153 return mDismissed;
154 }
155
156 public boolean isImported() {
157 return mImported;
158 }
159
160 public boolean isImportable() {
161 if (Log.isLoggable(TAG, Log.DEBUG)) {
162 Log.d(TAG, "isImportable: isDismissed? " + isDismissed() +
163 " isImported? " + isImported() + " contacts=" + mContacts);
164 }
165 return !isDismissed() && !isImported() && hasContacts();
166 }
167
Marcus Hagerott1dd62282016-11-07 16:31:47 -0800168 /**
169 * Returns the contacts for this SIM card or null if the contacts have not been initialized.
170 */
Marcus Hagerott66e8b222016-10-23 15:41:55 -0700171 public List<SimContact> getContacts() {
Marcus Hagerott66e8b222016-10-23 15:41:55 -0700172 return mContacts;
173 }
174
Marcus Hagerott66e8b222016-10-23 15:41:55 -0700175 public SimCard withImportAndDismissStates(boolean imported, boolean dismissed) {
176 SimCard copy = new SimCard(this);
177 copy.mImported = imported;
178 copy.mDismissed = dismissed;
179 return copy;
180 }
181
182 public SimCard withImportedState(boolean imported) {
183 return withImportAndDismissStates(imported, mDismissed);
184 }
185
186 public SimCard withDismissedState(boolean dismissed) {
Marcus Hagerott76c06332016-11-08 13:33:50 -0800187 return withImportAndDismissStates(mImported, dismissed);
Marcus Hagerott66e8b222016-10-23 15:41:55 -0700188 }
189
Marcus Hagerott2aa31982016-10-25 14:36:25 -0700190 public SimCard withContacts(List<SimContact> contacts) {
191 final SimCard copy = new SimCard(this);
192 copy.mContacts = contacts;
193 return copy;
194 }
195
Marcus Hagerott66e8b222016-10-23 15:41:55 -0700196 public SimCard withContacts(SimContact... contacts) {
197 final SimCard copy = new SimCard(this);
198 copy.mContacts = Arrays.asList(contacts);
199 return copy;
200 }
201
202 @Override
203 public boolean equals(Object o) {
204 if (this == o) return true;
205 if (o == null || getClass() != o.getClass()) return false;
206
207 SimCard simCard = (SimCard) o;
208
209 return mSubscriptionId == simCard.mSubscriptionId && mDismissed == simCard.mDismissed &&
210 mImported == simCard.mImported && Objects.equals(mSimId, simCard.mSimId) &&
211 Objects.equals(mPhoneNumber, simCard.mPhoneNumber) &&
212 Objects.equals(mCountryCode, simCard.mCountryCode);
213 }
214
215 @Override
216 public int hashCode() {
217 int result = Objects.hash(mSimId, mPhoneNumber, mCountryCode);
218 result = 31 * result + mSubscriptionId;
219 result = 31 * result + (mDismissed ? 1 : 0);
220 result = 31 * result + (mImported ? 1 : 0);
221 return result;
222 }
223
224
225 @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
226 public static SimCard create(SubscriptionInfo info) {
227 return new SimCard(info.getIccId(), info.getSubscriptionId(),
228 info.getCarrierName(), info.getDisplayName(), info.getNumber(),
229 info.getCountryIso());
230 }
231
Marcus Hagerott2aa31982016-10-25 14:36:25 -0700232 public static SimCard create(TelephonyManager telephony, String displayLabel) {
233 if (telephony.getSimState() == TelephonyManager.SIM_STATE_READY) {
234 return new SimCard(telephony.getSimSerialNumber(),
235 telephony.getSimOperatorName(), displayLabel, telephony.getLine1Number(),
236 telephony.getSimCountryIso());
237 } else {
238 // This should never happen but in case it does just fallback to an "empty" instance
239 return new SimCard(/* SIM id */ "", /* operator name */ null, displayLabel,
240 /* phone number */ "", /* Country code */ null);
241 }
Marcus Hagerott66e8b222016-10-23 15:41:55 -0700242 }
243}