• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.DEFAULT_LONG;
20 import static android.health.connect.Constants.DEFAULT_PAGE_SIZE;
21 import static android.health.connect.Constants.MAXIMUM_PAGE_SIZE;
22 
23 import android.annotation.IntRange;
24 import android.annotation.NonNull;
25 import android.annotation.Nullable;
26 import android.health.connect.aidl.ReadRecordsRequestParcel;
27 import android.health.connect.datatypes.DataOrigin;
28 import android.health.connect.datatypes.Record;
29 import android.os.OutcomeReceiver;
30 import android.util.ArraySet;
31 
32 import java.util.Objects;
33 import java.util.Set;
34 import java.util.concurrent.Executor;
35 
36 /**
37  * Class to represent a request based on time range and data origin filters for {@link
38  * HealthConnectManager#readRecords(ReadRecordsRequest, Executor, OutcomeReceiver)}
39  *
40  * @param <T> the type of the Record for the request
41  */
42 public final class ReadRecordsRequestUsingFilters<T extends Record> extends ReadRecordsRequest<T> {
43     private final TimeRangeFilter mTimeRangeFilter;
44     private final Set<DataOrigin> mDataOrigins;
45     private final int mPageSize;
46     private final long mPageToken;
47     private final boolean mAscending;
48 
49     /**
50      * @see Builder
51      */
ReadRecordsRequestUsingFilters( @onNull TimeRangeFilter timeRangeFilter, @NonNull Class<T> recordType, @NonNull Set<DataOrigin> dataOrigins, int pageSize, long pageToken, boolean ascending)52     private ReadRecordsRequestUsingFilters(
53             @NonNull TimeRangeFilter timeRangeFilter,
54             @NonNull Class<T> recordType,
55             @NonNull Set<DataOrigin> dataOrigins,
56             int pageSize,
57             long pageToken,
58             boolean ascending) {
59         super(recordType);
60         Objects.requireNonNull(dataOrigins);
61         mTimeRangeFilter = timeRangeFilter;
62         mDataOrigins = dataOrigins;
63         mPageSize = pageSize;
64         if (pageToken != DEFAULT_LONG) {
65             mAscending = pageToken % 2 == 0 ? true : false;
66         } else {
67             mAscending = ascending;
68         }
69         mPageToken = pageToken;
70     }
71 
72     /** Returns time range b/w which the read operation is to be performed */
73     @Nullable
getTimeRangeFilter()74     public TimeRangeFilter getTimeRangeFilter() {
75         return mTimeRangeFilter;
76     }
77 
78     /**
79      * Returns the set of {@link DataOrigin data origins} to be read, or empty list for no filter
80      */
81     @NonNull
getDataOrigins()82     public Set<DataOrigin> getDataOrigins() {
83         return mDataOrigins;
84     }
85 
86     /** Returns maximum number of records to be returned by the read operation */
87     @IntRange(from = 1, to = 5000)
getPageSize()88     public int getPageSize() {
89         return mPageSize;
90     }
91 
92     /** Returns page token to read the current page of the result. -1 if none available */
getPageToken()93     public long getPageToken() {
94         return mPageToken;
95     }
96 
97     /** Returns ordering of results to be returned */
isAscending()98     public boolean isAscending() {
99         return mAscending;
100     }
101 
102     /**
103      * Returns an object of ReadRecordsRequestParcel to carry read request
104      *
105      * @hide
106      */
107     @NonNull
toReadRecordsRequestParcel()108     public ReadRecordsRequestParcel toReadRecordsRequestParcel() {
109         return new ReadRecordsRequestParcel(this);
110     }
111 
112     /** Builder class for {@link ReadRecordsRequestUsingFilters} */
113     public static final class Builder<T extends Record> {
114         private final Class<T> mRecordType;
115         private final Set<DataOrigin> mDataOrigins = new ArraySet<>();
116         private TimeRangeFilter mTimeRangeFilter;
117         private int mPageSize = DEFAULT_PAGE_SIZE;
118         private long mPageToken = DEFAULT_LONG;
119         private boolean mAscending = true;
120         private boolean mIsOrderingSet = false;
121 
122         /**
123          * @param recordType Class object of {@link Record} type that needs to be read
124          */
Builder(@onNull Class<T> recordType)125         public Builder(@NonNull Class<T> recordType) {
126             Objects.requireNonNull(recordType);
127 
128             mRecordType = recordType;
129         }
130 
131         /**
132          * Sets the data origin filter based on which the read operation is to be performed
133          *
134          * @param dataOrigin Adds {@link DataOrigin} for which to read records.
135          *     <p>If no {@link DataOrigin} is added then records by all {@link DataOrigin}s will be
136          *     read
137          */
138         @NonNull
addDataOrigins(@onNull DataOrigin dataOrigin)139         public Builder<T> addDataOrigins(@NonNull DataOrigin dataOrigin) {
140             Objects.requireNonNull(dataOrigin);
141             mDataOrigins.add(dataOrigin);
142 
143             return this;
144         }
145 
146         /**
147          * Sets time range b/w which the read operation is to be performed
148          *
149          * @param timeRangeFilter Time range b/w which the read operation is to be performed.
150          *     <p>If not time range filter is present all the records will be read without any time
151          *     constraints.
152          */
153         @NonNull
setTimeRangeFilter(@ullable TimeRangeFilter timeRangeFilter)154         public Builder<T> setTimeRangeFilter(@Nullable TimeRangeFilter timeRangeFilter) {
155             mTimeRangeFilter = timeRangeFilter;
156             return this;
157         }
158 
159         /**
160          * Sets maximum number of records to be returned by the read operation
161          *
162          * @param pageSize number of records to be returned by the read operation.
163          *     <p>This sets to limit number of rows returned by a read. If not set default is 1000
164          *     and maximum of 5000 records can be sent.
165          */
166         @NonNull
setPageSize(@ntRangefrom = 1, to = 5000) int pageSize)167         public Builder<T> setPageSize(@IntRange(from = 1, to = 5000) int pageSize) {
168             if (pageSize > MAXIMUM_PAGE_SIZE) {
169                 throw new IllegalArgumentException(
170                         "Maximum allowed pageSize is "
171                                 + MAXIMUM_PAGE_SIZE
172                                 + ", requested "
173                                 + pageSize);
174             }
175             mPageSize = pageSize;
176             return this;
177         }
178 
179         /**
180          * Sets page token to read the requested page of the result.
181          *
182          * @param pageToken to read the requested page of the result. -1 if none available
183          */
184         @NonNull
setPageToken(long pageToken)185         public Builder<T> setPageToken(long pageToken) {
186             mPageToken = pageToken;
187             return this;
188         }
189 
190         /**
191          * Sets ordering of results to be returned based on start time. Ordering cannot be set along
192          * with page token for subsequent requests. IllegalState exception is thrown when ordering
193          * is set along with the page token.
194          *
195          * @param ascending specifies sorting order of results, if set to true records are sorted on
196          *     start time in ascending fashion, else if set to false then in descending.
197          */
198         @NonNull
setAscending(boolean ascending)199         public Builder<T> setAscending(boolean ascending) {
200             mAscending = ascending;
201             mIsOrderingSet = true;
202             return this;
203         }
204 
205         /**
206          * Returns an Object of {@link ReadRecordsRequestUsingFilters}
207          *
208          * <p>For subsequent read requests, {@link ReadRecordsRequestUsingFilters} does not allow
209          * both pageToken and sort order to be set together.
210          *
211          * <p>If pageToken is set then records will be sorted in same order as the previous result
212          *
213          * <p>If both pageToken and sortOrder are not set then by default records will be sorted by
214          * start time in ascending order.
215          *
216          * @throws IllegalStateException if both pageToken and sort order is set.
217          */
218         @NonNull
build()219         public ReadRecordsRequestUsingFilters<T> build() {
220             if (mPageToken != DEFAULT_LONG && mIsOrderingSet) {
221                 throw new IllegalStateException("Cannot set both pageToken and sort order");
222             }
223             return new ReadRecordsRequestUsingFilters<>(
224                     mTimeRangeFilter, mRecordType, mDataOrigins, mPageSize, mPageToken, mAscending);
225         }
226     }
227 }
228