1 /*
2  * Copyright (C) 2012 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.NonNull;
20 import android.annotation.Nullable;
21 import android.annotation.SystemApi;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 
25 /**
26  * Represents the location and geographical scope of a cell broadcast message.
27  * For GSM/UMTS, the Location Area and Cell ID are set when the broadcast
28  * geographical scope is cell wide or Location Area wide. For CDMA, the
29  * broadcast geographical scope is always PLMN wide.
30  *
31  * @hide
32  */
33 @SystemApi
34 public final class SmsCbLocation implements Parcelable {
35 
36     /** The PLMN. Note that this field may be an empty string. */
37     @NonNull
38     private final String mPlmn;
39 
40     private final int mLac;
41     private final int mCid;
42 
43     /**
44      * Construct an empty location object. This is used for some test cases, and for
45      * cell broadcasts saved in older versions of the database without location info.
46      * @hide
47      */
SmsCbLocation()48     public SmsCbLocation() {
49         mPlmn = "";
50         mLac = -1;
51         mCid = -1;
52     }
53 
54     /**
55      * Construct a location object for the PLMN. This class is immutable, so
56      * the same object can be reused for multiple broadcasts.
57      * @hide
58      */
SmsCbLocation(String plmn)59     public SmsCbLocation(String plmn) {
60         mPlmn = plmn;
61         mLac = -1;
62         mCid = -1;
63     }
64 
65     /**
66      * Construct a location object for the PLMN, LAC, and Cell ID. This class is immutable, so
67      * the same object can be reused for multiple broadcasts.
68      *
69      * @param plmn the MCC/MNC of the network
70      * @param lac the GSM location area code, or UMTS service area code
71      * @param cid the GSM or UMTS cell ID
72      */
SmsCbLocation(@onNull String plmn, int lac, int cid)73     public SmsCbLocation(@NonNull String plmn, int lac, int cid) {
74         mPlmn = plmn;
75         mLac = lac;
76         mCid = cid;
77     }
78 
79     /**
80      * Initialize the object from a Parcel.
81      * @hide
82      */
SmsCbLocation(Parcel in)83     public SmsCbLocation(Parcel in) {
84         mPlmn = in.readString();
85         mLac = in.readInt();
86         mCid = in.readInt();
87     }
88 
89     /**
90      * Returns the MCC/MNC of the network as a String.
91      * @return the PLMN identifier (MCC+MNC) as a String
92      */
93     @NonNull
getPlmn()94     public String getPlmn() {
95         return mPlmn;
96     }
97 
98     /**
99      * Returns the GSM location area code, or UMTS service area code.
100      * @return location area code, -1 if unknown, 0xffff max legal value
101      */
getLac()102     public int getLac() {
103         return mLac;
104     }
105 
106     /**
107      * Returns the GSM or UMTS cell ID.
108      * @return gsm cell id, -1 if unknown, 0xffff max legal value
109      */
getCid()110     public int getCid() {
111         return mCid;
112     }
113 
114     @Override
hashCode()115     public int hashCode() {
116         int hash = mPlmn.hashCode();
117         hash = hash * 31 + mLac;
118         hash = hash * 31 + mCid;
119         return hash;
120     }
121 
122     @Override
equals(Object o)123     public boolean equals(Object o) {
124         if (o == this) {
125             return true;
126         }
127         if (o == null || !(o instanceof SmsCbLocation)) {
128             return false;
129         }
130         SmsCbLocation other = (SmsCbLocation) o;
131         return mPlmn.equals(other.mPlmn) && mLac == other.mLac && mCid == other.mCid;
132     }
133 
134     @Override
toString()135     public String toString() {
136         return '[' + mPlmn + ',' + mLac + ',' + mCid + ']';
137     }
138 
139     /**
140      * Test whether this location is within the location area of the specified object.
141      *
142      * @param area the location area to compare with this location
143      * @return true if this location is contained within the specified location area
144      */
isInLocationArea(@onNull SmsCbLocation area)145     public boolean isInLocationArea(@NonNull SmsCbLocation area) {
146         if (mCid != -1 && mCid != area.mCid) {
147             return false;
148         }
149         if (mLac != -1 && mLac != area.mLac) {
150             return false;
151         }
152         return mPlmn.equals(area.mPlmn);
153     }
154 
155     /**
156      * Test whether this location is within the location area of the CellLocation.
157      *
158      * @param plmn the PLMN to use for comparison
159      * @param lac the Location Area (GSM) or Service Area (UMTS) to compare with
160      * @param cid the Cell ID to compare with
161      * @return true if this location is contained within the specified PLMN, LAC, and Cell ID
162      */
isInLocationArea(@ullable String plmn, int lac, int cid)163     public boolean isInLocationArea(@Nullable String plmn, int lac, int cid) {
164         if (!mPlmn.equals(plmn)) {
165             return false;
166         }
167 
168         if (mLac != -1 && mLac != lac) {
169             return false;
170         }
171 
172         if (mCid != -1 && mCid != cid) {
173             return false;
174         }
175 
176         return true;
177     }
178 
179     /**
180      * Flatten this object into a Parcel.
181      *
182      * @param dest  The Parcel in which the object should be written.
183      * @param flags Additional flags about how the object should be written (ignored).
184      */
185     @Override
writeToParcel(Parcel dest, int flags)186     public void writeToParcel(Parcel dest, int flags) {
187         dest.writeString(mPlmn);
188         dest.writeInt(mLac);
189         dest.writeInt(mCid);
190     }
191 
192     @NonNull
193     public static final Parcelable.Creator<SmsCbLocation> CREATOR =
194             new Parcelable.Creator<SmsCbLocation>() {
195         @Override
196         public SmsCbLocation createFromParcel(Parcel in) {
197             return new SmsCbLocation(in);
198         }
199 
200         @Override
201         public SmsCbLocation[] newArray(int size) {
202             return new SmsCbLocation[size];
203         }
204     };
205 
206     /**
207      * Describe the kinds of special objects contained in the marshalled representation.
208      * @return a bitmask indicating this Parcelable contains no special objects
209      */
210     @Override
describeContents()211     public int describeContents() {
212         return 0;
213     }
214 }
215