blob: 969d96d100fa7b6276dbfaf83fec0e341ea99d09 [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.contacts.model;
import android.os.Build;
import androidx.annotation.RequiresApi;
import android.telephony.PhoneNumberUtils;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
/**
* Holds data for a SIM card in the device.
*/
public class SimCard {
private static final String TAG = "SimCard";
public static final int NO_SUBSCRIPTION_ID = -1;
// This state is created from the info we get from the system
private final String mSimId;
private final int mSubscriptionId;
private final CharSequence mCarrierName;
private final CharSequence mDisplayName;
private final String mPhoneNumber;
private final String mCountryCode;
// This is our own state that we associate with SIM cards. Currently these are only used
// in the GoogleContacts app.
// Note: these are logically immutable but are not final to reduce required constructor
// parameters
private boolean mDismissed = false;
private boolean mImported = false;
private List<SimContact> mContacts;
public SimCard(SimCard other) {
mSimId = other.mSimId;
mSubscriptionId = other.mSubscriptionId;
mCarrierName = other.mCarrierName;
mDisplayName = other.mDisplayName;
mPhoneNumber = other.mPhoneNumber;
mCountryCode = other.mCountryCode;
mDismissed = other.mDismissed;
mImported = other.mImported;
if (other.mContacts != null) {
mContacts = new ArrayList<>(other.mContacts);
}
}
public SimCard(String simId, int subscriptionId, CharSequence carrierName,
CharSequence displayName, String phoneNumber, String countryCode) {
mSimId = simId;
mSubscriptionId = subscriptionId;
mCarrierName = carrierName;
mDisplayName = displayName;
mPhoneNumber = phoneNumber;
mCountryCode = countryCode != null ? countryCode.toUpperCase(Locale.US) : null;
}
public String getSimId() {
return mSimId;
}
public int getSubscriptionId() {
return mSubscriptionId;
}
public boolean hasValidSubscriptionId() {
return mSubscriptionId != NO_SUBSCRIPTION_ID;
}
public CharSequence getDisplayName() {
return mDisplayName;
}
public String getPhone() {
return mPhoneNumber;
}
public CharSequence getFormattedPhone() {
if (mPhoneNumber == null) {
return null;
}
return PhoneNumberUtils.formatNumber(mPhoneNumber, mCountryCode);
}
public boolean hasPhone() {
return mPhoneNumber != null;
}
public String getCountryCode() {
return mCountryCode;
}
/**
* Returns whether the contacts for this SIM card have been initialized.
*/
public boolean areContactsAvailable() {
return mContacts != null;
}
/**
* Returns whether this SIM card has any SIM contacts.
*
* A precondition of this method is that the contacts have been initialized.
*/
public boolean hasContacts() {
if (mContacts == null) {
throw new IllegalStateException("Contacts not loaded.");
}
return !mContacts.isEmpty();
}
/**
* Returns the number of contacts stored on this SIM card.
*
* A precondition of this method is that the contacts have been initialized.
*/
public int getContactCount() {
if (mContacts == null) {
throw new IllegalStateException("Contacts not loaded.");
}
return mContacts.size();
}
public boolean isDismissed() {
return mDismissed;
}
public boolean isImported() {
return mImported;
}
public boolean isImportable() {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "isImportable: isDismissed? " + isDismissed() +
" isImported? " + isImported() + " contacts=" + mContacts);
}
return !isDismissed() && !isImported() && hasContacts();
}
/**
* Returns the contacts for this SIM card or null if the contacts have not been initialized.
*/
public List<SimContact> getContacts() {
return mContacts;
}
public SimCard withImportAndDismissStates(boolean imported, boolean dismissed) {
SimCard copy = new SimCard(this);
copy.mImported = imported;
copy.mDismissed = dismissed;
return copy;
}
public SimCard withImportedState(boolean imported) {
return withImportAndDismissStates(imported, mDismissed);
}
public SimCard withDismissedState(boolean dismissed) {
return withImportAndDismissStates(mImported, dismissed);
}
public SimCard withContacts(List<SimContact> contacts) {
final SimCard copy = new SimCard(this);
copy.mContacts = contacts;
return copy;
}
public SimCard withContacts(SimContact... contacts) {
final SimCard copy = new SimCard(this);
copy.mContacts = Arrays.asList(contacts);
return copy;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
SimCard simCard = (SimCard) o;
return mSubscriptionId == simCard.mSubscriptionId && mDismissed == simCard.mDismissed &&
mImported == simCard.mImported && Objects.equals(mSimId, simCard.mSimId) &&
Objects.equals(mPhoneNumber, simCard.mPhoneNumber) &&
Objects.equals(mCountryCode, simCard.mCountryCode);
}
@Override
public int hashCode() {
int result = Objects.hash(mSimId, mPhoneNumber, mCountryCode);
result = 31 * result + mSubscriptionId;
result = 31 * result + (mDismissed ? 1 : 0);
result = 31 * result + (mImported ? 1 : 0);
return result;
}
@Override
public String toString() {
return "SimCard{" +
"mSimId='" + mSimId + '\'' +
", mSubscriptionId=" + mSubscriptionId +
", mCarrierName=" + mCarrierName +
", mDisplayName=" + mDisplayName +
", mPhoneNumber='" + mPhoneNumber + '\'' +
", mCountryCode='" + mCountryCode + '\'' +
", mDismissed=" + mDismissed +
", mImported=" + mImported +
", mContacts=" + mContacts +
'}';
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
public static SimCard create(SubscriptionInfo info) {
return new SimCard(info.getIccId(), info.getSubscriptionId(),
info.getCarrierName(), info.getDisplayName(), info.getNumber(),
info.getCountryIso());
}
public static SimCard create(TelephonyManager telephony, String displayLabel) {
if (telephony.getSimState() == TelephonyManager.SIM_STATE_READY) {
return new SimCard(telephony.getSimSerialNumber(), telephony.getSubscriptionId(),
telephony.getSimOperatorName(), displayLabel, telephony.getLine1Number(),
telephony.getSimCountryIso());
} else {
// This should never happen but in case it does just fallback to an "empty" instance
return new SimCard(/* SIM id */ "",
/* subscriptionId */ SubscriptionManager.INVALID_SUBSCRIPTION_ID,
/* operator name */ null, displayLabel,
/* phone number */ "", /* Country code */ null);
}
}
}