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.InstantRecord;
21 import android.os.Parcel;
22 
23 import java.time.Instant;
24 import java.time.LocalDate;
25 import java.time.ZoneOffset;
26 
27 /**
28  * Base class for all health connect datatype records that require a time and a zone offseet.
29  *
30  * @param <T> instant record
31  * @hide
32  */
33 public abstract class InstantRecordInternal<T extends InstantRecord> extends RecordInternal<T> {
34     private long mTime;
35     private int mZoneOffset;
36 
getTimeInMillis()37     public long getTimeInMillis() {
38         return mTime;
39     }
40 
getZoneOffsetInSeconds()41     public int getZoneOffsetInSeconds() {
42         return mZoneOffset;
43     }
44 
45     /**
46      * @return the {@link LocalDate} object of this activity time.
47      */
48     @Override
49     @NonNull
getLocalDate()50     public LocalDate getLocalDate() {
51         return LocalDate.ofInstant(this.getTime(), this.getZoneOffset());
52     }
53 
54     @Override
populateRecordFrom(@onNull Parcel parcel)55     void populateRecordFrom(@NonNull Parcel parcel) {
56         mTime = parcel.readLong();
57         mZoneOffset = parcel.readInt();
58 
59         populateInstantRecordFrom(parcel);
60     }
61 
62     @Override
populateRecordTo(@onNull Parcel parcel)63     void populateRecordTo(@NonNull Parcel parcel) {
64         parcel.writeLong(mTime);
65         parcel.writeInt(mZoneOffset);
66 
67         populateInstantRecordTo(parcel);
68     }
69 
getTime()70     Instant getTime() {
71         return Instant.ofEpochMilli(mTime);
72     }
73 
74     /**
75      * @param time time to update this object with
76      * @return this object
77      */
78     @NonNull
setTime(long time)79     public InstantRecordInternal<T> setTime(long time) {
80         mTime = time;
81         return this;
82     }
83 
getZoneOffset()84     ZoneOffset getZoneOffset() {
85         return ZoneOffset.ofTotalSeconds(mZoneOffset);
86     }
87 
88     /**
89      * @param zoneOffset zoneOffset to update this object with
90      * @return this object
91      */
92     @NonNull
setZoneOffset(int zoneOffset)93     public InstantRecordInternal<T> setZoneOffset(int zoneOffset) {
94         mZoneOffset = zoneOffset;
95         return this;
96     }
97 
98     /**
99      * Child class must implement this method and populates itself with the data present in {@code
100      * bundle}. Reads should be in the same order as write
101      */
populateInstantRecordFrom(@onNull Parcel parcel)102     abstract void populateInstantRecordFrom(@NonNull Parcel parcel);
103 
104     /**
105      * Populate {@code bundle} with the data required to un-bundle self. This is used during IPC
106      * transmissions
107      */
populateInstantRecordTo(@onNull Parcel parcel)108     abstract void populateInstantRecordTo(@NonNull Parcel parcel);
109 }
110