• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 package android.health.connect;
17 
18 import static android.health.connect.Constants.DEFAULT_PAGE_SIZE;
19 import static android.health.connect.Constants.MAXIMUM_PAGE_SIZE;
20 import static android.health.connect.Constants.MINIMUM_PAGE_SIZE;
21 import static android.health.connect.datatypes.MedicalDataSource.validateMedicalDataSourceIds;
22 import static android.health.connect.datatypes.MedicalResource.MedicalResourceType;
23 import static android.health.connect.datatypes.MedicalResource.validateMedicalResourceType;
24 import static android.health.connect.datatypes.validation.ValidationUtils.requireInRange;
25 
26 import static com.android.healthfitness.flags.Flags.FLAG_PERSONAL_HEALTH_RECORD;
27 
28 import static java.util.Objects.hash;
29 import static java.util.Objects.requireNonNull;
30 
31 import android.annotation.FlaggedApi;
32 import android.annotation.IntRange;
33 import android.annotation.NonNull;
34 import android.health.connect.aidl.ReadMedicalResourcesRequestParcel;
35 import android.health.connect.datatypes.MedicalDataSource;
36 import android.health.connect.datatypes.MedicalResource;
37 import android.util.ArraySet;
38 
39 import java.util.HashSet;
40 import java.util.Set;
41 
42 /**
43  * An initial read request with specified filters for {@link
44  * HealthConnectManager#readMedicalResources}.
45  *
46  * <p>On receiving the response, if {@link ReadMedicalResourcesResponse#getNextPageToken()} is not
47  * {@code null}, then use the next token with {@link ReadMedicalResourcesPageRequest} to read the
48  * next page.
49  *
50  * <p>Example usage:
51  *
52  * <pre>{@code
53  * ReadMedicalResourcesInitialRequest initialRequest
54  *     = new ReadMedicalResourcesInitialRequest.Builder(...).build();
55  * ReadMedicalResourcesResponse response = makeRequest(initialRequest);
56  * String pageToken = response.getNextPageToken();
57  *
58  * while (pageToken != null) {
59  *     ReadMedicalResourcesPageRequest pageRequest = new ReadMedicalResourcesPageRequest(pageToken);
60  *     response = makeRequest(pageRequest);
61  *     pageToken = response.getNextPageToken();
62  * }
63  * }</pre>
64  */
65 @FlaggedApi(FLAG_PERSONAL_HEALTH_RECORD)
66 public final class ReadMedicalResourcesInitialRequest extends ReadMedicalResourcesRequest {
67     @MedicalResourceType private final int mMedicalResourceType;
68     @NonNull private final Set<String> mDataSourceIds;
69 
70     /**
71      * Creates a new instance of {@link ReadMedicalResourcesInitialRequest}. Please see {@link
72      * ReadMedicalResourcesInitialRequest.Builder} for more detailed parameters information.
73      */
ReadMedicalResourcesInitialRequest( @edicalResourceType int medicalResourceType, @NonNull Set<String> dataSourceIds, @IntRange(from = MINIMUM_PAGE_SIZE, to = MAXIMUM_PAGE_SIZE) int pageSize)74     private ReadMedicalResourcesInitialRequest(
75             @MedicalResourceType int medicalResourceType,
76             @NonNull Set<String> dataSourceIds,
77             @IntRange(from = MINIMUM_PAGE_SIZE, to = MAXIMUM_PAGE_SIZE) int pageSize) {
78         super(pageSize);
79         validateMedicalResourceType(medicalResourceType);
80         requireNonNull(dataSourceIds);
81         validateMedicalDataSourceIds(dataSourceIds);
82 
83         mMedicalResourceType = medicalResourceType;
84         mDataSourceIds = dataSourceIds;
85     }
86 
87     /** Returns the medical resource type. */
88     @MedicalResourceType
getMedicalResourceType()89     public int getMedicalResourceType() {
90         return mMedicalResourceType;
91     }
92 
93     /**
94      * Returns the set of IDs of the {@link MedicalDataSource} filter to read from, or an empty set
95      * for no filter.
96      */
97     @NonNull
getDataSourceIds()98     public Set<String> getDataSourceIds() {
99         return new ArraySet<>(mDataSourceIds);
100     }
101 
102     @Override
equals(Object o)103     public boolean equals(Object o) {
104         if (this == o) return true;
105         if (!(o instanceof ReadMedicalResourcesInitialRequest that)) return false;
106 
107         return getMedicalResourceType() == that.getMedicalResourceType()
108                 && getDataSourceIds().equals(that.getDataSourceIds())
109                 && getPageSize() == that.getPageSize();
110     }
111 
112     @Override
hashCode()113     public int hashCode() {
114         return hash(getMedicalResourceType(), getDataSourceIds(), getPageSize());
115     }
116 
117     @Override
toString()118     public String toString() {
119         return this.getClass().getSimpleName()
120                 + "{"
121                 + "medicalResourceType="
122                 + getMedicalResourceType()
123                 + ",dataSourceIds="
124                 + getDataSourceIds()
125                 + ",pageSize="
126                 + getPageSize()
127                 + "}";
128     }
129 
130     /**
131      * Returns an instance of {@link ReadMedicalResourcesRequestParcel} to carry the request.
132      *
133      * @hide
134      */
toParcel()135     public ReadMedicalResourcesRequestParcel toParcel() {
136         return new ReadMedicalResourcesRequestParcel(this);
137     }
138 
139     /** Builder class for {@link ReadMedicalResourcesInitialRequest}. */
140     public static final class Builder {
141         @MedicalResourceType private int mMedicalResourceType;
142         @NonNull private Set<String> mDataSourceIds = new HashSet<>();
143         private int mPageSize = DEFAULT_PAGE_SIZE;
144 
145         /**
146          * Constructs a new {@link ReadMedicalResourcesInitialRequest.Builder} instance.
147          *
148          * @param medicalResourceType The medical resource type.
149          * @throws IllegalArgumentException if the provided {@code medicalResourceType} is not a
150          *     supported type.
151          */
Builder(@edicalResourceType int medicalResourceType)152         public Builder(@MedicalResourceType int medicalResourceType) {
153             validateMedicalResourceType(medicalResourceType);
154             mMedicalResourceType = medicalResourceType;
155         }
156 
157         /** Constructs a clone of the other {@link ReadMedicalResourcesInitialRequest.Builder}. */
Builder(@onNull Builder other)158         public Builder(@NonNull Builder other) {
159             mMedicalResourceType = other.mMedicalResourceType;
160             mDataSourceIds.addAll(other.mDataSourceIds);
161             mPageSize = other.mPageSize;
162         }
163 
164         /** Constructs a clone of the other {@link ReadMedicalResourcesInitialRequest} instance. */
Builder(@onNull ReadMedicalResourcesInitialRequest other)165         public Builder(@NonNull ReadMedicalResourcesInitialRequest other) {
166             mMedicalResourceType = other.getMedicalResourceType();
167             mDataSourceIds.addAll(other.getDataSourceIds());
168             mPageSize = other.getPageSize();
169         }
170 
171         /**
172          * Sets the medical resource type.
173          *
174          * @throws IllegalArgumentException if the provided {@code medicalResourceType} is not a
175          *     supported type.
176          */
177         @NonNull
setMedicalResourceType(@edicalResourceType int medicalResourceType)178         public Builder setMedicalResourceType(@MedicalResourceType int medicalResourceType) {
179             validateMedicalResourceType(medicalResourceType);
180             mMedicalResourceType = medicalResourceType;
181             return this;
182         }
183 
184         /**
185          * Adds the data source ID based on which the read operation is to be performed. This should
186          * be an ID of the existing {@link MedicalDataSource}.
187          *
188          * <p>If no {@link MedicalDataSource} ID is added, then {@link MedicalResource}s from all
189          * {@link MedicalDataSource}s will be read.
190          *
191          * @throws IllegalArgumentException if the provided {@code dataSourceId} is not a valid ID.
192          */
193         @NonNull
addDataSourceId(@onNull String dataSourceId)194         public Builder addDataSourceId(@NonNull String dataSourceId) {
195             requireNonNull(dataSourceId);
196             validateMedicalDataSourceIds(Set.of(dataSourceId));
197             mDataSourceIds.add(dataSourceId);
198             return this;
199         }
200 
201         /**
202          * Adds all data source IDs based on which the read operation is to be performed. This
203          * should all be IDs of existing {@link MedicalDataSource}s.
204          *
205          * <p>If no {@link MedicalDataSource} IDs are added, then {@link MedicalResource}s from all
206          * {@link MedicalDataSource}s will be read.
207          *
208          * @throws IllegalArgumentException if the provided {@code dataSourceIds} is null, or any ID
209          *     in it is not valid.
210          */
211         @NonNull
addDataSourceIds(@onNull Set<String> dataSourceIds)212         public Builder addDataSourceIds(@NonNull Set<String> dataSourceIds) {
213             requireNonNull(dataSourceIds);
214             validateMedicalDataSourceIds(dataSourceIds);
215             mDataSourceIds.addAll(dataSourceIds);
216             return this;
217         }
218 
219         /** Clears all the {@link MedicalDataSource} filters for this builder. */
220         @NonNull
clearDataSourceIds()221         public Builder clearDataSourceIds() {
222             mDataSourceIds.clear();
223             return this;
224         }
225 
226         /**
227          * Sets the maximum number of {@code MedicalResource}s to be returned by the read operation.
228          *
229          * <p>If not set, default to 1000.
230          *
231          * @throws IllegalArgumentException if the provided {@code pageSize} is less than 1 or more
232          *     than 5000.
233          */
234         @NonNull
setPageSize( @ntRangefrom = MINIMUM_PAGE_SIZE, to = MAXIMUM_PAGE_SIZE) int pageSize)235         public Builder setPageSize(
236                 @IntRange(from = MINIMUM_PAGE_SIZE, to = MAXIMUM_PAGE_SIZE) int pageSize) {
237             requireInRange(pageSize, MINIMUM_PAGE_SIZE, MAXIMUM_PAGE_SIZE, "pageSize");
238             mPageSize = pageSize;
239             return this;
240         }
241 
242         /**
243          * Returns a new instance of {@link ReadMedicalResourcesInitialRequest} with the specified
244          * parameters.
245          */
246         @NonNull
build()247         public ReadMedicalResourcesInitialRequest build() {
248             return new ReadMedicalResourcesInitialRequest(
249                     mMedicalResourceType, mDataSourceIds, mPageSize);
250         }
251     }
252 }
253