• 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.MINDFULNESS;
42 import static android.health.connect.HealthPermissionCategory.NUTRITION;
43 import static android.health.connect.HealthPermissionCategory.OVULATION_TEST;
44 import static android.health.connect.HealthPermissionCategory.OXYGEN_SATURATION;
45 import static android.health.connect.HealthPermissionCategory.PLANNED_EXERCISE;
46 import static android.health.connect.HealthPermissionCategory.POWER;
47 import static android.health.connect.HealthPermissionCategory.RESPIRATORY_RATE;
48 import static android.health.connect.HealthPermissionCategory.RESTING_HEART_RATE;
49 import static android.health.connect.HealthPermissionCategory.SEXUAL_ACTIVITY;
50 import static android.health.connect.HealthPermissionCategory.SKIN_TEMPERATURE;
51 import static android.health.connect.HealthPermissionCategory.SLEEP;
52 import static android.health.connect.HealthPermissionCategory.SPEED;
53 import static android.health.connect.HealthPermissionCategory.STEPS;
54 import static android.health.connect.HealthPermissionCategory.TOTAL_CALORIES_BURNED;
55 import static android.health.connect.HealthPermissionCategory.VO2_MAX;
56 import static android.health.connect.HealthPermissionCategory.WEIGHT;
57 import static android.health.connect.HealthPermissionCategory.WHEELCHAIR_PUSHES;
58 
59 import static com.android.healthfitness.flags.AconfigFlagHelper.isPersonalHealthRecordEnabled;
60 import static com.android.healthfitness.flags.Flags.FLAG_ACTIVITY_INTENSITY;
61 import static com.android.healthfitness.flags.Flags.FLAG_MINDFULNESS;
62 import static com.android.healthfitness.flags.Flags.FLAG_PERSONAL_HEALTH_RECORD;
63 
64 import android.annotation.FlaggedApi;
65 import android.annotation.NonNull;
66 import android.annotation.Nullable;
67 import android.annotation.SystemApi;
68 import android.content.Context;
69 import android.content.pm.PackageInfo;
70 import android.content.pm.PermissionInfo;
71 import android.health.connect.datatypes.ExerciseRoute;
72 import android.health.connect.internal.datatypes.utils.HealthConnectMappings;
73 import android.util.ArrayMap;
74 import android.util.ArraySet;
75 
76 import com.android.healthfitness.flags.Flags;
77 
78 import java.util.HashSet;
79 import java.util.Map;
80 import java.util.Objects;
81 import java.util.Set;
82 
83 // TODO(b/255340973): consider generate this class.
84 /**
85  * Permissions for accessing the HealthConnect APIs.
86  *
87  * <p>Apps must support {@link android.content.Intent#ACTION_VIEW_PERMISSION_USAGE} with {@link
88  * HealthConnectManager#CATEGORY_HEALTH_PERMISSIONS} category to be granted read/write health data
89  * permissions.
90  */
91 public final class HealthPermissions {
92     /**
93      * Allows an application to grant/revoke health-related permissions.
94      *
95      * <p>Protection level: signature.
96      *
97      * @hide
98      */
99     @SystemApi
100     public static final String MANAGE_HEALTH_PERMISSIONS =
101             "android.permission.MANAGE_HEALTH_PERMISSIONS";
102 
103     // Below permission was earlier declared in HealthConnectManager since it was only permission
104     // used by access logs API, is now declared here along with the other system permission.
105     // Please suggest if it will be ok to have it here.
106     /**
107      * Allows an application to modify health data.
108      *
109      * <p>Protection level: privileged.
110      *
111      * @hide
112      */
113     @SystemApi
114     public static final String MANAGE_HEALTH_DATA_PERMISSION =
115             "android.permission.MANAGE_HEALTH_DATA";
116 
117     /**
118      * Allows an application to launch client onboarding activities responsible for connecting to
119      * Health Connect. This permission can only be held by the system. Client apps that choose to
120      * export an onboarding activity must guard it with this permission so that only the system can
121      * launch it.
122      *
123      * <p>See {@link HealthConnectManager#ACTION_SHOW_ONBOARDING} for the corresponding intent used
124      * by the system to launch onboarding activities.
125      *
126      * <p>Protection level: signature.
127      *
128      * @hide
129      */
130     public static final String START_ONBOARDING = "android.permission.health.START_ONBOARDING";
131 
132     /**
133      * Used for runtime permissions which grant access to Health Connect data.
134      *
135      * @hide
136      */
137     @SystemApi
138     public static final String HEALTH_PERMISSION_GROUP = "android.permission-group.HEALTH";
139 
140     /**
141      * Allows an application to read health data (of any type) in background.
142      *
143      * <p>Protection level: dangerous.
144      */
145     @FlaggedApi("com.android.healthconnect.flags.background_read")
146     public static final String READ_HEALTH_DATA_IN_BACKGROUND =
147             "android.permission.health.READ_HEALTH_DATA_IN_BACKGROUND";
148 
149     /**
150      * Allows an application to read the entire history of health data (of any type).
151      *
152      * <p>Protection level: dangerous.
153      */
154     @FlaggedApi("com.android.healthconnect.flags.history_read")
155     public static final String READ_HEALTH_DATA_HISTORY =
156             "android.permission.health.READ_HEALTH_DATA_HISTORY";
157 
158     /**
159      * Allows an application to read the user's active calories burned data.
160      *
161      * <p>Protection level: dangerous.
162      */
163     public static final String READ_ACTIVE_CALORIES_BURNED =
164             "android.permission.health.READ_ACTIVE_CALORIES_BURNED";
165 
166     /**
167      * Allows an application to read the user's activity intensity data.
168      *
169      * <p>Protection level: dangerous.
170      */
171     @FlaggedApi(FLAG_ACTIVITY_INTENSITY)
172     public static final String READ_ACTIVITY_INTENSITY =
173             "android.permission.health.READ_ACTIVITY_INTENSITY";
174 
175     /**
176      * Allows an application to read the user's distance data.
177      *
178      * <p>Protection level: dangerous.
179      */
180     public static final String READ_DISTANCE = "android.permission.health.READ_DISTANCE";
181 
182     /**
183      * Allows an application to read the user's elevation gained data.
184      *
185      * <p>Protection level: dangerous.
186      */
187     public static final String READ_ELEVATION_GAINED =
188             "android.permission.health.READ_ELEVATION_GAINED";
189 
190     /**
191      * Allows an application to read the user's exercise data.
192      *
193      * <p>Protection level: dangerous.
194      */
195     public static final String READ_EXERCISE = "android.permission.health.READ_EXERCISE";
196 
197     /**
198      * Allows an application to read any {@link ExerciseRoute}. Not connected with READ_EXERCISE
199      * permission, as it's used only by HealthConnectController to show routes in UI and share one
200      * particular route with third party app after one-time user consent.
201      *
202      * <p>Protection level: signature.
203      *
204      * @hide
205      */
206     public static final String READ_EXERCISE_ROUTE =
207             "android.permission.health.READ_EXERCISE_ROUTE";
208 
209     /**
210      * Allows an application to read {@link ExerciseRoute}.
211      *
212      * <p>This permission can only be granted manually by a user in Health Connect settings or in
213      * the route request activity which can be launched using {@link ACTION_REQUEST_EXERCISE_ROUTE}.
214      * Attempts to request the permission by applications will be ignored.
215      *
216      * <p>Applications should check if the permission has been granted before reading {@link
217      * ExerciseRoute}.
218      *
219      * <p>Protection level: dangerous.
220      */
221     @FlaggedApi("com.android.healthconnect.flags.read_exercise_routes_all_enabled")
222     public static final String READ_EXERCISE_ROUTES =
223             "android.permission.health.READ_EXERCISE_ROUTES";
224 
225     /**
226      * Allows an application to read the user's floors climbed data.
227      *
228      * <p>Protection level: dangerous.
229      */
230     public static final String READ_FLOORS_CLIMBED =
231             "android.permission.health.READ_FLOORS_CLIMBED";
232 
233     /**
234      * Allows an application to read the user's steps data.
235      *
236      * <p>Protection level: dangerous.
237      */
238     public static final String READ_STEPS = "android.permission.health.READ_STEPS";
239 
240     /**
241      * Allows an application to read the user's total calories burned data.
242      *
243      * <p>Protection level: dangerous.
244      */
245     public static final String READ_TOTAL_CALORIES_BURNED =
246             "android.permission.health.READ_TOTAL_CALORIES_BURNED";
247 
248     /**
249      * Allows an application to read the user's vo2 maximum data.
250      *
251      * <p>Protection level: dangerous.
252      */
253     public static final String READ_VO2_MAX = "android.permission.health.READ_VO2_MAX";
254 
255     /**
256      * Allows an application to read the user's wheelchair pushes data.
257      *
258      * <p>Protection level: dangerous.
259      */
260     public static final String READ_WHEELCHAIR_PUSHES =
261             "android.permission.health.READ_WHEELCHAIR_PUSHES";
262 
263     /**
264      * Allows an application to read the user's power data.
265      *
266      * <p>Protection level: dangerous.
267      */
268     public static final String READ_POWER = "android.permission.health.READ_POWER";
269 
270     /**
271      * Allows an application to read the user's speed data.
272      *
273      * <p>Protection level: dangerous.
274      */
275     public static final String READ_SPEED = "android.permission.health.READ_SPEED";
276 
277     /**
278      * Allows an application to read the user's basal metabolic rate data.
279      *
280      * <p>Protection level: dangerous.
281      */
282     public static final String READ_BASAL_METABOLIC_RATE =
283             "android.permission.health.READ_BASAL_METABOLIC_RATE";
284 
285     /**
286      * Allows an application to read the user's body fat data.
287      *
288      * <p>Protection level: dangerous.
289      */
290     public static final String READ_BODY_FAT = "android.permission.health.READ_BODY_FAT";
291 
292     /**
293      * Allows an application to read the user's body water mass data.
294      *
295      * <p>Protection level: dangerous.
296      */
297     public static final String READ_BODY_WATER_MASS =
298             "android.permission.health.READ_BODY_WATER_MASS";
299 
300     /**
301      * Allows an application to read the user's bone mass data.
302      *
303      * <p>Protection level: dangerous.
304      */
305     public static final String READ_BONE_MASS = "android.permission.health.READ_BONE_MASS";
306 
307     /**
308      * Allows an application to read the user's height data.
309      *
310      * <p>Protection level: dangerous.
311      */
312     public static final String READ_HEIGHT = "android.permission.health.READ_HEIGHT";
313 
314     /**
315      * Allows an application to read the user's lean body mass data.
316      *
317      * <p>Protection level: dangerous.
318      */
319     public static final String READ_LEAN_BODY_MASS =
320             "android.permission.health.READ_LEAN_BODY_MASS";
321 
322     /**
323      * Allows an application to read the user's weight data.
324      *
325      * <p>Protection level: dangerous.
326      */
327     public static final String READ_WEIGHT = "android.permission.health.READ_WEIGHT";
328 
329     /**
330      * Allows an application to read the user's cervical mucus data.
331      *
332      * <p>Protection level: dangerous.
333      */
334     public static final String READ_CERVICAL_MUCUS =
335             "android.permission.health.READ_CERVICAL_MUCUS";
336 
337     /**
338      * Allows an application to read the user's menstruation data.
339      *
340      * <p>Protection level: dangerous.
341      */
342     public static final String READ_MENSTRUATION = "android.permission.health.READ_MENSTRUATION";
343 
344     /**
345      * Allows an application to read the user's intermenstrual bleeding data.
346      *
347      * <p>Protection level: dangerous.
348      */
349     public static final String READ_INTERMENSTRUAL_BLEEDING =
350             "android.permission.health.READ_INTERMENSTRUAL_BLEEDING";
351 
352     /**
353      * Allows an application to read the user's ovulation test data.
354      *
355      * <p>Protection level: dangerous.
356      */
357     public static final String READ_OVULATION_TEST =
358             "android.permission.health.READ_OVULATION_TEST";
359 
360     /**
361      * Allows an application to read the user's sexual activity data.
362      *
363      * <p>Protection level: dangerous.
364      */
365     public static final String READ_SEXUAL_ACTIVITY =
366             "android.permission.health.READ_SEXUAL_ACTIVITY";
367 
368     /**
369      * Allows an application to read the user's hydration data.
370      *
371      * <p>Protection level: dangerous.
372      */
373     public static final String READ_HYDRATION = "android.permission.health.READ_HYDRATION";
374 
375     /**
376      * Allows an application to read the user's nutrition data.
377      *
378      * <p>Protection level: dangerous.
379      */
380     public static final String READ_NUTRITION = "android.permission.health.READ_NUTRITION";
381 
382     /**
383      * Allows an application to read the user's sleep data.
384      *
385      * <p>Protection level: dangerous.
386      */
387     public static final String READ_SLEEP = "android.permission.health.READ_SLEEP";
388 
389     /**
390      * Allows an application to read the user's body temperature data.
391      *
392      * <p>Protection level: dangerous.
393      */
394     public static final String READ_BASAL_BODY_TEMPERATURE =
395             "android.permission.health.READ_BASAL_BODY_TEMPERATURE";
396 
397     /**
398      * Allows an application to read the user's blood glucose data.
399      *
400      * <p>Protection level: dangerous.
401      */
402     public static final String READ_BLOOD_GLUCOSE = "android.permission.health.READ_BLOOD_GLUCOSE";
403 
404     /**
405      * Allows an application to read the user's blood pressure data.
406      *
407      * <p>Protection level: dangerous.
408      */
409     public static final String READ_BLOOD_PRESSURE =
410             "android.permission.health.READ_BLOOD_PRESSURE";
411 
412     /**
413      * Allows an application to read the user's body temperature data.
414      *
415      * <p>Protection level: dangerous.
416      */
417     public static final String READ_BODY_TEMPERATURE =
418             "android.permission.health.READ_BODY_TEMPERATURE";
419 
420     /**
421      * Allows an application to read the user's heart rate data.
422      *
423      * <p>Protection level: dangerous.
424      */
425     public static final String READ_HEART_RATE = "android.permission.health.READ_HEART_RATE";
426 
427     /**
428      * Allows an application to read the user's heart rate variability data.
429      *
430      * <p>Protection level: dangerous.
431      */
432     public static final String READ_HEART_RATE_VARIABILITY =
433             "android.permission.health.READ_HEART_RATE_VARIABILITY";
434 
435     /**
436      * Allows an application to read the user's oxygen saturation data.
437      *
438      * <p>Protection level: dangerous.
439      */
440     public static final String READ_OXYGEN_SATURATION =
441             "android.permission.health.READ_OXYGEN_SATURATION";
442 
443     /**
444      * Allows an application to read the user's respiratory rate data.
445      *
446      * <p>Protection level: dangerous.
447      */
448     public static final String READ_RESPIRATORY_RATE =
449             "android.permission.health.READ_RESPIRATORY_RATE";
450 
451     /**
452      * Allows an application to read the user's resting heart rate data.
453      *
454      * <p>Protection level: dangerous.
455      */
456     public static final String READ_RESTING_HEART_RATE =
457             "android.permission.health.READ_RESTING_HEART_RATE";
458 
459     /**
460      * Allows an application to read the user's skin temperature data.
461      *
462      * <p>Protection level: dangerous.
463      */
464     @FlaggedApi("com.android.healthconnect.flags.skin_temperature")
465     public static final String READ_SKIN_TEMPERATURE =
466             "android.permission.health.READ_SKIN_TEMPERATURE";
467 
468     /**
469      * Allows an application to read the user's training plan data.
470      *
471      * <p>Protection level: dangerous.
472      */
473     @FlaggedApi("com.android.healthconnect.flags.training_plans")
474     public static final String READ_PLANNED_EXERCISE =
475             "android.permission.health.READ_PLANNED_EXERCISE";
476 
477     /**
478      * Allows an application to read user's mindfulness data.
479      *
480      * <p>Protection level: dangerous.
481      */
482     @FlaggedApi(FLAG_MINDFULNESS)
483     public static final String READ_MINDFULNESS = "android.permission.health.READ_MINDFULNESS";
484 
485     /**
486      * Allows an application to write the user's calories burned data.
487      *
488      * <p>Protection level: dangerous.
489      */
490     public static final String WRITE_ACTIVE_CALORIES_BURNED =
491             "android.permission.health.WRITE_ACTIVE_CALORIES_BURNED";
492 
493     /**
494      * Allows an application to write the user's activity intensity data.
495      *
496      * <p>Protection level: dangerous.
497      */
498     @FlaggedApi(FLAG_ACTIVITY_INTENSITY)
499     public static final String WRITE_ACTIVITY_INTENSITY =
500             "android.permission.health.WRITE_ACTIVITY_INTENSITY";
501 
502     /**
503      * Allows an application to write the user's distance data.
504      *
505      * <p>Protection level: dangerous.
506      */
507     public static final String WRITE_DISTANCE = "android.permission.health.WRITE_DISTANCE";
508 
509     /**
510      * Allows an application to write the user's elevation gained data.
511      *
512      * <p>Protection level: dangerous.
513      */
514     public static final String WRITE_ELEVATION_GAINED =
515             "android.permission.health.WRITE_ELEVATION_GAINED";
516 
517     /**
518      * Allows an application to write the user's exercise data. Additional permission {@link
519      * HealthPermissions#WRITE_EXERCISE_ROUTE} is required to write user's exercise route.
520      *
521      * <p>Protection level: dangerous.
522      */
523     public static final String WRITE_EXERCISE = "android.permission.health.WRITE_EXERCISE";
524 
525     /**
526      * Allows an application to write the user's exercise route.
527      *
528      * <p>Protection level: dangerous.
529      */
530     public static final String WRITE_EXERCISE_ROUTE =
531             "android.permission.health.WRITE_EXERCISE_ROUTE";
532 
533     /**
534      * Allows an application to write the user's floors climbed data.
535      *
536      * <p>Protection level: dangerous.
537      */
538     public static final String WRITE_FLOORS_CLIMBED =
539             "android.permission.health.WRITE_FLOORS_CLIMBED";
540 
541     /**
542      * Allows an application to write the user's steps data.
543      *
544      * <p>Protection level: dangerous.
545      */
546     public static final String WRITE_STEPS = "android.permission.health.WRITE_STEPS";
547 
548     /**
549      * Allows an application to write the user's total calories burned data.
550      *
551      * <p>Protection level: dangerous.
552      */
553     public static final String WRITE_TOTAL_CALORIES_BURNED =
554             "android.permission.health.WRITE_TOTAL_CALORIES_BURNED";
555 
556     /**
557      * Allows an application to write the user's vo2 maximum data.
558      *
559      * <p>Protection level: dangerous.
560      */
561     public static final String WRITE_VO2_MAX = "android.permission.health.WRITE_VO2_MAX";
562 
563     /**
564      * Allows an application to write the user's wheelchair pushes data.
565      *
566      * <p>Protection level: dangerous.
567      */
568     public static final String WRITE_WHEELCHAIR_PUSHES =
569             "android.permission.health.WRITE_WHEELCHAIR_PUSHES";
570 
571     /**
572      * Allows an application to write the user's power data.
573      *
574      * <p>Protection level: dangerous.
575      */
576     public static final String WRITE_POWER = "android.permission.health.WRITE_POWER";
577 
578     /**
579      * Allows an application to write the user's speed data.
580      *
581      * <p>Protection level: dangerous.
582      */
583     public static final String WRITE_SPEED = "android.permission.health.WRITE_SPEED";
584 
585     /**
586      * Allows an application to write the user's basal metabolic rate data.
587      *
588      * <p>Protection level: dangerous.
589      */
590     public static final String WRITE_BASAL_METABOLIC_RATE =
591             "android.permission.health.WRITE_BASAL_METABOLIC_RATE";
592 
593     /**
594      * Allows an application to write the user's body fat data.
595      *
596      * <p>Protection level: dangerous.
597      */
598     public static final String WRITE_BODY_FAT = "android.permission.health.WRITE_BODY_FAT";
599 
600     /**
601      * Allows an application to write the user's body water mass data.
602      *
603      * <p>Protection level: dangerous.
604      */
605     public static final String WRITE_BODY_WATER_MASS =
606             "android.permission.health.WRITE_BODY_WATER_MASS";
607 
608     /**
609      * Allows an application to write the user's bone mass data.
610      *
611      * <p>Protection level: dangerous.
612      */
613     public static final String WRITE_BONE_MASS = "android.permission.health.WRITE_BONE_MASS";
614 
615     /**
616      * Allows an application to write the user's height data.
617      *
618      * <p>Protection level: dangerous.
619      */
620     public static final String WRITE_HEIGHT = "android.permission.health.WRITE_HEIGHT";
621 
622     /**
623      * Allows an application to write the user's lean body mass data.
624      *
625      * <p>Protection level: dangerous.
626      */
627     public static final String WRITE_LEAN_BODY_MASS =
628             "android.permission.health.WRITE_LEAN_BODY_MASS";
629 
630     /**
631      * Allows an application to write the user's weight data.
632      *
633      * <p>Protection level: dangerous.
634      */
635     public static final String WRITE_WEIGHT = "android.permission.health.WRITE_WEIGHT";
636 
637     /**
638      * Allows an application to write the user's cervical mucus data.
639      *
640      * <p>Protection level: dangerous.
641      */
642     public static final String WRITE_CERVICAL_MUCUS =
643             "android.permission.health.WRITE_CERVICAL_MUCUS";
644 
645     /**
646      * Allows an application to write the user's menstruation data.
647      *
648      * <p>Protection level: dangerous.
649      */
650     public static final String WRITE_MENSTRUATION = "android.permission.health.WRITE_MENSTRUATION";
651 
652     /**
653      * Allows an application to write the user's intermenstrual bleeding data.
654      *
655      * <p>Protection level: dangerous.
656      */
657     public static final String WRITE_INTERMENSTRUAL_BLEEDING =
658             "android.permission.health.WRITE_INTERMENSTRUAL_BLEEDING";
659 
660     /**
661      * Allows an application to write the user's ovulation test data.
662      *
663      * <p>Protection level: dangerous.
664      */
665     public static final String WRITE_OVULATION_TEST =
666             "android.permission.health.WRITE_OVULATION_TEST";
667 
668     /**
669      * Allows an application to write the user's sexual activity data.
670      *
671      * <p>Protection level: dangerous.
672      */
673     public static final String WRITE_SEXUAL_ACTIVITY =
674             "android.permission.health.WRITE_SEXUAL_ACTIVITY";
675 
676     /**
677      * Allows an application to write the user's hydration data.
678      *
679      * <p>Protection level: dangerous.
680      */
681     public static final String WRITE_HYDRATION = "android.permission.health.WRITE_HYDRATION";
682 
683     /**
684      * Allows an application to write the user's nutrition data.
685      *
686      * <p>Protection level: dangerous.
687      */
688     public static final String WRITE_NUTRITION = "android.permission.health.WRITE_NUTRITION";
689 
690     /**
691      * Allows an application to write the user's sleep data.
692      *
693      * <p>Protection level: dangerous.
694      */
695     public static final String WRITE_SLEEP = "android.permission.health.WRITE_SLEEP";
696 
697     /**
698      * Allows an application to write the user's basal body temperature data.
699      *
700      * <p>Protection level: dangerous.
701      */
702     public static final String WRITE_BASAL_BODY_TEMPERATURE =
703             "android.permission.health.WRITE_BASAL_BODY_TEMPERATURE";
704 
705     /**
706      * Allows an application to write the user's blood glucose data.
707      *
708      * <p>Protection level: dangerous.
709      */
710     public static final String WRITE_BLOOD_GLUCOSE =
711             "android.permission.health.WRITE_BLOOD_GLUCOSE";
712 
713     /**
714      * Allows an application to write the user's blood pressure data.
715      *
716      * <p>Protection level: dangerous.
717      */
718     public static final String WRITE_BLOOD_PRESSURE =
719             "android.permission.health.WRITE_BLOOD_PRESSURE";
720 
721     /**
722      * Allows an application to write the user's body temperature data.
723      *
724      * <p>Protection level: dangerous.
725      */
726     public static final String WRITE_BODY_TEMPERATURE =
727             "android.permission.health.WRITE_BODY_TEMPERATURE";
728 
729     /**
730      * Allows an application to write the user's heart rate data.
731      *
732      * <p>Protection level: dangerous.
733      */
734     public static final String WRITE_HEART_RATE = "android.permission.health.WRITE_HEART_RATE";
735 
736     /**
737      * Allows an application to write the user's heart rate variability data.
738      *
739      * <p>Protection level: dangerous.
740      */
741     public static final String WRITE_HEART_RATE_VARIABILITY =
742             "android.permission.health.WRITE_HEART_RATE_VARIABILITY";
743 
744     /**
745      * Allows an application to write the user's oxygen saturation data.
746      *
747      * <p>Protection level: dangerous.
748      */
749     public static final String WRITE_OXYGEN_SATURATION =
750             "android.permission.health.WRITE_OXYGEN_SATURATION";
751 
752     /**
753      * Allows an application to write the user's respiratory rate data.
754      *
755      * <p>Protection level: dangerous.
756      */
757     public static final String WRITE_RESPIRATORY_RATE =
758             "android.permission.health.WRITE_RESPIRATORY_RATE";
759 
760     /**
761      * Allows an application to write the user's resting heart rate data.
762      *
763      * <p>Protection level: dangerous.
764      */
765     public static final String WRITE_RESTING_HEART_RATE =
766             "android.permission.health.WRITE_RESTING_HEART_RATE";
767 
768     /**
769      * Allows an application to write the user's skin temperature data.
770      *
771      * <p>Protection level: dangerous.
772      */
773     @FlaggedApi("com.android.healthconnect.flags.skin_temperature")
774     public static final String WRITE_SKIN_TEMPERATURE =
775             "android.permission.health.WRITE_SKIN_TEMPERATURE";
776 
777     /**
778      * Allows an application to write the user's training plan data.
779      *
780      * <p>Protection level: dangerous.
781      */
782     @FlaggedApi("com.android.healthconnect.flags.training_plans")
783     public static final String WRITE_PLANNED_EXERCISE =
784             "android.permission.health.WRITE_PLANNED_EXERCISE";
785 
786     /**
787      * Allows an application to write user's mindfulness data.
788      *
789      * <p>Protection level: dangerous.
790      */
791     @FlaggedApi(FLAG_MINDFULNESS)
792     public static final String WRITE_MINDFULNESS = "android.permission.health.WRITE_MINDFULNESS";
793 
794     /* Personal Health Record permissions */
795 
796     /**
797      * Allows an application to read the user's data about allergies and intolerances.
798      *
799      * <p>Protection level: dangerous.
800      */
801     @FlaggedApi(FLAG_PERSONAL_HEALTH_RECORD)
802     public static final String READ_MEDICAL_DATA_ALLERGIES_INTOLERANCES =
803             "android.permission.health.READ_MEDICAL_DATA_ALLERGIES_INTOLERANCES";
804 
805     /**
806      * Allows an application to read the user's data about medical conditions.
807      *
808      * <p>Protection level: dangerous.
809      */
810     @FlaggedApi(FLAG_PERSONAL_HEALTH_RECORD)
811     public static final String READ_MEDICAL_DATA_CONDITIONS =
812             "android.permission.health.READ_MEDICAL_DATA_CONDITIONS";
813 
814     /**
815      * Allows an application to read the user's laboratory result data.
816      *
817      * <p>Protection level: dangerous.
818      */
819     @FlaggedApi(FLAG_PERSONAL_HEALTH_RECORD)
820     public static final String READ_MEDICAL_DATA_LABORATORY_RESULTS =
821             "android.permission.health.READ_MEDICAL_DATA_LABORATORY_RESULTS";
822 
823     /**
824      * Allows an application to read the user's medication data.
825      *
826      * <p>Protection level: dangerous.
827      */
828     @FlaggedApi(FLAG_PERSONAL_HEALTH_RECORD)
829     public static final String READ_MEDICAL_DATA_MEDICATIONS =
830             "android.permission.health.READ_MEDICAL_DATA_MEDICATIONS";
831 
832     /**
833      * Allows an application to read the user's personal details.
834      *
835      * <p>This is demographic information such as name, date of birth, contact details like address
836      * or telephone number and so on. For more examples see the <a
837      * href="https://www.hl7.org/fhir/patient.html">FHIR Patient resource</a>.
838      *
839      * <p>Protection level: dangerous.
840      */
841     @FlaggedApi(FLAG_PERSONAL_HEALTH_RECORD)
842     public static final String READ_MEDICAL_DATA_PERSONAL_DETAILS =
843             "android.permission.health.READ_MEDICAL_DATA_PERSONAL_DETAILS";
844 
845     /**
846      * Allows an application to read the user's data about the practitioners who have interacted
847      * with them in their medical record. This is the information about the clinicians (doctors,
848      * nurses, etc) but also other practitioners (masseurs, physiotherapists, etc) who have been
849      * involved with the patient.
850      *
851      * <p>Protection level: dangerous.
852      */
853     @FlaggedApi(FLAG_PERSONAL_HEALTH_RECORD)
854     public static final String READ_MEDICAL_DATA_PRACTITIONER_DETAILS =
855             "android.permission.health.READ_MEDICAL_DATA_PRACTITIONER_DETAILS";
856 
857     /**
858      * Allows an application to read the user's pregnancy data.
859      *
860      * <p>Protection level: dangerous.
861      */
862     @FlaggedApi(FLAG_PERSONAL_HEALTH_RECORD)
863     public static final String READ_MEDICAL_DATA_PREGNANCY =
864             "android.permission.health.READ_MEDICAL_DATA_PREGNANCY";
865 
866     /**
867      * Allows an application to read the user's data about medical procedures.
868      *
869      * <p>Protection level: dangerous.
870      */
871     @FlaggedApi(FLAG_PERSONAL_HEALTH_RECORD)
872     public static final String READ_MEDICAL_DATA_PROCEDURES =
873             "android.permission.health.READ_MEDICAL_DATA_PROCEDURES";
874 
875     /**
876      * Allows an application to read the user's social history data.
877      *
878      * <p>Protection level: dangerous.
879      */
880     @FlaggedApi(FLAG_PERSONAL_HEALTH_RECORD)
881     public static final String READ_MEDICAL_DATA_SOCIAL_HISTORY =
882             "android.permission.health.READ_MEDICAL_DATA_SOCIAL_HISTORY";
883 
884     /**
885      * Allows an application to read the user's data about immunizations and vaccinations.
886      *
887      * <p>Protection level: dangerous.
888      */
889     @FlaggedApi(FLAG_PERSONAL_HEALTH_RECORD)
890     public static final String READ_MEDICAL_DATA_VACCINES =
891             "android.permission.health.READ_MEDICAL_DATA_VACCINES";
892 
893     /**
894      * Allows an application to read the user's information about their encounters with health care
895      * practitioners, including things like location, time of appointment, and name of organization
896      * the visit was with. Despite the name visit it covers remote encounters such as telephone or
897      * videoconference appointments.
898      *
899      * <p>Protection level: dangerous.
900      */
901     @FlaggedApi(FLAG_PERSONAL_HEALTH_RECORD)
902     public static final String READ_MEDICAL_DATA_VISITS =
903             "android.permission.health.READ_MEDICAL_DATA_VISITS";
904 
905     /**
906      * Allows an application to read the user's vital signs data.
907      *
908      * <p>Protection level: dangerous.
909      */
910     @FlaggedApi(FLAG_PERSONAL_HEALTH_RECORD)
911     public static final String READ_MEDICAL_DATA_VITAL_SIGNS =
912             "android.permission.health.READ_MEDICAL_DATA_VITAL_SIGNS";
913 
914     /**
915      * Allows an application to write the user's medical data.
916      *
917      * <p>Protection level: dangerous.
918      */
919     @FlaggedApi(FLAG_PERSONAL_HEALTH_RECORD)
920     public static final String WRITE_MEDICAL_DATA = "android.permission.health.WRITE_MEDICAL_DATA";
921 
922     private static final Set<String> sWritePermissionsSet =
923             new ArraySet<>(
924                     Set.of(
925                             WRITE_ACTIVE_CALORIES_BURNED,
926                             WRITE_DISTANCE,
927                             WRITE_ELEVATION_GAINED,
928                             WRITE_EXERCISE,
929                             WRITE_FLOORS_CLIMBED,
930                             WRITE_STEPS,
931                             WRITE_TOTAL_CALORIES_BURNED,
932                             WRITE_VO2_MAX,
933                             WRITE_WHEELCHAIR_PUSHES,
934                             WRITE_POWER,
935                             WRITE_SPEED,
936                             WRITE_BASAL_METABOLIC_RATE,
937                             WRITE_BODY_FAT,
938                             WRITE_BODY_WATER_MASS,
939                             WRITE_BONE_MASS,
940                             WRITE_HEIGHT,
941                             WRITE_LEAN_BODY_MASS,
942                             WRITE_WEIGHT,
943                             WRITE_CERVICAL_MUCUS,
944                             WRITE_MENSTRUATION,
945                             WRITE_INTERMENSTRUAL_BLEEDING,
946                             WRITE_OVULATION_TEST,
947                             WRITE_SEXUAL_ACTIVITY,
948                             WRITE_HYDRATION,
949                             WRITE_NUTRITION,
950                             WRITE_SLEEP,
951                             WRITE_BASAL_BODY_TEMPERATURE,
952                             WRITE_BLOOD_GLUCOSE,
953                             WRITE_BLOOD_PRESSURE,
954                             WRITE_BODY_TEMPERATURE,
955                             WRITE_HEART_RATE,
956                             WRITE_HEART_RATE_VARIABILITY,
957                             WRITE_OXYGEN_SATURATION,
958                             WRITE_RESPIRATORY_RATE,
959                             WRITE_RESTING_HEART_RATE,
960                             WRITE_SKIN_TEMPERATURE,
961                             WRITE_PLANNED_EXERCISE,
962                             WRITE_MINDFULNESS));
963 
964     private static final Map<String, Integer> sWriteHealthPermissionToHealthDataCategoryMap =
965             new ArrayMap<>();
966     private static final Map<Integer, String> sHealthCategoryToReadPermissionMap = new ArrayMap<>();
967     private static final Map<Integer, String> sHealthCategoryToWritePermissionMap =
968             new ArrayMap<>();
969 
970     private static final Map<Integer, String[]> sDataCategoryToWritePermissionsMap =
971             new ArrayMap<>();
972 
HealthPermissions()973     private HealthPermissions() {}
974 
975     /**
976      * @return true if {@code permissionName} is a write-permission
977      * @hide
978      * @deprecated use {@link HealthConnectMappings#isWritePermission(String)}
979      */
980     @Deprecated
isWritePermission(@onNull String permissionName)981     public static boolean isWritePermission(@NonNull String permissionName) {
982         Objects.requireNonNull(permissionName);
983 
984         return sWritePermissionsSet.contains(permissionName);
985     }
986 
987     /**
988      * @deprecated Use {@link HealthConnectMappings#getHealthDataCategoryForWritePermission(String)}
989      * @return {@link HealthDataCategory} for a WRITE {@code permissionName}. -1 if permission
990      *     category for {@code permissionName} is not found (or if {@code permissionName} is READ)
991      * @hide
992      */
993     @Deprecated
994     @HealthDataCategory.Type
getHealthDataCategoryForWritePermission(@ullable String permissionName)995     public static int getHealthDataCategoryForWritePermission(@Nullable String permissionName) {
996         if (sWriteHealthPermissionToHealthDataCategoryMap.isEmpty()) {
997             populateWriteHealthPermissionToHealthDataCategoryMap();
998         }
999 
1000         return sWriteHealthPermissionToHealthDataCategoryMap.getOrDefault(
1001                 permissionName, DEFAULT_INT);
1002     }
1003 
1004     /**
1005      * @return {@link HealthDataCategory} for {@code permissionName}. -1 if permission category for
1006      *     {@code permissionName} is not found
1007      * @deprecated Use {@link HealthConnectMappings#getWriteHealthPermissionsFor(int)}
1008      * @hide
1009      */
1010     @Deprecated
getWriteHealthPermissionsFor(@ealthDataCategory.Type int dataCategory)1011     public static String[] getWriteHealthPermissionsFor(@HealthDataCategory.Type int dataCategory) {
1012         if (sDataCategoryToWritePermissionsMap.isEmpty()) {
1013             populateWriteHealthPermissionToHealthDataCategoryMap();
1014         }
1015 
1016         return sDataCategoryToWritePermissionsMap.getOrDefault(dataCategory, new String[] {});
1017     }
1018 
1019     /**
1020      * @deprecated Use {@link HealthConnectMappings#getHealthReadPermission(int)}.
1021      * @hide
1022      */
1023     @SuppressWarnings("NullAway") // TODO(b/317029272): fix this suppression
1024     @Deprecated
getHealthReadPermission( @ealthPermissionCategory.Type int permissionCategory)1025     public static String getHealthReadPermission(
1026             @HealthPermissionCategory.Type int permissionCategory) {
1027         if (sHealthCategoryToReadPermissionMap.isEmpty()) {
1028             populateHealthPermissionToHealthPermissionCategoryMap();
1029         }
1030 
1031         return sHealthCategoryToReadPermissionMap.get(permissionCategory);
1032     }
1033 
1034     /**
1035      * @deprecated Use {@link HealthConnectMappings#getHealthWritePermission(int)}.
1036      * @hide
1037      */
1038     @Deprecated
getHealthWritePermission( @ealthPermissionCategory.Type int permissionCategory)1039     public static String getHealthWritePermission(
1040             @HealthPermissionCategory.Type int permissionCategory) {
1041         if (sHealthCategoryToWritePermissionMap.isEmpty()) {
1042             populateHealthPermissionToHealthPermissionCategoryMap();
1043         }
1044 
1045         String healthWritePermission = sHealthCategoryToWritePermissionMap.get(permissionCategory);
1046         Objects.requireNonNull(
1047                 healthWritePermission,
1048                 "Health write permission not found for "
1049                         + "PermissionCategory : "
1050                         + permissionCategory);
1051         return healthWritePermission;
1052     }
1053 
1054     /**
1055      * Returns all medical permissions (read and write).
1056      *
1057      * @hide
1058      */
getAllMedicalPermissions()1059     public static Set<String> getAllMedicalPermissions() {
1060         if (!isPersonalHealthRecordEnabled()) {
1061             throw new UnsupportedOperationException("getAllMedicalPermissions is not supported");
1062         }
1063 
1064         Set<String> permissions = new ArraySet<>();
1065         permissions.add(WRITE_MEDICAL_DATA);
1066         permissions.add(READ_MEDICAL_DATA_ALLERGIES_INTOLERANCES);
1067         permissions.add(READ_MEDICAL_DATA_CONDITIONS);
1068         permissions.add(READ_MEDICAL_DATA_LABORATORY_RESULTS);
1069         permissions.add(READ_MEDICAL_DATA_MEDICATIONS);
1070         permissions.add(READ_MEDICAL_DATA_PERSONAL_DETAILS);
1071         permissions.add(READ_MEDICAL_DATA_PRACTITIONER_DETAILS);
1072         permissions.add(READ_MEDICAL_DATA_PREGNANCY);
1073         permissions.add(READ_MEDICAL_DATA_PROCEDURES);
1074         permissions.add(READ_MEDICAL_DATA_SOCIAL_HISTORY);
1075         permissions.add(READ_MEDICAL_DATA_VACCINES);
1076         permissions.add(READ_MEDICAL_DATA_VISITS);
1077         permissions.add(READ_MEDICAL_DATA_VITAL_SIGNS);
1078         return permissions;
1079     }
1080 
1081     /**
1082      * Returns a set of dataCategories for which this package has WRITE permissions
1083      *
1084      * @hide
1085      */
1086     @NonNull
getDataCategoriesWithWritePermissionsForPackage( @onNull PackageInfo packageInfo, @NonNull Context context)1087     public static Set<Integer> getDataCategoriesWithWritePermissionsForPackage(
1088             @NonNull PackageInfo packageInfo, @NonNull Context context) {
1089 
1090         Set<Integer> dataCategoriesWithPermissions = new HashSet<>();
1091 
1092         for (int i = 0; i < packageInfo.requestedPermissions.length; i++) {
1093             String currPerm = packageInfo.requestedPermissions[i];
1094             if (!HealthConnectManager.isHealthPermission(context, currPerm)) {
1095                 continue;
1096             }
1097             if ((packageInfo.requestedPermissionsFlags[i]
1098                             & PackageInfo.REQUESTED_PERMISSION_GRANTED)
1099                     == 0) {
1100                 continue;
1101             }
1102 
1103             int dataCategory = getHealthDataCategoryForWritePermission(currPerm);
1104             if (dataCategory >= 0) {
1105                 dataCategoriesWithPermissions.add(dataCategory);
1106             }
1107         }
1108 
1109         return dataCategoriesWithPermissions;
1110     }
1111 
1112     /**
1113      * Returns true if this package has at least one granted WRITE permission for this category.
1114      *
1115      * @hide
1116      */
getPackageHasWriteHealthPermissionsForCategory( @onNull PackageInfo packageInfo, @HealthDataCategory.Type int dataCategory, @NonNull Context context)1117     public static boolean getPackageHasWriteHealthPermissionsForCategory(
1118             @NonNull PackageInfo packageInfo,
1119             @HealthDataCategory.Type int dataCategory,
1120             @NonNull Context context) {
1121         return getDataCategoriesWithWritePermissionsForPackage(packageInfo, context)
1122                 .contains(dataCategory);
1123     }
1124 
1125     /** @hide */
isValidHealthPermission(PermissionInfo permissionInfo)1126     public static boolean isValidHealthPermission(PermissionInfo permissionInfo) {
1127         return HEALTH_PERMISSION_GROUP.equals(permissionInfo.group)
1128                 && isPermissionEnabled(permissionInfo.name);
1129     }
1130 
1131     /** @hide */
1132     // TODO(b/377285620): flag the permissions in the Manifest when fully supported.
isPermissionEnabled(@onNull String permission)1133     static boolean isPermissionEnabled(@NonNull String permission) {
1134         return switch (permission) {
1135             case READ_ACTIVITY_INTENSITY, WRITE_ACTIVITY_INTENSITY -> Flags.activityIntensity();
1136             default -> true;
1137         };
1138     }
1139 
populateHealthPermissionToHealthPermissionCategoryMap()1140     private static synchronized void populateHealthPermissionToHealthPermissionCategoryMap() {
1141         if (!sHealthCategoryToWritePermissionMap.isEmpty()) {
1142             return;
1143         }
1144 
1145         // Populate permission category to write permission map
1146         sHealthCategoryToWritePermissionMap.put(
1147                 ACTIVE_CALORIES_BURNED, WRITE_ACTIVE_CALORIES_BURNED);
1148         sHealthCategoryToWritePermissionMap.put(DISTANCE, WRITE_DISTANCE);
1149         sHealthCategoryToWritePermissionMap.put(ELEVATION_GAINED, WRITE_ELEVATION_GAINED);
1150         sHealthCategoryToWritePermissionMap.put(EXERCISE, WRITE_EXERCISE);
1151         sHealthCategoryToWritePermissionMap.put(FLOORS_CLIMBED, WRITE_FLOORS_CLIMBED);
1152         sHealthCategoryToWritePermissionMap.put(STEPS, WRITE_STEPS);
1153         sHealthCategoryToWritePermissionMap.put(TOTAL_CALORIES_BURNED, WRITE_TOTAL_CALORIES_BURNED);
1154         sHealthCategoryToWritePermissionMap.put(VO2_MAX, WRITE_VO2_MAX);
1155         sHealthCategoryToWritePermissionMap.put(WHEELCHAIR_PUSHES, WRITE_WHEELCHAIR_PUSHES);
1156         sHealthCategoryToWritePermissionMap.put(POWER, WRITE_POWER);
1157         sHealthCategoryToWritePermissionMap.put(SPEED, WRITE_SPEED);
1158         sHealthCategoryToWritePermissionMap.put(BASAL_METABOLIC_RATE, WRITE_BASAL_METABOLIC_RATE);
1159         sHealthCategoryToWritePermissionMap.put(BODY_FAT, WRITE_BODY_FAT);
1160         sHealthCategoryToWritePermissionMap.put(BODY_WATER_MASS, WRITE_BODY_WATER_MASS);
1161         sHealthCategoryToWritePermissionMap.put(BONE_MASS, WRITE_BONE_MASS);
1162         sHealthCategoryToWritePermissionMap.put(HEIGHT, WRITE_HEIGHT);
1163         sHealthCategoryToWritePermissionMap.put(LEAN_BODY_MASS, WRITE_LEAN_BODY_MASS);
1164         sHealthCategoryToWritePermissionMap.put(WEIGHT, WRITE_WEIGHT);
1165         sHealthCategoryToWritePermissionMap.put(CERVICAL_MUCUS, WRITE_CERVICAL_MUCUS);
1166         sHealthCategoryToWritePermissionMap.put(MENSTRUATION, WRITE_MENSTRUATION);
1167         sHealthCategoryToWritePermissionMap.put(
1168                 INTERMENSTRUAL_BLEEDING, WRITE_INTERMENSTRUAL_BLEEDING);
1169         sHealthCategoryToWritePermissionMap.put(OVULATION_TEST, WRITE_OVULATION_TEST);
1170         sHealthCategoryToWritePermissionMap.put(SEXUAL_ACTIVITY, WRITE_SEXUAL_ACTIVITY);
1171         sHealthCategoryToWritePermissionMap.put(HYDRATION, WRITE_HYDRATION);
1172         sHealthCategoryToWritePermissionMap.put(NUTRITION, WRITE_NUTRITION);
1173         sHealthCategoryToWritePermissionMap.put(SLEEP, WRITE_SLEEP);
1174         sHealthCategoryToWritePermissionMap.put(
1175                 BASAL_BODY_TEMPERATURE, WRITE_BASAL_BODY_TEMPERATURE);
1176         sHealthCategoryToWritePermissionMap.put(BLOOD_GLUCOSE, WRITE_BLOOD_GLUCOSE);
1177         sHealthCategoryToWritePermissionMap.put(BLOOD_PRESSURE, WRITE_BLOOD_PRESSURE);
1178         sHealthCategoryToWritePermissionMap.put(BODY_TEMPERATURE, WRITE_BODY_TEMPERATURE);
1179         sHealthCategoryToWritePermissionMap.put(HEART_RATE, WRITE_HEART_RATE);
1180         sHealthCategoryToWritePermissionMap.put(
1181                 HEART_RATE_VARIABILITY, WRITE_HEART_RATE_VARIABILITY);
1182         sHealthCategoryToWritePermissionMap.put(OXYGEN_SATURATION, WRITE_OXYGEN_SATURATION);
1183         sHealthCategoryToWritePermissionMap.put(RESPIRATORY_RATE, WRITE_RESPIRATORY_RATE);
1184         sHealthCategoryToWritePermissionMap.put(RESTING_HEART_RATE, WRITE_RESTING_HEART_RATE);
1185         sHealthCategoryToWritePermissionMap.put(SKIN_TEMPERATURE, WRITE_SKIN_TEMPERATURE);
1186         sHealthCategoryToWritePermissionMap.put(PLANNED_EXERCISE, WRITE_PLANNED_EXERCISE);
1187         sHealthCategoryToWritePermissionMap.put(MINDFULNESS, WRITE_MINDFULNESS);
1188 
1189         // Populate permission category to read permission map
1190         sHealthCategoryToReadPermissionMap.put(ACTIVE_CALORIES_BURNED, READ_ACTIVE_CALORIES_BURNED);
1191         sHealthCategoryToReadPermissionMap.put(DISTANCE, READ_DISTANCE);
1192         sHealthCategoryToReadPermissionMap.put(ELEVATION_GAINED, READ_ELEVATION_GAINED);
1193         sHealthCategoryToReadPermissionMap.put(EXERCISE, READ_EXERCISE);
1194         sHealthCategoryToReadPermissionMap.put(FLOORS_CLIMBED, READ_FLOORS_CLIMBED);
1195         sHealthCategoryToReadPermissionMap.put(STEPS, READ_STEPS);
1196         sHealthCategoryToReadPermissionMap.put(TOTAL_CALORIES_BURNED, READ_TOTAL_CALORIES_BURNED);
1197         sHealthCategoryToReadPermissionMap.put(VO2_MAX, READ_VO2_MAX);
1198         sHealthCategoryToReadPermissionMap.put(WHEELCHAIR_PUSHES, READ_WHEELCHAIR_PUSHES);
1199         sHealthCategoryToReadPermissionMap.put(POWER, READ_POWER);
1200         sHealthCategoryToReadPermissionMap.put(SPEED, READ_SPEED);
1201         sHealthCategoryToReadPermissionMap.put(BASAL_METABOLIC_RATE, READ_BASAL_METABOLIC_RATE);
1202         sHealthCategoryToReadPermissionMap.put(BODY_FAT, READ_BODY_FAT);
1203         sHealthCategoryToReadPermissionMap.put(BODY_WATER_MASS, READ_BODY_WATER_MASS);
1204         sHealthCategoryToReadPermissionMap.put(BONE_MASS, READ_BONE_MASS);
1205         sHealthCategoryToReadPermissionMap.put(HEIGHT, READ_HEIGHT);
1206         sHealthCategoryToReadPermissionMap.put(LEAN_BODY_MASS, READ_LEAN_BODY_MASS);
1207         sHealthCategoryToReadPermissionMap.put(WEIGHT, READ_WEIGHT);
1208         sHealthCategoryToReadPermissionMap.put(CERVICAL_MUCUS, READ_CERVICAL_MUCUS);
1209         sHealthCategoryToReadPermissionMap.put(MENSTRUATION, READ_MENSTRUATION);
1210         sHealthCategoryToReadPermissionMap.put(
1211                 INTERMENSTRUAL_BLEEDING, READ_INTERMENSTRUAL_BLEEDING);
1212         sHealthCategoryToReadPermissionMap.put(OVULATION_TEST, READ_OVULATION_TEST);
1213         sHealthCategoryToReadPermissionMap.put(SEXUAL_ACTIVITY, READ_SEXUAL_ACTIVITY);
1214         sHealthCategoryToReadPermissionMap.put(HYDRATION, READ_HYDRATION);
1215         sHealthCategoryToReadPermissionMap.put(NUTRITION, READ_NUTRITION);
1216         sHealthCategoryToReadPermissionMap.put(SLEEP, READ_SLEEP);
1217         sHealthCategoryToReadPermissionMap.put(BASAL_BODY_TEMPERATURE, READ_BASAL_BODY_TEMPERATURE);
1218         sHealthCategoryToReadPermissionMap.put(BLOOD_GLUCOSE, READ_BLOOD_GLUCOSE);
1219         sHealthCategoryToReadPermissionMap.put(BLOOD_PRESSURE, READ_BLOOD_PRESSURE);
1220         sHealthCategoryToReadPermissionMap.put(BODY_TEMPERATURE, READ_BODY_TEMPERATURE);
1221         sHealthCategoryToReadPermissionMap.put(HEART_RATE, READ_HEART_RATE);
1222         sHealthCategoryToReadPermissionMap.put(HEART_RATE_VARIABILITY, READ_HEART_RATE_VARIABILITY);
1223         sHealthCategoryToReadPermissionMap.put(OXYGEN_SATURATION, READ_OXYGEN_SATURATION);
1224         sHealthCategoryToReadPermissionMap.put(RESPIRATORY_RATE, READ_RESPIRATORY_RATE);
1225         sHealthCategoryToReadPermissionMap.put(RESTING_HEART_RATE, READ_RESTING_HEART_RATE);
1226         sHealthCategoryToReadPermissionMap.put(SKIN_TEMPERATURE, READ_SKIN_TEMPERATURE);
1227         sHealthCategoryToReadPermissionMap.put(PLANNED_EXERCISE, READ_PLANNED_EXERCISE);
1228         sHealthCategoryToReadPermissionMap.put(MINDFULNESS, READ_MINDFULNESS);
1229     }
1230 
populateWriteHealthPermissionToHealthDataCategoryMap()1231     private static synchronized void populateWriteHealthPermissionToHealthDataCategoryMap() {
1232         if (!sWriteHealthPermissionToHealthDataCategoryMap.isEmpty()) {
1233             return;
1234         }
1235 
1236         // Write permissions
1237         sWriteHealthPermissionToHealthDataCategoryMap.put(
1238                 WRITE_ACTIVE_CALORIES_BURNED, HealthDataCategory.ACTIVITY);
1239         sWriteHealthPermissionToHealthDataCategoryMap.put(
1240                 WRITE_DISTANCE, HealthDataCategory.ACTIVITY);
1241         sWriteHealthPermissionToHealthDataCategoryMap.put(
1242                 WRITE_ELEVATION_GAINED, HealthDataCategory.ACTIVITY);
1243         sWriteHealthPermissionToHealthDataCategoryMap.put(
1244                 WRITE_EXERCISE, HealthDataCategory.ACTIVITY);
1245         sWriteHealthPermissionToHealthDataCategoryMap.put(
1246                 WRITE_PLANNED_EXERCISE, HealthDataCategory.ACTIVITY);
1247         sWriteHealthPermissionToHealthDataCategoryMap.put(
1248                 WRITE_FLOORS_CLIMBED, HealthDataCategory.ACTIVITY);
1249         sWriteHealthPermissionToHealthDataCategoryMap.put(WRITE_STEPS, HealthDataCategory.ACTIVITY);
1250         sWriteHealthPermissionToHealthDataCategoryMap.put(
1251                 WRITE_TOTAL_CALORIES_BURNED, HealthDataCategory.ACTIVITY);
1252         sWriteHealthPermissionToHealthDataCategoryMap.put(
1253                 WRITE_VO2_MAX, HealthDataCategory.ACTIVITY);
1254         sWriteHealthPermissionToHealthDataCategoryMap.put(
1255                 WRITE_WHEELCHAIR_PUSHES, HealthDataCategory.ACTIVITY);
1256         sWriteHealthPermissionToHealthDataCategoryMap.put(WRITE_POWER, HealthDataCategory.ACTIVITY);
1257         sWriteHealthPermissionToHealthDataCategoryMap.put(WRITE_SPEED, HealthDataCategory.ACTIVITY);
1258 
1259         sWriteHealthPermissionToHealthDataCategoryMap.put(
1260                 WRITE_BASAL_METABOLIC_RATE, HealthDataCategory.BODY_MEASUREMENTS);
1261         sWriteHealthPermissionToHealthDataCategoryMap.put(
1262                 WRITE_BODY_FAT, HealthDataCategory.BODY_MEASUREMENTS);
1263         sWriteHealthPermissionToHealthDataCategoryMap.put(
1264                 WRITE_BODY_WATER_MASS, HealthDataCategory.BODY_MEASUREMENTS);
1265         sWriteHealthPermissionToHealthDataCategoryMap.put(
1266                 WRITE_BONE_MASS, HealthDataCategory.BODY_MEASUREMENTS);
1267         sWriteHealthPermissionToHealthDataCategoryMap.put(
1268                 WRITE_HEIGHT, HealthDataCategory.BODY_MEASUREMENTS);
1269         sWriteHealthPermissionToHealthDataCategoryMap.put(
1270                 WRITE_LEAN_BODY_MASS, HealthDataCategory.BODY_MEASUREMENTS);
1271         sWriteHealthPermissionToHealthDataCategoryMap.put(
1272                 WRITE_WEIGHT, HealthDataCategory.BODY_MEASUREMENTS);
1273 
1274         sWriteHealthPermissionToHealthDataCategoryMap.put(
1275                 WRITE_CERVICAL_MUCUS, HealthDataCategory.CYCLE_TRACKING);
1276         sWriteHealthPermissionToHealthDataCategoryMap.put(
1277                 WRITE_MENSTRUATION, HealthDataCategory.CYCLE_TRACKING);
1278         sWriteHealthPermissionToHealthDataCategoryMap.put(
1279                 WRITE_OVULATION_TEST, HealthDataCategory.CYCLE_TRACKING);
1280         sWriteHealthPermissionToHealthDataCategoryMap.put(
1281                 WRITE_SEXUAL_ACTIVITY, HealthDataCategory.CYCLE_TRACKING);
1282         sWriteHealthPermissionToHealthDataCategoryMap.put(
1283                 WRITE_INTERMENSTRUAL_BLEEDING, HealthDataCategory.CYCLE_TRACKING);
1284 
1285         sWriteHealthPermissionToHealthDataCategoryMap.put(
1286                 WRITE_HYDRATION, HealthDataCategory.NUTRITION);
1287         sWriteHealthPermissionToHealthDataCategoryMap.put(
1288                 WRITE_NUTRITION, HealthDataCategory.NUTRITION);
1289         sWriteHealthPermissionToHealthDataCategoryMap.put(WRITE_SLEEP, HealthDataCategory.SLEEP);
1290 
1291         sWriteHealthPermissionToHealthDataCategoryMap.put(
1292                 WRITE_BASAL_BODY_TEMPERATURE, HealthDataCategory.VITALS);
1293         sWriteHealthPermissionToHealthDataCategoryMap.put(
1294                 WRITE_SKIN_TEMPERATURE, HealthDataCategory.VITALS);
1295         sWriteHealthPermissionToHealthDataCategoryMap.put(
1296                 WRITE_BLOOD_GLUCOSE, HealthDataCategory.VITALS);
1297         sWriteHealthPermissionToHealthDataCategoryMap.put(
1298                 WRITE_BLOOD_PRESSURE, HealthDataCategory.VITALS);
1299         sWriteHealthPermissionToHealthDataCategoryMap.put(
1300                 WRITE_BODY_TEMPERATURE, HealthDataCategory.VITALS);
1301         sWriteHealthPermissionToHealthDataCategoryMap.put(
1302                 WRITE_HEART_RATE, HealthDataCategory.VITALS);
1303         sWriteHealthPermissionToHealthDataCategoryMap.put(
1304                 WRITE_HEART_RATE_VARIABILITY, HealthDataCategory.VITALS);
1305         sWriteHealthPermissionToHealthDataCategoryMap.put(
1306                 WRITE_OXYGEN_SATURATION, HealthDataCategory.VITALS);
1307         sWriteHealthPermissionToHealthDataCategoryMap.put(
1308                 WRITE_RESPIRATORY_RATE, HealthDataCategory.VITALS);
1309         sWriteHealthPermissionToHealthDataCategoryMap.put(
1310                 WRITE_RESTING_HEART_RATE, HealthDataCategory.VITALS);
1311 
1312         sWriteHealthPermissionToHealthDataCategoryMap.put(
1313                 WRITE_MINDFULNESS, HealthDataCategory.WELLNESS);
1314 
1315         sDataCategoryToWritePermissionsMap.put(
1316                 HealthDataCategory.ACTIVITY,
1317                 new String[] {
1318                     WRITE_ACTIVE_CALORIES_BURNED,
1319                     WRITE_DISTANCE,
1320                     WRITE_ELEVATION_GAINED,
1321                     WRITE_EXERCISE,
1322                     WRITE_PLANNED_EXERCISE,
1323                     WRITE_FLOORS_CLIMBED,
1324                     WRITE_STEPS,
1325                     WRITE_TOTAL_CALORIES_BURNED,
1326                     WRITE_VO2_MAX,
1327                     WRITE_WHEELCHAIR_PUSHES,
1328                     WRITE_POWER,
1329                     WRITE_SPEED
1330                 });
1331 
1332         sDataCategoryToWritePermissionsMap.put(
1333                 HealthDataCategory.BODY_MEASUREMENTS,
1334                 new String[] {
1335                     WRITE_BASAL_METABOLIC_RATE,
1336                     WRITE_BODY_FAT,
1337                     WRITE_BODY_WATER_MASS,
1338                     WRITE_BONE_MASS,
1339                     WRITE_HEIGHT,
1340                     WRITE_LEAN_BODY_MASS,
1341                     WRITE_WEIGHT
1342                 });
1343 
1344         sDataCategoryToWritePermissionsMap.put(
1345                 HealthDataCategory.CYCLE_TRACKING,
1346                 new String[] {
1347                     WRITE_CERVICAL_MUCUS,
1348                     WRITE_MENSTRUATION,
1349                     WRITE_OVULATION_TEST,
1350                     WRITE_SEXUAL_ACTIVITY,
1351                     WRITE_INTERMENSTRUAL_BLEEDING
1352                 });
1353 
1354         sDataCategoryToWritePermissionsMap.put(
1355                 HealthDataCategory.NUTRITION, new String[] {WRITE_HYDRATION, WRITE_NUTRITION});
1356 
1357         sDataCategoryToWritePermissionsMap.put(
1358                 HealthDataCategory.SLEEP, new String[] {WRITE_SLEEP});
1359 
1360         sDataCategoryToWritePermissionsMap.put(
1361                 HealthDataCategory.VITALS,
1362                 new String[] {
1363                     WRITE_BASAL_BODY_TEMPERATURE,
1364                     WRITE_BLOOD_GLUCOSE,
1365                     WRITE_BLOOD_PRESSURE,
1366                     WRITE_BODY_TEMPERATURE,
1367                     WRITE_HEART_RATE,
1368                     WRITE_HEART_RATE_VARIABILITY,
1369                     WRITE_OXYGEN_SATURATION,
1370                     WRITE_RESPIRATORY_RATE,
1371                     WRITE_RESTING_HEART_RATE,
1372                     WRITE_SKIN_TEMPERATURE
1373                 });
1374 
1375         if (Flags.mindfulness()) {
1376             sDataCategoryToWritePermissionsMap.put(
1377                     HealthDataCategory.WELLNESS, new String[] {WRITE_MINDFULNESS});
1378         }
1379     }
1380 }
1381