blob: 479e4b4efb4c49e5ae13ff9bdf40a3394b49971b [file] [log] [blame]
Neil Fulleraf3eeaf2019-10-15 14:37:37 +01001/*
2 * Copyright (C) 2019 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.app.timedetector;
18
19import android.annotation.NonNull;
20import android.annotation.Nullable;
21import android.os.Parcel;
22import android.os.Parcelable;
Neil Fuller35cc2962020-01-08 16:31:44 +000023import android.os.TimestampedValue;
Neil Fulleraf3eeaf2019-10-15 14:37:37 +010024
25import java.util.ArrayList;
Neil Fulleraf3eeaf2019-10-15 14:37:37 +010026import java.util.Collections;
27import java.util.List;
28import java.util.Objects;
29
30/**
Neil Fuller568fd892019-11-20 14:39:06 +000031 * A time signal from a telephony source. The value can be {@code null} to indicate that the
32 * telephony source has entered an "un-opinionated" state and any previously sent suggestions are
33 * being withdrawn. When not {@code null}, the value consists of the number of milliseconds elapsed
Neil Fulleraf3eeaf2019-10-15 14:37:37 +010034 * since 1/1/1970 00:00:00 UTC and the time according to the elapsed realtime clock when that number
35 * was established. The elapsed realtime clock is considered accurate but volatile, so time signals
36 * must not be persisted across device resets.
37 *
38 * @hide
39 */
40public final class PhoneTimeSuggestion implements Parcelable {
41
42 public static final @NonNull Parcelable.Creator<PhoneTimeSuggestion> CREATOR =
43 new Parcelable.Creator<PhoneTimeSuggestion>() {
44 public PhoneTimeSuggestion createFromParcel(Parcel in) {
45 return PhoneTimeSuggestion.createFromParcel(in);
46 }
47
48 public PhoneTimeSuggestion[] newArray(int size) {
49 return new PhoneTimeSuggestion[size];
50 }
51 };
52
53 private final int mPhoneId;
Neil Fuller0db51fc2019-11-29 17:12:57 +000054 @Nullable private final TimestampedValue<Long> mUtcTime;
Neil Fuller568fd892019-11-20 14:39:06 +000055 @Nullable private ArrayList<String> mDebugInfo;
Neil Fulleraf3eeaf2019-10-15 14:37:37 +010056
Neil Fuller0db51fc2019-11-29 17:12:57 +000057 private PhoneTimeSuggestion(Builder builder) {
58 mPhoneId = builder.mPhoneId;
59 mUtcTime = builder.mUtcTime;
60 mDebugInfo = builder.mDebugInfo != null ? new ArrayList<>(builder.mDebugInfo) : null;
Neil Fulleraf3eeaf2019-10-15 14:37:37 +010061 }
62
63 private static PhoneTimeSuggestion createFromParcel(Parcel in) {
64 int phoneId = in.readInt();
Neil Fuller0db51fc2019-11-29 17:12:57 +000065 PhoneTimeSuggestion suggestion = new PhoneTimeSuggestion.Builder(phoneId)
66 .setUtcTime(in.readParcelable(null /* classLoader */))
67 .build();
Neil Fulleraf3eeaf2019-10-15 14:37:37 +010068 @SuppressWarnings("unchecked")
69 ArrayList<String> debugInfo = (ArrayList<String>) in.readArrayList(null /* classLoader */);
Neil Fuller0db51fc2019-11-29 17:12:57 +000070 if (debugInfo != null) {
71 suggestion.addDebugInfo(debugInfo);
72 }
Neil Fulleraf3eeaf2019-10-15 14:37:37 +010073 return suggestion;
74 }
75
76 @Override
77 public int describeContents() {
78 return 0;
79 }
80
81 @Override
82 public void writeToParcel(@NonNull Parcel dest, int flags) {
83 dest.writeInt(mPhoneId);
84 dest.writeParcelable(mUtcTime, 0);
85 dest.writeList(mDebugInfo);
86 }
87
88 public int getPhoneId() {
89 return mPhoneId;
90 }
91
Neil Fuller568fd892019-11-20 14:39:06 +000092 @Nullable
Neil Fulleraf3eeaf2019-10-15 14:37:37 +010093 public TimestampedValue<Long> getUtcTime() {
94 return mUtcTime;
95 }
96
97 @NonNull
98 public List<String> getDebugInfo() {
Neil Fuller0db51fc2019-11-29 17:12:57 +000099 return mDebugInfo == null
100 ? Collections.emptyList() : Collections.unmodifiableList(mDebugInfo);
Neil Fulleraf3eeaf2019-10-15 14:37:37 +0100101 }
102
103 /**
104 * Associates information with the instance that can be useful for debugging / logging. The
105 * information is present in {@link #toString()} but is not considered for
106 * {@link #equals(Object)} and {@link #hashCode()}.
107 */
Neil Fuller0db51fc2019-11-29 17:12:57 +0000108 public void addDebugInfo(String debugInfo) {
Neil Fulleraf3eeaf2019-10-15 14:37:37 +0100109 if (mDebugInfo == null) {
110 mDebugInfo = new ArrayList<>();
111 }
Neil Fuller0db51fc2019-11-29 17:12:57 +0000112 mDebugInfo.add(debugInfo);
113 }
114
115 /**
116 * Associates information with the instance that can be useful for debugging / logging. The
117 * information is present in {@link #toString()} but is not considered for
118 * {@link #equals(Object)} and {@link #hashCode()}.
119 */
120 public void addDebugInfo(@NonNull List<String> debugInfo) {
121 if (mDebugInfo == null) {
122 mDebugInfo = new ArrayList<>(debugInfo.size());
123 }
124 mDebugInfo.addAll(debugInfo);
Neil Fulleraf3eeaf2019-10-15 14:37:37 +0100125 }
126
127 @Override
128 public boolean equals(Object o) {
129 if (this == o) {
130 return true;
131 }
132 if (o == null || getClass() != o.getClass()) {
133 return false;
134 }
135 PhoneTimeSuggestion that = (PhoneTimeSuggestion) o;
136 return mPhoneId == that.mPhoneId
137 && Objects.equals(mUtcTime, that.mUtcTime);
138 }
139
140 @Override
141 public int hashCode() {
142 return Objects.hash(mPhoneId, mUtcTime);
143 }
144
145 @Override
146 public String toString() {
147 return "PhoneTimeSuggestion{"
148 + "mPhoneId='" + mPhoneId + '\''
149 + ", mUtcTime=" + mUtcTime
150 + ", mDebugInfo=" + mDebugInfo
151 + '}';
152 }
Neil Fuller0db51fc2019-11-29 17:12:57 +0000153
154 /**
155 * Builds {@link PhoneTimeSuggestion} instances.
156 *
157 * @hide
158 */
159 public static class Builder {
160 private final int mPhoneId;
161 private TimestampedValue<Long> mUtcTime;
162 private List<String> mDebugInfo;
163
164 public Builder(int phoneId) {
165 mPhoneId = phoneId;
166 }
167
168 /** Returns the builder for call chaining. */
Neil Fuller312da9b2019-11-26 13:07:09 +0000169 public Builder setUtcTime(@Nullable TimestampedValue<Long> utcTime) {
170 if (utcTime != null) {
171 // utcTime can be null, but the value it holds cannot.
172 Objects.requireNonNull(utcTime.getValue());
173 }
174
Neil Fuller0db51fc2019-11-29 17:12:57 +0000175 mUtcTime = utcTime;
176 return this;
177 }
178
179 /** Returns the builder for call chaining. */
180 public Builder addDebugInfo(@NonNull String debugInfo) {
181 if (mDebugInfo == null) {
182 mDebugInfo = new ArrayList<>();
183 }
184 mDebugInfo.add(debugInfo);
185 return this;
186 }
187
188 /** Returns the {@link PhoneTimeSuggestion}. */
189 public PhoneTimeSuggestion build() {
190 return new PhoneTimeSuggestion(this);
191 }
192 }
Neil Fulleraf3eeaf2019-10-15 14:37:37 +0100193}