• 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.aidl;
18 
19 import static android.health.connect.Constants.DEFAULT_INT;
20 import static android.health.connect.Constants.DEFAULT_LONG;
21 
22 import android.annotation.NonNull;
23 import android.annotation.Nullable;
24 import android.health.connect.AggregateRecordsRequest;
25 import android.health.connect.LocalTimeRangeFilter;
26 import android.health.connect.TimeInstantRangeFilter;
27 import android.health.connect.TimeRangeFilter;
28 import android.health.connect.TimeRangeFilterHelper;
29 import android.health.connect.datatypes.AggregationType;
30 import android.health.connect.datatypes.DataOrigin;
31 import android.os.Parcel;
32 import android.os.Parcelable;
33 
34 import java.time.Duration;
35 import java.time.Instant;
36 import java.time.Period;
37 import java.util.List;
38 import java.util.stream.Collectors;
39 
40 /** @hide */
41 public class AggregateDataRequestParcel implements Parcelable {
42     public static final Creator<AggregateDataRequestParcel> CREATOR =
43             new Creator<>() {
44                 @Override
45                 public AggregateDataRequestParcel createFromParcel(Parcel in) {
46                     return new AggregateDataRequestParcel(in);
47                 }
48 
49                 @Override
50                 public AggregateDataRequestParcel[] newArray(int size) {
51                     return new AggregateDataRequestParcel[size];
52                 }
53             };
54     private final long mStartTime;
55     private final long mEndTime;
56     private final int[] mAggregateIds;
57     private final List<String> mPackageFilters;
58     // If set represents that the aggregations have to be grouped by on {@code mDuration}
59     private Duration mDuration;
60     // If set represents that the aggregations have to be grouped by on {@code mPeriod}. If both are
61     // set the duration takes precedence, but there should not be case when both are set.
62     private Period mPeriod;
63 
64     private boolean mLocalTimeFilter;
65 
AggregateDataRequestParcel(AggregateRecordsRequest<?> request)66     public AggregateDataRequestParcel(AggregateRecordsRequest<?> request) {
67         mStartTime = TimeRangeFilterHelper.getFilterStartTimeMillis(request.getTimeRangeFilter());
68         mEndTime = TimeRangeFilterHelper.getFilterEndTimeMillis(request.getTimeRangeFilter());
69         mAggregateIds = new int[request.getAggregationTypes().size()];
70         mLocalTimeFilter = TimeRangeFilterHelper.isLocalTimeFilter(request.getTimeRangeFilter());
71 
72         int i = 0;
73         for (AggregationType<?> aggregationType : request.getAggregationTypes()) {
74             mAggregateIds[i++] = aggregationType.getAggregationTypeIdentifier();
75         }
76         mPackageFilters =
77                 request.getDataOriginsFilters().stream()
78                         .map(DataOrigin::getPackageName)
79                         .collect(Collectors.toList());
80         // Use durations group by single queries as it support null values
81         mDuration = Duration.ofMillis(mEndTime - mStartTime);
82     }
83 
AggregateDataRequestParcel(AggregateRecordsRequest request, Duration duration)84     public AggregateDataRequestParcel(AggregateRecordsRequest request, Duration duration) {
85         this(request);
86         mDuration = duration;
87     }
88 
AggregateDataRequestParcel(AggregateRecordsRequest request, Period period)89     public AggregateDataRequestParcel(AggregateRecordsRequest request, Period period) {
90         this(request);
91         mDuration = null;
92         mPeriod = period;
93 
94         if (!TimeRangeFilterHelper.isLocalTimeFilter(request.getTimeRangeFilter())) {
95             throw new UnsupportedOperationException(
96                     "For period requests should use LocalTimeRangeFilter");
97         }
98     }
99 
AggregateDataRequestParcel(Parcel in)100     protected AggregateDataRequestParcel(Parcel in) {
101         mStartTime = in.readLong();
102         mEndTime = in.readLong();
103         mLocalTimeFilter = in.readBoolean();
104         mAggregateIds = in.createIntArray();
105         mPackageFilters = in.createStringArrayList();
106         int periodDays = in.readInt();
107         if (periodDays != DEFAULT_INT) {
108             int periodMonths = in.readInt();
109             int periodYears = in.readInt();
110             mPeriod = Period.of(periodYears, periodMonths, periodDays);
111         }
112 
113         long duration = in.readLong();
114         if (duration != DEFAULT_LONG) {
115             mDuration = Duration.ofMillis(duration);
116         }
117     }
118 
119     @Nullable
getDuration()120     public Duration getDuration() {
121         return mDuration;
122     }
123 
124     @Nullable
getPeriod()125     public Period getPeriod() {
126         return mPeriod;
127     }
128 
129     @Override
describeContents()130     public int describeContents() {
131         return 0;
132     }
133 
134     @Override
writeToParcel(@onNull Parcel dest, int flags)135     public void writeToParcel(@NonNull Parcel dest, int flags) {
136         dest.writeLong(mStartTime);
137         dest.writeLong(mEndTime);
138         dest.writeBoolean(mLocalTimeFilter);
139         dest.writeIntArray(mAggregateIds);
140         dest.writeStringList(mPackageFilters);
141         if (mPeriod != null) {
142             dest.writeInt(mPeriod.getDays());
143             dest.writeInt(mPeriod.getMonths());
144             dest.writeInt(mPeriod.getYears());
145         } else {
146             dest.writeInt(DEFAULT_INT);
147         }
148 
149         if (mDuration != null) {
150             dest.writeLong(mDuration.toMillis());
151         } else {
152             dest.writeLong(DEFAULT_LONG);
153         }
154     }
155 
getStartTime()156     public long getStartTime() {
157         return mStartTime;
158     }
159 
getEndTime()160     public long getEndTime() {
161         return mEndTime;
162     }
163 
getAggregateIds()164     public int[] getAggregateIds() {
165         return mAggregateIds;
166     }
167 
168     @NonNull
getPackageFilters()169     public List<String> getPackageFilters() {
170         return mPackageFilters;
171     }
172 
173     @NonNull
getTimeRangeFilter()174     public TimeRangeFilter getTimeRangeFilter() {
175         if (mLocalTimeFilter) {
176             return new LocalTimeRangeFilter.Builder()
177                     .setStartTime(TimeRangeFilterHelper.getLocalTimeFromMillis(mStartTime))
178                     .setEndTime(TimeRangeFilterHelper.getLocalTimeFromMillis(mEndTime))
179                     .build();
180         } else {
181             return new TimeInstantRangeFilter.Builder()
182                     .setStartTime(Instant.ofEpochMilli(mStartTime))
183                     .setEndTime(Instant.ofEpochMilli(mEndTime))
184                     .build();
185         }
186     }
187 }
188