1 /* 2 * Copyright (C) 2022 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 com.android.permission.safetylabel; 18 19 import static java.lang.annotation.RetentionPolicy.SOURCE; 20 21 import android.annotation.StringDef; 22 import android.util.ArrayMap; 23 24 import java.lang.annotation.Retention; 25 import java.util.Arrays; 26 import java.util.Collections; 27 import java.util.HashSet; 28 import java.util.Map; 29 import java.util.Set; 30 31 /** 32 * Constants and util methods for determining valid {@link String} data categories for usage within 33 * {@link SafetyLabel}, {@link DataCategory}, and {@link DataType} 34 */ 35 public class DataTypeConstants { 36 37 /** 38 * List of valid Safety Label data collection/sharing types for {@link 39 * DataCategoryConstants#CATEGORY_PERSONAL} 40 */ 41 @Retention(SOURCE) 42 @StringDef( 43 prefix = "PERSONAL_", 44 value = { 45 PERSONAL_NAME, 46 PERSONAL_EMAIL_ADDRESS, 47 PERSONAL_PHYSICAL_ADDRESS, 48 PERSONAL_PHONE_NUMBER, 49 PERSONAL_RACE_ETHNICITY, 50 PERSONAL_POLITICAL_OR_RELIGIOUS_BELIEFS, 51 PERSONAL_SEXUAL_ORIENTATION_OR_GENDER_IDENTITY, 52 PERSONAL_IDENTIFIERS, 53 PERSONAL_OTHER, 54 }) 55 public @interface PersonalType {} 56 57 public static final String PERSONAL_NAME = "name"; 58 public static final String PERSONAL_EMAIL_ADDRESS = "email_address"; 59 public static final String PERSONAL_PHYSICAL_ADDRESS = "physical_address"; 60 public static final String PERSONAL_PHONE_NUMBER = "phone_number"; 61 public static final String PERSONAL_RACE_ETHNICITY = "race_ethnicity"; 62 public static final String PERSONAL_POLITICAL_OR_RELIGIOUS_BELIEFS = 63 "political_or_religious_beliefs"; 64 public static final String PERSONAL_SEXUAL_ORIENTATION_OR_GENDER_IDENTITY = 65 "sexual_orientation_or_gender_identity"; 66 public static final String PERSONAL_IDENTIFIERS = "personal_identifiers"; 67 public static final String PERSONAL_OTHER = "other"; 68 69 @PersonalType 70 private static final Set<String> VALID_TYPES_PERSONAL = 71 Collections.unmodifiableSet( 72 new HashSet<>( 73 Arrays.asList( 74 PERSONAL_NAME, 75 PERSONAL_EMAIL_ADDRESS, 76 PERSONAL_PHYSICAL_ADDRESS, 77 PERSONAL_PHONE_NUMBER, 78 PERSONAL_RACE_ETHNICITY, 79 PERSONAL_POLITICAL_OR_RELIGIOUS_BELIEFS, 80 PERSONAL_SEXUAL_ORIENTATION_OR_GENDER_IDENTITY, 81 PERSONAL_IDENTIFIERS, 82 PERSONAL_OTHER))); 83 84 /** 85 * List of valid Safety Label data collection/sharing types for {@link 86 * DataCategoryConstants#CATEGORY_FINANCIAL} 87 */ 88 @Retention(SOURCE) 89 @StringDef( 90 prefix = "FINANCIAL_", 91 value = { 92 FINANCIAL_CARD_BANK_ACCOUNT, 93 FINANCIAL_PURCHASE_HISTORY, 94 FINANCIAL_CREDIT_SCORE, 95 FINANCIAL_OTHER, 96 }) 97 public @interface FinancialType {} 98 99 public static final String FINANCIAL_CARD_BANK_ACCOUNT = "card_bank_account"; 100 public static final String FINANCIAL_PURCHASE_HISTORY = "purchase_history"; 101 public static final String FINANCIAL_CREDIT_SCORE = "credit_score"; 102 public static final String FINANCIAL_OTHER = "other"; 103 104 @FinancialType 105 private static final Set<String> VALID_TYPES_FINANCIAL = 106 Collections.unmodifiableSet( 107 new HashSet<>( 108 Arrays.asList( 109 FINANCIAL_CARD_BANK_ACCOUNT, 110 FINANCIAL_PURCHASE_HISTORY, 111 FINANCIAL_CREDIT_SCORE, 112 FINANCIAL_OTHER))); 113 114 /** 115 * List of valid Safety Label data collection/sharing types for {@link 116 * DataCategoryConstants#CATEGORY_LOCATION} 117 */ 118 @Retention(SOURCE) 119 @StringDef( 120 prefix = "LOCATION_", 121 value = { 122 LOCATION_APPROX_LOCATION, 123 LOCATION_PRECISE_LOCATION, 124 }) 125 public @interface LocationType {} 126 127 public static final String LOCATION_APPROX_LOCATION = "approx_location"; 128 public static final String LOCATION_PRECISE_LOCATION = "precise_location"; 129 130 @LocationType 131 private static final Set<String> VALID_TYPES_LOCATION = 132 Collections.unmodifiableSet( 133 new HashSet<>( 134 Arrays.asList(LOCATION_APPROX_LOCATION, LOCATION_PRECISE_LOCATION))); 135 136 /** 137 * List of valid Safety Label data collection/sharing types for {@link 138 * DataCategoryConstants#CATEGORY_EMAIL_TEXT_MESSAGE} 139 */ 140 @Retention(SOURCE) 141 @StringDef( 142 prefix = "EMAIL_TEXT_MESSAGE_", 143 value = { 144 EMAIL_TEXT_MESSAGE_EMAILS, 145 EMAIL_TEXT_MESSAGE_TEXT_MESSAGES, 146 EMAIL_TEXT_MESSAGE_OTHER, 147 }) 148 public @interface EmailTextMessageType {} 149 150 public static final String EMAIL_TEXT_MESSAGE_EMAILS = "emails"; 151 public static final String EMAIL_TEXT_MESSAGE_TEXT_MESSAGES = "text_messages"; 152 public static final String EMAIL_TEXT_MESSAGE_OTHER = "other"; 153 154 @EmailTextMessageType 155 private static final Set<String> VALID_TYPES_EMAIL_TEXT_MESSAGE = 156 Collections.unmodifiableSet( 157 new HashSet<>( 158 Arrays.asList( 159 EMAIL_TEXT_MESSAGE_EMAILS, 160 EMAIL_TEXT_MESSAGE_TEXT_MESSAGES, 161 EMAIL_TEXT_MESSAGE_OTHER))); 162 163 /** 164 * List of valid Safety Label data collection/sharing types for {@link 165 * DataCategoryConstants#CATEGORY_PHOTO_VIDEO} 166 */ 167 @Retention(SOURCE) 168 @StringDef( 169 prefix = "PHOTO_VIDEO_", 170 value = { 171 PHOTO_VIDEO_PHOTOS, 172 PHOTO_VIDEO_VIDEOS, 173 }) 174 public @interface PhotoVideoType {} 175 176 public static final String PHOTO_VIDEO_PHOTOS = "photos"; 177 public static final String PHOTO_VIDEO_VIDEOS = "videos"; 178 179 @PhotoVideoType 180 private static final Set<String> VALID_TYPES_PHOTO_VIDEO = 181 Collections.unmodifiableSet( 182 new HashSet<>(Arrays.asList(PHOTO_VIDEO_PHOTOS, PHOTO_VIDEO_VIDEOS))); 183 184 /** 185 * List of valid Safety Label data collection/sharing types for {@link 186 * DataCategoryConstants#CATEGORY_AUDIO} 187 */ 188 @Retention(SOURCE) 189 @StringDef( 190 prefix = "AUDIO_", 191 value = {AUDIO_SOUND_RECORDINGS, AUDIO_MUSIC_FILES, AUDIO_OTHER}) 192 public @interface AudioType {} 193 194 public static final String AUDIO_SOUND_RECORDINGS = "sound_recordings"; 195 public static final String AUDIO_MUSIC_FILES = "music_files"; 196 public static final String AUDIO_OTHER = "other"; 197 198 @AudioType 199 private static final Set<String> VALID_TYPES_AUDIO = 200 Collections.unmodifiableSet( 201 new HashSet<>( 202 Arrays.asList(AUDIO_SOUND_RECORDINGS, AUDIO_MUSIC_FILES, AUDIO_OTHER))); 203 204 /** 205 * List of valid Safety Label data collection/sharing types for {@link 206 * DataCategoryConstants#CATEGORY_STORAGE} 207 */ 208 @Retention(SOURCE) 209 @StringDef( 210 prefix = "STORAGE_", 211 value = { 212 STORAGE_FILES_DOCS, 213 }) 214 public @interface StorageType {} 215 216 public static final String STORAGE_FILES_DOCS = "files_docs"; 217 218 @StorageType 219 private static final Set<String> VALID_TYPES_STORAGE = 220 Collections.unmodifiableSet(new HashSet<>(Arrays.asList(STORAGE_FILES_DOCS))); 221 222 /** 223 * List of valid Safety Label data collection/sharing types for {@link 224 * DataCategoryConstants#CATEGORY_HEALTH_FITNESS} 225 */ 226 @Retention(SOURCE) 227 @StringDef( 228 prefix = "HEALTH_FITNESS_", 229 value = { 230 HEALTH_FITNESS_HEALTH, 231 HEALTH_FITNESS_FITNESS, 232 }) 233 public @interface HealthFitnessType {} 234 235 public static final String HEALTH_FITNESS_HEALTH = "health"; 236 public static final String HEALTH_FITNESS_FITNESS = "fitness"; 237 238 @HealthFitnessType 239 private static final Set<String> VALID_TYPES_HEALTH_FITNESS = 240 Collections.unmodifiableSet( 241 new HashSet<>(Arrays.asList(HEALTH_FITNESS_HEALTH, HEALTH_FITNESS_FITNESS))); 242 243 /** 244 * List of valid Safety Label data collection/sharing types for {@link 245 * DataCategoryConstants#CATEGORY_CONTACTS} 246 */ 247 @Retention(SOURCE) 248 @StringDef( 249 prefix = "CONTACTS_", 250 value = { 251 CONTACTS_CONTACTS, 252 }) 253 public @interface ContactsType {} 254 255 public static final String CONTACTS_CONTACTS = "contacts"; 256 257 @ContactsType 258 private static final Set<String> VALID_TYPES_CONTACTS = 259 Collections.unmodifiableSet(new HashSet<>(Arrays.asList(CONTACTS_CONTACTS))); 260 261 /** 262 * List of valid Safety Label data collection/sharing types for {@link 263 * DataCategoryConstants#CATEGORY_CALENDAR} 264 */ 265 @Retention(SOURCE) 266 @StringDef( 267 prefix = "CALENDAR_", 268 value = { 269 CALENDAR_CALENDAR, 270 }) 271 public @interface CalendarType {} 272 273 public static final String CALENDAR_CALENDAR = "calendar"; 274 275 @CalendarType 276 private static final Set<String> VALID_TYPES_CALENDAR = 277 Collections.unmodifiableSet(new HashSet<>(Arrays.asList(CALENDAR_CALENDAR))); 278 279 /** 280 * List of valid Safety Label data collection/sharing types for {@link 281 * DataCategoryConstants#CATEGORY_IDENTIFIERS} 282 */ 283 @Retention(SOURCE) 284 @StringDef( 285 prefix = "IDENTIFIERS_", 286 value = { 287 IDENTIFIERS_OTHER, 288 }) 289 public @interface IdentifiersType {} 290 291 public static final String IDENTIFIERS_OTHER = "other"; 292 293 @IdentifiersType 294 private static final Set<String> VALID_TYPES_IDENTIFIERS = 295 Collections.unmodifiableSet(new HashSet<>(Arrays.asList(IDENTIFIERS_OTHER))); 296 297 /** 298 * List of valid Safety Label data collection/sharing types for {@link 299 * DataCategoryConstants#CATEGORY_APP_PERFORMANCE} 300 */ 301 @Retention(SOURCE) 302 @StringDef( 303 prefix = "APP_PERFORMANCE_", 304 value = { 305 APP_PERFORMANCE_CRASH_LOGS, 306 APP_PERFORMANCE_PERFORMANCE_DIAGNOSTICS, 307 APP_PERFORMANCE_OTHER, 308 }) 309 public @interface AppPerformanceType {} 310 311 public static final String APP_PERFORMANCE_CRASH_LOGS = "crash_logs"; 312 public static final String APP_PERFORMANCE_PERFORMANCE_DIAGNOSTICS = "performance_diagnostics"; 313 public static final String APP_PERFORMANCE_OTHER = "other"; 314 315 @AppPerformanceType 316 private static final Set<String> VALID_TYPES_APP_PERFORMANCE = 317 Collections.unmodifiableSet( 318 new HashSet<>( 319 Arrays.asList( 320 APP_PERFORMANCE_CRASH_LOGS, 321 APP_PERFORMANCE_PERFORMANCE_DIAGNOSTICS, 322 APP_PERFORMANCE_OTHER))); 323 324 /** 325 * List of valid Safety Label data collection/sharing types for {@link 326 * DataCategoryConstants#CATEGORY_ACTIONS_IN_APP} 327 */ 328 @Retention(SOURCE) 329 @StringDef( 330 prefix = "ACTIONS_IN_APP_", 331 value = { 332 ACTIONS_IN_APP_USER_INTERACTION, 333 ACTIONS_IN_APP_IN_APP_SEARCH_HISTORY, 334 ACTIONS_IN_APP_INSTALLED_APPS, 335 ACTIONS_IN_APP_USER_GENERATED_CONTENT, 336 ACTIONS_IN_APP_OTHER, 337 }) 338 public @interface ActionsInAppType {} 339 340 public static final String ACTIONS_IN_APP_USER_INTERACTION = "user_interaction"; 341 public static final String ACTIONS_IN_APP_IN_APP_SEARCH_HISTORY = "in_app_search_history"; 342 public static final String ACTIONS_IN_APP_INSTALLED_APPS = "installed_apps"; 343 public static final String ACTIONS_IN_APP_USER_GENERATED_CONTENT = "user_generated_content"; 344 public static final String ACTIONS_IN_APP_OTHER = "other"; 345 346 @ActionsInAppType 347 private static final Set<String> VALID_TYPES_ACTIONS_IN_APP = 348 Collections.unmodifiableSet( 349 new HashSet<>( 350 Arrays.asList( 351 ACTIONS_IN_APP_USER_INTERACTION, 352 ACTIONS_IN_APP_IN_APP_SEARCH_HISTORY, 353 ACTIONS_IN_APP_INSTALLED_APPS, 354 ACTIONS_IN_APP_USER_GENERATED_CONTENT, 355 ACTIONS_IN_APP_OTHER))); 356 357 /** 358 * List of valid Safety Label data collection/sharing types for {@link 359 * DataCategoryConstants#CATEGORY_SEARCH_AND_BROWSING} 360 */ 361 @Retention(SOURCE) 362 @StringDef( 363 prefix = "SEARCH_AND_BROWSING_", 364 value = { 365 SEARCH_AND_BROWSING_WEB_BROWSING_HISTORY, 366 }) 367 public @interface SearchAndBrowsingType {} 368 369 public static final String SEARCH_AND_BROWSING_WEB_BROWSING_HISTORY = "web_browsing_history"; 370 371 @SearchAndBrowsingType 372 private static final Set<String> VALID_TYPES_SEARCH_AND_BROWSING = 373 Collections.unmodifiableSet( 374 new HashSet<>(Arrays.asList(SEARCH_AND_BROWSING_WEB_BROWSING_HISTORY))); 375 376 private static final Map<String, Set<String>> VALID_TYPES_FOR_CATEGORY_MAP; 377 378 /** Returns {@link Set} of valid types for the specified {@link String} category key */ getValidDataTypesForCategory( @ataCategoryConstants.Category String category)379 public static Set<String> getValidDataTypesForCategory( 380 @DataCategoryConstants.Category String category) { 381 return VALID_TYPES_FOR_CATEGORY_MAP.containsKey(category) 382 ? VALID_TYPES_FOR_CATEGORY_MAP.get(category) 383 : Collections.emptySet(); 384 } 385 386 static { 387 VALID_TYPES_FOR_CATEGORY_MAP = new ArrayMap<>(); VALID_TYPES_FOR_CATEGORY_MAP.put( DataCategoryConstants.CATEGORY_PERSONAL, VALID_TYPES_PERSONAL)388 VALID_TYPES_FOR_CATEGORY_MAP.put( 389 DataCategoryConstants.CATEGORY_PERSONAL, VALID_TYPES_PERSONAL); VALID_TYPES_FOR_CATEGORY_MAP.put( DataCategoryConstants.CATEGORY_FINANCIAL, VALID_TYPES_FINANCIAL)390 VALID_TYPES_FOR_CATEGORY_MAP.put( 391 DataCategoryConstants.CATEGORY_FINANCIAL, VALID_TYPES_FINANCIAL); VALID_TYPES_FOR_CATEGORY_MAP.put( DataCategoryConstants.CATEGORY_LOCATION, VALID_TYPES_LOCATION)392 VALID_TYPES_FOR_CATEGORY_MAP.put( 393 DataCategoryConstants.CATEGORY_LOCATION, VALID_TYPES_LOCATION); VALID_TYPES_FOR_CATEGORY_MAP.put( DataCategoryConstants.CATEGORY_EMAIL_TEXT_MESSAGE, VALID_TYPES_EMAIL_TEXT_MESSAGE)394 VALID_TYPES_FOR_CATEGORY_MAP.put( 395 DataCategoryConstants.CATEGORY_EMAIL_TEXT_MESSAGE, VALID_TYPES_EMAIL_TEXT_MESSAGE); VALID_TYPES_FOR_CATEGORY_MAP.put( DataCategoryConstants.CATEGORY_PHOTO_VIDEO, VALID_TYPES_PHOTO_VIDEO)396 VALID_TYPES_FOR_CATEGORY_MAP.put( 397 DataCategoryConstants.CATEGORY_PHOTO_VIDEO, VALID_TYPES_PHOTO_VIDEO); VALID_TYPES_FOR_CATEGORY_MAP.put(DataCategoryConstants.CATEGORY_AUDIO, VALID_TYPES_AUDIO)398 VALID_TYPES_FOR_CATEGORY_MAP.put(DataCategoryConstants.CATEGORY_AUDIO, VALID_TYPES_AUDIO); VALID_TYPES_FOR_CATEGORY_MAP.put( DataCategoryConstants.CATEGORY_STORAGE, VALID_TYPES_STORAGE)399 VALID_TYPES_FOR_CATEGORY_MAP.put( 400 DataCategoryConstants.CATEGORY_STORAGE, VALID_TYPES_STORAGE); VALID_TYPES_FOR_CATEGORY_MAP.put( DataCategoryConstants.CATEGORY_HEALTH_FITNESS, VALID_TYPES_HEALTH_FITNESS)401 VALID_TYPES_FOR_CATEGORY_MAP.put( 402 DataCategoryConstants.CATEGORY_HEALTH_FITNESS, VALID_TYPES_HEALTH_FITNESS); VALID_TYPES_FOR_CATEGORY_MAP.put( DataCategoryConstants.CATEGORY_CONTACTS, VALID_TYPES_CONTACTS)403 VALID_TYPES_FOR_CATEGORY_MAP.put( 404 DataCategoryConstants.CATEGORY_CONTACTS, VALID_TYPES_CONTACTS); VALID_TYPES_FOR_CATEGORY_MAP.put( DataCategoryConstants.CATEGORY_CALENDAR, VALID_TYPES_CALENDAR)405 VALID_TYPES_FOR_CATEGORY_MAP.put( 406 DataCategoryConstants.CATEGORY_CALENDAR, VALID_TYPES_CALENDAR); VALID_TYPES_FOR_CATEGORY_MAP.put( DataCategoryConstants.CATEGORY_IDENTIFIERS, VALID_TYPES_IDENTIFIERS)407 VALID_TYPES_FOR_CATEGORY_MAP.put( 408 DataCategoryConstants.CATEGORY_IDENTIFIERS, VALID_TYPES_IDENTIFIERS); VALID_TYPES_FOR_CATEGORY_MAP.put( DataCategoryConstants.CATEGORY_APP_PERFORMANCE, VALID_TYPES_APP_PERFORMANCE)409 VALID_TYPES_FOR_CATEGORY_MAP.put( 410 DataCategoryConstants.CATEGORY_APP_PERFORMANCE, VALID_TYPES_APP_PERFORMANCE); VALID_TYPES_FOR_CATEGORY_MAP.put( DataCategoryConstants.CATEGORY_ACTIONS_IN_APP, VALID_TYPES_ACTIONS_IN_APP)411 VALID_TYPES_FOR_CATEGORY_MAP.put( 412 DataCategoryConstants.CATEGORY_ACTIONS_IN_APP, VALID_TYPES_ACTIONS_IN_APP); VALID_TYPES_FOR_CATEGORY_MAP.put( DataCategoryConstants.CATEGORY_SEARCH_AND_BROWSING, VALID_TYPES_SEARCH_AND_BROWSING)413 VALID_TYPES_FOR_CATEGORY_MAP.put( 414 DataCategoryConstants.CATEGORY_SEARCH_AND_BROWSING, 415 VALID_TYPES_SEARCH_AND_BROWSING); 416 } 417 DataTypeConstants()418 private DataTypeConstants() { 419 /* do nothing - hide constructor */ 420 } 421 } 422