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 static android.health.connect.Constants.MAXIMUM_PAGE_SIZE; 20 21 import android.annotation.NonNull; 22 import android.annotation.SuppressLint; 23 import android.health.connect.aidl.ReadRecordsRequestParcel; 24 import android.health.connect.datatypes.Metadata; 25 import android.health.connect.datatypes.Record; 26 import android.os.OutcomeReceiver; 27 28 import java.util.ArrayList; 29 import java.util.List; 30 import java.util.Objects; 31 import java.util.concurrent.Executor; 32 33 /** 34 * A request class to represent request based on {@link RecordIdFilter RecordIdFilters} for {@link 35 * HealthConnectManager#readRecords(ReadRecordsRequest, Executor, OutcomeReceiver)} 36 * 37 * <p>A {@link RecordIdFilter} can be constructed with either {@link RecordIdFilter#fromId(Class, 38 * String) record ID} or {@link RecordIdFilter#fromClientRecordId(Class, String) client record ID}. 39 * However, it's worth noting that only reading with own client record IDs is allowed, using client 40 * record IDs to read records inserted by another app will return no result. 41 * 42 * @param <T> the type of the Record for the request 43 */ 44 public final class ReadRecordsRequestUsingIds<T extends Record> extends ReadRecordsRequest<T> { 45 /** List of {@link RecordIdFilter} */ 46 private final List<RecordIdFilter> mRecordIdFiltersList; 47 48 /** 49 * @see Builder 50 */ ReadRecordsRequestUsingIds( @onNull Class<T> recordType, @NonNull List<RecordIdFilter> recordIdFiltersList)51 private ReadRecordsRequestUsingIds( 52 @NonNull Class<T> recordType, @NonNull List<RecordIdFilter> recordIdFiltersList) { 53 super(recordType); 54 Objects.requireNonNull(recordIdFiltersList); 55 mRecordIdFiltersList = recordIdFiltersList; 56 } 57 58 /** Returns List of RecordId */ 59 @NonNull getRecordIdFilters()60 public List<RecordIdFilter> getRecordIdFilters() { 61 return mRecordIdFiltersList; 62 } 63 64 /** 65 * Returns an object of ReadRecordsRequestParcel to carry read request 66 * 67 * @hide 68 */ 69 @NonNull toReadRecordsRequestParcel()70 public ReadRecordsRequestParcel toReadRecordsRequestParcel() { 71 return new ReadRecordsRequestParcel(this); 72 } 73 74 /** Builder class for {@link ReadRecordsRequestUsingIds} */ 75 public static final class Builder<T extends Record> { 76 private final Class<T> mRecordType; 77 private final List<RecordIdFilter> mRecordIdFiltersList = new ArrayList<>(); 78 79 /** 80 * @param recordType Record class for which the id is being set 81 */ Builder(@onNull Class<T> recordType)82 public Builder(@NonNull Class<T> recordType) { 83 Objects.requireNonNull(recordType); 84 85 mRecordType = recordType; 86 } 87 88 /** 89 * Add an UUID to the read request. 90 * 91 * <p>The maximum number of ids in a single {@link ReadRecordsRequestUsingIds} that Health 92 * Connect accepts is 5000. The limit includes all {@code id}s and {@code clientId}s. 93 * 94 * @param id Identifier generated by the platform and returned by {@link 95 * HealthConnectManager#insertRecords} 96 * @see #addClientRecordId(String) 97 */ 98 @NonNull 99 @SuppressLint("MissingGetterMatchingBuilder") addId(@onNull String id)100 public Builder<T> addId(@NonNull String id) { 101 if (mRecordIdFiltersList.size() >= MAXIMUM_PAGE_SIZE) { 102 throw new IllegalArgumentException( 103 "Maximum allowed pageSize is " + MAXIMUM_PAGE_SIZE); 104 } 105 mRecordIdFiltersList.add(RecordIdFilter.fromId(mRecordType, id)); 106 return this; 107 } 108 109 /** 110 * Add a client id to the read request. 111 * 112 * <p>The maximum number of ids in a single {@link ReadRecordsRequestUsingIds} that Health 113 * Connect accepts is 5000. The limit includes all {@code id}s and {@code clientId}s. 114 * 115 * @param clientRecordId identifier that was set while inserting the record 116 * @see Metadata 117 * @see #addId(String) 118 */ 119 @SuppressLint("MissingGetterMatchingBuilder") 120 @NonNull addClientRecordId(@onNull String clientRecordId)121 public Builder<T> addClientRecordId(@NonNull String clientRecordId) { 122 if (mRecordIdFiltersList.size() >= MAXIMUM_PAGE_SIZE) { 123 throw new IllegalArgumentException( 124 "Maximum allowed pageSize is " + MAXIMUM_PAGE_SIZE); 125 } 126 mRecordIdFiltersList.add( 127 RecordIdFilter.fromClientRecordId(mRecordType, clientRecordId)); 128 return this; 129 } 130 131 /** Returns Object of {@link ReadRecordsRequestUsingIds} */ 132 @NonNull build()133 public ReadRecordsRequestUsingIds<T> build() { 134 if (mRecordIdFiltersList.isEmpty()) { 135 throw new IllegalArgumentException( 136 "RecordIdFilter list is empty, " 137 + "Either record id or client record id must be set"); 138 } 139 return new ReadRecordsRequestUsingIds<>(mRecordType, mRecordIdFiltersList); 140 } 141 } 142 } 143