1 /* 2 * Copyright (C) 2024 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.exportimport; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.os.Parcel; 23 import android.os.Parcelable; 24 25 import java.lang.annotation.Retention; 26 import java.lang.annotation.RetentionPolicy; 27 import java.time.Instant; 28 29 /** 30 * Status for a scheduled export. Parcelable used to communicate the status of a scheduled export 31 * between the system server and the UI components via HealthConnectService. 32 * 33 * @hide 34 */ 35 public final class ScheduledExportStatus implements Parcelable { 36 @NonNull 37 public static final Creator<ScheduledExportStatus> CREATOR = 38 new Creator<>() { 39 @Override 40 public ScheduledExportStatus createFromParcel(Parcel in) { 41 return new ScheduledExportStatus(in); 42 } 43 44 @Override 45 public ScheduledExportStatus[] newArray(int size) { 46 return new ScheduledExportStatus[size]; 47 } 48 }; 49 50 /** 51 * No error or success state available yet. 52 * 53 * @hide 54 */ 55 public static final int DATA_EXPORT_ERROR_UNSPECIFIED = -1; 56 57 /** 58 * No error during the last data export. 59 * 60 * @hide 61 */ 62 public static final int DATA_EXPORT_ERROR_NONE = 0; 63 64 /** 65 * Unknown error during the last data export. 66 * 67 * @hide 68 */ 69 public static final int DATA_EXPORT_ERROR_UNKNOWN = 1; 70 71 /** 72 * Indicates that the last export failed because we lost access to the export file location. 73 * 74 * @hide 75 */ 76 public static final int DATA_EXPORT_LOST_FILE_ACCESS = 2; 77 78 /** 79 * Indicates that an export was started and is ongoing. 80 * 81 * @hide 82 */ 83 public static final int DATA_EXPORT_STARTED = 3; 84 85 /** 86 * Indicates that the last export failed while trying to clear the log tables. Probably because 87 * the file was corrupted during the copy, and it was not a valid HealthConnectDatabase anymore. 88 * 89 * @hide 90 */ 91 public static final int DATA_EXPORT_ERROR_CLEARING_LOG_TABLES = 4; 92 93 /** 94 * Indicates that the last export failed while trying to clear the PHR tables. Probably because 95 * the file was corrupted during the copy, and it was not a valid HealthConnectDatabase anymore. 96 * 97 * @hide 98 */ 99 public static final int DATA_EXPORT_ERROR_CLEARING_PHR_TABLES = 5; 100 101 /** @hide */ 102 // TODO(b/356393172) rename to Status & include DATA_EXPORT_STARTED during Statuses cleanup. 103 @Retention(RetentionPolicy.SOURCE) 104 @IntDef({ 105 DATA_EXPORT_ERROR_UNSPECIFIED, 106 DATA_EXPORT_ERROR_UNKNOWN, 107 DATA_EXPORT_ERROR_NONE, 108 DATA_EXPORT_LOST_FILE_ACCESS, 109 DATA_EXPORT_ERROR_CLEARING_LOG_TABLES 110 }) 111 public @interface DataExportError {} 112 113 @Nullable private final Instant mLastSuccessfulExportTime; 114 115 @Nullable private final Instant mLastFailedExportTime; 116 117 @DataExportError private final int mDataExportError; 118 private final int mPeriodInDays; 119 @Nullable private final String mLastExportFileName; 120 @Nullable private final String mLastExportAppName; 121 @Nullable private final String mNextExportFileName; 122 @Nullable private final String mNextExportAppName; 123 private final int mNextExportSequentialNumber; 124 ScheduledExportStatus( @ullable Instant lastSuccessfulExportTime, @Nullable Instant lastFailedExportTime, @DataExportError int dataExportError, int periodInDays, @Nullable String lastExportFileName, @Nullable String lastExportAppName, @Nullable String nextExportFileName, @Nullable String nextExportAppName, int nextExportSequentialNumber)125 private ScheduledExportStatus( 126 @Nullable Instant lastSuccessfulExportTime, 127 @Nullable Instant lastFailedExportTime, 128 @DataExportError int dataExportError, 129 int periodInDays, 130 @Nullable String lastExportFileName, 131 @Nullable String lastExportAppName, 132 @Nullable String nextExportFileName, 133 @Nullable String nextExportAppName, 134 int nextExportSequentialNumber) { 135 mLastSuccessfulExportTime = lastSuccessfulExportTime; 136 mLastFailedExportTime = lastFailedExportTime; 137 mDataExportError = dataExportError; 138 mPeriodInDays = periodInDays; 139 mLastExportFileName = lastExportFileName; 140 mLastExportAppName = lastExportAppName; 141 mNextExportFileName = nextExportFileName; 142 mNextExportAppName = nextExportAppName; 143 mNextExportSequentialNumber = nextExportSequentialNumber; 144 } 145 146 /** 147 * Returns the time for the last successful export, or null if there hasn't been a successful 148 * export to the current location. 149 */ 150 @Nullable getLastSuccessfulExportTime()151 public Instant getLastSuccessfulExportTime() { 152 return mLastSuccessfulExportTime; 153 } 154 155 /** 156 * Returns the time of the last failed export attempt, or null if there hasn't been a failed 157 * export. 158 */ 159 @Nullable getLastFailedExportTime()160 public Instant getLastFailedExportTime() { 161 return mLastFailedExportTime; 162 } 163 164 /** Returns the error status of the last export attempt. */ getDataExportError()165 public int getDataExportError() { 166 return mDataExportError; 167 } 168 169 /** 170 * Returns the period between scheduled exports. 171 * 172 * <p>A value of 0 indicates that no setting has been set. 173 */ 174 // TODO(b/341017907): Consider adding hasPeriodInDays. getPeriodInDays()175 public int getPeriodInDays() { 176 return mPeriodInDays; 177 } 178 179 /** Returns the file name of the last successful export. */ 180 @Nullable getLastExportFileName()181 public String getLastExportFileName() { 182 return mLastExportFileName; 183 } 184 185 /** Returns the app name of the last successful export. */ 186 @Nullable getLastExportAppName()187 public String getLastExportAppName() { 188 return mLastExportAppName; 189 } 190 191 /** Returns the file name of the next export. */ 192 @Nullable getNextExportFileName()193 public String getNextExportFileName() { 194 return mNextExportFileName; 195 } 196 197 /** Returns the app name of the last successful export. */ 198 @Nullable getNextExportAppName()199 public String getNextExportAppName() { 200 return mNextExportAppName; 201 } 202 203 /** Returns the next export sequential number. */ getNextExportSequentialNumber()204 public int getNextExportSequentialNumber() { 205 return mNextExportSequentialNumber; 206 } 207 208 @Override describeContents()209 public int describeContents() { 210 return 0; 211 } 212 ScheduledExportStatus(@onNull Parcel in)213 private ScheduledExportStatus(@NonNull Parcel in) { 214 long timestamp = in.readLong(); 215 mLastSuccessfulExportTime = timestamp == 0 ? null : Instant.ofEpochMilli(timestamp); 216 long lastFailedExportTimestamp = in.readLong(); 217 mLastFailedExportTime = 218 timestamp == 0 ? null : Instant.ofEpochMilli(lastFailedExportTimestamp); 219 mDataExportError = in.readInt(); 220 mPeriodInDays = in.readInt(); 221 mLastExportFileName = in.readString(); 222 mLastExportAppName = in.readString(); 223 mNextExportFileName = in.readString(); 224 mNextExportAppName = in.readString(); 225 mNextExportSequentialNumber = in.readInt(); 226 } 227 228 @Override writeToParcel(@onNull Parcel dest, int flags)229 public void writeToParcel(@NonNull Parcel dest, int flags) { 230 dest.writeLong( 231 mLastSuccessfulExportTime == null ? 0 : mLastSuccessfulExportTime.toEpochMilli()); 232 dest.writeLong(mLastFailedExportTime == null ? 0 : mLastFailedExportTime.toEpochMilli()); 233 dest.writeInt(mDataExportError); 234 dest.writeInt(mPeriodInDays); 235 dest.writeString(mLastExportFileName); 236 dest.writeString(mLastExportAppName); 237 dest.writeString(mNextExportFileName); 238 dest.writeString(mNextExportAppName); 239 dest.writeInt(mNextExportSequentialNumber); 240 } 241 242 /** Builder for {@link ScheduledExportStatus}. */ 243 public static final class Builder { 244 @Nullable private Instant mLastSuccessfulExportTime; 245 @Nullable private Instant mLastFailedExportTime; 246 @DataExportError private int mDataExportError; 247 private int mPeriodInDays; 248 @Nullable private String mLastExportFileName; 249 @Nullable private String mLastExportAppName; 250 @Nullable private String mNextExportFileName; 251 @Nullable private String mNextExportAppName; 252 private int mNextExportSequentialNumber; 253 Builder()254 public Builder() {} 255 256 /** 257 * Sets the time for the last successful export, or null if there hasn't been a successful 258 * export to the current location. 259 */ setLastSuccessfulExportTime(@ullable Instant lastSuccessfulExportTime)260 public Builder setLastSuccessfulExportTime(@Nullable Instant lastSuccessfulExportTime) { 261 mLastSuccessfulExportTime = lastSuccessfulExportTime; 262 return this; 263 } 264 265 /** 266 * Sets the time of the last failed export attempt, or null if there hasn't been a failed 267 * export. 268 */ setLastFailedExportTime(@ullable Instant lastFailedExportTime)269 public Builder setLastFailedExportTime(@Nullable Instant lastFailedExportTime) { 270 mLastFailedExportTime = lastFailedExportTime; 271 return this; 272 } 273 274 /** 275 * Sets the error status of the last export attempt. 276 * 277 * <p>Defaults to {@link ScheduledExportStatus#DATA_EXPORT_ERROR_NONE}. 278 */ setDataExportError(@ataExportError int dataExportError)279 public Builder setDataExportError(@DataExportError int dataExportError) { 280 mDataExportError = dataExportError; 281 return this; 282 } 283 284 /** 285 * Sets the period between scheduled exports. 286 * 287 * <p>A value of 0 indicates that no setting has been set. 288 */ setPeriodInDays(int periodInDays)289 public Builder setPeriodInDays(int periodInDays) { 290 mPeriodInDays = periodInDays; 291 return this; 292 } 293 294 /** 295 * Sets the file name of the last successful export. 296 * 297 * <p>Defaults to null. 298 */ setLastExportFileName(@ullable String lastExportFileName)299 public Builder setLastExportFileName(@Nullable String lastExportFileName) { 300 mLastExportFileName = lastExportFileName; 301 return this; 302 } 303 304 /** 305 * Sets the app name of the last successful export. 306 * 307 * <p>Defaults to null. 308 */ setLastExportAppName(@ullable String lastExportAppName)309 public Builder setLastExportAppName(@Nullable String lastExportAppName) { 310 mLastExportAppName = lastExportAppName; 311 return this; 312 } 313 314 /** 315 * Sets the file name of the next export. 316 * 317 * <p>Defaults to null. 318 */ setNextExportFileName(@ullable String nextExportFileName)319 public Builder setNextExportFileName(@Nullable String nextExportFileName) { 320 mNextExportFileName = nextExportFileName; 321 return this; 322 } 323 324 /** 325 * Sets the app name of the next export. 326 * 327 * <p>Defaults to null. 328 */ setNextExportAppName(@ullable String nextExportAppName)329 public Builder setNextExportAppName(@Nullable String nextExportAppName) { 330 mNextExportAppName = nextExportAppName; 331 return this; 332 } 333 334 /** Sets the next export sequential number. */ setNextExportSequentialNumber(int nextExportSequentialNumber)335 public Builder setNextExportSequentialNumber(int nextExportSequentialNumber) { 336 mNextExportSequentialNumber = nextExportSequentialNumber; 337 return this; 338 } 339 340 /** Builds a {@link ScheduledExportStatus} object. */ build()341 public ScheduledExportStatus build() { 342 return new ScheduledExportStatus( 343 mLastSuccessfulExportTime, 344 mLastFailedExportTime, 345 mDataExportError, 346 mPeriodInDays, 347 mLastExportFileName, 348 mLastExportAppName, 349 mNextExportFileName, 350 mNextExportAppName, 351 mNextExportSequentialNumber); 352 } 353 } 354 } 355