1 /*
2  * Copyright 2021 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 com.android.internal.telephony;
18 
19 import android.annotation.DurationMillisLong;
20 import android.annotation.ElapsedRealtimeLong;
21 import android.annotation.NonNull;
22 import android.app.time.UnixEpochTime;
23 
24 import java.time.Duration;
25 import java.util.Objects;
26 
27 /** NITZ information and associated metadata. */
28 public final class NitzSignal {
29 
30     @ElapsedRealtimeLong private final long mReceiptElapsedMillis;
31     @NonNull private final NitzData mNitzData;
32     @DurationMillisLong private final long mAgeMillis;
33 
34     /**
35      * @param receiptElapsedMillis the time according to {@link
36      *     android.os.SystemClock#elapsedRealtime()} when the NITZ signal was first received by
37      *     the platform code
38      * @param nitzData the NITZ data
39      * @param ageMillis the age of the NITZ when it was passed to the platform, e.g. if it was
40      *     cached by the modem for a period of time. Must not be negative.
41      */
NitzSignal( @lapsedRealtimeLong long receiptElapsedMillis, @NonNull NitzData nitzData, long ageMillis)42     public NitzSignal(
43             @ElapsedRealtimeLong long receiptElapsedMillis,
44             @NonNull NitzData nitzData,
45             long ageMillis) {
46         mReceiptElapsedMillis = receiptElapsedMillis;
47         mNitzData = Objects.requireNonNull(nitzData);
48         if (ageMillis < 0) {
49             throw new IllegalArgumentException("ageMillis < 0");
50         }
51         mAgeMillis = ageMillis;
52     }
53 
54     /**
55      * Returns the time according to {@link android.os.SystemClock#elapsedRealtime()} when the NITZ
56      * signal was first received by the platform code.
57      */
58     @ElapsedRealtimeLong
getReceiptElapsedRealtimeMillis()59     public long getReceiptElapsedRealtimeMillis() {
60         return mReceiptElapsedMillis;
61     }
62 
63     /**
64      * Returns the NITZ data.
65      */
66     @NonNull
getNitzData()67     public NitzData getNitzData() {
68         return mNitzData;
69     }
70 
71     /**
72      * Returns the age of the NITZ when it was passed to the platform, e.g. if it was cached by the
73      * modem for a period of time. Must not be negative.
74      */
75     @DurationMillisLong
getAgeMillis()76     public long getAgeMillis() {
77         return mAgeMillis;
78     }
79 
80     /**
81      * Returns a derived property of {@code receiptElapsedMillis - ageMillis}, i.e. the time
82      * according to the elapsed realtime clock when the NITZ signal was actually received by this
83      * device taking into time it was cached by layers before the RIL.
84      */
85     @ElapsedRealtimeLong
getAgeAdjustedElapsedRealtimeMillis()86     public long getAgeAdjustedElapsedRealtimeMillis() {
87         return mReceiptElapsedMillis - mAgeMillis;
88     }
89 
90     /**
91      * Creates a {@link UnixEpochTime} containing the UTC time as the number of milliseconds since
92      * the start of the Unix epoch. The reference time is the time according to the elapsed realtime
93      * clock when that would have been the time, accounting for receipt time and age.
94      */
createTimeSignal()95     public UnixEpochTime createTimeSignal() {
96         return new UnixEpochTime(
97                 getAgeAdjustedElapsedRealtimeMillis(),
98                 getNitzData().getCurrentTimeInMillis());
99     }
100 
101     @Override
equals(Object o)102     public boolean equals(Object o) {
103         if (this == o) {
104             return true;
105         }
106         if (o == null || getClass() != o.getClass()) {
107             return false;
108         }
109         NitzSignal that = (NitzSignal) o;
110         return mReceiptElapsedMillis == that.mReceiptElapsedMillis
111                 && mAgeMillis == that.mAgeMillis
112                 && mNitzData.equals(that.mNitzData);
113     }
114 
115     @Override
hashCode()116     public int hashCode() {
117         return Objects.hash(mReceiptElapsedMillis, mNitzData, mAgeMillis);
118     }
119 
120     @Override
toString()121     public String toString() {
122         return "NitzSignal{"
123                 + "mReceiptElapsedMillis=" + Duration.ofMillis(mReceiptElapsedMillis)
124                 + ", mNitzData=" + mNitzData
125                 + ", mAgeMillis=" + mAgeMillis
126                 + '}';
127     }
128 }
129