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.annotation.Nullable; 21 import android.health.connect.datatypes.ExerciseSessionRecord; 22 import android.health.connect.datatypes.ExerciseSessionType; 23 import android.health.connect.datatypes.Identifier; 24 import android.health.connect.datatypes.RecordTypeIdentifier; 25 import android.os.Parcel; 26 27 import java.util.ArrayList; 28 import java.util.List; 29 import java.util.Objects; 30 31 /** 32 * @see ExerciseSessionRecord 33 * @hide 34 */ 35 @Identifier(recordIdentifier = RecordTypeIdentifier.RECORD_TYPE_EXERCISE_SESSION) 36 public final class ExerciseSessionRecordInternal 37 extends IntervalRecordInternal<ExerciseSessionRecord> { 38 private String mNotes; 39 private int mExerciseType; 40 private String mTitle; 41 private ExerciseRouteInternal mExerciseRoute; 42 43 private List<ExerciseLapInternal> mExerciseLaps; 44 45 private List<ExerciseSegmentInternal> mExerciseSegments; 46 private boolean mHasRoute; 47 48 @Nullable getNotes()49 public String getNotes() { 50 return mNotes; 51 } 52 53 /** returns this object with the specified notes */ 54 @NonNull setNotes(String notes)55 public ExerciseSessionRecordInternal setNotes(String notes) { 56 this.mNotes = notes; 57 return this; 58 } 59 60 @ExerciseSessionType.ExerciseSessionTypes getExerciseType()61 public int getExerciseType() { 62 return mExerciseType; 63 } 64 65 /** returns this object with the specified exerciseType */ 66 @NonNull setExerciseType(int exerciseType)67 public ExerciseSessionRecordInternal setExerciseType(int exerciseType) { 68 this.mExerciseType = exerciseType; 69 return this; 70 } 71 72 @Nullable getTitle()73 public String getTitle() { 74 return mTitle; 75 } 76 77 /** returns this object with the specified title */ 78 @NonNull setTitle(String title)79 public ExerciseSessionRecordInternal setTitle(String title) { 80 this.mTitle = title; 81 return this; 82 } 83 84 /** 85 * @return route of this activity 86 */ 87 @Nullable getRoute()88 public ExerciseRouteInternal getRoute() { 89 return mExerciseRoute; 90 } 91 92 /** returns this object with the specified route */ 93 @NonNull setRoute(ExerciseRouteInternal route)94 public ExerciseSessionRecordInternal setRoute(ExerciseRouteInternal route) { 95 this.mExerciseRoute = route; 96 if (route != null) { 97 this.mHasRoute = true; 98 } 99 return this; 100 } 101 102 /** returns if this session has route */ hasRoute()103 public boolean hasRoute() { 104 return mHasRoute; 105 } 106 107 /** returns this object with hasRoute set */ 108 @NonNull setHasRoute(boolean hasRoute)109 public ExerciseSessionRecordInternal setHasRoute(boolean hasRoute) { 110 if (mExerciseRoute != null && !hasRoute) { 111 throw new IllegalArgumentException("HasRoute must be true if the route is not null"); 112 } 113 this.mHasRoute = hasRoute; 114 return this; 115 } 116 117 /** returns laps of this session */ 118 @Nullable getLaps()119 public List<ExerciseLapInternal> getLaps() { 120 return mExerciseLaps; 121 } 122 123 /** returns this object with exercise laps set */ setExerciseLaps( @onNull List<ExerciseLapInternal> exerciseLaps)124 public ExerciseSessionRecordInternal setExerciseLaps( 125 @NonNull List<ExerciseLapInternal> exerciseLaps) { 126 Objects.requireNonNull(exerciseLaps); 127 mExerciseLaps = new ArrayList<>(exerciseLaps); 128 return this; 129 } 130 131 @Nullable getSegments()132 public List<ExerciseSegmentInternal> getSegments() { 133 return mExerciseSegments; 134 } 135 136 /** returns this object with exercise segments set */ setExerciseSegments( @onNull List<ExerciseSegmentInternal> exerciseSegments)137 public ExerciseSessionRecordInternal setExerciseSegments( 138 @NonNull List<ExerciseSegmentInternal> exerciseSegments) { 139 Objects.requireNonNull(exerciseSegments); 140 mExerciseSegments = new ArrayList<>(exerciseSegments); 141 return this; 142 } 143 144 @NonNull 145 @Override toExternalRecord()146 public ExerciseSessionRecord toExternalRecord() { 147 ExerciseSessionRecord.Builder builder = 148 new ExerciseSessionRecord.Builder( 149 buildMetaData(), getStartTime(), getEndTime(), getExerciseType()); 150 151 if (getStartZoneOffset() != null) { 152 builder.setStartZoneOffset(getStartZoneOffset()); 153 } 154 155 if (getEndZoneOffset() != null) { 156 builder.setEndZoneOffset(getEndZoneOffset()); 157 } 158 159 if (getNotes() != null) { 160 builder.setNotes(getNotes()); 161 } 162 163 if (getTitle() != null) { 164 builder.setTitle(getTitle()); 165 } 166 167 if (mExerciseRoute != null) { 168 builder.setRoute(mExerciseRoute.toExternalRoute()); 169 } 170 171 builder.setHasRoute(mHasRoute); 172 173 if (getLaps() != null) { 174 builder.setLaps(ExerciseLapInternal.getExternalLaps(mExerciseLaps)); 175 } 176 177 if (getSegments() != null) { 178 builder.setSegments(ExerciseSegmentInternal.getExternalSegments(mExerciseSegments)); 179 } 180 return builder.buildWithoutValidation(); 181 } 182 183 @Override populateIntervalRecordTo(@onNull Parcel parcel)184 public void populateIntervalRecordTo(@NonNull Parcel parcel) { 185 parcel.writeString(mNotes); 186 parcel.writeInt(mExerciseType); 187 parcel.writeString(mTitle); 188 parcel.writeBoolean(mHasRoute); 189 ExerciseRouteInternal.writeToParcel(mExerciseRoute, parcel); 190 ExerciseLapInternal.writeLapsToParcel(mExerciseLaps, parcel); 191 ExerciseSegmentInternal.writeSegmentsToParcel(mExerciseSegments, parcel); 192 } 193 194 @Override populateIntervalRecordFrom(@onNull Parcel parcel)195 public void populateIntervalRecordFrom(@NonNull Parcel parcel) { 196 mNotes = parcel.readString(); 197 mExerciseType = parcel.readInt(); 198 mTitle = parcel.readString(); 199 mHasRoute = parcel.readBoolean(); 200 mExerciseRoute = ExerciseRouteInternal.readFromParcel(parcel); 201 mExerciseLaps = ExerciseLapInternal.populateLapsFromParcel(parcel); 202 mExerciseSegments = ExerciseSegmentInternal.populateSegmentsFromParcel(parcel); 203 } 204 205 /** Add route location to the session */ addRouteLocation(ExerciseRouteInternal.LocationInternal location)206 public void addRouteLocation(ExerciseRouteInternal.LocationInternal location) { 207 if (mExerciseRoute == null) { 208 mExerciseRoute = new ExerciseRouteInternal(List.of(location)); 209 mHasRoute = true; 210 } else { 211 mExerciseRoute.addLocation(location); 212 } 213 } 214 } 215