1 /*
2  * Copyright (C) 2023 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.uwb;
18 
19 import android.annotation.ElapsedRealtimeLong;
20 import android.annotation.IntRange;
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.annotation.SystemApi;
24 import android.os.Parcel;
25 import android.os.Parcelable;
26 import android.uwb.UwbManager.AdapterStateCallback.State;
27 
28 import java.util.Objects;
29 
30 /**
31  * Record of energy and activity information from controller and
32  * underlying Uwb stack state. Timestamp the record with elapsed
33  * real-time.
34  * @hide
35  */
36 @SystemApi
37 public final class UwbActivityEnergyInfo implements Parcelable {
38     private final long mTimeSinceBootMillis;
39     private final @State int mStackState;
40     private final long mControllerTxDurationMillis;
41     private final long mControllerRxDurationMillis;
42     private final long mControllerIdleDurationMillis;
43     private final long mControllerWakeCount;
44 
UwbActivityEnergyInfo( @lapsedRealtimeLong long timeSinceBootMillis, @State int stackState, @IntRange(from = 0) long txDurationMillis, @IntRange(from = 0) long rxDurationMillis, @IntRange(from = 0) long idleDurationMillis, @IntRange(from = 0) long wakeCount)45     private UwbActivityEnergyInfo(
46             @ElapsedRealtimeLong long timeSinceBootMillis,
47             @State int stackState,
48             @IntRange(from = 0) long txDurationMillis,
49             @IntRange(from = 0) long rxDurationMillis,
50             @IntRange(from = 0) long idleDurationMillis,
51             @IntRange(from = 0) long wakeCount) {
52         mTimeSinceBootMillis = timeSinceBootMillis;
53         mStackState = stackState;
54         mControllerTxDurationMillis = txDurationMillis;
55         mControllerRxDurationMillis = rxDurationMillis;
56         mControllerIdleDurationMillis = idleDurationMillis;
57         mControllerWakeCount = wakeCount;
58     }
59 
60     /**
61      * @hide
62      */
63     @Override
equals(@ullable Object obj)64     public boolean equals(@Nullable Object obj) {
65         if (this == obj) {
66             return true;
67         }
68 
69         if (obj instanceof UwbActivityEnergyInfo) {
70             UwbActivityEnergyInfo other = (UwbActivityEnergyInfo) obj;
71             return mTimeSinceBootMillis == other.getTimeSinceBootMillis()
72                     && mStackState == other.getStackState()
73                     && mControllerTxDurationMillis == other.getControllerTxDurationMillis()
74                     && mControllerRxDurationMillis == other.getControllerRxDurationMillis()
75                     && mControllerIdleDurationMillis == other.getControllerIdleDurationMillis()
76                     && mControllerWakeCount == other.getControllerWakeCount();
77         }
78         return false;
79     }
80 
81     /**
82      * @hide
83      */
84     @Override
hashCode()85     public int hashCode() {
86         return Objects.hash(mTimeSinceBootMillis, mStackState, mControllerTxDurationMillis,
87                 mControllerRxDurationMillis, mControllerIdleDurationMillis, mControllerWakeCount);
88     }
89 
90     @Override
toString()91     public String toString() {
92         return "UwbActivityEnergyInfo{"
93                 + " mTimeSinceBootMillis=" + mTimeSinceBootMillis
94                 + " mStackState=" + mStackState
95                 + " mControllerTxDurationMillis=" + mControllerTxDurationMillis
96                 + " mControllerRxDurationMillis=" + mControllerRxDurationMillis
97                 + " mControllerIdleDurationMillis=" + mControllerIdleDurationMillis
98                 + " mControllerWakeCount=" + mControllerWakeCount
99                 + " }";
100     }
101 
102     public static final @NonNull Creator<UwbActivityEnergyInfo> CREATOR =
103             new Creator<UwbActivityEnergyInfo>() {
104                 @Override
105                 public UwbActivityEnergyInfo createFromParcel(Parcel in) {
106                     Builder builder = new Builder();
107                     builder.setTimeSinceBootMillis(in.readLong());
108                     builder.setStackState(in.readInt());
109                     builder.setControllerTxDurationMillis(in.readLong());
110                     builder.setControllerRxDurationMillis(in.readLong());
111                     builder.setControllerIdleDurationMillis(in.readLong());
112                     builder.setControllerWakeCount(in.readLong());
113                     return builder.build();
114                 }
115                 @Override
116                 public UwbActivityEnergyInfo[] newArray(int size) {
117                     return new UwbActivityEnergyInfo[size];
118                 }
119             };
120 
121     @Override
writeToParcel(@onNull Parcel out, int flags)122     public void writeToParcel(@NonNull Parcel out, int flags) {
123         out.writeLong(mTimeSinceBootMillis);
124         out.writeInt(mStackState);
125         out.writeLong(mControllerTxDurationMillis);
126         out.writeLong(mControllerRxDurationMillis);
127         out.writeLong(mControllerIdleDurationMillis);
128         out.writeLong(mControllerWakeCount);
129     }
130 
131     @Override
describeContents()132     public int describeContents() {
133         return 0;
134     }
135 
136     /** Get the timestamp (elapsed real time milliseconds since boot) of record creation. */
137     @ElapsedRealtimeLong
getTimeSinceBootMillis()138     public long getTimeSinceBootMillis() {
139         return mTimeSinceBootMillis;
140     }
141 
142     /** Get the Uwb stack reported state. */
143     @State
getStackState()144     public int getStackState() {
145         return mStackState;
146     }
147 
148     /** Get the Uwb transmission duration, in milliseconds. */
149     @IntRange(from = 0)
getControllerTxDurationMillis()150     public long getControllerTxDurationMillis() {
151         return mControllerTxDurationMillis;
152     }
153 
154     /** Get the Uwb receive duration, in milliseconds. */
155     @IntRange(from = 0)
getControllerRxDurationMillis()156     public long getControllerRxDurationMillis() {
157         return mControllerRxDurationMillis;
158     }
159 
160     /** Get the Uwb idle duration, in milliseconds. */
161     @IntRange(from = 0)
getControllerIdleDurationMillis()162     public long getControllerIdleDurationMillis() {
163         return mControllerIdleDurationMillis;
164     }
165 
166     /** Get the Uwb wakeup count. */
167     @IntRange(from = 0)
getControllerWakeCount()168     public long getControllerWakeCount() {
169         return mControllerWakeCount;
170     }
171 
172     /**
173      * Builder for a {@link UwbActivityEnergyInfo} object.
174      */
175     public static final class Builder {
176         private long mTimeSinceBootMillis = -1L;
177         private int mStackState = -1;
178         private long mControllerTxDurationMillis = -1L;
179         private long mControllerRxDurationMillis = -1L;
180         private long mControllerIdleDurationMillis = -1L;
181         private long mControllerWakeCount = -1L;
182 
183         /**
184          * Set the timestamp (elapsed real time milliseconds since boot) of record creation.
185          *
186          * @param timeSinceBootMillis the elapsed real time since boot, in milliseconds
187          */
188         @NonNull
setTimeSinceBootMillis(@lapsedRealtimeLong long timeSinceBootMillis)189         public Builder setTimeSinceBootMillis(@ElapsedRealtimeLong long timeSinceBootMillis) {
190             if (timeSinceBootMillis < 0) {
191                 throw new IllegalArgumentException("timeSinceBootMillis must be >= 0");
192             }
193             mTimeSinceBootMillis = timeSinceBootMillis;
194             return this;
195         }
196 
197         /**
198          * Set the Uwb stack reported state.
199          *
200          * @param stackState Uwb stack reported state
201          */
202         @NonNull
setStackState(@tate int stackState)203         public Builder setStackState(@State int stackState) {
204             if (stackState != UwbManager.AdapterStateCallback.STATE_DISABLED
205                     && stackState != UwbManager.AdapterStateCallback.STATE_ENABLED_INACTIVE
206                     && stackState != UwbManager.AdapterStateCallback.STATE_ENABLED_ACTIVE) {
207                 throw new IllegalArgumentException("invalid UWB stack state");
208             }
209             mStackState = stackState;
210             return this;
211         }
212 
213         /**
214          * Set the Uwb transmission duration, in milliseconds.
215          *
216          * @param txDurationMillis cumulative milliseconds of active transmission
217          */
218         @NonNull
setControllerTxDurationMillis(@ntRangefrom = 0) long txDurationMillis)219         public Builder setControllerTxDurationMillis(@IntRange(from = 0) long txDurationMillis) {
220             if (txDurationMillis < 0) {
221                 throw new IllegalArgumentException("txDurationMillis must be >= 0");
222             }
223             mControllerTxDurationMillis = txDurationMillis;
224             return this;
225         }
226 
227         /**
228          * Set the Uwb receive duration, in milliseconds.
229          *
230          * @param rxDurationMillis cumulative milliseconds of active receive
231          */
232         @NonNull
setControllerRxDurationMillis(@ntRangefrom = 0) long rxDurationMillis)233         public Builder setControllerRxDurationMillis(@IntRange(from = 0) long rxDurationMillis) {
234             if (rxDurationMillis < 0) {
235                 throw new IllegalArgumentException("rxDurationMillis must be >= 0");
236             }
237             mControllerRxDurationMillis = rxDurationMillis;
238             return this;
239         }
240 
241         /**
242          * Set the Uwb idle duration, in milliseconds.
243          *
244          * @param idleDurationMillis cumulative milliseconds when radio is awake but not
245          *                           transmitting or receiving
246          */
247         @NonNull
setControllerIdleDurationMillis( @ntRangefrom = 0) long idleDurationMillis)248         public Builder setControllerIdleDurationMillis(
249                 @IntRange(from = 0) long idleDurationMillis) {
250             if (idleDurationMillis < 0) {
251                 throw new IllegalArgumentException("idleDurationMillis must be >= 0");
252             }
253             mControllerIdleDurationMillis = idleDurationMillis;
254             return this;
255         }
256 
257         /**
258          * Set the Uwb wakeup count.
259          *
260          * @param wakeCount cumulative number of wakeup count for the radio
261          */
262         @NonNull
setControllerWakeCount(@ntRangefrom = 0) long wakeCount)263         public Builder setControllerWakeCount(@IntRange(from = 0) long wakeCount) {
264             if (wakeCount < 0) {
265                 throw new IllegalArgumentException("wakeCount must be >= 0");
266             }
267             mControllerWakeCount = wakeCount;
268             return this;
269         }
270 
271         /**
272          * Build the {@link UwbActivityEnergyInfo} object
273          *
274          * @throws IllegalStateException if timeSinceBootMillis, stackState, txDurationMillis,
275          *                               rxDurationMillis, idleDurationMillis or wakeCount
276          *                               is invalid
277          */
278         @NonNull
build()279         public UwbActivityEnergyInfo build() {
280             if (mTimeSinceBootMillis < 0) {
281                 throw new IllegalStateException(
282                         "timeSinceBootMillis must be >= 0: " + mTimeSinceBootMillis);
283             }
284 
285             if (mStackState != UwbManager.AdapterStateCallback.STATE_DISABLED
286                     && mStackState != UwbManager.AdapterStateCallback.STATE_ENABLED_INACTIVE
287                     && mStackState != UwbManager.AdapterStateCallback.STATE_ENABLED_ACTIVE) {
288                 throw new IllegalStateException("invalid UWB stack state");
289             }
290 
291             if (mControllerTxDurationMillis < 0) {
292                 throw new IllegalStateException(
293                         "txDurationMillis must be >= 0: " + mControllerTxDurationMillis);
294             }
295 
296             if (mControllerRxDurationMillis < 0) {
297                 throw new IllegalStateException(
298                         "rxDurationMillis must be >= 0: " + mControllerRxDurationMillis);
299             }
300 
301             if (mControllerIdleDurationMillis < 0) {
302                 throw new IllegalStateException(
303                         "idleDurationMillis must be >= 0: " + mControllerIdleDurationMillis);
304             }
305 
306             if (mControllerWakeCount < 0) {
307                 throw new IllegalStateException(
308                         "wakeCount must be >= 0: " + mControllerWakeCount);
309             }
310 
311             return new UwbActivityEnergyInfo(mTimeSinceBootMillis, mStackState,
312                     mControllerTxDurationMillis, mControllerRxDurationMillis,
313                     mControllerIdleDurationMillis, mControllerWakeCount);
314         }
315     }
316 }
317