187 lines
5.3 KiB
Java
187 lines
5.3 KiB
Java
package org.thoughtcrime.securesms.registration.viewmodel;
|
|
|
|
import android.os.Parcel;
|
|
import android.os.Parcelable;
|
|
|
|
import androidx.annotation.NonNull;
|
|
import androidx.annotation.Nullable;
|
|
|
|
import com.google.i18n.phonenumbers.NumberParseException;
|
|
import com.google.i18n.phonenumbers.PhoneNumberUtil;
|
|
import com.google.i18n.phonenumbers.Phonenumber;
|
|
|
|
import org.whispersystems.signalservice.api.util.PhoneNumberFormatter;
|
|
|
|
import java.util.Objects;
|
|
|
|
public final class NumberViewState implements Parcelable {
|
|
|
|
public static final NumberViewState INITIAL = new Builder().build();
|
|
|
|
private final String selectedCountryName;
|
|
private final int countryCode;
|
|
private final long nationalNumber;
|
|
|
|
private NumberViewState(Builder builder) {
|
|
this.selectedCountryName = builder.countryDisplayName;
|
|
this.countryCode = builder.countryCode;
|
|
this.nationalNumber = builder.nationalNumber;
|
|
}
|
|
|
|
public Builder toBuilder() {
|
|
return new Builder().countryCode(countryCode)
|
|
.selectedCountryDisplayName(selectedCountryName)
|
|
.nationalNumber(nationalNumber);
|
|
}
|
|
|
|
public int getCountryCode() {
|
|
return countryCode;
|
|
}
|
|
|
|
public long getNationalNumber() {
|
|
return nationalNumber;
|
|
}
|
|
|
|
public String getCountryDisplayName() {
|
|
if (selectedCountryName != null) {
|
|
return selectedCountryName;
|
|
}
|
|
|
|
PhoneNumberUtil util = PhoneNumberUtil.getInstance();
|
|
|
|
if (isValid()) {
|
|
String actualCountry = getActualCountry(util, getE164Number());
|
|
|
|
if (actualCountry != null) {
|
|
return actualCountry;
|
|
}
|
|
}
|
|
|
|
String regionCode = util.getRegionCodeForCountryCode(countryCode);
|
|
return PhoneNumberFormatter.getRegionDisplayName(regionCode);
|
|
}
|
|
|
|
/**
|
|
* Finds actual name of region from a valid number. So for example +1 might map to US or Canada or other territories.
|
|
*/
|
|
private static @Nullable String getActualCountry(@NonNull PhoneNumberUtil util, @NonNull String e164Number) {
|
|
try {
|
|
Phonenumber.PhoneNumber phoneNumber = getPhoneNumber(util, e164Number);
|
|
String regionCode = util.getRegionCodeForNumber(phoneNumber);
|
|
|
|
if (regionCode != null) {
|
|
return PhoneNumberFormatter.getRegionDisplayName(regionCode);
|
|
}
|
|
|
|
} catch (NumberParseException e) {
|
|
return null;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public boolean isValid() {
|
|
return PhoneNumberFormatter.isValidNumber(getE164Number(), Integer.toString(getCountryCode()));
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
int hash = countryCode;
|
|
hash *= 31;
|
|
hash += (int) (nationalNumber ^ (nationalNumber >>> 32));
|
|
hash *= 31;
|
|
hash += selectedCountryName != null ? selectedCountryName.hashCode() : 0;
|
|
return hash;
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(@Nullable Object obj) {
|
|
if (obj == null) return false;
|
|
if (obj.getClass() != getClass()) return false;
|
|
|
|
NumberViewState other = (NumberViewState) obj;
|
|
|
|
return other.countryCode == countryCode &&
|
|
other.nationalNumber == nationalNumber &&
|
|
Objects.equals(other.selectedCountryName, selectedCountryName);
|
|
}
|
|
|
|
public String getE164Number() {
|
|
return getConfiguredE164Number(countryCode, nationalNumber);
|
|
}
|
|
|
|
public String getFullFormattedNumber() {
|
|
return formatNumber(PhoneNumberUtil.getInstance(), getE164Number());
|
|
}
|
|
|
|
private static String formatNumber(@NonNull PhoneNumberUtil util, @NonNull String e164Number) {
|
|
try {
|
|
Phonenumber.PhoneNumber number = getPhoneNumber(util, e164Number);
|
|
return util.format(number, PhoneNumberUtil.PhoneNumberFormat.INTERNATIONAL);
|
|
} catch (NumberParseException e) {
|
|
return e164Number;
|
|
}
|
|
}
|
|
|
|
private static String getConfiguredE164Number(int countryCode, long number) {
|
|
return PhoneNumberFormatter.formatE164(String.valueOf(countryCode), String.valueOf(number));
|
|
}
|
|
|
|
private static Phonenumber.PhoneNumber getPhoneNumber(@NonNull PhoneNumberUtil util, @NonNull String e164Number)
|
|
throws NumberParseException
|
|
{
|
|
return util.parse(e164Number, null);
|
|
}
|
|
|
|
public static class Builder {
|
|
private String countryDisplayName;
|
|
private int countryCode;
|
|
private long nationalNumber;
|
|
|
|
public Builder countryCode(int countryCode) {
|
|
this.countryCode = countryCode;
|
|
return this;
|
|
}
|
|
|
|
public Builder selectedCountryDisplayName(String countryDisplayName) {
|
|
this.countryDisplayName = countryDisplayName;
|
|
return this;
|
|
}
|
|
|
|
public Builder nationalNumber(long nationalNumber) {
|
|
this.nationalNumber = nationalNumber;
|
|
return this;
|
|
}
|
|
|
|
public NumberViewState build() {
|
|
return new NumberViewState(this);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public int describeContents() {
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public void writeToParcel(Parcel parcel, int i) {
|
|
parcel.writeString(selectedCountryName);
|
|
parcel.writeInt(countryCode);
|
|
parcel.writeLong(nationalNumber);
|
|
}
|
|
|
|
public static final Creator<NumberViewState> CREATOR = new Creator<NumberViewState>() {
|
|
@Override
|
|
public NumberViewState createFromParcel(Parcel in) {
|
|
return new Builder().selectedCountryDisplayName(in.readString())
|
|
.countryCode(in.readInt())
|
|
.nationalNumber(in.readLong())
|
|
.build();
|
|
}
|
|
|
|
@Override
|
|
public NumberViewState[] newArray(int size) {
|
|
return new NumberViewState[size];
|
|
}
|
|
};
|
|
}
|