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
17package android.telephony;
18
19import android.os.Parcel;
20import android.os.Parcelable;
21
22/**
23 * Immutable cell information from a point in time.
24 */
25public abstract class CellInfo implements Parcelable {
26
27    // Type fields for parceling
28    /** @hide */
29    protected static final int TYPE_GSM = 1;
30    /** @hide */
31    protected static final int TYPE_CDMA = 2;
32    /** @hide */
33    protected static final int TYPE_LTE = 3;
34    /** @hide */
35    protected static final int TYPE_WCDMA = 4;
36
37    // Type to distinguish where time stamp gets recorded.
38
39    /** @hide */
40    public static final int TIMESTAMP_TYPE_UNKNOWN = 0;
41    /** @hide */
42    public static final int TIMESTAMP_TYPE_ANTENNA = 1;
43    /** @hide */
44    public static final int TIMESTAMP_TYPE_MODEM = 2;
45    /** @hide */
46    public static final int TIMESTAMP_TYPE_OEM_RIL = 3;
47    /** @hide */
48    public static final int TIMESTAMP_TYPE_JAVA_RIL = 4;
49
50    // True if device is mRegistered to the mobile network
51    private boolean mRegistered;
52
53    // Observation time stamped as type in nanoseconds since boot
54    private long mTimeStamp;
55
56    // Where time stamp gets recorded.
57    // Value of TIMESTAMP_TYPE_XXXX
58    private int mTimeStampType;
59
60    /** @hide */
61    protected CellInfo() {
62        this.mRegistered = false;
63        this.mTimeStampType = TIMESTAMP_TYPE_UNKNOWN;
64        this.mTimeStamp = Long.MAX_VALUE;
65    }
66
67    /** @hide */
68    protected CellInfo(CellInfo ci) {
69        this.mRegistered = ci.mRegistered;
70        this.mTimeStampType = ci.mTimeStampType;
71        this.mTimeStamp = ci.mTimeStamp;
72    }
73
74    /** True if this cell is registered to the mobile network */
75    public boolean isRegistered() {
76        return mRegistered;
77    }
78    /** @hide */
79    public void setRegistered(boolean registered) {
80        mRegistered = registered;
81    }
82
83    /** Approximate time of this cell information in nanos since boot */
84    public long getTimeStamp() {
85        return mTimeStamp;
86    }
87    /** @hide */
88    public void setTimeStamp(long timeStamp) {
89        mTimeStamp = timeStamp;
90    }
91
92    /**
93     * Where time stamp gets recorded.
94     * @return one of TIMESTAMP_TYPE_XXXX
95     *
96     * @hide
97     */
98    public int getTimeStampType() {
99        return mTimeStampType;
100    }
101    /** @hide */
102    public void setTimeStampType(int timeStampType) {
103        if (timeStampType < TIMESTAMP_TYPE_UNKNOWN || timeStampType > TIMESTAMP_TYPE_JAVA_RIL) {
104            mTimeStampType = TIMESTAMP_TYPE_UNKNOWN;
105        } else {
106            mTimeStampType = timeStampType;
107        }
108    }
109
110    @Override
111    public int hashCode() {
112        int primeNum = 31;
113        return ((mRegistered ? 0 : 1) * primeNum) + ((int)(mTimeStamp / 1000) * primeNum)
114                + (mTimeStampType * primeNum);
115    }
116
117    @Override
118    public boolean equals(Object other) {
119        if (other == null) {
120            return false;
121        }
122        if (this == other) {
123            return true;
124        }
125        try {
126            CellInfo o = (CellInfo) other;
127            return mRegistered == o.mRegistered
128                    && mTimeStamp == o.mTimeStamp && mTimeStampType == o.mTimeStampType;
129        } catch (ClassCastException e) {
130            return false;
131        }
132    }
133
134    private static String timeStampTypeToString(int type) {
135        switch (type) {
136            case 1:
137                return "antenna";
138            case 2:
139                return "modem";
140            case 3:
141                return "oem_ril";
142            case 4:
143                return "java_ril";
144            default:
145                return "unknown";
146        }
147    }
148
149    @Override
150    public String toString() {
151        StringBuffer sb = new StringBuffer();
152        String timeStampType;
153
154        sb.append("mRegistered=").append(mRegistered ? "YES" : "NO");
155        timeStampType = timeStampTypeToString(mTimeStampType);
156        sb.append(" mTimeStampType=").append(timeStampType);
157        sb.append(" mTimeStamp=").append(mTimeStamp).append("ns");
158
159        return sb.toString();
160    }
161
162    /**
163     * Implement the Parcelable interface
164     */
165    @Override
166    public int describeContents() {
167        return 0;
168    }
169
170    /** Implement the Parcelable interface */
171    @Override
172    public abstract void writeToParcel(Parcel dest, int flags);
173
174    /**
175     * Used by child classes for parceling.
176     *
177     * @hide
178     */
179    protected void writeToParcel(Parcel dest, int flags, int type) {
180        dest.writeInt(type);
181        dest.writeInt(mRegistered ? 1 : 0);
182        dest.writeInt(mTimeStampType);
183        dest.writeLong(mTimeStamp);
184    }
185
186    /**
187     * Used by child classes for parceling
188     *
189     * @hide
190     */
191    protected CellInfo(Parcel in) {
192        mRegistered = (in.readInt() == 1) ? true : false;
193        mTimeStampType = in.readInt();
194        mTimeStamp = in.readLong();
195    }
196
197    /** Implement the Parcelable interface */
198    public static final Creator<CellInfo> CREATOR = new Creator<CellInfo>() {
199        @Override
200        public CellInfo createFromParcel(Parcel in) {
201                int type = in.readInt();
202                switch (type) {
203                    case TYPE_GSM: return CellInfoGsm.createFromParcelBody(in);
204                    case TYPE_CDMA: return CellInfoCdma.createFromParcelBody(in);
205                    case TYPE_LTE: return CellInfoLte.createFromParcelBody(in);
206                    case TYPE_WCDMA: return CellInfoWcdma.createFromParcelBody(in);
207                    default: throw new RuntimeException("Bad CellInfo Parcel");
208                }
209        }
210
211        @Override
212        public CellInfo[] newArray(int size) {
213            return new CellInfo[size];
214        }
215    };
216}
217