1 /* 2 * Copyright 2017 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 android.telephony; 18 19 import android.annotation.CallSuper; 20 import android.annotation.IntDef; 21 import android.annotation.Nullable; 22 import android.os.Parcel; 23 import android.os.Parcelable; 24 import android.text.TextUtils; 25 26 import java.lang.annotation.Retention; 27 import java.lang.annotation.RetentionPolicy; 28 import java.util.Objects; 29 30 /** 31 * CellIdentity represents the identity of a unique cell. This is the base class for 32 * CellIdentityXxx which represents cell identity for specific network access technology. 33 */ 34 public abstract class CellIdentity implements Parcelable { 35 /** 36 * Cell identity type 37 * @hide 38 */ 39 @Retention(RetentionPolicy.SOURCE) 40 @IntDef(prefix = "TYPE_", value = {TYPE_GSM, TYPE_CDMA, TYPE_LTE, TYPE_WCDMA, TYPE_TDSCDMA}) 41 public @interface Type {} 42 43 /** 44 * Unknown cell identity type 45 * @hide 46 */ 47 public static final int TYPE_UNKNOWN = 0; 48 /** 49 * GSM cell identity type 50 * @hide 51 */ 52 public static final int TYPE_GSM = 1; 53 /** 54 * CDMA cell identity type 55 * @hide 56 */ 57 public static final int TYPE_CDMA = 2; 58 /** 59 * LTE cell identity type 60 * @hide 61 */ 62 public static final int TYPE_LTE = 3; 63 /** 64 * WCDMA cell identity type 65 * @hide 66 */ 67 public static final int TYPE_WCDMA = 4; 68 /** 69 * TDS-CDMA cell identity type 70 * @hide 71 */ 72 public static final int TYPE_TDSCDMA = 5; 73 74 /** @hide */ 75 public static final int INVALID_CHANNEL_NUMBER = -1; 76 77 // Log tag 78 /** @hide */ 79 protected final String mTag; 80 // Cell identity type 81 /** @hide */ 82 protected final int mType; 83 // 3-digit Mobile Country Code in string format. Null for CDMA cell identity. 84 /** @hide */ 85 protected final String mMccStr; 86 // 2 or 3-digit Mobile Network Code in string format. Null for CDMA cell identity. 87 /** @hide */ 88 protected final String mMncStr; 89 90 // long alpha Operator Name String or Enhanced Operator Name String 91 /** @hide */ 92 protected final String mAlphaLong; 93 // short alpha Operator Name String or Enhanced Operator Name String 94 /** @hide */ 95 protected final String mAlphaShort; 96 97 /** @hide */ CellIdentity(String tag, int type, String mcc, String mnc, String alphal, String alphas)98 protected CellIdentity(String tag, int type, String mcc, String mnc, String alphal, 99 String alphas) { 100 mTag = tag; 101 mType = type; 102 103 // Only allow INT_MAX if unknown string mcc/mnc 104 if (mcc == null || mcc.matches("^[0-9]{3}$")) { 105 mMccStr = mcc; 106 } else if (mcc.isEmpty() || mcc.equals(String.valueOf(Integer.MAX_VALUE))) { 107 // If the mccStr is empty or unknown, set it as null. 108 mMccStr = null; 109 } else { 110 // TODO: b/69384059 Should throw IllegalArgumentException for the invalid MCC format 111 // after the bug got fixed. 112 mMccStr = null; 113 log("invalid MCC format: " + mcc); 114 } 115 116 if (mnc == null || mnc.matches("^[0-9]{2,3}$")) { 117 mMncStr = mnc; 118 } else if (mnc.isEmpty() || mnc.equals(String.valueOf(Integer.MAX_VALUE))) { 119 // If the mncStr is empty or unknown, set it as null. 120 mMncStr = null; 121 } else { 122 // TODO: b/69384059 Should throw IllegalArgumentException for the invalid MNC format 123 // after the bug got fixed. 124 mMncStr = null; 125 log("invalid MNC format: " + mnc); 126 } 127 mAlphaLong = alphal; 128 mAlphaShort = alphas; 129 } 130 131 /** Implement the Parcelable interface */ 132 @Override describeContents()133 public int describeContents() { 134 return 0; 135 } 136 137 /** 138 * @hide 139 * @return The type of the cell identity 140 */ getType()141 public @Type int getType() { return mType; } 142 143 /** 144 * Returns the channel number of the cell identity. 145 * 146 * @hide 147 * @return The channel number, or {@link #INVALID_CHANNEL_NUMBER} if not implemented 148 */ getChannelNumber()149 public int getChannelNumber() { 150 return INVALID_CHANNEL_NUMBER; 151 } 152 153 /** 154 * @return The long alpha tag associated with the current scan result (may be the operator 155 * name string or extended operator name string). May be null if unknown. 156 */ 157 @Nullable getOperatorAlphaLong()158 public CharSequence getOperatorAlphaLong() { 159 return mAlphaLong; 160 } 161 162 /** 163 * @return The short alpha tag associated with the current scan result (may be the operator 164 * name string or extended operator name string). May be null if unknown. 165 */ 166 @Nullable getOperatorAlphaShort()167 public CharSequence getOperatorAlphaShort() { 168 return mAlphaShort; 169 } 170 171 @Override equals(Object other)172 public boolean equals(Object other) { 173 if (!(other instanceof CellIdentity)) { 174 return false; 175 } 176 177 CellIdentity o = (CellIdentity) other; 178 return TextUtils.equals(mAlphaLong, o.mAlphaLong) 179 && TextUtils.equals(mAlphaShort, o.mAlphaShort); 180 } 181 182 @Override hashCode()183 public int hashCode() { 184 return Objects.hash(mAlphaLong, mAlphaShort, mMccStr, mMncStr, mType); 185 } 186 187 /** 188 * Used by child classes for parceling. 189 * 190 * @hide 191 */ 192 @CallSuper writeToParcel(Parcel dest, int type)193 public void writeToParcel(Parcel dest, int type) { 194 dest.writeInt(type); 195 dest.writeString(mMccStr); 196 dest.writeString(mMncStr); 197 dest.writeString(mAlphaLong); 198 dest.writeString(mAlphaShort); 199 } 200 201 /** 202 * Construct from Parcel 203 * @hide 204 */ CellIdentity(String tag, int type, Parcel source)205 protected CellIdentity(String tag, int type, Parcel source) { 206 this(tag, type, source.readString(), source.readString(), 207 source.readString(), source.readString()); 208 } 209 210 /** Implement the Parcelable interface */ 211 public static final Creator<CellIdentity> CREATOR = 212 new Creator<CellIdentity>() { 213 @Override 214 public CellIdentity createFromParcel(Parcel in) { 215 int type = in.readInt(); 216 switch (type) { 217 case TYPE_GSM: return CellIdentityGsm.createFromParcelBody(in); 218 case TYPE_WCDMA: return CellIdentityWcdma.createFromParcelBody(in); 219 case TYPE_CDMA: return CellIdentityCdma.createFromParcelBody(in); 220 case TYPE_LTE: return CellIdentityLte.createFromParcelBody(in); 221 case TYPE_TDSCDMA: return CellIdentityTdscdma.createFromParcelBody(in); 222 default: throw new IllegalArgumentException("Bad Cell identity Parcel"); 223 } 224 } 225 226 @Override 227 public CellIdentity[] newArray(int size) { 228 return new CellIdentity[size]; 229 } 230 }; 231 232 /** @hide */ log(String s)233 protected void log(String s) { 234 Rlog.w(mTag, s); 235 } 236 }