diff options
6 files changed, 422 insertions, 234 deletions
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/data/SafetyLabelInfoLiveData.kt b/PermissionController/src/com/android/permissioncontroller/permission/data/SafetyLabelInfoLiveData.kt index 9e7865b4f..d2ba7031d 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/data/SafetyLabelInfoLiveData.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/data/SafetyLabelInfoLiveData.kt @@ -25,6 +25,7 @@ import com.android.permission.safetylabel.DataCategoryConstants import com.android.permission.safetylabel.DataLabelConstants import com.android.permission.safetylabel.DataTypeConstants import com.android.permission.safetylabel.SafetyLabel +import com.android.permission.safetylabel.SafetyLabel.KEY_VERSION import com.android.permissioncontroller.PermissionControllerApplication import com.android.permissioncontroller.permission.model.livedatatypes.SafetyLabelInfo import com.android.permissioncontroller.permission.utils.KotlinUtils.isPlaceholderSafetyLabelDataEnabled @@ -136,16 +137,21 @@ private constructor( putPersistableBundle(DataLabelConstants.DATA_USAGE_SHARED, dataSharedBundle) } - val safetyLabelBundle = - PersistableBundle().apply { putPersistableBundle("data_labels", dataLabelBundle) } + val safetyLabelBundle = PersistableBundle().apply { + putLong(KEY_VERSION, INITIAL_SAFETY_LABELS_VERSION) + putPersistableBundle("data_labels", dataLabelBundle) + } return PersistableBundle().apply { + putLong(KEY_VERSION, INITIAL_METADATA_VERSION) putPersistableBundle("safety_labels", safetyLabelBundle) } } - companion object : - DataRepositoryForPackage<Pair<String, UserHandle>, SafetyLabelInfoLiveData>() { + companion object : DataRepositoryForPackage<Pair<String, UserHandle>, SafetyLabelInfoLiveData>( + ) { + private const val INITIAL_METADATA_VERSION = 1L + private const val INITIAL_SAFETY_LABELS_VERSION = 1L private val LOG_TAG = SafetyLabelInfoLiveData::class.java.simpleName override fun newValue(key: Pair<String, UserHandle>): SafetyLabelInfoLiveData { diff --git a/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/safetylabel/AppsSafetyLabelHistoryTest.kt b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/safetylabel/AppsSafetyLabelHistoryTest.kt index d73c78a2c..e96f50631 100644 --- a/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/safetylabel/AppsSafetyLabelHistoryTest.kt +++ b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/safetylabel/AppsSafetyLabelHistoryTest.kt @@ -19,6 +19,7 @@ package com.android.permissioncontroller.tests.mocking.safetylabel import android.os.Build import android.os.PersistableBundle import androidx.test.filters.SdkSuppress +import com.android.permission.safetylabel.SafetyLabel.KEY_VERSION import com.android.permission.safetylabel.SafetyLabel as AppMetadataSafetyLabel import com.android.permissioncontroller.safetylabel.AppsSafetyLabelHistory import com.android.permissioncontroller.safetylabel.AppsSafetyLabelHistory.AppInfo @@ -94,6 +95,8 @@ class AppsSafetyLabelHistoryTest { private const val DATA_SHARED_KEY = "data_shared" private const val DATA_LABEL_KEY = "data_labels" private const val PURPOSES_KEY = "purposes" + private const val TOP_LEVEL_VERSION = 1L + private const val SAFETY_LABELS_VERSION = 1L private val DATE_2022_09_01 = ZonedDateTime.parse("2022-09-01T00:00:00.000Z").toInstant() private val DATE_2022_10_10 = ZonedDateTime.parse("2022-10-10T00:00:00.000Z").toInstant() @@ -140,9 +143,12 @@ class AppsSafetyLabelHistoryTest { } val safetyLabelBundle = - PersistableBundle().apply { putPersistableBundle(DATA_LABEL_KEY, dataLabelBundle) } + PersistableBundle().apply { + putLong(KEY_VERSION, SAFETY_LABELS_VERSION) + putPersistableBundle(DATA_LABEL_KEY, dataLabelBundle) } return PersistableBundle().apply { + putLong(KEY_VERSION, TOP_LEVEL_VERSION) putPersistableBundle(SAFETY_LABEL_KEY, safetyLabelBundle) } } diff --git a/SafetyLabel/TEST_MAPPING b/SafetyLabel/TEST_MAPPING new file mode 100644 index 000000000..f2560add0 --- /dev/null +++ b/SafetyLabel/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "postsubmit": [ + { + "name" : "SafetyLabelTests" + } + ] +}
\ No newline at end of file diff --git a/SafetyLabel/java/com/android/permission/safetylabel/SafetyLabel.java b/SafetyLabel/java/com/android/permission/safetylabel/SafetyLabel.java index 822e9c4fe..f6b3c8f31 100644 --- a/SafetyLabel/java/com/android/permission/safetylabel/SafetyLabel.java +++ b/SafetyLabel/java/com/android/permission/safetylabel/SafetyLabel.java @@ -17,14 +17,19 @@ package com.android.permission.safetylabel; import android.os.PersistableBundle; +import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import java.util.Locale; + /** Safety Label representation containing zero or more {@link DataCategory} for data shared */ public class SafetyLabel { + private static final String TAG = "SafetyLabel"; @VisibleForTesting static final String KEY_SAFETY_LABEL = "safety_labels"; + public static final String KEY_VERSION = "version"; private final DataLabel mDataLabel; private SafetyLabel(@NonNull DataLabel dataLabel) { @@ -34,8 +39,14 @@ public class SafetyLabel { /** Returns {@link SafetyLabel} created by parsing a metadata {@link PersistableBundle} */ @Nullable public static SafetyLabel getSafetyLabelFromMetadata(@Nullable PersistableBundle bundle) { - // TODO(b/261069412): add versioning and nonnull empty/invalid cases - if (bundle == null) { + if (bundle == null || bundle.isEmpty()) { + return null; + } + + if (bundle.getLong(KEY_VERSION, 0L) <= 0) { + Log.w(TAG, String.format( + Locale.US, "The top level metadata bundle have an invalid version %d", + bundle.getLong(KEY_VERSION, 0L))); return null; } @@ -44,6 +55,13 @@ public class SafetyLabel { return null; } + long safetyLabelsVersion = safetyLabelBundle.getLong(KEY_VERSION, 0L); + if (safetyLabelsVersion <= 0) { + Log.w(TAG, String.format(Locale.US, + "The safety labels have an invalid version %d", safetyLabelsVersion)); + return null; + } + DataLabel dataLabel = DataLabel.getDataLabel(safetyLabelBundle); if (dataLabel == null) { return null; diff --git a/SafetyLabel/tests/java/com/android/permission/safetylabel/SafetyLabelTest.kt b/SafetyLabel/tests/java/com/android/permission/safetylabel/SafetyLabelTest.kt index ce9f24634..1b694cc9a 100644 --- a/SafetyLabel/tests/java/com/android/permission/safetylabel/SafetyLabelTest.kt +++ b/SafetyLabel/tests/java/com/android/permission/safetylabel/SafetyLabelTest.kt @@ -16,11 +16,18 @@ package com.android.permission.safetylabel -import android.os.PersistableBundle import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.permission.safetylabel.SafetyLabel.KEY_SAFETY_LABEL +import com.android.permission.safetylabel.SafetyLabel.KEY_VERSION import com.android.permission.safetylabel.SafetyLabelTestPersistableBundles.createInvalidMetadataPersistableBundle import com.android.permission.safetylabel.SafetyLabelTestPersistableBundles.createMetadataPersistableBundle +import com.android.permission.safetylabel.SafetyLabelTestPersistableBundles.createMetadataPersistableBundleInvalidVersion import com.android.permission.safetylabel.SafetyLabelTestPersistableBundles.createMetadataPersistableBundleWithInvalidSafetyLabel +import com.android.permission.safetylabel.SafetyLabelTestPersistableBundles.createMetadataPersistableBundleWithoutVersion +import com.android.permission.safetylabel.SafetyLabelTestPersistableBundles.createNonVersionedEmptyMetadataPersistableBundle +import com.android.permission.safetylabel.SafetyLabelTestPersistableBundles.createSafetyLabelPersistableBundleWithInvalidVersion +import com.android.permission.safetylabel.SafetyLabelTestPersistableBundles.createSafetyLabelPersistableBundleWithoutVersion +import com.android.permission.safetylabel.SafetyLabelTestPersistableBundles.createVersionedEmptyMetadataPersistableBundle import com.google.common.truth.Truth.assertThat import org.junit.Test import org.junit.runner.RunWith @@ -29,42 +36,94 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class SafetyLabelTest { - @Test - fun getSafetyLabelFromMetaData_nullMetadataBundle_nullSafetyLabel() { - val safetyLabel = SafetyLabel.getSafetyLabelFromMetadata(null) + @Test + fun getSafetyLabelFromMetadata_nullMetadataBundle_nullSafetyLabel() { + val safetyLabel = SafetyLabel.getSafetyLabelFromMetadata(null) - assertThat(safetyLabel).isNull() - } + assertThat(safetyLabel).isNull() + } - @Test - fun getSafetyLabelFromMetaData_emptyMetadataBundle_nullSafetyLabel() { - val safetyLabel = SafetyLabel.getSafetyLabelFromMetadata(PersistableBundle.EMPTY) + @Test + fun getSafetyLabelFromMetadata_emptyMetadataBundle_nullSafetyLabel() { + val safetyLabel = + SafetyLabel.getSafetyLabelFromMetadata(createNonVersionedEmptyMetadataPersistableBundle()) - assertThat(safetyLabel).isNull() - } + assertThat(safetyLabel).isNull() + } - @Test - fun getSafetyLabelFromMetaData_invalidMetadataBundle_nullSafetyLabel() { - val safetyLabel = - SafetyLabel.getSafetyLabelFromMetadata(createInvalidMetadataPersistableBundle()) + @Test + fun getSafetyLabelFromMetadata_emptyVersionedMetadataBundle_nullSafetyLabel() { + val safetyLabel = + SafetyLabel.getSafetyLabelFromMetadata(createVersionedEmptyMetadataPersistableBundle()) - assertThat(safetyLabel).isNull() - } + assertThat(safetyLabel).isNull() + } - @Test - fun getSafetyLabelFromMetaData_invalidSafetyLabelBundle_dataSharedEmpty() { - val safetyLabel = - SafetyLabel.getSafetyLabelFromMetadata( - createMetadataPersistableBundleWithInvalidSafetyLabel()) + @Test + fun getSafetyLabelFromMetadata_invalidMetadataBundle_nullSafetyLabel() { + val safetyLabel = + SafetyLabel.getSafetyLabelFromMetadata(createInvalidMetadataPersistableBundle()) - assertThat(safetyLabel).isNull() - } + assertThat(safetyLabel).isNull() + } - @Test - fun getSafetyLabelFromMetaData_validBundle_hasDataShared() { - val safetyLabel = SafetyLabel.getSafetyLabelFromMetadata(createMetadataPersistableBundle()) + @Test + fun getSafetyLabelFromMetadata_invalidSafetyLabelBundle_dataSharedEmpty() { + val safetyLabel = + SafetyLabel.getSafetyLabelFromMetadata( + createMetadataPersistableBundleWithInvalidSafetyLabel()) - assertThat(safetyLabel).isNotNull() - assertThat(safetyLabel?.dataLabel).isNotNull() - } -} + assertThat(safetyLabel).isNull() + } + + @Test + fun getSafetyLabelFromMetadata_validBundle_hasDataShared() { + val bundle = createMetadataPersistableBundle(TOP_LEVEL_VERSION, SAFETY_LABELS_VERSION) + val topLevelVersion = bundle.getLong(KEY_VERSION) + val safetyLabelBundle = bundle.getPersistableBundle(KEY_SAFETY_LABEL) + val safetyLabelsVersion = safetyLabelBundle?.getLong(KEY_VERSION) + val safetyLabel = SafetyLabel.getSafetyLabelFromMetadata(bundle) + + assertThat(topLevelVersion).isEqualTo(TOP_LEVEL_VERSION) + assertThat(safetyLabelsVersion).isEqualTo(SAFETY_LABELS_VERSION) + assertThat(safetyLabel).isNotNull() + assertThat(safetyLabel?.dataLabel).isNotNull() + } + + @Test + fun getSafetyLabelFromMetadata_invalidBundle_noTopLevelBundleVersion() { + val safetyLabel = + SafetyLabel.getSafetyLabelFromMetadata(createMetadataPersistableBundleWithoutVersion()) + assertThat(safetyLabel).isNull() + } + + @Test + fun getSafetyLabelFromMetadata_invalidBundle_InvalidTopLevelBundleVersion() { + val safetyLabel = + SafetyLabel.getSafetyLabelFromMetadata(createMetadataPersistableBundleInvalidVersion()) + assertThat(safetyLabel).isNull() + } + + @Test + fun getSafetyLabelFromMetadata_invalidBundle_NoSafetyLabelBundleVersion() { + val bundle = createVersionedEmptyMetadataPersistableBundle() + bundle.putPersistableBundle( + SafetyLabel.KEY_SAFETY_LABEL, createSafetyLabelPersistableBundleWithoutVersion()) + val safetyLabel = SafetyLabel.getSafetyLabelFromMetadata(bundle) + assertThat(safetyLabel).isNull() + } + + @Test + fun getSafetyLabelFromMetadata_invalidBundle_InvalidSafetyLabelBundleVersion() { + val bundle = createVersionedEmptyMetadataPersistableBundle() + bundle.putPersistableBundle( + SafetyLabel.KEY_SAFETY_LABEL, createSafetyLabelPersistableBundleWithInvalidVersion()) + val safetyLabel = SafetyLabel.getSafetyLabelFromMetadata(bundle) + assertThat(safetyLabel).isNull() + } + + companion object { + private const val TOP_LEVEL_VERSION = 3L + private const val SAFETY_LABELS_VERSION = 2L + } +}
\ No newline at end of file diff --git a/SafetyLabel/tests/java/com/android/permission/safetylabel/SafetyLabelTestPersistableBundles.kt b/SafetyLabel/tests/java/com/android/permission/safetylabel/SafetyLabelTestPersistableBundles.kt index 2d2811633..482323f6a 100644 --- a/SafetyLabel/tests/java/com/android/permission/safetylabel/SafetyLabelTestPersistableBundles.kt +++ b/SafetyLabel/tests/java/com/android/permission/safetylabel/SafetyLabelTestPersistableBundles.kt @@ -17,6 +17,9 @@ package com.android.permission.safetylabel import android.os.PersistableBundle + +import androidx.annotation.VisibleForTesting + import com.android.permission.safetylabel.DataCategoryConstants.CATEGORY_LOCATION import com.android.permission.safetylabel.DataCategoryConstants.Category import com.android.permission.safetylabel.DataPurposeConstants.PURPOSE_ADVERTISING @@ -24,238 +27,327 @@ import com.android.permission.safetylabel.DataPurposeConstants.PURPOSE_APP_FUNCT import com.android.permission.safetylabel.DataType.KEY_EPHEMERAL import com.android.permission.safetylabel.DataType.KEY_PURPOSES import com.android.permission.safetylabel.DataType.KEY_USER_CONTROL +import com.android.permission.safetylabel.SafetyLabel.KEY_VERSION /** A class that facilitates creating test safety label persistable bundles. */ object SafetyLabelTestPersistableBundles { - const val INVALID_KEY = "invalid_key" - - fun createMetadataPersistableBundle(): PersistableBundle { - return PersistableBundle().apply { - putPersistableBundle(SafetyLabel.KEY_SAFETY_LABEL, createSafetyLabelPersistableBundle()) - } + private const val TOP_LEVEL_VERSION = 1L + private const val SAFETY_LABELS_VERSION = 1L + @VisibleForTesting const val INVALID_TOP_LEVEL_VERSION = -1L + @VisibleForTesting const val INVALID_SAFETY_LABELS_VERSION = -2L + const val INVALID_KEY = "invalid_key" + + /** + * Returns [PersistableBundle] representation of an empty top level metadata persistable bundle. + */ + fun createNonVersionedEmptyMetadataPersistableBundle(): PersistableBundle { + return PersistableBundle() + } + + /** + * Returns [PersistableBundle] representation of a top level metadata versioned by the provided + * top level version number, or the default value [TOP_LEVEL_VERSION] if not provided. + */ + fun createVersionedEmptyMetadataPersistableBundle( + version: Long = TOP_LEVEL_VERSION + ): PersistableBundle { + return PersistableBundle().apply { + putLong(KEY_VERSION, version) } - - fun createInvalidMetadataPersistableBundle(): PersistableBundle { - return PersistableBundle().apply { - putPersistableBundle(INVALID_KEY, createSafetyLabelPersistableBundle()) - } + } + + /** + * Returns [PersistableBundle] representation of a top level metadata versioned by the provided + * top level version number, or the default value [TOP_LEVEL_VERSION] if not provided. + * And the embedded safety labels will be versioned by the provided safety labels version number, + * or the default value [SAFETY_LABELS_VERSION] if not provided. + */ + fun createMetadataPersistableBundle( + topLevelVersion: Long = TOP_LEVEL_VERSION, + safetyLabelsVersion: Long = SAFETY_LABELS_VERSION + ): PersistableBundle { + return createVersionedEmptyMetadataPersistableBundle(topLevelVersion).apply { + putPersistableBundle(SafetyLabel.KEY_SAFETY_LABEL, + createSafetyLabelPersistableBundle(safetyLabelsVersion)) } - - fun createMetadataPersistableBundleWithInvalidSafetyLabel(): PersistableBundle { - return PersistableBundle().apply { - putPersistableBundle( - SafetyLabel.KEY_SAFETY_LABEL, createInvalidSafetyLabelPersistableBundle()) - } + } + + /** + * Returns [PersistableBundle] representation of a metadata with invalid safety label key. + */ + fun createInvalidMetadataPersistableBundle(): PersistableBundle { + return createVersionedEmptyMetadataPersistableBundle().apply { + putPersistableBundle(INVALID_KEY, createSafetyLabelPersistableBundle()) } - - /** Returns [PersistableBundle] representation of a valid safety label */ - fun createSafetyLabelPersistableBundle(): PersistableBundle { - return PersistableBundle().apply { - putPersistableBundle(DataLabel.KEY_DATA_LABEL, createDataLabelPersistableBundle()) - } + } + + /** + * Returns [PersistableBundle] representation of a metadata with invalid safety label bundle. + */ + fun createMetadataPersistableBundleWithInvalidSafetyLabel(): PersistableBundle { + return createVersionedEmptyMetadataPersistableBundle().apply { + putPersistableBundle( + SafetyLabel.KEY_SAFETY_LABEL, createInvalidSafetyLabelPersistableBundle()) } - - /** Returns [PersistableBundle] representation of an ivnalid safety label */ - fun createInvalidSafetyLabelPersistableBundle(): PersistableBundle { - return PersistableBundle().apply { - putPersistableBundle(INVALID_KEY, createDataLabelPersistableBundle()) - } + } + + /** + * Returns [PersistableBundle] representation of an invalid metadata without version number. + */ + fun createMetadataPersistableBundleWithoutVersion(): PersistableBundle { + return createMetadataPersistableBundle().apply { remove(KEY_VERSION) } + } + + /** + * Returns [PersistableBundle] representation of a metadata with invalid top level version number. + */ + fun createMetadataPersistableBundleInvalidVersion(): PersistableBundle { + return createMetadataPersistableBundle().apply { + putLong(KEY_VERSION, INVALID_TOP_LEVEL_VERSION) } - - /** Returns [PersistableBundle] representation of an ivnalid safety label */ - fun createSafetyLabelPersistableBundleWithNullDataCollected(): PersistableBundle { - return PersistableBundle().apply { - putPersistableBundle( - DataLabel.KEY_DATA_LABEL, createDataLabelPersistableBundleWithNullDataCollected()) - } + } + + /** + * Returns [PersistableBundle] representation of an empty safety label versioned by the provided + * version number, or the default value [SAFETY_LABELS_VERSION] if not provided. + */ + private fun createVersionedEmptySafetyLabelsPersistableBundle( + version: Long = SAFETY_LABELS_VERSION + ): PersistableBundle { + return PersistableBundle().apply { + putLong(KEY_VERSION, version) } + } + + /** Returns [PersistableBundle] representation of a valid safety label */ + fun createSafetyLabelPersistableBundle( + version: Long = SAFETY_LABELS_VERSION + ): PersistableBundle { + return createVersionedEmptySafetyLabelsPersistableBundle(version).apply { + putPersistableBundle(DataLabel.KEY_DATA_LABEL, createDataLabelPersistableBundle()) + } + } - /** Returns [PersistableBundle] representation of an ivnalid safety label */ - fun createSafetyLabelPersistableBundleWithNullDataShared(): PersistableBundle { - return PersistableBundle().apply { - putPersistableBundle( - DataLabel.KEY_DATA_LABEL, createDataLabelPersistableBundleWithNullDataShared()) - } + /** Returns [PersistableBundle] representation of a non-versioned invalid safety label */ + fun createSafetyLabelPersistableBundleWithoutVersion(): PersistableBundle { + return createSafetyLabelPersistableBundle().apply { + remove(KEY_VERSION) } + } - /** Returns [PersistableBundle] representation of an ivnalid safety label */ - fun createSafetyLabelPersistableBundleWithEmptyDataCollected(): PersistableBundle { - return PersistableBundle().apply { - putPersistableBundle( - DataLabel.KEY_DATA_LABEL, createDataLabelPersistableBundleWithEmptyDataCollected()) - } + /** Returns [PersistableBundle] representation of a safety label with invalid version number */ + fun createSafetyLabelPersistableBundleWithInvalidVersion(): PersistableBundle { + return createSafetyLabelPersistableBundle().apply { + putLong(KEY_VERSION, INVALID_SAFETY_LABELS_VERSION) } + } - /** Returns [PersistableBundle] representation of an ivnalid safety label */ - fun createSafetyLabelPersistableBundleWithEmptyDataShared(): PersistableBundle { - return PersistableBundle().apply { - putPersistableBundle( - DataLabel.KEY_DATA_LABEL, createDataLabelPersistableBundleWithEmptyDataShared()) - } + /** Returns [PersistableBundle] representation of an invalid safety label */ + fun createInvalidSafetyLabelPersistableBundle(): PersistableBundle { + return createVersionedEmptySafetyLabelsPersistableBundle().apply { + putPersistableBundle(INVALID_KEY, createDataLabelPersistableBundle()) } + } - /** Returns [PersistableBundle] representation of an ivnalid safety label */ - fun createSafetyLabelPersistableBundleWithInvalidDataCollected(): PersistableBundle { - return PersistableBundle().apply { - putPersistableBundle( - DataLabel.KEY_DATA_LABEL, - createDataLabelPersistableBundleWithInvalidDataCollected()) - } + /** Returns [PersistableBundle] representation of an invalid safety label */ + fun createSafetyLabelPersistableBundleWithNullDataCollected(): PersistableBundle { + return createVersionedEmptySafetyLabelsPersistableBundle().apply { + putPersistableBundle( + DataLabel.KEY_DATA_LABEL, createDataLabelPersistableBundleWithNullDataCollected()) } + } - /** Returns [PersistableBundle] representation of an ivnalid safety label */ - fun createSafetyLabelPersistableBundleWithInvalidDataShared(): PersistableBundle { - return PersistableBundle().apply { - putPersistableBundle( - DataLabel.KEY_DATA_LABEL, createDataLabelPersistableBundleWithInvalidDataShared()) - } + /** Returns [PersistableBundle] representation of an invalid safety label */ + fun createSafetyLabelPersistableBundleWithNullDataShared(): PersistableBundle { + return createVersionedEmptySafetyLabelsPersistableBundle().apply { + putPersistableBundle( + DataLabel.KEY_DATA_LABEL, createDataLabelPersistableBundleWithNullDataShared()) } + } - fun createDataLabelPersistableBundle(): PersistableBundle { - return PersistableBundle().apply { - putPersistableBundle( - DataLabelConstants.DATA_USAGE_SHARED, createCategoryMapPersistableBundle()) - putPersistableBundle( - DataLabelConstants.DATA_USAGE_COLLECTED, createCategoryMapPersistableBundle()) - } + /** Returns [PersistableBundle] representation of an invalid safety label */ + fun createSafetyLabelPersistableBundleWithEmptyDataCollected(): PersistableBundle { + return createVersionedEmptySafetyLabelsPersistableBundle().apply { + putPersistableBundle( + DataLabel.KEY_DATA_LABEL, createDataLabelPersistableBundleWithEmptyDataCollected()) } + } - fun createInvalidDataLabelPersistableBundle(): PersistableBundle { - return PersistableBundle().apply { - putPersistableBundle(INVALID_KEY, createCategoryMapPersistableBundle()) - } + /** Returns [PersistableBundle] representation of an invalid safety label */ + fun createSafetyLabelPersistableBundleWithEmptyDataShared(): PersistableBundle { + return createVersionedEmptySafetyLabelsPersistableBundle().apply { + putPersistableBundle( + DataLabel.KEY_DATA_LABEL, createDataLabelPersistableBundleWithEmptyDataShared()) } + } - private fun createDataLabelPersistableBundleWithNullDataCollected(): PersistableBundle { - val bundle = createDataLabelPersistableBundle() - bundle.remove(DataLabelConstants.DATA_USAGE_COLLECTED) - return bundle + /** Returns [PersistableBundle] representation of an invalid safety label */ + fun createSafetyLabelPersistableBundleWithInvalidDataCollected(): PersistableBundle { + return createVersionedEmptySafetyLabelsPersistableBundle().apply { + putPersistableBundle( + DataLabel.KEY_DATA_LABEL, createDataLabelPersistableBundleWithInvalidDataCollected()) } + } - private fun createDataLabelPersistableBundleWithNullDataShared(): PersistableBundle { - val bundle = createDataLabelPersistableBundle() - bundle.remove(DataLabelConstants.DATA_USAGE_SHARED) - return bundle + /** Returns [PersistableBundle] representation of an invalid safety label */ + fun createSafetyLabelPersistableBundleWithInvalidDataShared(): PersistableBundle { + return createVersionedEmptySafetyLabelsPersistableBundle().apply { + putPersistableBundle( + DataLabel.KEY_DATA_LABEL, createDataLabelPersistableBundleWithInvalidDataShared()) + } + } + + /** Returns [PersistableBundle] representation of a data label */ + fun createDataLabelPersistableBundle(): PersistableBundle { + return createVersionedEmptySafetyLabelsPersistableBundle().apply { + putPersistableBundle( + DataLabelConstants.DATA_USAGE_SHARED, createCategoryMapPersistableBundle()) + putPersistableBundle( + DataLabelConstants.DATA_USAGE_COLLECTED, createCategoryMapPersistableBundle()) } + } - private fun createDataLabelPersistableBundleWithEmptyDataCollected(): PersistableBundle { - val bundle = createDataLabelPersistableBundle() - bundle.remove(DataLabelConstants.DATA_USAGE_COLLECTED) - bundle.putPersistableBundle( - DataLabelConstants.DATA_USAGE_COLLECTED, PersistableBundle.EMPTY) - return bundle + /** Returns [PersistableBundle] representation of an invalid data label */ + fun createInvalidDataLabelPersistableBundle(): PersistableBundle { + return createVersionedEmptySafetyLabelsPersistableBundle().apply { + putPersistableBundle(INVALID_KEY, createCategoryMapPersistableBundle()) } + } - private fun createDataLabelPersistableBundleWithEmptyDataShared(): PersistableBundle { - val bundle = createDataLabelPersistableBundle() - bundle.remove(DataLabelConstants.DATA_USAGE_SHARED) - bundle.putPersistableBundle(DataLabelConstants.DATA_USAGE_SHARED, PersistableBundle.EMPTY) - return bundle - } - - private fun createDataLabelPersistableBundleWithInvalidDataCollected(): PersistableBundle { - val bundle = createDataLabelPersistableBundle() - bundle.remove(DataLabelConstants.DATA_USAGE_COLLECTED) - bundle.putPersistableBundle( - DataLabelConstants.DATA_USAGE_COLLECTED, createInvalidCategoryMapPersistableBundle()) - return bundle + /** Returns [PersistableBundle] representation of a null data collected data label */ + private fun createDataLabelPersistableBundleWithNullDataCollected(): PersistableBundle { + return createDataLabelPersistableBundle().apply { + remove(DataLabelConstants.DATA_USAGE_COLLECTED) } + } + + /** Returns [PersistableBundle] representation of a null data shared data label */ + private fun createDataLabelPersistableBundleWithNullDataShared(): PersistableBundle { + return createDataLabelPersistableBundle().apply { remove(DataLabelConstants.DATA_USAGE_SHARED) } + } + + /** Returns [PersistableBundle] representation of an empty data collected data label */ + private fun createDataLabelPersistableBundleWithEmptyDataCollected(): PersistableBundle { + return createDataLabelPersistableBundle().apply { + remove(DataLabelConstants.DATA_USAGE_COLLECTED) + putPersistableBundle(DataLabelConstants.DATA_USAGE_COLLECTED, PersistableBundle.EMPTY) + } + } - private fun createDataLabelPersistableBundleWithInvalidDataShared(): PersistableBundle { - val bundle = createDataLabelPersistableBundle() - bundle.remove(DataLabelConstants.DATA_USAGE_SHARED) - bundle.putPersistableBundle( - DataLabelConstants.DATA_USAGE_SHARED, createInvalidCategoryMapPersistableBundle()) - return bundle + /** Returns [PersistableBundle] representation of an empty data shared data label */ + private fun createDataLabelPersistableBundleWithEmptyDataShared(): PersistableBundle { + return createDataLabelPersistableBundle().apply { + remove(DataLabelConstants.DATA_USAGE_SHARED) + putPersistableBundle(DataLabelConstants.DATA_USAGE_SHARED, PersistableBundle.EMPTY) + } + } + + /** Returns [PersistableBundle] representation of an invalid data collected data label */ + private fun createDataLabelPersistableBundleWithInvalidDataCollected(): PersistableBundle { + return createDataLabelPersistableBundle().apply { + remove(DataLabelConstants.DATA_USAGE_COLLECTED) + putPersistableBundle( + DataLabelConstants.DATA_USAGE_COLLECTED, createInvalidCategoryMapPersistableBundle()) + } + } + + /** Returns [PersistableBundle] representation of an invalid data shared data label */ + private fun createDataLabelPersistableBundleWithInvalidDataShared(): PersistableBundle { + return createDataLabelPersistableBundle().apply { + remove(DataLabelConstants.DATA_USAGE_SHARED) + putPersistableBundle( + DataLabelConstants.DATA_USAGE_SHARED, createInvalidCategoryMapPersistableBundle()) + } + } + + /** Returns [PersistableBundle] representation of data label with additional invalid categories*/ + fun createDataLabelPersistableBundleWithAdditonalInvalidCategory(): PersistableBundle { + return PersistableBundle().apply { + putPersistableBundle( + DataLabelConstants.DATA_USAGE_SHARED, + createCategoryMapPersistableBundleWithAdditionalInvalidCategory()) + putPersistableBundle( + DataLabelConstants.DATA_USAGE_COLLECTED, + createCategoryMapPersistableBundleWithAdditionalInvalidCategory()) + } + } + + /** Returns [PersistableBundle] representation of a [Map] of valid data categories */ + fun createCategoryMapPersistableBundle(): PersistableBundle { + return PersistableBundle().apply { + DataCategoryConstants.VALID_CATEGORIES.forEach { categoryKey -> + putPersistableBundle(categoryKey, createTypeMapPersistableBundle(categoryKey)) + } } + } + + /** Returns [PersistableBundle] representation of a [Map] of valid data categories */ + fun createCategoryMapPersistableBundleWithAdditionalInvalidCategory(): PersistableBundle { + return PersistableBundle().apply { + DataCategoryConstants.VALID_CATEGORIES.forEach { categoryKey -> + putPersistableBundle(categoryKey, createTypeMapPersistableBundle(categoryKey)) + } + putPersistableBundle(INVALID_KEY, createTypeMapPersistableBundle(CATEGORY_LOCATION)) + } + } + + /** + * Returns [PersistableBundle] representation of a [Map] of valid data categories and invalid + * types + */ + fun createCategoryMapPersistableBundleWithInvalidTypes(): PersistableBundle { + return PersistableBundle().apply { + DataCategoryConstants.VALID_CATEGORIES.forEach { categoryKey -> + putPersistableBundle(categoryKey, createInvalidTypeMapPersistableBundle()) + } + } + } - fun createDataLabelPersistableBundleWithAdditonalInvalidCategory(): PersistableBundle { - return PersistableBundle().apply { - putPersistableBundle( - DataLabelConstants.DATA_USAGE_SHARED, - createCategoryMapPersistableBundleWithAdditionalInvalidCategory()) - putPersistableBundle( - DataLabelConstants.DATA_USAGE_COLLECTED, - createCategoryMapPersistableBundleWithAdditionalInvalidCategory()) - } - } - - /** Returns [PersistableBundle] representation of a [Map] of valid data categories */ - fun createCategoryMapPersistableBundle(): PersistableBundle { - return PersistableBundle().apply { - DataCategoryConstants.VALID_CATEGORIES.forEach { categoryKey -> - putPersistableBundle(categoryKey, createTypeMapPersistableBundle(categoryKey)) - } - } - } - - /** Returns [PersistableBundle] representation of a [Map] of valid data categories */ - fun createCategoryMapPersistableBundleWithAdditionalInvalidCategory(): PersistableBundle { - return PersistableBundle().apply { - DataCategoryConstants.VALID_CATEGORIES.forEach { categoryKey -> - putPersistableBundle(categoryKey, createTypeMapPersistableBundle(categoryKey)) - } - putPersistableBundle(INVALID_KEY, createTypeMapPersistableBundle(CATEGORY_LOCATION)) - } - } - - /** - * Returns [PersistableBundle] representation of a [Map] of valid data categories and invalid - * types - */ - fun createCategoryMapPersistableBundleWithInvalidTypes(): PersistableBundle { - return PersistableBundle().apply { - DataCategoryConstants.VALID_CATEGORIES.forEach { categoryKey -> - putPersistableBundle(categoryKey, createInvalidTypeMapPersistableBundle()) - } - } + /** Returns [PersistableBundle] representation of a [Map] of invalid data categories */ + fun createInvalidCategoryMapPersistableBundle(): PersistableBundle { + return PersistableBundle().apply { + putPersistableBundle(INVALID_KEY, createTypeMapPersistableBundle(CATEGORY_LOCATION)) } - - /** Returns [PersistableBundle] representation of a [Map] of invalid data categories */ - fun createInvalidCategoryMapPersistableBundle(): PersistableBundle { - return PersistableBundle().apply { - putPersistableBundle(INVALID_KEY, createTypeMapPersistableBundle(CATEGORY_LOCATION)) - } + } + + /** Returns [PersistableBundle] representation of a [Map] of valid data type */ + fun createTypeMapPersistableBundle(@Category category: String): PersistableBundle { + return PersistableBundle().apply { + DataTypeConstants.getValidDataTypesForCategory(category).forEach { type -> + putPersistableBundle(type, createTypePersistableBundle()) + } } + } - /** Returns [PersistableBundle] representation of a [Map] of valid data type */ - fun createTypeMapPersistableBundle(@Category category: String): PersistableBundle { - return PersistableBundle().apply { - DataTypeConstants.getValidDataTypesForCategory(category).forEach { type -> - putPersistableBundle(type, createTypePersistableBundle()) - } - } - } - - /** Returns [PersistableBundle] representation of a [Map] of invalid data type */ - fun createInvalidTypeMapPersistableBundle(): PersistableBundle { - return PersistableBundle().apply { - putPersistableBundle(INVALID_KEY, createTypePersistableBundle()) - } - } - - /** Returns [PersistableBundle] representation of a [Map] of valid type, with invalid data */ - fun createTypeMapWithInvalidTypeDataPersistableBundle( - @Category category: String - ): PersistableBundle { - return PersistableBundle().apply { - DataTypeConstants.getValidDataTypesForCategory(category).forEach { type -> - putPersistableBundle(type, createInvalidTypePersistableBundle()) - } - } - } - - /** Returns [PersistableBundle] representation of a valid data type */ - fun createTypePersistableBundle(): PersistableBundle { - return PersistableBundle().apply { - putIntArray(KEY_PURPOSES, intArrayOf(PURPOSE_APP_FUNCTIONALITY, PURPOSE_ADVERTISING)) - putBoolean(KEY_USER_CONTROL, true) - putBoolean(KEY_EPHEMERAL, true) - } - } - - /** Returns [PersistableBundle] representation of an invalid data type */ - fun createInvalidTypePersistableBundle(): PersistableBundle { - return PersistableBundle().apply { putLong(INVALID_KEY, 0) } + /** Returns [PersistableBundle] representation of a [Map] of invalid data type */ + fun createInvalidTypeMapPersistableBundle(): PersistableBundle { + return PersistableBundle().apply { + putPersistableBundle(INVALID_KEY, createTypePersistableBundle()) + } + } + + /** Returns [PersistableBundle] representation of a [Map] of valid type, with invalid data */ + fun createTypeMapWithInvalidTypeDataPersistableBundle( + @Category category: String + ): PersistableBundle { + return PersistableBundle().apply { + DataTypeConstants.getValidDataTypesForCategory(category).forEach { type -> + putPersistableBundle(type, createInvalidTypePersistableBundle()) + } } + } + + /** Returns [PersistableBundle] representation of a valid data type */ + fun createTypePersistableBundle(): PersistableBundle { + return PersistableBundle().apply { + putIntArray(KEY_PURPOSES, intArrayOf(PURPOSE_APP_FUNCTIONALITY, PURPOSE_ADVERTISING)) + putBoolean(KEY_USER_CONTROL, true) + putBoolean(KEY_EPHEMERAL, true) + } + } + + /** Returns [PersistableBundle] representation of an invalid data type */ + fun createInvalidTypePersistableBundle(): PersistableBundle { + return PersistableBundle().apply { putLong(INVALID_KEY, 0) } + } } |