1 /* <lambda>null2 * 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 android.os.PersistableBundle 20 21 import androidx.annotation.VisibleForTesting 22 23 import com.android.permission.safetylabel.DataCategoryConstants.CATEGORY_LOCATION 24 import com.android.permission.safetylabel.DataCategoryConstants.Category 25 import com.android.permission.safetylabel.DataPurposeConstants.PURPOSE_ADVERTISING 26 import com.android.permission.safetylabel.DataPurposeConstants.PURPOSE_APP_FUNCTIONALITY 27 import com.android.permission.safetylabel.DataType.KEY_EPHEMERAL 28 import com.android.permission.safetylabel.DataType.KEY_PURPOSES 29 import com.android.permission.safetylabel.DataType.KEY_IS_COLLECTION_OPTIONAL 30 import com.android.permission.safetylabel.SafetyLabel.KEY_VERSION 31 32 /** A class that facilitates creating test safety label persistable bundles. */ 33 object SafetyLabelTestPersistableBundles { 34 private const val TOP_LEVEL_VERSION = 1L 35 private const val SAFETY_LABELS_VERSION = 1L 36 @VisibleForTesting const val INVALID_TOP_LEVEL_VERSION = -1L 37 @VisibleForTesting const val INVALID_SAFETY_LABELS_VERSION = -2L 38 const val INVALID_KEY = "invalid_key" 39 40 /** 41 * Returns [PersistableBundle] representation of an empty top level metadata persistable bundle. 42 */ 43 fun createNonVersionedEmptyMetadataPersistableBundle(): PersistableBundle { 44 return PersistableBundle() 45 } 46 47 /** 48 * Returns [PersistableBundle] representation of a top level metadata versioned by the provided 49 * top level version number, or the default value [TOP_LEVEL_VERSION] if not provided. 50 */ 51 fun createVersionedEmptyMetadataPersistableBundle( 52 version: Long = TOP_LEVEL_VERSION 53 ): PersistableBundle { 54 return PersistableBundle().apply { 55 putLong(KEY_VERSION, version) 56 } 57 } 58 59 /** 60 * Returns [PersistableBundle] representation of a top level metadata versioned by the provided 61 * top level version number, or the default value [TOP_LEVEL_VERSION] if not provided. 62 * And the embedded safety labels will be versioned by the provided safety labels version number, 63 * or the default value [SAFETY_LABELS_VERSION] if not provided. 64 */ 65 fun createMetadataPersistableBundle( 66 topLevelVersion: Long = TOP_LEVEL_VERSION, 67 safetyLabelsVersion: Long = SAFETY_LABELS_VERSION 68 ): PersistableBundle { 69 return createVersionedEmptyMetadataPersistableBundle(topLevelVersion).apply { 70 putPersistableBundle(SafetyLabel.KEY_SAFETY_LABEL, 71 createSafetyLabelPersistableBundle(safetyLabelsVersion)) 72 } 73 } 74 75 /** 76 * Returns [PersistableBundle] representation of a metadata with invalid safety label key. 77 */ 78 fun createInvalidMetadataPersistableBundle(): PersistableBundle { 79 return createVersionedEmptyMetadataPersistableBundle().apply { 80 putPersistableBundle(INVALID_KEY, createSafetyLabelPersistableBundle()) 81 } 82 } 83 84 /** 85 * Returns [PersistableBundle] representation of a metadata with invalid safety label bundle. 86 */ 87 fun createMetadataPersistableBundleWithInvalidSafetyLabel(): PersistableBundle { 88 return createVersionedEmptyMetadataPersistableBundle().apply { 89 putPersistableBundle( 90 SafetyLabel.KEY_SAFETY_LABEL, createInvalidSafetyLabelPersistableBundle()) 91 } 92 } 93 94 /** 95 * Returns [PersistableBundle] representation of an invalid metadata without version number. 96 */ 97 fun createMetadataPersistableBundleWithoutVersion(): PersistableBundle { 98 return createMetadataPersistableBundle().apply { remove(KEY_VERSION) } 99 } 100 101 /** 102 * Returns [PersistableBundle] representation of a metadata with invalid top level version number. 103 */ 104 fun createMetadataPersistableBundleInvalidVersion(): PersistableBundle { 105 return createMetadataPersistableBundle().apply { 106 putLong(KEY_VERSION, INVALID_TOP_LEVEL_VERSION) 107 } 108 } 109 110 /** 111 * Returns [PersistableBundle] representation of an empty safety label versioned by the provided 112 * version number, or the default value [SAFETY_LABELS_VERSION] if not provided. 113 */ 114 private fun createVersionedEmptySafetyLabelsPersistableBundle( 115 version: Long = SAFETY_LABELS_VERSION 116 ): PersistableBundle { 117 return PersistableBundle().apply { 118 putLong(KEY_VERSION, version) 119 } 120 } 121 122 /** Returns [PersistableBundle] representation of a valid safety label */ 123 fun createSafetyLabelPersistableBundle( 124 version: Long = SAFETY_LABELS_VERSION 125 ): PersistableBundle { 126 return createVersionedEmptySafetyLabelsPersistableBundle(version).apply { 127 putPersistableBundle(DataLabel.KEY_DATA_LABEL, createDataLabelPersistableBundle()) 128 } 129 } 130 131 /** Returns [PersistableBundle] representation of a non-versioned invalid safety label */ 132 fun createSafetyLabelPersistableBundleWithoutVersion(): PersistableBundle { 133 return createSafetyLabelPersistableBundle().apply { 134 remove(KEY_VERSION) 135 } 136 } 137 138 /** Returns [PersistableBundle] representation of a safety label with invalid version number */ 139 fun createSafetyLabelPersistableBundleWithInvalidVersion(): PersistableBundle { 140 return createSafetyLabelPersistableBundle().apply { 141 putLong(KEY_VERSION, INVALID_SAFETY_LABELS_VERSION) 142 } 143 } 144 145 /** Returns [PersistableBundle] representation of an invalid safety label */ 146 fun createInvalidSafetyLabelPersistableBundle(): PersistableBundle { 147 return createVersionedEmptySafetyLabelsPersistableBundle().apply { 148 putPersistableBundle(INVALID_KEY, createDataLabelPersistableBundle()) 149 } 150 } 151 152 /** Returns [PersistableBundle] representation of an invalid safety label */ 153 fun createSafetyLabelPersistableBundleWithNullDataCollected(): PersistableBundle { 154 return createVersionedEmptySafetyLabelsPersistableBundle().apply { 155 putPersistableBundle( 156 DataLabel.KEY_DATA_LABEL, createDataLabelPersistableBundleWithNullDataCollected()) 157 } 158 } 159 160 /** Returns [PersistableBundle] representation of an invalid safety label */ 161 fun createSafetyLabelPersistableBundleWithNullDataShared(): PersistableBundle { 162 return createVersionedEmptySafetyLabelsPersistableBundle().apply { 163 putPersistableBundle( 164 DataLabel.KEY_DATA_LABEL, createDataLabelPersistableBundleWithNullDataShared()) 165 } 166 } 167 168 /** Returns [PersistableBundle] representation of an invalid safety label */ 169 fun createSafetyLabelPersistableBundleWithEmptyDataCollected(): PersistableBundle { 170 return createVersionedEmptySafetyLabelsPersistableBundle().apply { 171 putPersistableBundle( 172 DataLabel.KEY_DATA_LABEL, createDataLabelPersistableBundleWithEmptyDataCollected()) 173 } 174 } 175 176 /** Returns [PersistableBundle] representation of an invalid safety label */ 177 fun createSafetyLabelPersistableBundleWithEmptyDataShared(): PersistableBundle { 178 return createVersionedEmptySafetyLabelsPersistableBundle().apply { 179 putPersistableBundle( 180 DataLabel.KEY_DATA_LABEL, createDataLabelPersistableBundleWithEmptyDataShared()) 181 } 182 } 183 184 /** Returns [PersistableBundle] representation of an invalid safety label */ 185 fun createSafetyLabelPersistableBundleWithInvalidDataCollected(): PersistableBundle { 186 return createVersionedEmptySafetyLabelsPersistableBundle().apply { 187 putPersistableBundle( 188 DataLabel.KEY_DATA_LABEL, createDataLabelPersistableBundleWithInvalidDataCollected()) 189 } 190 } 191 192 /** Returns [PersistableBundle] representation of an invalid safety label */ 193 fun createSafetyLabelPersistableBundleWithInvalidDataShared(): PersistableBundle { 194 return createVersionedEmptySafetyLabelsPersistableBundle().apply { 195 putPersistableBundle( 196 DataLabel.KEY_DATA_LABEL, createDataLabelPersistableBundleWithInvalidDataShared()) 197 } 198 } 199 200 /** Returns [PersistableBundle] representation of a data label */ 201 fun createDataLabelPersistableBundle(): PersistableBundle { 202 return createVersionedEmptySafetyLabelsPersistableBundle().apply { 203 putPersistableBundle( 204 DataLabelConstants.DATA_USAGE_SHARED, createCategoryMapPersistableBundle()) 205 putPersistableBundle( 206 DataLabelConstants.DATA_USAGE_COLLECTED, createCategoryMapPersistableBundle()) 207 } 208 } 209 210 /** Returns [PersistableBundle] representation of an invalid data label */ 211 fun createInvalidDataLabelPersistableBundle(): PersistableBundle { 212 return createVersionedEmptySafetyLabelsPersistableBundle().apply { 213 putPersistableBundle(INVALID_KEY, createCategoryMapPersistableBundle()) 214 } 215 } 216 217 /** Returns [PersistableBundle] representation of a null data collected data label */ 218 private fun createDataLabelPersistableBundleWithNullDataCollected(): PersistableBundle { 219 return createDataLabelPersistableBundle().apply { 220 remove(DataLabelConstants.DATA_USAGE_COLLECTED) 221 } 222 } 223 224 /** Returns [PersistableBundle] representation of a null data shared data label */ 225 private fun createDataLabelPersistableBundleWithNullDataShared(): PersistableBundle { 226 return createDataLabelPersistableBundle().apply { remove(DataLabelConstants.DATA_USAGE_SHARED) } 227 } 228 229 /** Returns [PersistableBundle] representation of an empty data collected data label */ 230 private fun createDataLabelPersistableBundleWithEmptyDataCollected(): PersistableBundle { 231 return createDataLabelPersistableBundle().apply { 232 remove(DataLabelConstants.DATA_USAGE_COLLECTED) 233 putPersistableBundle(DataLabelConstants.DATA_USAGE_COLLECTED, PersistableBundle.EMPTY) 234 } 235 } 236 237 /** Returns [PersistableBundle] representation of an empty data shared data label */ 238 private fun createDataLabelPersistableBundleWithEmptyDataShared(): PersistableBundle { 239 return createDataLabelPersistableBundle().apply { 240 remove(DataLabelConstants.DATA_USAGE_SHARED) 241 putPersistableBundle(DataLabelConstants.DATA_USAGE_SHARED, PersistableBundle.EMPTY) 242 } 243 } 244 245 /** Returns [PersistableBundle] representation of an invalid data collected data label */ 246 private fun createDataLabelPersistableBundleWithInvalidDataCollected(): PersistableBundle { 247 return createDataLabelPersistableBundle().apply { 248 remove(DataLabelConstants.DATA_USAGE_COLLECTED) 249 putPersistableBundle( 250 DataLabelConstants.DATA_USAGE_COLLECTED, createInvalidCategoryMapPersistableBundle()) 251 } 252 } 253 254 /** Returns [PersistableBundle] representation of an invalid data shared data label */ 255 private fun createDataLabelPersistableBundleWithInvalidDataShared(): PersistableBundle { 256 return createDataLabelPersistableBundle().apply { 257 remove(DataLabelConstants.DATA_USAGE_SHARED) 258 putPersistableBundle( 259 DataLabelConstants.DATA_USAGE_SHARED, createInvalidCategoryMapPersistableBundle()) 260 } 261 } 262 263 /** Returns [PersistableBundle] representation of data label with additional invalid categories*/ 264 fun createDataLabelPersistableBundleWithAdditonalInvalidCategory(): PersistableBundle { 265 return PersistableBundle().apply { 266 putPersistableBundle( 267 DataLabelConstants.DATA_USAGE_SHARED, 268 createCategoryMapPersistableBundleWithAdditionalInvalidCategory()) 269 putPersistableBundle( 270 DataLabelConstants.DATA_USAGE_COLLECTED, 271 createCategoryMapPersistableBundleWithAdditionalInvalidCategory()) 272 } 273 } 274 275 /** Returns [PersistableBundle] representation of a [Map] of valid data categories */ 276 fun createCategoryMapPersistableBundle(): PersistableBundle { 277 return PersistableBundle().apply { 278 DataCategoryConstants.VALID_CATEGORIES.forEach { categoryKey -> 279 putPersistableBundle(categoryKey, createTypeMapPersistableBundle(categoryKey)) 280 } 281 } 282 } 283 284 /** Returns [PersistableBundle] representation of a [Map] of valid data categories */ 285 fun createCategoryMapPersistableBundleWithAdditionalInvalidCategory(): PersistableBundle { 286 return PersistableBundle().apply { 287 DataCategoryConstants.VALID_CATEGORIES.forEach { categoryKey -> 288 putPersistableBundle(categoryKey, createTypeMapPersistableBundle(categoryKey)) 289 } 290 putPersistableBundle(INVALID_KEY, createTypeMapPersistableBundle(CATEGORY_LOCATION)) 291 } 292 } 293 294 /** 295 * Returns [PersistableBundle] representation of a [Map] of valid data categories and invalid 296 * types 297 */ 298 fun createCategoryMapPersistableBundleWithInvalidTypes(): PersistableBundle { 299 return PersistableBundle().apply { 300 DataCategoryConstants.VALID_CATEGORIES.forEach { categoryKey -> 301 putPersistableBundle(categoryKey, createInvalidTypeMapPersistableBundle()) 302 } 303 } 304 } 305 306 /** Returns [PersistableBundle] representation of a [Map] of invalid data categories */ 307 fun createInvalidCategoryMapPersistableBundle(): PersistableBundle { 308 return PersistableBundle().apply { 309 putPersistableBundle(INVALID_KEY, createTypeMapPersistableBundle(CATEGORY_LOCATION)) 310 } 311 } 312 313 /** Returns [PersistableBundle] representation of a [Map] of valid data type */ 314 fun createTypeMapPersistableBundle(@Category category: String): PersistableBundle { 315 return PersistableBundle().apply { 316 DataTypeConstants.getValidDataTypesForCategory(category).forEach { type -> 317 putPersistableBundle(type, createTypePersistableBundle()) 318 } 319 } 320 } 321 322 /** Returns [PersistableBundle] representation of a [Map] of invalid data type */ 323 fun createInvalidTypeMapPersistableBundle(): PersistableBundle { 324 return PersistableBundle().apply { 325 putPersistableBundle(INVALID_KEY, createTypePersistableBundle()) 326 } 327 } 328 329 /** Returns [PersistableBundle] representation of a [Map] of valid type, with invalid data */ 330 fun createTypeMapWithInvalidTypeDataPersistableBundle( 331 @Category category: String 332 ): PersistableBundle { 333 return PersistableBundle().apply { 334 DataTypeConstants.getValidDataTypesForCategory(category).forEach { type -> 335 putPersistableBundle(type, createInvalidTypePersistableBundle()) 336 } 337 } 338 } 339 340 /** Returns [PersistableBundle] representation of a valid data type */ 341 fun createTypePersistableBundle(): PersistableBundle { 342 return PersistableBundle().apply { 343 putIntArray(KEY_PURPOSES, intArrayOf(PURPOSE_APP_FUNCTIONALITY, PURPOSE_ADVERTISING)) 344 putBoolean(KEY_IS_COLLECTION_OPTIONAL, true) 345 putBoolean(KEY_EPHEMERAL, true) 346 } 347 } 348 349 /** Returns [PersistableBundle] representation of an invalid data type */ 350 fun createInvalidTypePersistableBundle(): PersistableBundle { 351 return PersistableBundle().apply { putLong(INVALID_KEY, 0) } 352 } 353 } 354