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.health.connect.internal.datatypes;
18 
19 import android.annotation.NonNull;
20 import android.health.connect.datatypes.SleepSessionRecord;
21 import android.os.Parcel;
22 
23 import com.android.internal.annotations.VisibleForTesting;
24 
25 import java.time.Instant;
26 import java.util.ArrayList;
27 import java.util.List;
28 import java.util.Objects;
29 
30 /**
31  * Internal {@link SleepSessionRecord.Stage}. Part of {@link SleepSessionRecordInternal}
32  *
33  * @hide
34  */
35 public final class SleepStageInternal {
36     private long mStartTime;
37     private long mEndTime;
38     @SleepSessionRecord.StageType.StageTypes private int mStageType;
39 
40     /** Reads record from parcel. */
41     @VisibleForTesting
readFromParcel(Parcel parcel)42     public static SleepStageInternal readFromParcel(Parcel parcel) {
43         return new SleepStageInternal()
44                 .setStartTime(parcel.readLong())
45                 .setEndTime(parcel.readLong())
46                 .setStageType(parcel.readInt());
47     }
48 
49     @SuppressWarnings("NullAway") // TODO(b/317029272): fix this suppression
populateStagesFromParcel(Parcel parcel)50     static List<SleepStageInternal> populateStagesFromParcel(Parcel parcel) {
51         int size = parcel.readInt();
52         if (size == 0) {
53             return null;
54         }
55         ArrayList<SleepStageInternal> stages = new ArrayList<>(size);
56         for (int i = 0; i < size; i++) {
57             stages.add(SleepStageInternal.readFromParcel(parcel));
58         }
59         return stages;
60     }
61 
getExternalStages( @onNull List<SleepStageInternal> internalStages)62     static List<SleepSessionRecord.Stage> getExternalStages(
63             @NonNull List<SleepStageInternal> internalStages) {
64         List<SleepSessionRecord.Stage> externalStages = new ArrayList<>(internalStages.size());
65         internalStages.forEach((stage) -> externalStages.add(stage.toExternalRecord()));
66         return externalStages;
67     }
68 
writeStagesToParcel(List<SleepStageInternal> stages, Parcel parcel)69     static void writeStagesToParcel(List<SleepStageInternal> stages, Parcel parcel) {
70         if (stages == null) {
71             parcel.writeInt(0);
72             return;
73         }
74         parcel.writeInt(stages.size());
75         stages.forEach((stage) -> stage.writeToParcel(parcel));
76     }
77 
78     /** Writes record to parcel. */
79     @VisibleForTesting
writeToParcel(Parcel parcel)80     public void writeToParcel(Parcel parcel) {
81         parcel.writeLong(mStartTime);
82         parcel.writeLong(mEndTime);
83         parcel.writeInt(mStageType);
84     }
85 
86     /** Sets stage type. Returns record with type set. */
87     @VisibleForTesting
toExternalRecord()88     public SleepSessionRecord.Stage toExternalRecord() {
89         return new SleepSessionRecord.Stage(
90                 Instant.ofEpochMilli(getStartTime()),
91                 Instant.ofEpochMilli(getEndTime()),
92                 getStageType());
93     }
94 
95     /** Sets stage start time. Returns record with start time set. */
setStartTime(long startTime)96     public SleepStageInternal setStartTime(long startTime) {
97         mStartTime = startTime;
98         return this;
99     }
100 
101     /** Sets stage end time. Returns record with end time set. */
setEndTime(long endTime)102     public SleepStageInternal setEndTime(long endTime) {
103         mEndTime = endTime;
104         return this;
105     }
106 
107     /** Returns stage start time. */
getStartTime()108     public long getStartTime() {
109         return mStartTime;
110     }
111 
112     /** Returns stage end time. */
getEndTime()113     public long getEndTime() {
114         return mEndTime;
115     }
116 
117     /** Returns stage type. */
118     @SleepSessionRecord.StageType.StageTypes
getStageType()119     public int getStageType() {
120         return mStageType;
121     }
122 
123     /** Sets stage type. Returns record with type set. */
setStageType(@leepSessionRecord.StageType.StageTypes int stageType)124     public SleepStageInternal setStageType(@SleepSessionRecord.StageType.StageTypes int stageType) {
125         mStageType = stageType;
126         return this;
127     }
128 
129     @Override
equals(Object o)130     public boolean equals(Object o) {
131         if (this == o) return true;
132         if (!(o instanceof SleepStageInternal)) return false;
133         SleepStageInternal that = (SleepStageInternal) o;
134         return mStartTime == that.mStartTime
135                 && mEndTime == that.mEndTime
136                 && mStageType == that.mStageType;
137     }
138 
139     @Override
hashCode()140     public int hashCode() {
141         return Objects.hash(mStartTime, mEndTime, mStageType);
142     }
143 }
144