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.IntDef;
20 import android.annotation.Nullable;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 
24 import java.lang.annotation.Retention;
25 import java.lang.annotation.RetentionPolicy;
26 import java.util.Arrays;
27 import java.util.Objects;
28 
29 /**
30  * Description of a mobile network registration state
31  * @hide
32  */
33 public class NetworkRegistrationState implements Parcelable {
34     /**
35      * Network domain
36      * @hide
37      */
38     @Retention(RetentionPolicy.SOURCE)
39     @IntDef(prefix = "DOMAIN_", value = {DOMAIN_CS, DOMAIN_PS})
40     public @interface Domain {}
41 
42     /** Circuit switching domain */
43     public static final int DOMAIN_CS = 1;
44     /** Packet switching domain */
45     public static final int DOMAIN_PS = 2;
46 
47     /**
48      * Registration state
49      * @hide
50      */
51     @Retention(RetentionPolicy.SOURCE)
52     @IntDef(prefix = "REG_STATE_",
53             value = {REG_STATE_NOT_REG_NOT_SEARCHING, REG_STATE_HOME, REG_STATE_NOT_REG_SEARCHING,
54                     REG_STATE_DENIED, REG_STATE_UNKNOWN, REG_STATE_ROAMING})
55     public @interface RegState {}
56 
57     /** Not registered. The device is not currently searching a new operator to register */
58     public static final int REG_STATE_NOT_REG_NOT_SEARCHING = 0;
59     /** Registered on home network */
60     public static final int REG_STATE_HOME = 1;
61     /** Not registered. The device is currently searching a new operator to register */
62     public static final int REG_STATE_NOT_REG_SEARCHING = 2;
63     /** Registration denied */
64     public static final int REG_STATE_DENIED = 3;
65     /** Registration state is unknown */
66     public static final int REG_STATE_UNKNOWN = 4;
67     /** Registered on roaming network */
68     public static final int REG_STATE_ROAMING = 5;
69 
70     /**
71      * Supported service type
72      * @hide
73      */
74     @Retention(RetentionPolicy.SOURCE)
75     @IntDef(prefix = "SERVICE_TYPE_",
76             value = {SERVICE_TYPE_VOICE, SERVICE_TYPE_DATA, SERVICE_TYPE_SMS, SERVICE_TYPE_VIDEO,
77                     SERVICE_TYPE_EMERGENCY})
78     public @interface ServiceType {}
79 
80     public static final int SERVICE_TYPE_VOICE = 1;
81     public static final int SERVICE_TYPE_DATA = 2;
82     public static final int SERVICE_TYPE_SMS = 3;
83     public static final int SERVICE_TYPE_VIDEO = 4;
84     public static final int SERVICE_TYPE_EMERGENCY = 5;
85 
86     /** {@link AccessNetworkConstants.TransportType}*/
87     private final int mTransportType;
88 
89     @Domain
90     private final int mDomain;
91 
92     @RegState
93     private final int mRegState;
94 
95     private final int mAccessNetworkTechnology;
96 
97     private final int mReasonForDenial;
98 
99     private final boolean mEmergencyOnly;
100 
101     private final int[] mAvailableServices;
102 
103     @Nullable
104     private final CellIdentity mCellIdentity;
105 
106     @Nullable
107     private VoiceSpecificRegistrationStates mVoiceSpecificStates;
108 
109     @Nullable
110     private DataSpecificRegistrationStates mDataSpecificStates;
111 
112     /**
113      * @param transportType Transport type. Must be {@link AccessNetworkConstants.TransportType}
114      * @param domain Network domain. Must be DOMAIN_CS or DOMAIN_PS.
115      * @param regState Network registration state.
116      * @param accessNetworkTechnology See TelephonyManager NETWORK_TYPE_XXXX.
117      * @param reasonForDenial Reason for denial if the registration state is DENIED.
118      * @param availableServices The supported service.
119      * @param cellIdentity The identity representing a unique cell
120      */
NetworkRegistrationState(int transportType, int domain, int regState, int accessNetworkTechnology, int reasonForDenial, boolean emergencyOnly, int[] availableServices, @Nullable CellIdentity cellIdentity)121     public NetworkRegistrationState(int transportType, int domain, int regState,
122             int accessNetworkTechnology, int reasonForDenial, boolean emergencyOnly,
123             int[] availableServices, @Nullable CellIdentity cellIdentity) {
124         mTransportType = transportType;
125         mDomain = domain;
126         mRegState = regState;
127         mAccessNetworkTechnology = accessNetworkTechnology;
128         mReasonForDenial = reasonForDenial;
129         mAvailableServices = availableServices;
130         mCellIdentity = cellIdentity;
131         mEmergencyOnly = emergencyOnly;
132     }
133 
134     /**
135      * Constructor for voice network registration states.
136      * @hide
137      */
NetworkRegistrationState(int transportType, int domain, int regState, int accessNetworkTechnology, int reasonForDenial, boolean emergencyOnly, int[] availableServices, @Nullable CellIdentity cellIdentity, boolean cssSupported, int roamingIndicator, int systemIsInPrl, int defaultRoamingIndicator)138     public NetworkRegistrationState(int transportType, int domain, int regState,
139             int accessNetworkTechnology, int reasonForDenial, boolean emergencyOnly,
140             int[] availableServices, @Nullable CellIdentity cellIdentity, boolean cssSupported,
141             int roamingIndicator, int systemIsInPrl, int defaultRoamingIndicator) {
142         this(transportType, domain, regState, accessNetworkTechnology,
143                 reasonForDenial, emergencyOnly, availableServices, cellIdentity);
144 
145         mVoiceSpecificStates = new VoiceSpecificRegistrationStates(cssSupported, roamingIndicator,
146                 systemIsInPrl, defaultRoamingIndicator);
147     }
148 
149     /**
150      * Constructor for data network registration states.
151      * @hide
152      */
NetworkRegistrationState(int transportType, int domain, int regState, int accessNetworkTechnology, int reasonForDenial, boolean emergencyOnly, int[] availableServices, @Nullable CellIdentity cellIdentity, int maxDataCalls)153     public NetworkRegistrationState(int transportType, int domain, int regState,
154             int accessNetworkTechnology, int reasonForDenial, boolean emergencyOnly,
155             int[] availableServices, @Nullable CellIdentity cellIdentity, int maxDataCalls) {
156         this(transportType, domain, regState, accessNetworkTechnology,
157                 reasonForDenial, emergencyOnly, availableServices, cellIdentity);
158 
159         mDataSpecificStates = new DataSpecificRegistrationStates(maxDataCalls);
160     }
161 
NetworkRegistrationState(Parcel source)162     protected NetworkRegistrationState(Parcel source) {
163         mTransportType = source.readInt();
164         mDomain = source.readInt();
165         mRegState = source.readInt();
166         mAccessNetworkTechnology = source.readInt();
167         mReasonForDenial = source.readInt();
168         mEmergencyOnly = source.readBoolean();
169         mAvailableServices = source.createIntArray();
170         mCellIdentity = source.readParcelable(CellIdentity.class.getClassLoader());
171         mVoiceSpecificStates = source.readParcelable(
172                 VoiceSpecificRegistrationStates.class.getClassLoader());
173         mDataSpecificStates = source.readParcelable(
174                 DataSpecificRegistrationStates.class.getClassLoader());
175     }
176 
177     /**
178      * @return The transport type.
179      */
getTransportType()180     public int getTransportType() { return mTransportType; }
181 
182     /**
183      * @return The network domain.
184      */
getDomain()185     public @Domain int getDomain() { return mDomain; }
186 
187     /**
188      * @return The registration state.
189      */
getRegState()190     public @RegState int getRegState() {
191         return mRegState;
192     }
193 
194     /**
195      * @return Whether emergency is enabled.
196      */
isEmergencyEnabled()197     public boolean isEmergencyEnabled() { return mEmergencyOnly; }
198 
199     /**
200      * @return List of available service types.
201      */
getAvailableServices()202     public int[] getAvailableServices() { return mAvailableServices; }
203 
204     /**
205      * @return The access network technology. Must be one of TelephonyManager.NETWORK_TYPE_XXXX.
206      */
getAccessNetworkTechnology()207     public int getAccessNetworkTechnology() {
208         return mAccessNetworkTechnology;
209     }
210 
211     /**
212      * @return Reason for denial from network.
213      */
getReasonForDenial()214     public int getReasonForDenial() {
215         return mReasonForDenial;
216     }
217 
218     /**
219      * @return The cell information.
220      */
getCellIdentity()221     public CellIdentity getCellIdentity() {
222         return mCellIdentity;
223     }
224 
225     /**
226      * @hide
227      */
228     @Nullable
getVoiceSpecificStates()229     public VoiceSpecificRegistrationStates getVoiceSpecificStates() {
230         return mVoiceSpecificStates;
231     }
232 
233     /**
234      * @hide
235      */
236     @Nullable
getDataSpecificStates()237     public DataSpecificRegistrationStates getDataSpecificStates() {
238         return mDataSpecificStates;
239     }
240 
241     @Override
describeContents()242     public int describeContents() {
243         return 0;
244     }
245 
regStateToString(int regState)246     private static String regStateToString(int regState) {
247         switch (regState) {
248             case REG_STATE_NOT_REG_NOT_SEARCHING: return "NOT_REG_NOT_SEARCHING";
249             case REG_STATE_HOME: return "HOME";
250             case REG_STATE_NOT_REG_SEARCHING: return "NOT_REG_SEARCHING";
251             case REG_STATE_DENIED: return "DENIED";
252             case REG_STATE_UNKNOWN: return "UNKNOWN";
253             case REG_STATE_ROAMING: return "ROAMING";
254         }
255         return "Unknown reg state " + regState;
256     }
257 
258     @Override
toString()259     public String toString() {
260         return new StringBuilder("NetworkRegistrationState{")
261                 .append("transportType=").append(mTransportType)
262                 .append(" domain=").append((mDomain == DOMAIN_CS) ? "CS" : "PS")
263                 .append(" regState=").append(regStateToString(mRegState))
264                 .append(" accessNetworkTechnology=")
265                 .append(TelephonyManager.getNetworkTypeName(mAccessNetworkTechnology))
266                 .append(" reasonForDenial=").append(mReasonForDenial)
267                 .append(" emergencyEnabled=").append(mEmergencyOnly)
268                 .append(" supportedServices=").append(mAvailableServices)
269                 .append(" cellIdentity=").append(mCellIdentity)
270                 .append(" voiceSpecificStates=").append(mVoiceSpecificStates)
271                 .append(" dataSpecificStates=").append(mDataSpecificStates)
272                 .append("}").toString();
273     }
274 
275     @Override
hashCode()276     public int hashCode() {
277         return Objects.hash(mTransportType, mDomain, mRegState, mAccessNetworkTechnology,
278                 mReasonForDenial, mEmergencyOnly, mAvailableServices, mCellIdentity,
279                 mVoiceSpecificStates, mDataSpecificStates);
280     }
281 
282     @Override
equals(Object o)283     public boolean equals(Object o) {
284         if (this == o) return true;
285 
286         if (o == null || !(o instanceof NetworkRegistrationState)) {
287             return false;
288         }
289 
290         NetworkRegistrationState other = (NetworkRegistrationState) o;
291         return mTransportType == other.mTransportType
292                 && mDomain == other.mDomain
293                 && mRegState == other.mRegState
294                 && mAccessNetworkTechnology == other.mAccessNetworkTechnology
295                 && mReasonForDenial == other.mReasonForDenial
296                 && mEmergencyOnly == other.mEmergencyOnly
297                 && (mAvailableServices == other.mAvailableServices
298                     || Arrays.equals(mAvailableServices, other.mAvailableServices))
299                 && equals(mCellIdentity, other.mCellIdentity)
300                 && equals(mVoiceSpecificStates, other.mVoiceSpecificStates)
301                 && equals(mDataSpecificStates, other.mDataSpecificStates);
302     }
303 
304     @Override
writeToParcel(Parcel dest, int flags)305     public void writeToParcel(Parcel dest, int flags) {
306         dest.writeInt(mTransportType);
307         dest.writeInt(mDomain);
308         dest.writeInt(mRegState);
309         dest.writeInt(mAccessNetworkTechnology);
310         dest.writeInt(mReasonForDenial);
311         dest.writeBoolean(mEmergencyOnly);
312         dest.writeIntArray(mAvailableServices);
313         dest.writeParcelable(mCellIdentity, 0);
314         dest.writeParcelable(mVoiceSpecificStates, 0);
315         dest.writeParcelable(mDataSpecificStates, 0);
316     }
317 
318     public static final Parcelable.Creator<NetworkRegistrationState> CREATOR =
319             new Parcelable.Creator<NetworkRegistrationState>() {
320         @Override
321         public NetworkRegistrationState createFromParcel(Parcel source) {
322             return new NetworkRegistrationState(source);
323         }
324 
325         @Override
326         public NetworkRegistrationState[] newArray(int size) {
327             return new NetworkRegistrationState[size];
328         }
329     };
330 
equals(Object o1, Object o2)331     private static boolean equals(Object o1, Object o2) {
332         if (o1 == o2) {
333             return true;
334         } else if (o1 == null) {
335             return false;
336         } else {
337             return o1.equals(o2);
338         }
339     }
340 }
341