• 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_INT;
20 import static android.health.connect.HealthPermissionCategory.ACTIVE_CALORIES_BURNED;
21 import static android.health.connect.HealthPermissionCategory.BASAL_BODY_TEMPERATURE;
22 import static android.health.connect.HealthPermissionCategory.BASAL_METABOLIC_RATE;
23 import static android.health.connect.HealthPermissionCategory.BLOOD_GLUCOSE;
24 import static android.health.connect.HealthPermissionCategory.BLOOD_PRESSURE;
25 import static android.health.connect.HealthPermissionCategory.BODY_FAT;
26 import static android.health.connect.HealthPermissionCategory.BODY_TEMPERATURE;
27 import static android.health.connect.HealthPermissionCategory.BODY_WATER_MASS;
28 import static android.health.connect.HealthPermissionCategory.BONE_MASS;
29 import static android.health.connect.HealthPermissionCategory.CERVICAL_MUCUS;
30 import static android.health.connect.HealthPermissionCategory.DISTANCE;
31 import static android.health.connect.HealthPermissionCategory.ELEVATION_GAINED;
32 import static android.health.connect.HealthPermissionCategory.EXERCISE;
33 import static android.health.connect.HealthPermissionCategory.FLOORS_CLIMBED;
34 import static android.health.connect.HealthPermissionCategory.HEART_RATE;
35 import static android.health.connect.HealthPermissionCategory.HEART_RATE_VARIABILITY;
36 import static android.health.connect.HealthPermissionCategory.HEIGHT;
37 import static android.health.connect.HealthPermissionCategory.HYDRATION;
38 import static android.health.connect.HealthPermissionCategory.INTERMENSTRUAL_BLEEDING;
39 import static android.health.connect.HealthPermissionCategory.LEAN_BODY_MASS;
40 import static android.health.connect.HealthPermissionCategory.MENSTRUATION;
41 import static android.health.connect.HealthPermissionCategory.NUTRITION;
42 import static android.health.connect.HealthPermissionCategory.OVULATION_TEST;
43 import static android.health.connect.HealthPermissionCategory.OXYGEN_SATURATION;
44 import static android.health.connect.HealthPermissionCategory.POWER;
45 import static android.health.connect.HealthPermissionCategory.RESPIRATORY_RATE;
46 import static android.health.connect.HealthPermissionCategory.RESTING_HEART_RATE;
47 import static android.health.connect.HealthPermissionCategory.SEXUAL_ACTIVITY;
48 import static android.health.connect.HealthPermissionCategory.SLEEP;
49 import static android.health.connect.HealthPermissionCategory.SPEED;
50 import static android.health.connect.HealthPermissionCategory.STEPS;
51 import static android.health.connect.HealthPermissionCategory.TOTAL_CALORIES_BURNED;
52 import static android.health.connect.HealthPermissionCategory.VO2_MAX;
53 import static android.health.connect.HealthPermissionCategory.WEIGHT;
54 import static android.health.connect.HealthPermissionCategory.WHEELCHAIR_PUSHES;
55 
56 import android.annotation.NonNull;
57 import android.annotation.Nullable;
58 import android.annotation.SystemApi;
59 import android.health.connect.datatypes.ExerciseRoute;
60 import android.util.ArrayMap;
61 import android.util.ArraySet;
62 
63 import java.util.Map;
64 import java.util.Objects;
65 import java.util.Set;
66 
67 // TODO(b/255340973): consider generate this class.
68 /**
69  * Permissions for accessing the HealthConnect APIs.
70  *
71  * <p>Apps must support {@link android.content.Intent#ACTION_VIEW_PERMISSION_USAGE} with {@link
72  * HealthConnectManager#CATEGORY_HEALTH_PERMISSIONS} category to be granted read/write health data
73  * permissions.
74  */
75 public final class HealthPermissions {
76     /**
77      * Allows an application to grant/revoke health-related permissions.
78      *
79      * <p>Protection level: signature.
80      *
81      * @hide
82      */
83     @SystemApi
84     public static final String MANAGE_HEALTH_PERMISSIONS =
85             "android.permission.MANAGE_HEALTH_PERMISSIONS";
86 
87     // Below permission was earlier declared in HealthConnectManager since it was only permission
88     // used by access logs API, is now declared here along with the other system permission.
89     // Please suggest if it will be ok to have it here.
90     /**
91      * Allows an application to modify health data.
92      *
93      * <p>Protection level: privileged.
94      *
95      * @hide
96      */
97     @SystemApi
98     public static final String MANAGE_HEALTH_DATA_PERMISSION =
99             "android.permission.MANAGE_HEALTH_DATA";
100 
101     /**
102      * Used for runtime permissions which grant access to Health Connect data.
103      *
104      * @hide
105      */
106     @SystemApi
107     public static final String HEALTH_PERMISSION_GROUP = "android.permission-group.HEALTH";
108     /**
109      * Allows an application to read the user's active calories burned data.
110      *
111      * <p>Protection level: dangerous.
112      */
113     public static final String READ_ACTIVE_CALORIES_BURNED =
114             "android.permission.health.READ_ACTIVE_CALORIES_BURNED";
115     /**
116      * Allows an application to read the user's distance data.
117      *
118      * <p>Protection level: dangerous.
119      */
120     public static final String READ_DISTANCE = "android.permission.health.READ_DISTANCE";
121     /**
122      * Allows an application to read the user's elevation gained data.
123      *
124      * <p>Protection level: dangerous.
125      */
126     public static final String READ_ELEVATION_GAINED =
127             "android.permission.health.READ_ELEVATION_GAINED";
128     /**
129      * Allows an application to read the user's exercise data.
130      *
131      * <p>Protection level: dangerous.
132      */
133     public static final String READ_EXERCISE = "android.permission.health.READ_EXERCISE";
134 
135     /**
136      * Allows an application to read any {@link ExerciseRoute}. Not connected with READ_EXERCISE
137      * permission, as it's used only by HealthConnectController to show routes in UI and share one
138      * particular route with third party app after one-time user consent.
139      *
140      * <p>Protection level: signature.
141      *
142      * @hide
143      */
144     public static final String READ_EXERCISE_ROUTE =
145             "android.permission.health.READ_EXERCISE_ROUTE";
146 
147     /**
148      * Allows an application to read the user's floors climbed data.
149      *
150      * <p>Protection level: dangerous.
151      */
152     public static final String READ_FLOORS_CLIMBED =
153             "android.permission.health.READ_FLOORS_CLIMBED";
154     /**
155      * Allows an application to read the user's steps data.
156      *
157      * <p>Protection level: dangerous.
158      */
159     public static final String READ_STEPS = "android.permission.health.READ_STEPS";
160     /**
161      * Allows an application to read the user's total calories burned data.
162      *
163      * <p>Protection level: dangerous.
164      */
165     public static final String READ_TOTAL_CALORIES_BURNED =
166             "android.permission.health.READ_TOTAL_CALORIES_BURNED";
167     /**
168      * Allows an application to read the user's vo2 maximum data.
169      *
170      * <p>Protection level: dangerous.
171      */
172     public static final String READ_VO2_MAX = "android.permission.health.READ_VO2_MAX";
173     /**
174      * Allows an application to read the user's wheelchair pushes data.
175      *
176      * <p>Protection level: dangerous.
177      */
178     public static final String READ_WHEELCHAIR_PUSHES =
179             "android.permission.health.READ_WHEELCHAIR_PUSHES";
180     /**
181      * Allows an application to read the user's power data.
182      *
183      * <p>Protection level: dangerous.
184      */
185     public static final String READ_POWER = "android.permission.health.READ_POWER";
186     /**
187      * Allows an application to read the user's speed data.
188      *
189      * <p>Protection level: dangerous.
190      */
191     public static final String READ_SPEED = "android.permission.health.READ_SPEED";
192     /**
193      * Allows an application to read the user's basal metabolic rate data.
194      *
195      * <p>Protection level: dangerous.
196      */
197     public static final String READ_BASAL_METABOLIC_RATE =
198             "android.permission.health.READ_BASAL_METABOLIC_RATE";
199     /**
200      * Allows an application to read the user's body fat data.
201      *
202      * <p>Protection level: dangerous.
203      */
204     public static final String READ_BODY_FAT = "android.permission.health.READ_BODY_FAT";
205     /**
206      * Allows an application to read the user's body water mass data.
207      *
208      * <p>Protection level: dangerous.
209      */
210     public static final String READ_BODY_WATER_MASS =
211             "android.permission.health.READ_BODY_WATER_MASS";
212     /**
213      * Allows an application to read the user's bone mass data.
214      *
215      * <p>Protection level: dangerous.
216      */
217     public static final String READ_BONE_MASS = "android.permission.health.READ_BONE_MASS";
218     /**
219      * Allows an application to read the user's height data.
220      *
221      * <p>Protection level: dangerous.
222      */
223     public static final String READ_HEIGHT = "android.permission.health.READ_HEIGHT";
224     /**
225      * Allows an application to read the user's lean body mass data.
226      *
227      * <p>Protection level: dangerous.
228      */
229     public static final String READ_LEAN_BODY_MASS =
230             "android.permission.health.READ_LEAN_BODY_MASS";
231     /**
232      * Allows an application to read the user's weight data.
233      *
234      * <p>Protection level: dangerous.
235      */
236     public static final String READ_WEIGHT = "android.permission.health.READ_WEIGHT";
237     /**
238      * Allows an application to read the user's cervical mucus data.
239      *
240      * <p>Protection level: dangerous.
241      */
242     public static final String READ_CERVICAL_MUCUS =
243             "android.permission.health.READ_CERVICAL_MUCUS";
244     /**
245      * Allows an application to read the user's menstruation data.
246      *
247      * <p>Protection level: dangerous.
248      */
249     public static final String READ_MENSTRUATION = "android.permission.health.READ_MENSTRUATION";
250     /**
251      * Allows an application to read the user's intermenstrual bleeding data.
252      *
253      * <p>Protection level: dangerous.
254      */
255     public static final String READ_INTERMENSTRUAL_BLEEDING =
256             "android.permission.health.READ_INTERMENSTRUAL_BLEEDING";
257     /**
258      * Allows an application to read the user's ovulation test data.
259      *
260      * <p>Protection level: dangerous.
261      */
262     public static final String READ_OVULATION_TEST =
263             "android.permission.health.READ_OVULATION_TEST";
264     /**
265      * Allows an application to read the user's sexual activity data.
266      *
267      * <p>Protection level: dangerous.
268      */
269     public static final String READ_SEXUAL_ACTIVITY =
270             "android.permission.health.READ_SEXUAL_ACTIVITY";
271     /**
272      * Allows an application to read the user's hydration data.
273      *
274      * <p>Protection level: dangerous.
275      */
276     public static final String READ_HYDRATION = "android.permission.health.READ_HYDRATION";
277     /**
278      * Allows an application to read the user's nutrition data.
279      *
280      * <p>Protection level: dangerous.
281      */
282     public static final String READ_NUTRITION = "android.permission.health.READ_NUTRITION";
283     /**
284      * Allows an application to read the user's sleep data.
285      *
286      * <p>Protection level: dangerous.
287      */
288     public static final String READ_SLEEP = "android.permission.health.READ_SLEEP";
289     /**
290      * Allows an application to read the user's body temperature data.
291      *
292      * <p>Protection level: dangerous.
293      */
294     public static final String READ_BASAL_BODY_TEMPERATURE =
295             "android.permission.health.READ_BASAL_BODY_TEMPERATURE";
296     /**
297      * Allows an application to read the user's blood glucose data.
298      *
299      * <p>Protection level: dangerous.
300      */
301     public static final String READ_BLOOD_GLUCOSE = "android.permission.health.READ_BLOOD_GLUCOSE";
302     /**
303      * Allows an application to read the user's blood pressure data.
304      *
305      * <p>Protection level: dangerous.
306      */
307     public static final String READ_BLOOD_PRESSURE =
308             "android.permission.health.READ_BLOOD_PRESSURE";
309     /**
310      * Allows an application to read the user's body temperature data.
311      *
312      * <p>Protection level: dangerous.
313      */
314     public static final String READ_BODY_TEMPERATURE =
315             "android.permission.health.READ_BODY_TEMPERATURE";
316     /**
317      * Allows an application to read the user's heart rate data.
318      *
319      * <p>Protection level: dangerous.
320      */
321     public static final String READ_HEART_RATE = "android.permission.health.READ_HEART_RATE";
322     /**
323      * Allows an application to read the user's heart rate variability data.
324      *
325      * <p>Protection level: dangerous.
326      */
327     public static final String READ_HEART_RATE_VARIABILITY =
328             "android.permission.health.READ_HEART_RATE_VARIABILITY";
329     /**
330      * Allows an application to read the user's oxygen saturation data.
331      *
332      * <p>Protection level: dangerous.
333      */
334     public static final String READ_OXYGEN_SATURATION =
335             "android.permission.health.READ_OXYGEN_SATURATION";
336     /**
337      * Allows an application to read the user's respiratory rate data.
338      *
339      * <p>Protection level: dangerous.
340      */
341     public static final String READ_RESPIRATORY_RATE =
342             "android.permission.health.READ_RESPIRATORY_RATE";
343     /**
344      * Allows an application to read the user's resting heart rate data.
345      *
346      * <p>Protection level: dangerous.
347      */
348     public static final String READ_RESTING_HEART_RATE =
349             "android.permission.health.READ_RESTING_HEART_RATE";
350     /**
351      * Allows an application to write the user's calories burned data.
352      *
353      * <p>Protection level: dangerous.
354      */
355     public static final String WRITE_ACTIVE_CALORIES_BURNED =
356             "android.permission.health.WRITE_ACTIVE_CALORIES_BURNED";
357     /**
358      * Allows an application to write the user's distance data.
359      *
360      * <p>Protection level: dangerous.
361      */
362     public static final String WRITE_DISTANCE = "android.permission.health.WRITE_DISTANCE";
363     /**
364      * Allows an application to write the user's elevation gained data.
365      *
366      * <p>Protection level: dangerous.
367      */
368     public static final String WRITE_ELEVATION_GAINED =
369             "android.permission.health.WRITE_ELEVATION_GAINED";
370     /**
371      * Allows an application to write the user's exercise data. Additional permission {@link
372      * HealthPermissions#WRITE_EXERCISE_ROUTE} is required to write user's exercise route.
373      *
374      * <p>Protection level: dangerous.
375      */
376     public static final String WRITE_EXERCISE = "android.permission.health.WRITE_EXERCISE";
377     /**
378      * Allows an application to write the user's exercise route.
379      *
380      * <p>Protection level: dangerous.
381      */
382     public static final String WRITE_EXERCISE_ROUTE =
383             "android.permission.health.WRITE_EXERCISE_ROUTE";
384     /**
385      * Allows an application to write the user's floors climbed data.
386      *
387      * <p>Protection level: dangerous.
388      */
389     public static final String WRITE_FLOORS_CLIMBED =
390             "android.permission.health.WRITE_FLOORS_CLIMBED";
391     /**
392      * Allows an application to write the user's steps data.
393      *
394      * <p>Protection level: dangerous.
395      */
396     public static final String WRITE_STEPS = "android.permission.health.WRITE_STEPS";
397     /**
398      * Allows an application to write the user's total calories burned data.
399      *
400      * <p>Protection level: dangerous.
401      */
402     public static final String WRITE_TOTAL_CALORIES_BURNED =
403             "android.permission.health.WRITE_TOTAL_CALORIES_BURNED";
404     /**
405      * Allows an application to write the user's vo2 maximum data.
406      *
407      * <p>Protection level: dangerous.
408      */
409     public static final String WRITE_VO2_MAX = "android.permission.health.WRITE_VO2_MAX";
410     /**
411      * Allows an application to write the user's wheelchair pushes data.
412      *
413      * <p>Protection level: dangerous.
414      */
415     public static final String WRITE_WHEELCHAIR_PUSHES =
416             "android.permission.health.WRITE_WHEELCHAIR_PUSHES";
417     /**
418      * Allows an application to write the user's power data.
419      *
420      * <p>Protection level: dangerous.
421      */
422     public static final String WRITE_POWER = "android.permission.health.WRITE_POWER";
423     /**
424      * Allows an application to write the user's speed data.
425      *
426      * <p>Protection level: dangerous.
427      */
428     public static final String WRITE_SPEED = "android.permission.health.WRITE_SPEED";
429     /**
430      * Allows an application to write the user's basal metabolic rate data.
431      *
432      * <p>Protection level: dangerous.
433      */
434     public static final String WRITE_BASAL_METABOLIC_RATE =
435             "android.permission.health.WRITE_BASAL_METABOLIC_RATE";
436     /**
437      * Allows an application to write the user's body fat data.
438      *
439      * <p>Protection level: dangerous.
440      */
441     public static final String WRITE_BODY_FAT = "android.permission.health.WRITE_BODY_FAT";
442     /**
443      * Allows an application to write the user's body water mass data.
444      *
445      * <p>Protection level: dangerous.
446      */
447     public static final String WRITE_BODY_WATER_MASS =
448             "android.permission.health.WRITE_BODY_WATER_MASS";
449     /**
450      * Allows an application to write the user's bone mass data.
451      *
452      * <p>Protection level: dangerous.
453      */
454     public static final String WRITE_BONE_MASS = "android.permission.health.WRITE_BONE_MASS";
455     /**
456      * Allows an application to write the user's height data.
457      *
458      * <p>Protection level: dangerous.
459      */
460     public static final String WRITE_HEIGHT = "android.permission.health.WRITE_HEIGHT";
461     /**
462      * Allows an application to write the user's lean body mass data.
463      *
464      * <p>Protection level: dangerous.
465      */
466     public static final String WRITE_LEAN_BODY_MASS =
467             "android.permission.health.WRITE_LEAN_BODY_MASS";
468     /**
469      * Allows an application to write the user's weight data.
470      *
471      * <p>Protection level: dangerous.
472      */
473     public static final String WRITE_WEIGHT = "android.permission.health.WRITE_WEIGHT";
474     /**
475      * Allows an application to write the user's cervical mucus data.
476      *
477      * <p>Protection level: dangerous.
478      */
479     public static final String WRITE_CERVICAL_MUCUS =
480             "android.permission.health.WRITE_CERVICAL_MUCUS";
481     /**
482      * Allows an application to write the user's menstruation data.
483      *
484      * <p>Protection level: dangerous.
485      */
486     public static final String WRITE_MENSTRUATION = "android.permission.health.WRITE_MENSTRUATION";
487     /**
488      * Allows an application to write the user's intermenstrual bleeding data.
489      *
490      * <p>Protection level: dangerous.
491      */
492     public static final String WRITE_INTERMENSTRUAL_BLEEDING =
493             "android.permission.health.WRITE_INTERMENSTRUAL_BLEEDING";
494     /**
495      * Allows an application to write the user's ovulation test data.
496      *
497      * <p>Protection level: dangerous.
498      */
499     public static final String WRITE_OVULATION_TEST =
500             "android.permission.health.WRITE_OVULATION_TEST";
501     /**
502      * Allows an application to write the user's sexual activity data.
503      *
504      * <p>Protection level: dangerous.
505      */
506     public static final String WRITE_SEXUAL_ACTIVITY =
507             "android.permission.health.WRITE_SEXUAL_ACTIVITY";
508     /**
509      * Allows an application to write the user's hydration data.
510      *
511      * <p>Protection level: dangerous.
512      */
513     public static final String WRITE_HYDRATION = "android.permission.health.WRITE_HYDRATION";
514     /**
515      * Allows an application to write the user's nutrition data.
516      *
517      * <p>Protection level: dangerous.
518      */
519     public static final String WRITE_NUTRITION = "android.permission.health.WRITE_NUTRITION";
520     /**
521      * Allows an application to write the user's sleep data.
522      *
523      * <p>Protection level: dangerous.
524      */
525     public static final String WRITE_SLEEP = "android.permission.health.WRITE_SLEEP";
526     /**
527      * Allows an application to write the user's basal body temperature data.
528      *
529      * <p>Protection level: dangerous.
530      */
531     public static final String WRITE_BASAL_BODY_TEMPERATURE =
532             "android.permission.health.WRITE_BASAL_BODY_TEMPERATURE";
533     /**
534      * Allows an application to write the user's blood glucose data.
535      *
536      * <p>Protection level: dangerous.
537      */
538     public static final String WRITE_BLOOD_GLUCOSE =
539             "android.permission.health.WRITE_BLOOD_GLUCOSE";
540     /**
541      * Allows an application to write the user's blood pressure data.
542      *
543      * <p>Protection level: dangerous.
544      */
545     public static final String WRITE_BLOOD_PRESSURE =
546             "android.permission.health.WRITE_BLOOD_PRESSURE";
547     /**
548      * Allows an application to write the user's body temperature data.
549      *
550      * <p>Protection level: dangerous.
551      */
552     public static final String WRITE_BODY_TEMPERATURE =
553             "android.permission.health.WRITE_BODY_TEMPERATURE";
554     /**
555      * Allows an application to write the user's heart rate data.
556      *
557      * <p>Protection level: dangerous.
558      */
559     public static final String WRITE_HEART_RATE = "android.permission.health.WRITE_HEART_RATE";
560     /**
561      * Allows an application to write the user's heart rate variability data.
562      *
563      * <p>Protection level: dangerous.
564      */
565     public static final String WRITE_HEART_RATE_VARIABILITY =
566             "android.permission.health.WRITE_HEART_RATE_VARIABILITY";
567     /**
568      * Allows an application to write the user's oxygen saturation data.
569      *
570      * <p>Protection level: dangerous.
571      */
572     public static final String WRITE_OXYGEN_SATURATION =
573             "android.permission.health.WRITE_OXYGEN_SATURATION";
574     /**
575      * Allows an application to write the user's respiratory rate data.
576      *
577      * <p>Protection level: dangerous.
578      */
579     public static final String WRITE_RESPIRATORY_RATE =
580             "android.permission.health.WRITE_RESPIRATORY_RATE";
581     /**
582      * Allows an application to write the user's resting heart rate data.
583      *
584      * <p>Protection level: dangerous.
585      */
586     public static final String WRITE_RESTING_HEART_RATE =
587             "android.permission.health.WRITE_RESTING_HEART_RATE";
588 
589     private static final Set<String> sWritePermissionsSet =
590             new ArraySet<>(
591                     Set.of(
592                             WRITE_ACTIVE_CALORIES_BURNED,
593                             WRITE_DISTANCE,
594                             WRITE_ELEVATION_GAINED,
595                             WRITE_EXERCISE,
596                             WRITE_FLOORS_CLIMBED,
597                             WRITE_STEPS,
598                             WRITE_TOTAL_CALORIES_BURNED,
599                             WRITE_VO2_MAX,
600                             WRITE_WHEELCHAIR_PUSHES,
601                             WRITE_POWER,
602                             WRITE_SPEED,
603                             WRITE_BASAL_METABOLIC_RATE,
604                             WRITE_BODY_FAT,
605                             WRITE_BODY_WATER_MASS,
606                             WRITE_BONE_MASS,
607                             WRITE_HEIGHT,
608                             WRITE_LEAN_BODY_MASS,
609                             WRITE_WEIGHT,
610                             WRITE_CERVICAL_MUCUS,
611                             WRITE_MENSTRUATION,
612                             WRITE_INTERMENSTRUAL_BLEEDING,
613                             WRITE_OVULATION_TEST,
614                             WRITE_SEXUAL_ACTIVITY,
615                             WRITE_HYDRATION,
616                             WRITE_NUTRITION,
617                             WRITE_SLEEP,
618                             WRITE_BASAL_BODY_TEMPERATURE,
619                             WRITE_BLOOD_GLUCOSE,
620                             WRITE_BLOOD_PRESSURE,
621                             WRITE_BODY_TEMPERATURE,
622                             WRITE_HEART_RATE,
623                             WRITE_HEART_RATE_VARIABILITY,
624                             WRITE_OXYGEN_SATURATION,
625                             WRITE_RESPIRATORY_RATE,
626                             WRITE_RESTING_HEART_RATE));
627 
628     private static final Map<String, Integer> sWriteHealthPermissionToHealthDataCategoryMap =
629             new ArrayMap<>();
630     private static final Map<Integer, String> sHealthCategoryToReadPermissionMap = new ArrayMap<>();
631     private static final Map<Integer, String> sHealthCategoryToWritePermissionMap =
632             new ArrayMap<>();
633 
634     private static final Map<Integer, String[]> sDataCategoryToWritePermissionsMap =
635             new ArrayMap<>();
636 
HealthPermissions()637     private HealthPermissions() {}
638 
639     /**
640      * @return true if {@code permissionName} is a write-permission
641      * @hide
642      */
isWritePermission(@onNull String permissionName)643     public static boolean isWritePermission(@NonNull String permissionName) {
644         Objects.requireNonNull(permissionName);
645 
646         return sWritePermissionsSet.contains(permissionName);
647     }
648 
649     /**
650      * @return {@link HealthDataCategory} for {@code permissionName}. -1 if permission category for
651      *     {@code permissionName} is not found
652      * @hide
653      */
654     @HealthDataCategory.Type
getHealthDataCategory(@ullable String permissionName)655     public static int getHealthDataCategory(@Nullable String permissionName) {
656         if (sWriteHealthPermissionToHealthDataCategoryMap.isEmpty()) {
657             populateWriteHealthPermissionToHealthDataCategoryMap();
658         }
659 
660         return sWriteHealthPermissionToHealthDataCategoryMap.getOrDefault(
661                 permissionName, DEFAULT_INT);
662     }
663 
664     /**
665      * @return {@link HealthDataCategory} for {@code permissionName}. -1 if permission category for
666      *     {@code permissionName} is not found
667      * @hide
668      */
getWriteHealthPermissionsFor(@ealthDataCategory.Type int dataCategory)669     public static String[] getWriteHealthPermissionsFor(@HealthDataCategory.Type int dataCategory) {
670         if (sDataCategoryToWritePermissionsMap.isEmpty()) {
671             populateWriteHealthPermissionToHealthDataCategoryMap();
672         }
673 
674         return sDataCategoryToWritePermissionsMap.getOrDefault(dataCategory, new String[] {});
675     }
676 
677     /** @hide */
getHealthReadPermission( @ealthPermissionCategory.Type int permissionCategory)678     public static String getHealthReadPermission(
679             @HealthPermissionCategory.Type int permissionCategory) {
680         if (sHealthCategoryToReadPermissionMap.isEmpty()) {
681             populateHealthPermissionToHealthPermissionCategoryMap();
682         }
683 
684         return sHealthCategoryToReadPermissionMap.get(permissionCategory);
685     }
686 
687     /** @hide */
getHealthWritePermission( @ealthPermissionCategory.Type int permissionCategory)688     public static String getHealthWritePermission(
689             @HealthPermissionCategory.Type int permissionCategory) {
690         if (sHealthCategoryToWritePermissionMap.isEmpty()) {
691             populateHealthPermissionToHealthPermissionCategoryMap();
692         }
693 
694         String healthWritePermission = sHealthCategoryToWritePermissionMap.get(permissionCategory);
695         Objects.requireNonNull(
696                 healthWritePermission,
697                 "Health write permission not found for "
698                         + "PermissionCategory : "
699                         + permissionCategory);
700         return healthWritePermission;
701     }
702 
populateHealthPermissionToHealthPermissionCategoryMap()703     private static synchronized void populateHealthPermissionToHealthPermissionCategoryMap() {
704         if (!sHealthCategoryToWritePermissionMap.isEmpty()) {
705             return;
706         }
707 
708         // Populate permission category to write permission map
709         sHealthCategoryToWritePermissionMap.put(
710                 ACTIVE_CALORIES_BURNED, WRITE_ACTIVE_CALORIES_BURNED);
711         sHealthCategoryToWritePermissionMap.put(DISTANCE, WRITE_DISTANCE);
712         sHealthCategoryToWritePermissionMap.put(ELEVATION_GAINED, WRITE_ELEVATION_GAINED);
713         sHealthCategoryToWritePermissionMap.put(EXERCISE, WRITE_EXERCISE);
714         sHealthCategoryToWritePermissionMap.put(FLOORS_CLIMBED, WRITE_FLOORS_CLIMBED);
715         sHealthCategoryToWritePermissionMap.put(STEPS, WRITE_STEPS);
716         sHealthCategoryToWritePermissionMap.put(TOTAL_CALORIES_BURNED, WRITE_TOTAL_CALORIES_BURNED);
717         sHealthCategoryToWritePermissionMap.put(VO2_MAX, WRITE_VO2_MAX);
718         sHealthCategoryToWritePermissionMap.put(WHEELCHAIR_PUSHES, WRITE_WHEELCHAIR_PUSHES);
719         sHealthCategoryToWritePermissionMap.put(POWER, WRITE_POWER);
720         sHealthCategoryToWritePermissionMap.put(SPEED, WRITE_SPEED);
721         sHealthCategoryToWritePermissionMap.put(BASAL_METABOLIC_RATE, WRITE_BASAL_METABOLIC_RATE);
722         sHealthCategoryToWritePermissionMap.put(BODY_FAT, WRITE_BODY_FAT);
723         sHealthCategoryToWritePermissionMap.put(BODY_WATER_MASS, WRITE_BODY_WATER_MASS);
724         sHealthCategoryToWritePermissionMap.put(BONE_MASS, WRITE_BONE_MASS);
725         sHealthCategoryToWritePermissionMap.put(HEIGHT, WRITE_HEIGHT);
726         sHealthCategoryToWritePermissionMap.put(LEAN_BODY_MASS, WRITE_LEAN_BODY_MASS);
727         sHealthCategoryToWritePermissionMap.put(WEIGHT, WRITE_WEIGHT);
728         sHealthCategoryToWritePermissionMap.put(CERVICAL_MUCUS, WRITE_CERVICAL_MUCUS);
729         sHealthCategoryToWritePermissionMap.put(MENSTRUATION, WRITE_MENSTRUATION);
730         sHealthCategoryToWritePermissionMap.put(
731                 INTERMENSTRUAL_BLEEDING, WRITE_INTERMENSTRUAL_BLEEDING);
732         sHealthCategoryToWritePermissionMap.put(OVULATION_TEST, WRITE_OVULATION_TEST);
733         sHealthCategoryToWritePermissionMap.put(SEXUAL_ACTIVITY, WRITE_SEXUAL_ACTIVITY);
734         sHealthCategoryToWritePermissionMap.put(HYDRATION, WRITE_HYDRATION);
735         sHealthCategoryToWritePermissionMap.put(NUTRITION, WRITE_NUTRITION);
736         sHealthCategoryToWritePermissionMap.put(SLEEP, WRITE_SLEEP);
737         sHealthCategoryToWritePermissionMap.put(
738                 BASAL_BODY_TEMPERATURE, WRITE_BASAL_BODY_TEMPERATURE);
739         sHealthCategoryToWritePermissionMap.put(BLOOD_GLUCOSE, WRITE_BLOOD_GLUCOSE);
740         sHealthCategoryToWritePermissionMap.put(BLOOD_PRESSURE, WRITE_BLOOD_PRESSURE);
741         sHealthCategoryToWritePermissionMap.put(BODY_TEMPERATURE, WRITE_BODY_TEMPERATURE);
742         sHealthCategoryToWritePermissionMap.put(HEART_RATE, WRITE_HEART_RATE);
743         sHealthCategoryToWritePermissionMap.put(
744                 HEART_RATE_VARIABILITY, WRITE_HEART_RATE_VARIABILITY);
745         sHealthCategoryToWritePermissionMap.put(OXYGEN_SATURATION, WRITE_OXYGEN_SATURATION);
746         sHealthCategoryToWritePermissionMap.put(RESPIRATORY_RATE, WRITE_RESPIRATORY_RATE);
747         sHealthCategoryToWritePermissionMap.put(RESTING_HEART_RATE, WRITE_RESTING_HEART_RATE);
748 
749         // Populate permission category to read permission map
750         sHealthCategoryToReadPermissionMap.put(ACTIVE_CALORIES_BURNED, READ_ACTIVE_CALORIES_BURNED);
751         sHealthCategoryToReadPermissionMap.put(DISTANCE, READ_DISTANCE);
752         sHealthCategoryToReadPermissionMap.put(ELEVATION_GAINED, READ_ELEVATION_GAINED);
753         sHealthCategoryToReadPermissionMap.put(EXERCISE, READ_EXERCISE);
754         sHealthCategoryToReadPermissionMap.put(FLOORS_CLIMBED, READ_FLOORS_CLIMBED);
755         sHealthCategoryToReadPermissionMap.put(STEPS, READ_STEPS);
756         sHealthCategoryToReadPermissionMap.put(TOTAL_CALORIES_BURNED, READ_TOTAL_CALORIES_BURNED);
757         sHealthCategoryToReadPermissionMap.put(VO2_MAX, READ_VO2_MAX);
758         sHealthCategoryToReadPermissionMap.put(WHEELCHAIR_PUSHES, READ_WHEELCHAIR_PUSHES);
759         sHealthCategoryToReadPermissionMap.put(POWER, READ_POWER);
760         sHealthCategoryToReadPermissionMap.put(SPEED, READ_SPEED);
761         sHealthCategoryToReadPermissionMap.put(BASAL_METABOLIC_RATE, READ_BASAL_METABOLIC_RATE);
762         sHealthCategoryToReadPermissionMap.put(BODY_FAT, READ_BODY_FAT);
763         sHealthCategoryToReadPermissionMap.put(BODY_WATER_MASS, READ_BODY_WATER_MASS);
764         sHealthCategoryToReadPermissionMap.put(BONE_MASS, READ_BONE_MASS);
765         sHealthCategoryToReadPermissionMap.put(HEIGHT, READ_HEIGHT);
766         sHealthCategoryToReadPermissionMap.put(LEAN_BODY_MASS, READ_LEAN_BODY_MASS);
767         sHealthCategoryToReadPermissionMap.put(WEIGHT, READ_WEIGHT);
768         sHealthCategoryToReadPermissionMap.put(CERVICAL_MUCUS, READ_CERVICAL_MUCUS);
769         sHealthCategoryToReadPermissionMap.put(MENSTRUATION, READ_MENSTRUATION);
770         sHealthCategoryToReadPermissionMap.put(
771                 INTERMENSTRUAL_BLEEDING, READ_INTERMENSTRUAL_BLEEDING);
772         sHealthCategoryToReadPermissionMap.put(OVULATION_TEST, READ_OVULATION_TEST);
773         sHealthCategoryToReadPermissionMap.put(SEXUAL_ACTIVITY, READ_SEXUAL_ACTIVITY);
774         sHealthCategoryToReadPermissionMap.put(HYDRATION, READ_HYDRATION);
775         sHealthCategoryToReadPermissionMap.put(NUTRITION, READ_NUTRITION);
776         sHealthCategoryToReadPermissionMap.put(SLEEP, READ_SLEEP);
777         sHealthCategoryToReadPermissionMap.put(BASAL_BODY_TEMPERATURE, READ_BASAL_BODY_TEMPERATURE);
778         sHealthCategoryToReadPermissionMap.put(BLOOD_GLUCOSE, READ_BLOOD_GLUCOSE);
779         sHealthCategoryToReadPermissionMap.put(BLOOD_PRESSURE, READ_BLOOD_PRESSURE);
780         sHealthCategoryToReadPermissionMap.put(BODY_TEMPERATURE, READ_BODY_TEMPERATURE);
781         sHealthCategoryToReadPermissionMap.put(HEART_RATE, READ_HEART_RATE);
782         sHealthCategoryToReadPermissionMap.put(HEART_RATE_VARIABILITY, READ_HEART_RATE_VARIABILITY);
783         sHealthCategoryToReadPermissionMap.put(OXYGEN_SATURATION, READ_OXYGEN_SATURATION);
784         sHealthCategoryToReadPermissionMap.put(RESPIRATORY_RATE, READ_RESPIRATORY_RATE);
785         sHealthCategoryToReadPermissionMap.put(RESTING_HEART_RATE, READ_RESTING_HEART_RATE);
786     }
787 
populateWriteHealthPermissionToHealthDataCategoryMap()788     private static synchronized void populateWriteHealthPermissionToHealthDataCategoryMap() {
789         if (!sWriteHealthPermissionToHealthDataCategoryMap.isEmpty()) {
790             return;
791         }
792 
793         // Write permissions
794         sWriteHealthPermissionToHealthDataCategoryMap.put(
795                 WRITE_ACTIVE_CALORIES_BURNED, HealthDataCategory.ACTIVITY);
796         sWriteHealthPermissionToHealthDataCategoryMap.put(
797                 WRITE_DISTANCE, HealthDataCategory.ACTIVITY);
798         sWriteHealthPermissionToHealthDataCategoryMap.put(
799                 WRITE_ELEVATION_GAINED, HealthDataCategory.ACTIVITY);
800         sWriteHealthPermissionToHealthDataCategoryMap.put(
801                 WRITE_EXERCISE, HealthDataCategory.ACTIVITY);
802         sWriteHealthPermissionToHealthDataCategoryMap.put(
803                 WRITE_FLOORS_CLIMBED, HealthDataCategory.ACTIVITY);
804         sWriteHealthPermissionToHealthDataCategoryMap.put(WRITE_STEPS, HealthDataCategory.ACTIVITY);
805         sWriteHealthPermissionToHealthDataCategoryMap.put(
806                 WRITE_TOTAL_CALORIES_BURNED, HealthDataCategory.ACTIVITY);
807         sWriteHealthPermissionToHealthDataCategoryMap.put(
808                 WRITE_VO2_MAX, HealthDataCategory.ACTIVITY);
809         sWriteHealthPermissionToHealthDataCategoryMap.put(
810                 WRITE_WHEELCHAIR_PUSHES, HealthDataCategory.ACTIVITY);
811         sWriteHealthPermissionToHealthDataCategoryMap.put(WRITE_POWER, HealthDataCategory.ACTIVITY);
812         sWriteHealthPermissionToHealthDataCategoryMap.put(WRITE_SPEED, HealthDataCategory.ACTIVITY);
813 
814         sWriteHealthPermissionToHealthDataCategoryMap.put(
815                 WRITE_BASAL_METABOLIC_RATE, HealthDataCategory.BODY_MEASUREMENTS);
816         sWriteHealthPermissionToHealthDataCategoryMap.put(
817                 WRITE_BODY_FAT, HealthDataCategory.BODY_MEASUREMENTS);
818         sWriteHealthPermissionToHealthDataCategoryMap.put(
819                 WRITE_BODY_WATER_MASS, HealthDataCategory.BODY_MEASUREMENTS);
820         sWriteHealthPermissionToHealthDataCategoryMap.put(
821                 WRITE_BONE_MASS, HealthDataCategory.BODY_MEASUREMENTS);
822         sWriteHealthPermissionToHealthDataCategoryMap.put(
823                 WRITE_HEIGHT, HealthDataCategory.BODY_MEASUREMENTS);
824         sWriteHealthPermissionToHealthDataCategoryMap.put(
825                 WRITE_LEAN_BODY_MASS, HealthDataCategory.BODY_MEASUREMENTS);
826         sWriteHealthPermissionToHealthDataCategoryMap.put(
827                 WRITE_WEIGHT, HealthDataCategory.BODY_MEASUREMENTS);
828 
829         sWriteHealthPermissionToHealthDataCategoryMap.put(
830                 WRITE_CERVICAL_MUCUS, HealthDataCategory.CYCLE_TRACKING);
831         sWriteHealthPermissionToHealthDataCategoryMap.put(
832                 WRITE_MENSTRUATION, HealthDataCategory.CYCLE_TRACKING);
833         sWriteHealthPermissionToHealthDataCategoryMap.put(
834                 WRITE_OVULATION_TEST, HealthDataCategory.CYCLE_TRACKING);
835         sWriteHealthPermissionToHealthDataCategoryMap.put(
836                 WRITE_SEXUAL_ACTIVITY, HealthDataCategory.CYCLE_TRACKING);
837         sWriteHealthPermissionToHealthDataCategoryMap.put(
838                 WRITE_INTERMENSTRUAL_BLEEDING, HealthDataCategory.CYCLE_TRACKING);
839 
840         sWriteHealthPermissionToHealthDataCategoryMap.put(
841                 WRITE_HYDRATION, HealthDataCategory.NUTRITION);
842         sWriteHealthPermissionToHealthDataCategoryMap.put(
843                 WRITE_NUTRITION, HealthDataCategory.NUTRITION);
844         sWriteHealthPermissionToHealthDataCategoryMap.put(WRITE_SLEEP, HealthDataCategory.SLEEP);
845 
846         sWriteHealthPermissionToHealthDataCategoryMap.put(
847                 WRITE_BASAL_BODY_TEMPERATURE, HealthDataCategory.VITALS);
848         sWriteHealthPermissionToHealthDataCategoryMap.put(
849                 WRITE_BLOOD_GLUCOSE, HealthDataCategory.VITALS);
850         sWriteHealthPermissionToHealthDataCategoryMap.put(
851                 WRITE_BLOOD_PRESSURE, HealthDataCategory.VITALS);
852         sWriteHealthPermissionToHealthDataCategoryMap.put(
853                 WRITE_BODY_TEMPERATURE, HealthDataCategory.VITALS);
854         sWriteHealthPermissionToHealthDataCategoryMap.put(
855                 WRITE_HEART_RATE, HealthDataCategory.VITALS);
856         sWriteHealthPermissionToHealthDataCategoryMap.put(
857                 WRITE_HEART_RATE_VARIABILITY, HealthDataCategory.VITALS);
858         sWriteHealthPermissionToHealthDataCategoryMap.put(
859                 WRITE_OXYGEN_SATURATION, HealthDataCategory.VITALS);
860         sWriteHealthPermissionToHealthDataCategoryMap.put(
861                 WRITE_RESPIRATORY_RATE, HealthDataCategory.VITALS);
862         sWriteHealthPermissionToHealthDataCategoryMap.put(
863                 WRITE_RESTING_HEART_RATE, HealthDataCategory.VITALS);
864 
865         sDataCategoryToWritePermissionsMap.put(
866                 HealthDataCategory.ACTIVITY,
867                 new String[] {
868                     WRITE_ACTIVE_CALORIES_BURNED,
869                     WRITE_DISTANCE,
870                     WRITE_ELEVATION_GAINED,
871                     WRITE_EXERCISE,
872                     WRITE_FLOORS_CLIMBED,
873                     WRITE_STEPS,
874                     WRITE_TOTAL_CALORIES_BURNED,
875                     WRITE_VO2_MAX,
876                     WRITE_WHEELCHAIR_PUSHES,
877                     WRITE_POWER,
878                     WRITE_SPEED
879                 });
880 
881         sDataCategoryToWritePermissionsMap.put(
882                 HealthDataCategory.BODY_MEASUREMENTS,
883                 new String[] {
884                     WRITE_BASAL_METABOLIC_RATE,
885                     WRITE_BODY_FAT,
886                     WRITE_BODY_WATER_MASS,
887                     WRITE_BONE_MASS,
888                     WRITE_HEIGHT,
889                     WRITE_LEAN_BODY_MASS,
890                     WRITE_WEIGHT
891                 });
892 
893         sDataCategoryToWritePermissionsMap.put(
894                 HealthDataCategory.CYCLE_TRACKING,
895                 new String[] {
896                     WRITE_CERVICAL_MUCUS,
897                     WRITE_MENSTRUATION,
898                     WRITE_OVULATION_TEST,
899                     WRITE_SEXUAL_ACTIVITY,
900                     WRITE_INTERMENSTRUAL_BLEEDING
901                 });
902 
903         sDataCategoryToWritePermissionsMap.put(
904                 HealthDataCategory.NUTRITION, new String[] {WRITE_HYDRATION, WRITE_NUTRITION});
905 
906         sDataCategoryToWritePermissionsMap.put(
907                 HealthDataCategory.SLEEP, new String[] {WRITE_SLEEP});
908 
909         sDataCategoryToWritePermissionsMap.put(
910                 HealthDataCategory.VITALS,
911                 new String[] {
912                     WRITE_BASAL_BODY_TEMPERATURE,
913                     WRITE_BLOOD_GLUCOSE,
914                     WRITE_BLOOD_PRESSURE,
915                     WRITE_BODY_TEMPERATURE,
916                     WRITE_HEART_RATE,
917                     WRITE_HEART_RATE_VARIABILITY,
918                     WRITE_OXYGEN_SATURATION,
919                     WRITE_RESPIRATORY_RATE,
920                     WRITE_RESTING_HEART_RATE
921                 });
922     }
923 }
924