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.NonNull;
20 import android.health.connect.datatypes.AggregationType;
21 import android.health.connect.datatypes.DataOrigin;
22 import android.util.ArraySet;
23 
24 import java.util.Objects;
25 import java.util.Set;
26 
27 /** A class to create requests for {@link HealthConnectManager#aggregate} */
28 public final class AggregateRecordsRequest<T> {
29     private final TimeRangeFilter mTimeRangeFilter;
30     private final Set<AggregationType<T>> mAggregationTypes;
31     private final Set<DataOrigin> mDataOriginsFilter;
32     /**
33      * @param timeRangeFilter Time range b/w which the aggregate operation is to be performed
34      * @param aggregationTypes Set of {@link AggregationType} to aggregate
35      * @param dataOriginsFilter Set of {@link DataOrigin}s to read from, or empty set for no filter.
36      *     <p>Filters applies to all the requests in {@code aggregationTypes}
37      *     <p>Here no filters means that data from all data origins will be considered for this
38      *     operation
39      */
AggregateRecordsRequest( @onNull Set<AggregationType<T>> aggregationTypes, @NonNull TimeRangeFilter timeRangeFilter, @NonNull Set<DataOrigin> dataOriginsFilter)40     private AggregateRecordsRequest(
41             @NonNull Set<AggregationType<T>> aggregationTypes,
42             @NonNull TimeRangeFilter timeRangeFilter,
43             @NonNull Set<DataOrigin> dataOriginsFilter) {
44         Objects.requireNonNull(timeRangeFilter);
45         Objects.requireNonNull(aggregationTypes);
46         Objects.requireNonNull(dataOriginsFilter);
47 
48         mTimeRangeFilter = timeRangeFilter;
49         mAggregationTypes = aggregationTypes;
50         mDataOriginsFilter = dataOriginsFilter;
51     }
52 
53     /**
54      * @return time range b/w which the aggregate operation is to be performed
55      */
56     @NonNull
getTimeRangeFilter()57     public TimeRangeFilter getTimeRangeFilter() {
58         return mTimeRangeFilter;
59     }
60 
61     /**
62      * @return Set of integers from {@link AggregationType} to aggregate
63      */
64     @NonNull
getAggregationTypes()65     public Set<AggregationType<T>> getAggregationTypes() {
66         return mAggregationTypes;
67     }
68 
69     /**
70      * @return Set of {@link DataOrigin}s to read from, or empty set for no filter
71      */
72     @NonNull
getDataOriginsFilters()73     public Set<DataOrigin> getDataOriginsFilters() {
74         return mDataOriginsFilter;
75     }
76 
77     public static final class Builder<T> {
78         private final TimeRangeFilter mTimeRangeFilter;
79         private final Set<AggregationType<T>> mAggregationTypes = new ArraySet<>();
80         private final Set<DataOrigin> mDataOriginsFilter = new ArraySet<>();
81 
82         /**
83          * @param timeRangeFilter Time range b/w which the aggregate operation is to be performed
84          *     <p>Filters applies to all the aggregate requests.
85          */
Builder(@onNull TimeRangeFilter timeRangeFilter)86         public Builder(@NonNull TimeRangeFilter timeRangeFilter) {
87             Objects.requireNonNull(timeRangeFilter);
88 
89             mTimeRangeFilter = timeRangeFilter;
90         }
91 
92         /**
93          * @param aggregationType {@link AggregationType} to aggregate.
94          */
95         @NonNull
addAggregationType(@onNull AggregationType<T> aggregationType)96         public Builder<T> addAggregationType(@NonNull AggregationType<T> aggregationType) {
97             mAggregationTypes.add(aggregationType);
98 
99             return this;
100         }
101 
102         /**
103          * Adds {@code dataOriginsFilter} to the set of {@link DataOrigin} to filter for this
104          * aggregation.
105          *
106          * <p>If not set data from all data origins will be considered for this operation
107          */
108         @NonNull
addDataOriginsFilter(@onNull DataOrigin dataOriginsFilter)109         public Builder<T> addDataOriginsFilter(@NonNull DataOrigin dataOriginsFilter) {
110             Objects.requireNonNull(dataOriginsFilter);
111 
112             mDataOriginsFilter.add(dataOriginsFilter);
113             return this;
114         }
115 
116         /**
117          * @return Object of {@link AggregateRecordsRequest}
118          */
119         @NonNull
build()120         public AggregateRecordsRequest<T> build() {
121             if (mAggregationTypes.isEmpty()) {
122                 throw new IllegalArgumentException(
123                         "At least one of the aggregation types must be set");
124             }
125 
126             return new AggregateRecordsRequest<T>(
127                     mAggregationTypes, mTimeRangeFilter, mDataOriginsFilter);
128         }
129     }
130 }
131