1 /*
2  * Copyright (C) 2006 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.cdma;
18 
19 import android.compat.annotation.UnsupportedAppUsage;
20 import android.os.Build;
21 import android.os.Bundle;
22 import android.telephony.CellLocation;
23 
24 /**
25  * Represents the cell location on a CDMA phone.
26  */
27 public class CdmaCellLocation extends CellLocation {
28     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
29     private int mBaseStationId = -1;
30 
31     /**
32      * @hide
33      */
34     public final static int INVALID_LAT_LONG = Integer.MAX_VALUE;
35 
36     /**
37      * Latitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0.
38      * It is represented in units of 0.25 seconds and ranges from -1296000
39      * to 1296000, both values inclusive (corresponding to a range of -90
40      * to +90 degrees). Integer.MAX_VALUE is considered invalid value.
41      */
42     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
43     private int mBaseStationLatitude = INVALID_LAT_LONG;
44 
45     /**
46      * Longitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0.
47      * It is represented in units of 0.25 seconds and ranges from -2592000
48      * to 2592000, both values inclusive (corresponding to a range of -180
49      * to +180 degrees). Integer.MAX_VALUE is considered invalid value.
50      */
51     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
52     private int mBaseStationLongitude = INVALID_LAT_LONG;
53 
54     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
55     private int mSystemId = -1;
56     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
57     private int mNetworkId = -1;
58 
59     /**
60      * Empty constructor.
61      * Initializes the BID, SID, NID and base station latitude and longitude
62      * to invalid values.
63      */
CdmaCellLocation()64     public CdmaCellLocation() {
65         this.mBaseStationId = -1;
66         this.mBaseStationLatitude = INVALID_LAT_LONG;
67         this.mBaseStationLongitude = INVALID_LAT_LONG;
68         this.mSystemId = -1;
69         this.mNetworkId = -1;
70     }
71 
72     /**
73      * Initialize the object from a bundle.
74      */
CdmaCellLocation(Bundle bundle)75     public CdmaCellLocation(Bundle bundle) {
76         this.mBaseStationId = bundle.getInt("baseStationId", mBaseStationId);
77         this.mBaseStationLatitude = bundle.getInt("baseStationLatitude", mBaseStationLatitude);
78         this.mBaseStationLongitude = bundle.getInt("baseStationLongitude", mBaseStationLongitude);
79         this.mSystemId = bundle.getInt("systemId", mSystemId);
80         this.mNetworkId = bundle.getInt("networkId", mNetworkId);
81     }
82 
83     /**
84      * @return cdma base station identification number, -1 if unknown
85      */
getBaseStationId()86     public int getBaseStationId() {
87         return this.mBaseStationId;
88     }
89 
90     /**
91      * Latitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0.
92      * (http://www.3gpp2.org/public_html/specs/C.S0005-A_v6.0.pdf)
93      * It is represented in units of 0.25 seconds and ranges from -1296000
94      * to 1296000, both values inclusive (corresponding to a range of -90
95      * to +90 degrees). Integer.MAX_VALUE is considered invalid value.
96      *
97      * @return cdma base station latitude in units of 0.25 seconds, Integer.MAX_VALUE if unknown
98      */
getBaseStationLatitude()99     public int getBaseStationLatitude() {
100         return this.mBaseStationLatitude;
101     }
102 
103     /**
104      * Longitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0.
105      * (http://www.3gpp2.org/public_html/specs/C.S0005-A_v6.0.pdf)
106      * It is represented in units of 0.25 seconds and ranges from -2592000
107      * to 2592000, both values inclusive (corresponding to a range of -180
108      * to +180 degrees). Integer.MAX_VALUE is considered invalid value.
109      *
110      * @return cdma base station longitude in units of 0.25 seconds, Integer.MAX_VALUE if unknown
111      */
getBaseStationLongitude()112     public int getBaseStationLongitude() {
113         return this.mBaseStationLongitude;
114     }
115 
116     /**
117      * @return cdma system identification number, -1 if unknown
118      */
getSystemId()119     public int getSystemId() {
120         return this.mSystemId;
121     }
122 
123     /**
124      * @return cdma network identification number, -1 if unknown
125      */
getNetworkId()126     public int getNetworkId() {
127         return this.mNetworkId;
128     }
129 
130     /**
131      * Invalidate this object.  The cell location data is set to invalid values.
132      */
133     @Override
setStateInvalid()134     public void setStateInvalid() {
135         this.mBaseStationId = -1;
136         this.mBaseStationLatitude = INVALID_LAT_LONG;
137         this.mBaseStationLongitude = INVALID_LAT_LONG;
138         this.mSystemId = -1;
139         this.mNetworkId = -1;
140     }
141 
142     /**
143      * Set the cell location data.
144      */
setCellLocationData(int baseStationId, int baseStationLatitude, int baseStationLongitude)145     public void setCellLocationData(int baseStationId, int baseStationLatitude,
146          int baseStationLongitude) {
147          // The following values have to be written in the correct sequence
148          this.mBaseStationId = baseStationId;
149          this.mBaseStationLatitude = baseStationLatitude;   //values[2];
150          this.mBaseStationLongitude = baseStationLongitude; //values[3];
151     }
152 
153     /**
154      * Set the cell location data.
155      */
setCellLocationData(int baseStationId, int baseStationLatitude, int baseStationLongitude, int systemId, int networkId)156      public void setCellLocationData(int baseStationId, int baseStationLatitude,
157          int baseStationLongitude, int systemId, int networkId) {
158          // The following values have to be written in the correct sequence
159          this.mBaseStationId = baseStationId;
160          this.mBaseStationLatitude = baseStationLatitude;   //values[2];
161          this.mBaseStationLongitude = baseStationLongitude; //values[3];
162          this.mSystemId = systemId;
163          this.mNetworkId = networkId;
164     }
165 
166     @Override
hashCode()167     public int hashCode() {
168         return this.mBaseStationId ^ this.mBaseStationLatitude ^ this.mBaseStationLongitude
169                 ^ this.mSystemId ^ this.mNetworkId;
170     }
171 
172     @Override
equals(Object o)173     public boolean equals(Object o) {
174         CdmaCellLocation s;
175 
176         try {
177             s = (CdmaCellLocation)o;
178         } catch (ClassCastException ex) {
179             return false;
180         }
181 
182         if (o == null) {
183             return false;
184         }
185 
186         return (equalsHandlesNulls(this.mBaseStationId, s.mBaseStationId) &&
187                 equalsHandlesNulls(this.mBaseStationLatitude, s.mBaseStationLatitude) &&
188                 equalsHandlesNulls(this.mBaseStationLongitude, s.mBaseStationLongitude) &&
189                 equalsHandlesNulls(this.mSystemId, s.mSystemId) &&
190                 equalsHandlesNulls(this.mNetworkId, s.mNetworkId)
191         );
192     }
193 
194     @Override
toString()195     public String toString() {
196         return "[" + this.mBaseStationId + ","
197                    + this.mBaseStationLatitude + ","
198                    + this.mBaseStationLongitude + ","
199                    + this.mSystemId + ","
200                    + this.mNetworkId + "]";
201     }
202 
203     /**
204      * Test whether two objects hold the same data values or both are null
205      *
206      * @param a first obj
207      * @param b second obj
208      * @return true if two objects equal or both are null
209      */
210     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
equalsHandlesNulls(Object a, Object b)211     private static boolean equalsHandlesNulls(Object a, Object b) {
212         return (a == null) ? (b == null) : a.equals (b);
213     }
214 
215     /**
216      * Fill the cell location data into the intent notifier Bundle based on service state
217      *
218      * @param bundleToFill intent notifier Bundle
219      */
fillInNotifierBundle(Bundle bundleToFill)220     public void fillInNotifierBundle(Bundle bundleToFill) {
221         bundleToFill.putInt("baseStationId", this.mBaseStationId);
222         bundleToFill.putInt("baseStationLatitude", this.mBaseStationLatitude);
223         bundleToFill.putInt("baseStationLongitude", this.mBaseStationLongitude);
224         bundleToFill.putInt("systemId", this.mSystemId);
225         bundleToFill.putInt("networkId", this.mNetworkId);
226     }
227 
228     /**
229      * @hide
230      */
isEmpty()231     public boolean isEmpty() {
232         return (this.mBaseStationId == -1 &&
233                 this.mBaseStationLatitude == INVALID_LAT_LONG &&
234                 this.mBaseStationLongitude == INVALID_LAT_LONG &&
235                 this.mSystemId == -1 &&
236                 this.mNetworkId == -1);
237     }
238 
239     /**
240      * Converts latitude or longitude from 0.25 seconds (as defined in the
241      * 3GPP2 C.S0005-A v6.0 standard) to decimal degrees
242      *
243      * @param quartSec latitude or longitude in 0.25 seconds units
244      * @return latitude or longitude in decimal degrees units
245      * @throws IllegalArgumentException if value is less than -2592000,
246      *                                  greater than 2592000, or is not a number.
247      */
convertQuartSecToDecDegrees(int quartSec)248     public static double convertQuartSecToDecDegrees(int quartSec) {
249         if(Double.isNaN(quartSec) || quartSec < -2592000 || quartSec > 2592000){
250             // Invalid value
251             throw new IllegalArgumentException("Invalid coordiante value:" + quartSec);
252         }
253         return ((double)quartSec) / (3600 * 4);
254     }
255 
256 }
257 
258 
259