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; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.SystemApi; 22 import android.os.Parcel; 23 import android.os.Parcelable; 24 25 import java.lang.annotation.Retention; 26 import java.lang.annotation.RetentionPolicy; 27 28 /** 29 * Represents the state of HealthConnect data as it goes through one of the following operations: 30 * <li>Data Restore: fetching and restoring the data either from the cloud or from another device. 31 * <li>Data Migration: migrating the data from the app using the data-migration APIs: {@link 32 * HealthConnectManager#startMigration}, {@link HealthConnectManager#writeMigrationData}, and 33 * {@link HealthConnectManager#finishMigration} 34 * 35 * @hide 36 */ 37 @SystemApi 38 public final class HealthConnectDataState implements Parcelable { 39 /** 40 * The default idle state of HealthConnect data restore process. This states means that nothing 41 * related to the data restore process is undergoing. {@link #getDataRestoreError()} could 42 * return an error for previous restoration attempt. 43 * 44 * <p>See also {@link DataRestoreState} 45 * 46 * @hide 47 */ 48 @SystemApi public static final int RESTORE_STATE_IDLE = 0; 49 50 /** 51 * The HealthConnect data is pending restoration. The system is in the process of fetching / 52 * staging the remote data on this device. Once the data has been fetched and staged for 53 * restoration an attempt will be made to restore the data. So, this will follow with {@link 54 * #RESTORE_STATE_IN_PROGRESS} state. 55 * 56 * <p>See also {@link DataRestoreState} 57 * 58 * @hide 59 */ 60 @SystemApi public static final int RESTORE_STATE_PENDING = 1; 61 62 /** 63 * The HealthConnect staged data is being restored. On a successful restore the data will be 64 * available for use on this device. 65 * 66 * <p>After the restore process is finished, we'll come back to the {@link #RESTORE_STATE_IDLE}. 67 * 68 * <p>See also {@link DataRestoreState} 69 * 70 * @hide 71 */ 72 @SystemApi public static final int RESTORE_STATE_IN_PROGRESS = 2; 73 74 /** @hide */ 75 @Retention(RetentionPolicy.SOURCE) 76 @IntDef({RESTORE_STATE_IDLE, RESTORE_STATE_PENDING, RESTORE_STATE_IN_PROGRESS}) 77 public @interface DataRestoreState {} 78 79 /** 80 * No error. 81 * 82 * @hide 83 */ 84 @SystemApi public static final int RESTORE_ERROR_NONE = 0; 85 86 /** 87 * An unknown error caused a failure in restoring the data. 88 * 89 * <p>This is a non-recoverable error. 90 * 91 * @hide 92 */ 93 @SystemApi public static final int RESTORE_ERROR_UNKNOWN = 1; 94 95 /** 96 * An error was encountered fetching the remote HealthConnect data. 97 * 98 * <p>This is a non-recoverable error. 99 * 100 * <p>For instance, this could have been caused by a network issue leading to download failure. 101 * In such a case a retry would've been attempted, but eventually that failed as well. 102 * 103 * @hide 104 */ 105 @SystemApi public static final int RESTORE_ERROR_FETCHING_DATA = 2; 106 107 /** 108 * The fetched remote data could not be restored because the current HealthConnect version on 109 * the device is behind the staged data version. 110 * 111 * <p>This is a recoverable error. 112 * 113 * <p>Until the module has been updated we'll be waiting in the {@link #RESTORE_STATE_PENDING} 114 * state. Once the HealthConnect version on the device is updated and rebooted then the restore 115 * will be attempted on the same device reboot. 116 * 117 * @hide 118 */ 119 @SystemApi public static final int RESTORE_ERROR_VERSION_DIFF = 3; 120 121 /** @hide */ 122 @Retention(RetentionPolicy.SOURCE) 123 @IntDef({ 124 RESTORE_ERROR_NONE, 125 RESTORE_ERROR_UNKNOWN, 126 RESTORE_ERROR_FETCHING_DATA, 127 RESTORE_ERROR_VERSION_DIFF 128 }) 129 public @interface DataRestoreError {} 130 131 /** 132 * The starting default state for the Migration process. 133 * 134 * <p>We'll begin in this state irrespective of whether there's an app installed that can 135 * perform Migration. If there's no such app installed then we stay in this state. However, if 136 * an installed app can be upgraded to become Migration-aware, then we'll move to the {@link 137 * #MIGRATION_STATE_APP_UPGRADE_REQUIRED} state. Please see {@link 138 * #MIGRATION_STATE_APP_UPGRADE_REQUIRED} for more info. 139 * 140 * <p>See also {@link DataMigrationState} 141 * 142 * @hide 143 */ 144 @SystemApi public static final int MIGRATION_STATE_IDLE = 0; 145 146 /** 147 * This reflects that the app needs an upgrade before it can start the Migration process. 148 * 149 * <p>This happens when the module finds out that there's an installed app that can perform the 150 * Migration process once it has been upgraded to the correct version. Once such an app is 151 * available then we'll move back to the {@link #MIGRATION_STATE_IDLE} state. 152 * 153 * <p>We can come here only from the {@link #MIGRATION_STATE_IDLE} state. 154 * 155 * <p>See also {@link DataMigrationState} 156 * 157 * @hide 158 */ 159 @SystemApi public static final int MIGRATION_STATE_APP_UPGRADE_REQUIRED = 1; 160 161 /** 162 * This reflects that the module needs an upgrade to handle the Migration process. 163 * 164 * <p>This happens when the version set by the caller is ahead of the HealthConnect module. Once 165 * the module has updated to a version greater or equal to the said set version, then we'll move 166 * to the {@link #MIGRATION_STATE_ALLOWED} state from where the Migration process can start. 167 * 168 * <p>We can come here only from the {@link #MIGRATION_STATE_IDLE} state. 169 * 170 * <p>See also {@link DataMigrationState} 171 * 172 * @hide 173 */ 174 @SystemApi public static final int MIGRATION_STATE_MODULE_UPGRADE_REQUIRED = 2; 175 176 /** 177 * We are in the process of integrating the data shared by the app using the {@link 178 * HealthConnectManager#writeMigrationData} API. 179 * 180 * <p>We get into this state when the app makes the {@link HealthConnectManager#startMigration} 181 * call. 182 * 183 * <p>We can come here from either {@link #MIGRATION_STATE_ALLOWED} or {@link 184 * #MIGRATION_STATE_IDLE} states when {@link HealthConnectManager#startMigration} is called. 185 * 186 * <p>From here we can go to either {@link #MIGRATION_STATE_ALLOWED} OR {@link 187 * #MIGRATION_STATE_COMPLETE} state. 188 * 189 * <p>All other HealthConnect APIs unrelated to Migration are blocked while we are in this 190 * state. For more info on this please see 191 * 192 * <p>See also {@link DataMigrationState} 193 * 194 * @hide 195 */ 196 @SystemApi public static final int MIGRATION_STATE_IN_PROGRESS = 3; 197 198 /** 199 * The Migration is now allowed and is waiting to start or resume. 200 * 201 * <p>We can come to this state from any of the following states: 202 * 203 * <ul> 204 * <li>{@link #MIGRATION_STATE_IDLE} if the module is ready to 205 * <li>{@link #MIGRATION_STATE_MODULE_UPGRADE_REQUIRED} when the module upgrades to the 206 * minimum required version. 207 * <li>{@link #MIGRATION_STATE_IN_PROGRESS} in case of a timeout of 12 hours. 208 * </ul> 209 * 210 * <p>From this state we can go to either {@link #MIGRATION_STATE_IN_PROGRESS} or {@link 211 * #MIGRATION_STATE_COMPLETE} (in case of timeout of 15 days). 212 * 213 * <p>See also {@link DataMigrationState} 214 * 215 * @hide 216 */ 217 @SystemApi public static final int MIGRATION_STATE_ALLOWED = 4; 218 219 /** 220 * This is the final state for the Migration process. We can come here from any other state: 221 * 222 * <ul> 223 * <li>From {@link #MIGRATION_STATE_IDLE} after a timeout of 30 days. 224 * <li>From {@link #MIGRATION_STATE_MODULE_UPGRADE_REQUIRED} after a timeout of 15 days. 225 * <li>From {@link #MIGRATION_STATE_IN_PROGRESS} when {@link 226 * HealthConnectManager#finishMigration} is called. 227 * <li>From {@link #MIGRATION_STATE_ALLOWED} after a timeout of 15 days. 228 * </ul> 229 * 230 * <p>See also {@link DataMigrationState} 231 * 232 * @hide 233 */ 234 @SystemApi public static final int MIGRATION_STATE_COMPLETE = 5; 235 236 /** @hide */ 237 @Retention(RetentionPolicy.SOURCE) 238 @IntDef({ 239 MIGRATION_STATE_IDLE, 240 MIGRATION_STATE_APP_UPGRADE_REQUIRED, 241 MIGRATION_STATE_MODULE_UPGRADE_REQUIRED, 242 MIGRATION_STATE_IN_PROGRESS, 243 MIGRATION_STATE_ALLOWED, 244 MIGRATION_STATE_COMPLETE 245 }) 246 public @interface DataMigrationState {} 247 248 private final @DataRestoreState int mDataRestoreState; 249 private final @DataRestoreError int mDataRestoreError; 250 private final @DataMigrationState int mDataMigrationState; 251 252 /** 253 * The state of the HealthConnect data as it goes through the Data Restore process. 254 * 255 * <p>See also {@link DataRestoreState} 256 */ getDataRestoreState()257 public @DataRestoreState int getDataRestoreState() { 258 return mDataRestoreState; 259 } 260 261 /** 262 * Get error encountered at the time of calling this API as we try to fetch and restore the 263 * remote HealthConnect data. 264 * 265 * <p>Since we stop at the first encounter of an error there can be only one error at any time. 266 * 267 * <p>Some of the errors are recoverable while others are non-recoverable. Please see {@link 268 * DataRestoreError} for more details on which errors are recoverable and how to recover from 269 * them. 270 */ getDataRestoreError()271 public @DataRestoreError int getDataRestoreError() { 272 return mDataRestoreError; 273 } 274 275 /** 276 * The state of the HealthConnect data as it goes through the Data Migration process. 277 * 278 * <p>See also {@link DataMigrationState} 279 */ getDataMigrationState()280 public @DataMigrationState int getDataMigrationState() { 281 return mDataMigrationState; 282 } 283 284 /** @hide */ HealthConnectDataState( @ataRestoreState int dataRestoreState, @DataRestoreError int dataRestoreError, @DataMigrationState int dataMigrationState)285 public HealthConnectDataState( 286 @DataRestoreState int dataRestoreState, 287 @DataRestoreError int dataRestoreError, 288 @DataMigrationState int dataMigrationState) { 289 this.mDataRestoreState = dataRestoreState; 290 this.mDataRestoreError = dataRestoreError; 291 this.mDataMigrationState = dataMigrationState; 292 } 293 294 @NonNull 295 public static final Creator<HealthConnectDataState> CREATOR = 296 new Creator<>() { 297 @Override 298 public HealthConnectDataState createFromParcel(Parcel in) { 299 return new HealthConnectDataState(in); 300 } 301 302 @Override 303 public HealthConnectDataState[] newArray(int size) { 304 return new HealthConnectDataState[size]; 305 } 306 }; 307 308 @Override describeContents()309 public int describeContents() { 310 return 0; 311 } 312 313 @Override writeToParcel(@onNull Parcel dest, int flags)314 public void writeToParcel(@NonNull Parcel dest, int flags) { 315 dest.writeInt(mDataRestoreState); 316 dest.writeInt(mDataRestoreError); 317 dest.writeInt(mDataMigrationState); 318 } 319 HealthConnectDataState(Parcel in)320 private HealthConnectDataState(Parcel in) { 321 mDataRestoreState = in.readInt(); 322 mDataRestoreError = in.readInt(); 323 mDataMigrationState = in.readInt(); 324 } 325 } 326