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;
18 
19 import static android.health.connect.Constants.DEFAULT_LONG;
20 import static android.health.connect.Constants.DEFAULT_PAGE_SIZE;
21 import static android.health.connect.Constants.MAXIMUM_PAGE_SIZE;
22 import static android.health.connect.Constants.MINIMUM_PAGE_SIZE;
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.datatypes.MedicalResource.MedicalResourceType;
35 import android.os.Parcel;
36 import android.os.Parcelable;
37 
38 /** A class to represent a read request for {@link HealthConnectManager#readMedicalResources}. */
39 @FlaggedApi(FLAG_PERSONAL_HEALTH_RECORD)
40 public final class ReadMedicalResourcesRequest implements Parcelable {
41     @MedicalResourceType private final int mMedicalResourceType;
42     private final int mPageSize;
43     private final long mPageToken;
44 
45     /**
46      * @param pageSize The maximum number of {@code MedicalResource}s to be returned by the read
47      *     operation.
48      * @param pageToken The page token to read the current page of the result.
49      */
ReadMedicalResourcesRequest( @edicalResourceType int medicalResourceType, @IntRange(from = MINIMUM_PAGE_SIZE, to = MAXIMUM_PAGE_SIZE) int pageSize, long pageToken)50     private ReadMedicalResourcesRequest(
51             @MedicalResourceType int medicalResourceType,
52             @IntRange(from = MINIMUM_PAGE_SIZE, to = MAXIMUM_PAGE_SIZE) int pageSize,
53             long pageToken) {
54         validateMedicalResourceType(medicalResourceType);
55         requireInRange(pageSize, MINIMUM_PAGE_SIZE, MAXIMUM_PAGE_SIZE, "pageSize");
56 
57         mMedicalResourceType = medicalResourceType;
58         mPageSize = pageSize;
59         mPageToken = pageToken;
60     }
61 
62     /**
63      * Constructs this object with the data present in {@code parcel}. It should be in the same
64      * order as {@link ReadMedicalResourcesRequest#writeToParcel}.
65      */
ReadMedicalResourcesRequest(@onNull Parcel in)66     private ReadMedicalResourcesRequest(@NonNull Parcel in) {
67         requireNonNull(in);
68         mMedicalResourceType = in.readInt();
69         mPageSize = in.readInt();
70         mPageToken = in.readLong();
71     }
72 
73     @NonNull
74     public static final Creator<ReadMedicalResourcesRequest> CREATOR =
75             new Creator<>() {
76                 @Override
77                 public ReadMedicalResourcesRequest createFromParcel(Parcel in) {
78                     return new ReadMedicalResourcesRequest(in);
79                 }
80 
81                 @Override
82                 public ReadMedicalResourcesRequest[] newArray(int size) {
83                     return new ReadMedicalResourcesRequest[size];
84                 }
85             };
86 
87     /** Returns the medical resource type. */
88     @MedicalResourceType
getMedicalResourceType()89     public int getMedicalResourceType() {
90         return mMedicalResourceType;
91     }
92 
93     /**
94      * Returns maximum number of {@code MedicalResource}s to be returned by the read operation if
95      * set, 1000 otherwise.
96      */
97     @IntRange(from = MINIMUM_PAGE_SIZE, to = MAXIMUM_PAGE_SIZE)
getPageSize()98     public int getPageSize() {
99         return mPageSize;
100     }
101 
102     /**
103      * Returns page token to read the current page of the result if set, -1 otherwise, which means
104      * the first page.
105      */
getPageToken()106     public long getPageToken() {
107         return mPageToken;
108     }
109 
110     @Override
describeContents()111     public int describeContents() {
112         return 0;
113     }
114 
115     /** Populates a {@link Parcel} with the self information. */
116     @Override
writeToParcel(@onNull Parcel dest, int flags)117     public void writeToParcel(@NonNull Parcel dest, int flags) {
118         dest.writeInt(mMedicalResourceType);
119         dest.writeInt(mPageSize);
120         dest.writeLong(mPageToken);
121     }
122 
123     /** Indicates whether some other object is "equal to" this one. */
124     @Override
equals(Object o)125     public boolean equals(Object o) {
126         if (this == o) return true;
127         if (!(o instanceof ReadMedicalResourcesRequest that)) return false;
128         return getMedicalResourceType() == that.getMedicalResourceType()
129                 && getPageSize() == that.getPageSize()
130                 && getPageToken() == that.getPageToken();
131     }
132 
133     /** Returns a hash code value for the object. */
134     @Override
hashCode()135     public int hashCode() {
136         return hash(getMedicalResourceType(), getPageSize(), getPageToken());
137     }
138 
139     /** Returns a string representation of this {@link ReadMedicalResourcesRequest}. */
140     @Override
toString()141     public String toString() {
142         StringBuilder sb = new StringBuilder();
143         sb.append(this.getClass().getSimpleName()).append("{");
144         sb.append("medicalResourceType=").append(getMedicalResourceType());
145         sb.append(",pageSize=").append(getPageSize());
146         sb.append(",pageToken=").append(getPageToken());
147         sb.append("}");
148         return sb.toString();
149     }
150 
151     /** Builder class for {@link ReadMedicalResourcesRequest} */
152     public static final class Builder {
153         @MedicalResourceType private int mMedicalResourceType;
154         private int mPageSize = DEFAULT_PAGE_SIZE;
155         private long mPageToken = DEFAULT_LONG;
156 
157         /**
158          * @param medicalResourceType The medical resource type.
159          */
Builder(@edicalResourceType int medicalResourceType)160         public Builder(@MedicalResourceType int medicalResourceType) {
161             validateMedicalResourceType(medicalResourceType);
162             mMedicalResourceType = medicalResourceType;
163         }
164 
165         /**
166          * @param original The other {@link ReadMedicalResourcesRequest.Builder} to provide data to
167          *     construct this new instance from.
168          */
Builder(@onNull Builder original)169         public Builder(@NonNull Builder original) {
170             requireNonNull(original);
171             mMedicalResourceType = original.mMedicalResourceType;
172             mPageSize = original.mPageSize;
173             mPageToken = original.mPageToken;
174         }
175 
176         /**
177          * @param original The other {@link ReadMedicalResourcesRequest} instance to provide data to
178          *     construct this new instance from.
179          */
Builder(@onNull ReadMedicalResourcesRequest original)180         public Builder(@NonNull ReadMedicalResourcesRequest original) {
181             requireNonNull(original);
182             mMedicalResourceType = original.getMedicalResourceType();
183             mPageSize = original.getPageSize();
184             mPageToken = original.getPageToken();
185         }
186 
187         /** Sets the medical resource type. */
188         @NonNull
setMedicalResourceType( @edicalResourceType int medicalResourceType)189         public ReadMedicalResourcesRequest.Builder setMedicalResourceType(
190                 @MedicalResourceType int medicalResourceType) {
191             validateMedicalResourceType(medicalResourceType);
192             mMedicalResourceType = medicalResourceType;
193             return this;
194         }
195 
196         /**
197          * Sets the maximum number of {@code MedicalResource}s to be returned by the read operation.
198          * The number must be in the range of [1, 5000].
199          *
200          * <p>If not set, default to 1000.
201          */
202         @NonNull
setPageSize( @ntRangefrom = MINIMUM_PAGE_SIZE, to = MAXIMUM_PAGE_SIZE) int pageSize)203         public Builder setPageSize(
204                 @IntRange(from = MINIMUM_PAGE_SIZE, to = MAXIMUM_PAGE_SIZE) int pageSize) {
205             requireInRange(pageSize, MINIMUM_PAGE_SIZE, MAXIMUM_PAGE_SIZE, "pageSize");
206             mPageSize = pageSize;
207             return this;
208         }
209 
210         /**
211          * Sets page token to read the requested page of the result.
212          *
213          * <p>If not set, default to -1, which means the first page.
214          */
215         @NonNull
setPageToken(long pageToken)216         public Builder setPageToken(long pageToken) {
217             mPageToken = pageToken;
218             return this;
219         }
220 
221         /**
222          * Returns a new instance of {@link ReadMedicalResourcesRequest} with the specified
223          * parameters.
224          */
225         @NonNull
build()226         public ReadMedicalResourcesRequest build() {
227             return new ReadMedicalResourcesRequest(mMedicalResourceType, mPageSize, mPageToken);
228         }
229     }
230 }
231