[SafetyCenter] Use restructured SafetyCenterManager APIs and refactored test API to override SafetyCenterConfig in CTS tests

Test: atest CtsSafetyCenterTestCases
Bug: 219195246
Bug: 219078602
Bug: 218852160
Bug: 219194453
Bug: 217944317

Change-Id: Id9dbe5b53616bab30b26a21a3ba868334053acad
Merged-In: Id9dbe5b53616bab30b26a21a3ba868334053acad
diff --git a/tests/tests/safetycenter/src/android/safetycenter/cts/SafetyCenterApisWithShellPermissions.kt b/tests/tests/safetycenter/src/android/safetycenter/cts/SafetyCenterApisWithShellPermissions.kt
index a6a9f0a..c3c7e726 100644
--- a/tests/tests/safetycenter/src/android/safetycenter/cts/SafetyCenterApisWithShellPermissions.kt
+++ b/tests/tests/safetycenter/src/android/safetycenter/cts/SafetyCenterApisWithShellPermissions.kt
@@ -22,26 +22,32 @@
 import android.safetycenter.SafetyCenterManager
 import android.safetycenter.SafetyCenterManager.OnSafetyCenterDataChangedListener
 import android.safetycenter.SafetySourceData
+import android.safetycenter.SafetyEvent
+import android.safetycenter.config.SafetyCenterConfig
 import com.android.compatibility.common.util.SystemUtil.callWithShellPermissionIdentity
 import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity
 import java.util.concurrent.Executor
 
 /**
- * Call {@link SafetyCenterManager#sendSafetyCenterUpdate} adopting Shell's
+ * Call {@link SafetyCenterManager#setSafetySourceData} adopting Shell's
  * {@link SEND_SAFETY_CENTER_UPDATE} permission.
  */
-fun SafetyCenterManager.sendUpdateWithPermission(safetySourceData: SafetySourceData) =
+fun SafetyCenterManager.setSafetySourceDataWithPermission(
+    safetySourceId: String,
+    safetySourceData: SafetySourceData,
+    safetyEvent: SafetyEvent
+) =
     runWithShellPermissionIdentity({
-        sendSafetyCenterUpdate(safetySourceData)
+        setSafetySourceData(safetySourceId, safetySourceData, safetyEvent)
     }, SEND_SAFETY_CENTER_UPDATE)
 
 /**
- * Call {@link SafetyCenterManager#getLastSafetyCenterUpdate} adopting Shell's
+ * Call {@link SafetyCenterManager#getSafetySourceData} adopting Shell's
  * {@link SEND_SAFETY_CENTER_UPDATE} permission.
  */
-fun SafetyCenterManager.getLastUpdateWithPermission(id: String): SafetySourceData? =
+fun SafetyCenterManager.getSafetySourceDataWithPermission(id: String): SafetySourceData? =
     callWithShellPermissionIdentity({
-        getLastSafetyCenterUpdate(id)
+        getSafetySourceData(id)
     }, SEND_SAFETY_CENTER_UPDATE)
 
 /**
@@ -82,24 +88,22 @@
     }, MANAGE_SAFETY_CENTER)
 
 /**
- * Call {@link SafetyCenterManager#clearSafetyCenterData} adopting Shell's
+ * Call {@link SafetyCenterManager#clearAllSafetySourceData} adopting Shell's
  * {@link MANAGE_SAFETY_CENTER} permission.
  */
-fun SafetyCenterManager.clearDataWithPermission() =
+fun SafetyCenterManager.clearAllSafetySourceDataWithPermission() =
     runWithShellPermissionIdentity({
-        clearSafetyCenterData()
+        clearAllSafetySourceData()
     }, MANAGE_SAFETY_CENTER)
 
-fun SafetyCenterManager.addAdditionalSafetySourceWithPermission(
-    sourceId: String,
-    packageName: String,
-    broadcastReceiverName: String
+fun SafetyCenterManager.setSafetyCenterConfigOverrideWithPermission(
+    safetyCenterConfig: SafetyCenterConfig
 ) =
     runWithShellPermissionIdentity({
-        addAdditionalSafetySource(sourceId, packageName, broadcastReceiverName)
+        setSafetyCenterConfigOverride(safetyCenterConfig)
     }, MANAGE_SAFETY_CENTER)
 
-fun SafetyCenterManager.clearAdditionalSafetySourcesWithPermission() =
+fun SafetyCenterManager.clearSafetyCenterConfigOverrideWithPermission() =
     runWithShellPermissionIdentity({
-        clearAdditionalSafetySources()
+        clearSafetyCenterConfigOverride()
     }, MANAGE_SAFETY_CENTER)
diff --git a/tests/tests/safetycenter/src/android/safetycenter/cts/SafetyCenterManagerTest.kt b/tests/tests/safetycenter/src/android/safetycenter/cts/SafetyCenterManagerTest.kt
index f86ce84..bd58849 100644
--- a/tests/tests/safetycenter/src/android/safetycenter/cts/SafetyCenterManagerTest.kt
+++ b/tests/tests/safetycenter/src/android/safetycenter/cts/SafetyCenterManagerTest.kt
@@ -34,9 +34,14 @@
 import android.safetycenter.SafetyCenterManager.OnSafetyCenterDataChangedListener
 import android.safetycenter.SafetySourceData
 import android.safetycenter.SafetySourceIssue
+import android.safetycenter.SafetyEvent
+import android.safetycenter.SafetyEvent.SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
 import android.safetycenter.SafetySourceIssue.SEVERITY_LEVEL_CRITICAL_WARNING
 import android.safetycenter.SafetySourceStatus
 import android.safetycenter.SafetySourceStatus.STATUS_LEVEL_CRITICAL_WARNING
+import android.safetycenter.config.SafetyCenterConfig
+import android.safetycenter.config.SafetySource
+import android.safetycenter.config.SafetySourcesGroup
 import androidx.test.core.app.ApplicationProvider.getApplicationContext
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SdkSuppress
@@ -59,13 +64,12 @@
 class SafetyCenterManagerTest {
     private val context: Context = getApplicationContext()
     private val safetyCenterManager = context.getSystemService(SafetyCenterManager::class.java)!!
-    private val sourceId = "source_id"
     private val somePendingIntent = PendingIntent.getActivity(
         context, 0 /* requestCode */,
         Intent(ACTION_SAFETY_CENTER).addFlags(FLAG_ACTIVITY_NEW_TASK),
         FLAG_IMMUTABLE
     )
-    private val safetySourceDataOnPageOpen = SafetySourceData.Builder(sourceId)
+    private val safetySourceDataOnPageOpen = SafetySourceData.Builder()
         .setStatus(
             SafetySourceStatus.Builder(
                 "safetySourceDataOnPageOpen status title",
@@ -76,7 +80,7 @@
                 .build()
         )
         .build()
-    private val safetySourceDataOnRescanClick = SafetySourceData.Builder(sourceId)
+    private val safetySourceDataOnRescanClick = SafetySourceData.Builder()
         .setStatus(
             SafetySourceStatus.Builder(
                 "safetySourceDataOnRescanClick status title",
@@ -100,51 +104,57 @@
     @After
     fun clearDataBetweenTest() {
         safetyCenterManager.removeOnSafetyCenterDataChangedListenerWithPermission(listener)
-        safetyCenterManager.clearDataWithPermission()
+        safetyCenterManager.clearAllSafetySourceDataWithPermission()
         SafetySourceBroadcastReceiver.reset()
     }
 
     @Before
-    fun addAdditionalSafetySourcesBeforeTest() {
-        safetyCenterManager.clearAdditionalSafetySourcesWithPermission()
-        safetyCenterManager.addAdditionalSafetySourceWithPermission(
-            sourceId, CTS_PACKAGE_NAME,
-            CTS_BROADCAST_RECEIVER_NAME
-        )
+    fun setSafetyCenterConfigOverrideBeforeTest() {
+        safetyCenterManager.clearSafetyCenterConfigOverrideWithPermission()
+        // TODO(b/217944317): When the test API impl is finalized to override XML config, only
+        //  override config in select test cases that require it. This is to ensure that we do have
+        //  some test cases running with the XML config.
+        safetyCenterManager.setSafetyCenterConfigOverrideWithPermission(CTS_ONLY_CONFIG)
     }
 
     @After
-    fun clearAdditionalSafetySourcesAfterTest() {
-        safetyCenterManager.clearAdditionalSafetySourcesWithPermission()
+    fun clearSafetyCenterConfigOverrideAfterTest() {
+        safetyCenterManager.clearSafetyCenterConfigOverrideWithPermission()
     }
 
     @Test
-    fun getLastSafetyCenterUpdate_noUpdate_returnsNull() {
-        val lastSafetyCenterUpdate =
-            safetyCenterManager.getLastUpdateWithPermission("some_unknown_id")
+    fun getSafetySourceData_notSet_returnsNull() {
+        val safetySourceData =
+            safetyCenterManager.getSafetySourceDataWithPermission("some_unknown_id")
 
-        assertThat(lastSafetyCenterUpdate).isNull()
+        assertThat(safetySourceData).isNull()
     }
 
     @Test
-    fun sendSafetyCenterUpdate_getLastSafetyCenterUpdateReturnsNewValue() {
-        val id = "some_known_id"
-        val safetyCenterUpdate = SafetySourceData.Builder(id).build()
-        safetyCenterManager.sendUpdateWithPermission(safetyCenterUpdate)
+    fun setSafetySourceData_getSafetySourceDataReturnsNewValue() {
+        val safetySourceData = SafetySourceData.Builder().build()
+        safetyCenterManager.setSafetySourceDataWithPermission(
+                CTS_SOURCE_ID,
+                safetySourceData,
+                EVENT_SOURCE_STATE_CHANGED
+        )
 
-        val lastSafetyCenterUpdate =
-            safetyCenterManager.getLastUpdateWithPermission(id)
+        val safetySourceDataResult =
+                safetyCenterManager.getSafetySourceDataWithPermission(CTS_SOURCE_ID)
 
-        assertThat(lastSafetyCenterUpdate).isEqualTo(safetyCenterUpdate)
+        assertThat(safetySourceDataResult).isEqualTo(safetySourceData)
     }
 
     @Test
-    fun sendSafetyCenterUpdate_withSameId_replacesValue() {
-        val id = "some_known_id"
-        val firstSafetyCenterUpdate = SafetySourceData.Builder(id).build()
-        safetyCenterManager.sendUpdateWithPermission(firstSafetyCenterUpdate)
+    fun setSafetySourceData_withSameId_replacesValue() {
+        val firstSafetySourceData = SafetySourceData.Builder().build()
+        safetyCenterManager.setSafetySourceDataWithPermission(
+                CTS_SOURCE_ID,
+                firstSafetySourceData,
+                EVENT_SOURCE_STATE_CHANGED
+        )
 
-        val secondSafetyCenterUpdate = SafetySourceData.Builder(id).setStatus(
+        val secondSafetySourceData = SafetySourceData.Builder().setStatus(
             SafetySourceStatus.Builder(
                 "Status title", "Summary of the status", STATUS_LEVEL_CRITICAL_WARNING,
                 somePendingIntent
@@ -163,12 +173,15 @@
                     ).build()
                 ).build()
         ).build()
-        safetyCenterManager.sendUpdateWithPermission(secondSafetyCenterUpdate)
+        safetyCenterManager.setSafetySourceDataWithPermission(
+                CTS_SOURCE_ID,
+                secondSafetySourceData,
+                EVENT_SOURCE_STATE_CHANGED
+        )
 
-        val lastSafetyCenterUpdate =
-            safetyCenterManager.getLastUpdateWithPermission(id)
+        val safetySourceData = safetyCenterManager.getSafetySourceDataWithPermission(CTS_SOURCE_ID)
 
-        assertThat(lastSafetyCenterUpdate).isEqualTo(secondSafetyCenterUpdate)
+        assertThat(safetySourceData).isEqualTo(secondSafetySourceData)
     }
 
     @Test
@@ -186,8 +199,7 @@
             )
         }
 
-        val isSafetyCenterEnabled =
-            safetyCenterManager.isSafetyCenterEnabledWithPermission()
+        val isSafetyCenterEnabled = safetyCenterManager.isSafetyCenterEnabledWithPermission()
 
         assertThat(isSafetyCenterEnabled).isTrue()
     }
@@ -207,8 +219,7 @@
             )
         }
 
-        val isSafetyCenterEnabled =
-            safetyCenterManager.isSafetyCenterEnabledWithPermission()
+        val isSafetyCenterEnabled = safetyCenterManager.isSafetyCenterEnabledWithPermission()
 
         assertThat(isSafetyCenterEnabled).isFalse()
     }
@@ -228,8 +239,7 @@
             )
         }
 
-        val isSafetyCenterEnabled =
-            safetyCenterManager.isSafetyCenterEnabledWithPermission()
+        val isSafetyCenterEnabled = safetyCenterManager.isSafetyCenterEnabledWithPermission()
 
         assertThat(isSafetyCenterEnabled).isFalse()
     }
@@ -249,8 +259,7 @@
             )
         }
 
-        val isSafetyCenterEnabled =
-            safetyCenterManager.isSafetyCenterEnabledWithPermission()
+        val isSafetyCenterEnabled = safetyCenterManager.isSafetyCenterEnabledWithPermission()
 
         assertThat(isSafetyCenterEnabled).isFalse()
     }
@@ -271,6 +280,7 @@
 
     @Test
     fun refreshSafetySources_whenReceiverDoesNotHaveSendingPermission_sourceDoesNotSendData() {
+        SafetySourceBroadcastReceiver.safetySourceId = CTS_SOURCE_ID
         SafetySourceBroadcastReceiver.safetySourceDataOnRescanClick = safetySourceDataOnRescanClick
 
         safetyCenterManager.refreshSafetySourcesWithPermission(
@@ -280,39 +290,40 @@
         assertFailsWith(TimeoutCancellationException::class) {
             SafetySourceBroadcastReceiver.waitTillOnReceiveComplete(TIMEOUT_SHORT)
         }
-        val lastSafetyCenterUpdate =
-            safetyCenterManager.getLastUpdateWithPermission(sourceId)
-        assertThat(lastSafetyCenterUpdate).isNull()
+        val safetySourceData =
+            safetyCenterManager.getSafetySourceDataWithPermission(CTS_SOURCE_ID)
+        assertThat(safetySourceData).isNull()
     }
 
     @Test
     fun refreshSafetySources_withRefreshReasonRescanButtonClick_sourceSendsRescanData() {
+        SafetySourceBroadcastReceiver.safetySourceId = CTS_SOURCE_ID
         SafetySourceBroadcastReceiver.safetySourceDataOnRescanClick = safetySourceDataOnRescanClick
 
         safetyCenterManager.refreshSafetySourcesWithReceiverPermissionAndWait(
             REFRESH_REASON_RESCAN_BUTTON_CLICK
         )
 
-        val lastSafetyCenterUpdate =
-            safetyCenterManager.getLastUpdateWithPermission(sourceId)
-        assertThat(lastSafetyCenterUpdate).isEqualTo(safetySourceDataOnRescanClick)
+        val safetySourceData = safetyCenterManager.getSafetySourceDataWithPermission(CTS_SOURCE_ID)
+        assertThat(safetySourceData).isEqualTo(safetySourceDataOnRescanClick)
     }
 
     @Test
     fun refreshSafetySources_withRefreshReasonPageOpen_sourceSendsPageOpenData() {
+        SafetySourceBroadcastReceiver.safetySourceId = CTS_SOURCE_ID
         SafetySourceBroadcastReceiver.safetySourceDataOnPageOpen = safetySourceDataOnPageOpen
 
         safetyCenterManager.refreshSafetySourcesWithReceiverPermissionAndWait(
             REFRESH_REASON_PAGE_OPEN
         )
 
-        val lastSafetyCenterUpdate =
-            safetyCenterManager.getLastUpdateWithPermission(sourceId)
-        assertThat(lastSafetyCenterUpdate).isEqualTo(safetySourceDataOnPageOpen)
+        val safetySourceData = safetyCenterManager.getSafetySourceDataWithPermission(CTS_SOURCE_ID)
+        assertThat(safetySourceData).isEqualTo(safetySourceDataOnPageOpen)
     }
 
     @Test
     fun refreshSafetySources_withInvalidRefreshSeason_throwsIllegalArgumentException() {
+        SafetySourceBroadcastReceiver.safetySourceId = CTS_SOURCE_ID
         SafetySourceBroadcastReceiver.safetySourceDataOnPageOpen = safetySourceDataOnPageOpen
         SafetySourceBroadcastReceiver.safetySourceDataOnRescanClick = safetySourceDataOnRescanClick
 
@@ -348,16 +359,19 @@
     }
 
     @Test
-    fun addOnSafetyCenterDataChangedListener_listenerCalledOnSafetyCenterUpdate() {
+    fun addOnSafetyCenterDataChangedListener_listenerCalledOnSafetySourceData() {
         safetyCenterManager.addOnSafetyCenterDataChangedListenerWithPermission(
             directExecutor(), listener
         )
         // Receive initial data.
         receiveListenerUpdate()
 
-        val id = "some_known_id"
-        val safetyCenterUpdate = SafetySourceData.Builder(id).build()
-        safetyCenterManager.sendUpdateWithPermission(safetyCenterUpdate)
+        val safetySourceData = SafetySourceData.Builder().build()
+        safetyCenterManager.setSafetySourceDataWithPermission(
+                CTS_SOURCE_ID,
+                safetySourceData,
+                EVENT_SOURCE_STATE_CHANGED
+        )
         val safetyCenterDataFromListener = receiveListenerUpdate()
 
         // TODO(b/218830137): Assert on content.
@@ -365,7 +379,7 @@
     }
 
     @Test
-    fun removeOnSafetyCenterDataChangedListener_listenerNotCalledOnSafetyCenterUpdate() {
+    fun removeOnSafetyCenterDataChangedListener_listenerNotCalledOnSafetySourceData() {
         safetyCenterManager.addOnSafetyCenterDataChangedListenerWithPermission(
             directExecutor(), listener
         )
@@ -373,9 +387,12 @@
         receiveListenerUpdate()
 
         safetyCenterManager.removeOnSafetyCenterDataChangedListenerWithPermission(listener)
-        val id = "some_known_id"
-        val safetyCenterUpdate = SafetySourceData.Builder(id).build()
-        safetyCenterManager.sendUpdateWithPermission(safetyCenterUpdate)
+        val safetySourceData = SafetySourceData.Builder().build()
+        safetyCenterManager.setSafetySourceDataWithPermission(
+                CTS_SOURCE_ID,
+                safetySourceData,
+                EVENT_SOURCE_STATE_CHANGED
+        )
 
         assertFailsWith(TimeoutCancellationException::class) {
             receiveListenerUpdate(TIMEOUT_SHORT)
@@ -454,5 +471,28 @@
             "android.safetycenter.cts.SafetySourceBroadcastReceiver"
         private val TIMEOUT_LONG: Duration = Duration.ofMillis(5000)
         private val TIMEOUT_SHORT: Duration = Duration.ofMillis(1000)
+        private val EVENT_SOURCE_STATE_CHANGED =
+                SafetyEvent.Builder(SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED).build()
+        private const val CTS_SOURCE_ID = "cts_source_id"
+        // TODO(b/217944317): Consider moving the following to a file where they can be used by
+        //  other tests.
+        private val CTS_SOURCE = SafetySource.Builder(SafetySource.SAFETY_SOURCE_TYPE_DYNAMIC)
+                .setId(CTS_SOURCE_ID)
+                .setPackageName(CTS_PACKAGE_NAME)
+                .setTitleResId(R.string.reference)
+                .setSummaryResId(R.string.reference)
+                .setIntentAction("SafetyCenterManagerTest.INTENT_ACTION")
+                .setBroadcastReceiverClassName(CTS_BROADCAST_RECEIVER_NAME)
+                .setProfile(SafetySource.PROFILE_PRIMARY)
+                .build()
+        private val CTS_SOURCE_GROUP = SafetySourcesGroup.Builder()
+                .setId("cts_source_group")
+                .setTitleResId(R.string.reference)
+                .setSummaryResId(R.string.reference)
+                .addSafetySource(CTS_SOURCE)
+                .build()
+        private val CTS_ONLY_CONFIG = SafetyCenterConfig.Builder()
+                .addSafetySourcesGroup(CTS_SOURCE_GROUP)
+                .build()
     }
 }
diff --git a/tests/tests/safetycenter/src/android/safetycenter/cts/SafetyEventTest.kt b/tests/tests/safetycenter/src/android/safetycenter/cts/SafetyEventTest.kt
new file mode 100644
index 0000000..bc9d538
--- /dev/null
+++ b/tests/tests/safetycenter/src/android/safetycenter/cts/SafetyEventTest.kt
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.safetycenter.cts
+
+import android.os.Build
+import android.safetycenter.SafetyEvent
+import android.safetycenter.SafetyEvent.SAFETY_EVENT_TYPE_REFRESH_REQUESTED
+import android.safetycenter.SafetyEvent.SAFETY_EVENT_TYPE_DEVICE_REBOOTED
+import android.safetycenter.SafetyEvent.SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED
+import android.safetycenter.SafetyEvent.SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED
+import android.safetycenter.testers.AnyTester.assertThatRepresentationsAreEqual
+import android.safetycenter.testers.AnyTester.assertThatRepresentationsAreNotEqual
+import android.safetycenter.testers.ParcelableTester.assertThatRoundTripReturnsOriginal
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/** CTS tests for [SafetyEvent]. */
+@RunWith(AndroidJUnit4::class)
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU, codeName = "Tiramisu")
+class SafetyEventTest {
+    @Test
+    fun getSafetyEventType_returnsSafetyEventType() {
+        val safetyEvent = SafetyEvent.Builder(SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED).build()
+
+        assertThat(safetyEvent.safetyEventType).isEqualTo(SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED)
+    }
+
+    @Test
+    fun getRefreshBroadcastId_returnsRefreshBroadcastId() {
+        val safetyEvent =
+                SafetyEvent.Builder(SAFETY_EVENT_TYPE_REFRESH_REQUESTED)
+                        .setRefreshBroadcastId(REFRESH_BROADCAST_ID)
+                        .build()
+
+        assertThat(safetyEvent.refreshBroadcastId).isEqualTo(REFRESH_BROADCAST_ID)
+    }
+
+    @Test
+    fun getSafetySourceIssueId_returnsSafetySourceIssueId() {
+        val safetyEvent =
+                SafetyEvent.Builder(SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED)
+                        .setSafetySourceIssueId(SAFETY_SOURCE_ISSUE_ID)
+                        .build()
+
+        assertThat(safetyEvent.safetySourceIssueId).isEqualTo(SAFETY_SOURCE_ISSUE_ID)
+    }
+
+    @Test
+    fun getSafetySourceIssueActionId_returnsSafetySourceIssueActionId() {
+        val safetyEvent =
+                SafetyEvent.Builder(SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED)
+                        .setSafetySourceIssueActionId(SAFETY_SOURCE_ISSUE_ACTION_ID)
+                        .build()
+
+        assertThat(safetyEvent.safetySourceIssueActionId).isEqualTo(SAFETY_SOURCE_ISSUE_ACTION_ID)
+    }
+
+    @Test
+    fun describeContents_returns0() {
+        val safetyEvent =
+                SafetyEvent.Builder(SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED)
+                        .setSafetySourceIssueId(SAFETY_SOURCE_ISSUE_ID)
+                        .setSafetySourceIssueActionId(SAFETY_SOURCE_ISSUE_ACTION_ID)
+                        .build()
+
+        assertThat(safetyEvent.describeContents()).isEqualTo(0)
+    }
+
+    @Test
+    fun createFromParcel_withWriteToParcel_returnsOriginalSafetySourceData() {
+        val safetyEvent =
+                SafetyEvent.Builder(SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED)
+                        .setSafetySourceIssueId(SAFETY_SOURCE_ISSUE_ID)
+                        .setSafetySourceIssueActionId(SAFETY_SOURCE_ISSUE_ACTION_ID)
+                        .build()
+
+        assertThatRoundTripReturnsOriginal(safetyEvent, SafetyEvent.CREATOR)
+    }
+
+    // TODO(b/208473675): Use `EqualsTester` for testing `hashcode` and `equals`.
+    @Test
+    fun hashCode_equals_toString_withEqualByReference_areEqual() {
+        val safetyEvent =
+                SafetyEvent.Builder(SAFETY_EVENT_TYPE_REFRESH_REQUESTED)
+                        .setRefreshBroadcastId(REFRESH_BROADCAST_ID)
+                        .build()
+        val otherSafetyEvent = safetyEvent
+
+        assertThatRepresentationsAreEqual(safetyEvent, otherSafetyEvent)
+    }
+
+    @Test
+    fun hashCode_equals_toString_withAllFieldsEqual_areEqual() {
+        val safetyEvent =
+                SafetyEvent.Builder(SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED)
+                        .setSafetySourceIssueId(SAFETY_SOURCE_ISSUE_ID)
+                        .setSafetySourceIssueActionId(SAFETY_SOURCE_ISSUE_ACTION_ID)
+                        .build()
+        val otherSafetyEvent =
+                SafetyEvent.Builder(SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED)
+                        .setSafetySourceIssueId(SAFETY_SOURCE_ISSUE_ID)
+                        .setSafetySourceIssueActionId(SAFETY_SOURCE_ISSUE_ACTION_ID)
+                        .build()
+
+        assertThatRepresentationsAreEqual(safetyEvent, otherSafetyEvent)
+    }
+
+    @Test
+    fun hashCode_equals_toString_withDifferentSafetyEventTypes_areNotEqual() {
+        val safetyEvent =
+                SafetyEvent.Builder(SAFETY_EVENT_TYPE_REFRESH_REQUESTED)
+                        .build()
+        val otherSafetyEvent =
+                SafetyEvent.Builder(SAFETY_EVENT_TYPE_DEVICE_REBOOTED)
+                        .build()
+
+        assertThatRepresentationsAreNotEqual(safetyEvent, otherSafetyEvent)
+    }
+
+    @Test
+    fun hashCode_equals_toString_withDifferentRefreshBroadcastIds_areNotEqual() {
+        val safetyEvent =
+                SafetyEvent.Builder(SAFETY_EVENT_TYPE_REFRESH_REQUESTED)
+                        .setRefreshBroadcastId(REFRESH_BROADCAST_ID)
+                        .build()
+        val otherSafetyEvent =
+                SafetyEvent.Builder(SAFETY_EVENT_TYPE_REFRESH_REQUESTED)
+                        .setRefreshBroadcastId(OTHER_REFRESH_BROADCAST_ID)
+                        .build()
+
+        assertThatRepresentationsAreNotEqual(safetyEvent, otherSafetyEvent)
+    }
+
+    @Test
+    fun hashCode_equals_toString_withDifferentIssueIds_areNotEqual() {
+        val safetyEvent =
+                SafetyEvent.Builder(SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED)
+                        .setSafetySourceIssueId(SAFETY_SOURCE_ISSUE_ID)
+                        .build()
+        val otherSafetyEvent =
+                SafetyEvent.Builder(SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED)
+                        .setSafetySourceIssueId(OTHER_SAFETY_SOURCE_ISSUE_ID)
+                        .build()
+
+        assertThatRepresentationsAreNotEqual(safetyEvent, otherSafetyEvent)
+    }
+
+    @Test
+    fun hashCode_equals_toString_withDifferentActionIds_areNotEqual() {
+        val safetyEvent =
+                SafetyEvent.Builder(SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED)
+                        .setSafetySourceIssueId(SAFETY_SOURCE_ISSUE_ID)
+                        .setSafetySourceIssueActionId(SAFETY_SOURCE_ISSUE_ACTION_ID)
+                        .build()
+        val otherSafetyEvent =
+                SafetyEvent.Builder(SAFETY_EVENT_TYPE_RESOLVING_ACTION_FAILED)
+                        .setSafetySourceIssueId(SAFETY_SOURCE_ISSUE_ID)
+                        .setSafetySourceIssueActionId(OTHER_SAFETY_SOURCE_ISSUE_ACTION_ID)
+                        .build()
+
+        assertThatRepresentationsAreNotEqual(safetyEvent, otherSafetyEvent)
+    }
+
+    companion object {
+        const val REFRESH_BROADCAST_ID = "refresh_broadcast_id"
+        const val OTHER_REFRESH_BROADCAST_ID = "other_refresh_broadcast_id"
+        const val SAFETY_SOURCE_ISSUE_ID = "safety_source_issue_id"
+        const val OTHER_SAFETY_SOURCE_ISSUE_ID = "other_safety_source_issue_id"
+        const val SAFETY_SOURCE_ISSUE_ACTION_ID = "safety_source_issue_action_id"
+        const val OTHER_SAFETY_SOURCE_ISSUE_ACTION_ID = "other_safety_source_issue_action_id"
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/safetycenter/src/android/safetycenter/cts/SafetySourceBroadcastReceiver.kt b/tests/tests/safetycenter/src/android/safetycenter/cts/SafetySourceBroadcastReceiver.kt
index 4924c94..5f8e8b8 100644
--- a/tests/tests/safetycenter/src/android/safetycenter/cts/SafetySourceBroadcastReceiver.kt
+++ b/tests/tests/safetycenter/src/android/safetycenter/cts/SafetySourceBroadcastReceiver.kt
@@ -25,6 +25,8 @@
 import android.safetycenter.SafetyCenterManager.EXTRA_REFRESH_SAFETY_SOURCES_REQUEST_TYPE
 import android.safetycenter.SafetyCenterManager
 import android.safetycenter.SafetySourceData
+import android.safetycenter.SafetyEvent
+import android.safetycenter.SafetyEvent.SAFETY_EVENT_TYPE_REFRESH_REQUESTED
 import kotlinx.coroutines.channels.Channel
 import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.withTimeout
@@ -45,9 +47,17 @@
 
         when (intent.getIntExtra(EXTRA_REFRESH_SAFETY_SOURCES_REQUEST_TYPE, -1)) {
             EXTRA_REFRESH_REQUEST_TYPE_GET_DATA ->
-                safetyCenterManager.sendUpdateWithPermission(safetySourceDataOnPageOpen!!)
+                safetyCenterManager.setSafetySourceDataWithPermission(
+                        safetySourceId!!,
+                        safetySourceDataOnPageOpen!!,
+                        EVENT_REFRESH_REQUESTED
+                )
             EXTRA_REFRESH_REQUEST_TYPE_FETCH_FRESH_DATA ->
-                safetyCenterManager.sendUpdateWithPermission(safetySourceDataOnRescanClick!!)
+                safetyCenterManager.setSafetySourceDataWithPermission(
+                        safetySourceId!!,
+                        safetySourceDataOnRescanClick!!,
+                        EVENT_REFRESH_REQUESTED
+                )
         }
 
         runBlocking {
@@ -57,10 +67,16 @@
 
     companion object {
         private var updateChannel = Channel<Unit>()
+        private val EVENT_REFRESH_REQUESTED =
+                SafetyEvent.Builder(SAFETY_EVENT_TYPE_REFRESH_REQUESTED)
+                        .setRefreshBroadcastId("refresh_id")
+                        .build()
+        var safetySourceId: String? = null
         var safetySourceDataOnPageOpen: SafetySourceData? = null
         var safetySourceDataOnRescanClick: SafetySourceData? = null
 
         fun reset() {
+            safetySourceId = null
             safetySourceDataOnRescanClick = null
             safetySourceDataOnPageOpen = null
             updateChannel = Channel()
diff --git a/tests/tests/safetycenter/src/android/safetycenter/cts/SafetySourceDataTest.kt b/tests/tests/safetycenter/src/android/safetycenter/cts/SafetySourceDataTest.kt
index 5706434..76090bf 100644
--- a/tests/tests/safetycenter/src/android/safetycenter/cts/SafetySourceDataTest.kt
+++ b/tests/tests/safetycenter/src/android/safetycenter/cts/SafetySourceDataTest.kt
@@ -104,22 +104,15 @@
         .build()
 
     @Test
-    fun getId_returnsId() {
-        val safetySourceData = SafetySourceData.Builder("Safety source id").build()
-
-        assertThat(safetySourceData.id).isEqualTo("Safety source id")
-    }
-
-    @Test
     fun getStatus_withDefaultBuilder_returnsNull() {
-        val safetySourceData = SafetySourceData.Builder("Safety source id").build()
+        val safetySourceData = SafetySourceData.Builder().build()
 
         assertThat(safetySourceData.status).isNull()
     }
 
     @Test
     fun getStatus_whenSetExplicitly_returnsStatus() {
-        val safetySourceData = SafetySourceData.Builder("Safety source id")
+        val safetySourceData = SafetySourceData.Builder()
                 .setStatus(status1)
                 .build()
 
@@ -128,14 +121,14 @@
 
     @Test
     fun getIssues_withDefaultBuilder_returnsEmptyList() {
-        val safetySourceData = SafetySourceData.Builder("Safety source id").build()
+        val safetySourceData = SafetySourceData.Builder().build()
 
         assertThat(safetySourceData.issues).isEmpty()
     }
 
     @Test
     fun getIssues_whenSetExplicitly_returnsIssues() {
-        val safetySourceData = SafetySourceData.Builder("Safety source id")
+        val safetySourceData = SafetySourceData.Builder()
                 .addIssue(issue1)
                 .addIssue(issue2)
                 .build()
@@ -145,7 +138,7 @@
 
     @Test
     fun clearIssues_removesAllIssues() {
-        val safetySourceData = SafetySourceData.Builder("Safety source id")
+        val safetySourceData = SafetySourceData.Builder()
             .addIssue(issue1)
             .addIssue(issue2)
             .clearIssues()
@@ -156,7 +149,7 @@
 
     @Test
     fun describeContents_returns0() {
-        val safetySourceData = SafetySourceData.Builder("Safety source id")
+        val safetySourceData = SafetySourceData.Builder()
                 .setStatus(status1)
                 .addIssue(issue1)
                 .addIssue(issue2)
@@ -167,7 +160,7 @@
 
     @Test
     fun createFromParcel_withWriteToParcel_returnsOriginalSafetySourceData() {
-        val safetySourceData = SafetySourceData.Builder("Safety source id")
+        val safetySourceData = SafetySourceData.Builder()
                 .setStatus(status1)
                 .addIssue(issue1)
                 .addIssue(issue2)
@@ -186,7 +179,7 @@
     // TODO(b/208473675): Use `EqualsTester` for testing `hashcode` and `equals`.
     @Test
     fun hashCode_equals_toString_withEqualByReference_withoutStatusAndIssues_areEqual() {
-        val safetySourceData = SafetySourceData.Builder("Safety source id").build()
+        val safetySourceData = SafetySourceData.Builder().build()
         val otherSafetySourceData = safetySourceData
 
         assertThat(safetySourceData.hashCode()).isEqualTo(otherSafetySourceData.hashCode())
@@ -196,7 +189,7 @@
 
     @Test
     fun hashCode_equals_toString_withEqualByReference_withoutIssues_areEqual() {
-        val safetySourceData = SafetySourceData.Builder("Safety source id")
+        val safetySourceData = SafetySourceData.Builder()
                 .setStatus(status1)
                 .build()
         val otherSafetySourceData = safetySourceData
@@ -208,7 +201,7 @@
 
     @Test
     fun hashCode_equals_toString_withEqualByReference_areEqual() {
-        val safetySourceData = SafetySourceData.Builder("Safety source id")
+        val safetySourceData = SafetySourceData.Builder()
                 .setStatus(status1)
                 .addIssue(issue1)
                 .addIssue(issue2)
@@ -222,12 +215,12 @@
 
     @Test
     fun hashCode_equals_toString_withAllFieldsEqual_areEqual() {
-        val safetySourceData = SafetySourceData.Builder("Safety source id")
+        val safetySourceData = SafetySourceData.Builder()
                 .setStatus(status1)
                 .addIssue(issue1)
                 .addIssue(issue2)
                 .build()
-        val otherSafetySourceData = SafetySourceData.Builder("Safety source id")
+        val otherSafetySourceData = SafetySourceData.Builder()
                 .setStatus(status1)
                 .addIssue(issue1)
                 .addIssue(issue2)
@@ -239,27 +232,13 @@
     }
 
     @Test
-    fun hashCode_equals_toString_withDifferentIds_areNotEqual() {
-        val safetySourceData = SafetySourceData.Builder("Safety source id")
-                .setStatus(status1)
-                .build()
-        val otherSafetySourceData = SafetySourceData.Builder("Safety source id 2")
-                .setStatus(status1)
-                .build()
-
-        assertThat(safetySourceData.hashCode()).isNotEqualTo(otherSafetySourceData.hashCode())
-        assertThat(safetySourceData).isNotEqualTo(otherSafetySourceData)
-        assertThat(safetySourceData.toString()).isNotEqualTo(otherSafetySourceData.toString())
-    }
-
-    @Test
     fun hashCode_equals_toString_withDifferentIssues_areNotEqual() {
-        val safetySourceData = SafetySourceData.Builder("Safety source id")
+        val safetySourceData = SafetySourceData.Builder()
                 .setStatus(status1)
                 .addIssue(issue1)
                 .addIssue(issue2)
                 .build()
-        val otherSafetySourceData = SafetySourceData.Builder("Safety source id")
+        val otherSafetySourceData = SafetySourceData.Builder()
                 .setStatus(status2)
                 .addIssue(issue1)
                 .addIssue(issue2)
@@ -272,12 +251,12 @@
 
     @Test
     fun hashCode_equals_toString_withDifferentStatuses_areNotEqual() {
-        val safetySourceData = SafetySourceData.Builder("Safety source id")
+        val safetySourceData = SafetySourceData.Builder()
                 .setStatus(status1)
                 .addIssue(issue1)
                 .addIssue(issue2)
                 .build()
-        val otherSafetySourceData = SafetySourceData.Builder("Safety source id")
+        val otherSafetySourceData = SafetySourceData.Builder()
                 .setStatus(status1)
                 .addIssue(issue1)
                 .build()
@@ -289,10 +268,10 @@
 
     @Test
     fun hashCode_equals_toString_withStatusSetInOneAndNotOther_areNotEqual() {
-        val safetySourceData = SafetySourceData.Builder("Safety source id")
+        val safetySourceData = SafetySourceData.Builder()
                 .setStatus(status1)
                 .build()
-        val otherSafetySourceData = SafetySourceData.Builder("Safety source id").build()
+        val otherSafetySourceData = SafetySourceData.Builder().build()
 
         assertThat(safetySourceData.hashCode()).isNotEqualTo(otherSafetySourceData.hashCode())
         assertThat(safetySourceData).isNotEqualTo(otherSafetySourceData)
@@ -301,12 +280,12 @@
 
     @Test
     fun hashCode_equals_toString_withIssuesSetInOneAndNotOther_areNotEqual() {
-        val safetySourceData = SafetySourceData.Builder("Safety source id")
+        val safetySourceData = SafetySourceData.Builder()
                 .setStatus(status1)
                 .addIssue(issue1)
                 .addIssue(issue2)
                 .build()
-        val otherSafetySourceData = SafetySourceData.Builder("Safety source id")
+        val otherSafetySourceData = SafetySourceData.Builder()
                 .setStatus(status1)
                 .build()
 
diff --git a/tests/tests/safetycenter/src/android/safetycenter/cts/SafetySourceErrorTest.kt b/tests/tests/safetycenter/src/android/safetycenter/cts/SafetySourceErrorTest.kt
index 2dba3c0..0d69f2c 100644
--- a/tests/tests/safetycenter/src/android/safetycenter/cts/SafetySourceErrorTest.kt
+++ b/tests/tests/safetycenter/src/android/safetycenter/cts/SafetySourceErrorTest.kt
@@ -16,107 +16,63 @@
 
 package android.safetycenter.cts
 
-import android.os.Parcel
+import android.os.Build
+import android.safetycenter.SafetyEvent
 import android.safetycenter.SafetySourceError
-import android.safetycenter.SafetySourceError.SOURCE_ERROR_TYPE_ACTION_ERROR
+import android.safetycenter.testers.AnyTester.assertThatRepresentationsAreEqual
+import android.safetycenter.testers.AnyTester.assertThatRepresentationsAreNotEqual
+import android.safetycenter.testers.ParcelableTester.assertThatRoundTripReturnsOriginal
 import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
 
+/** CTS tests for [SafetySourceError]. */
 @RunWith(AndroidJUnit4::class)
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU, codeName = "Tiramisu")
 class SafetySourceErrorTest {
-
-    val actionError1 = SafetySourceError.Builder(SOURCE_ERROR_TYPE_ACTION_ERROR)
-            .setIssueId("issue_id_1")
-            .setActionId("action_id_1")
-            .build()
-    val actionError2 = SafetySourceError.Builder(SOURCE_ERROR_TYPE_ACTION_ERROR)
-            .setIssueId("issue_id_2")
-            .setActionId("action_id_2")
-            .build()
-
     @Test
-    fun getType_returnsType() {
-        assertThat(actionError1.type).isEqualTo(SOURCE_ERROR_TYPE_ACTION_ERROR)
-        assertThat(actionError2.type).isEqualTo(SOURCE_ERROR_TYPE_ACTION_ERROR)
-    }
+    fun getSafetyEvent_returnsSafetyEvent() {
+        val safetySourceError = SafetySourceError(SAFETY_EVENT)
 
-    @Test
-    fun getIssueId_returnsIssueId() {
-        assertThat(actionError1.issueId).isEqualTo("issue_id_1")
-        assertThat(actionError2.issueId).isEqualTo("issue_id_2")
-    }
-
-    @Test
-    fun getActionId_returnsActionId() {
-        assertThat(actionError1.actionId).isEqualTo("action_id_1")
-        assertThat(actionError2.actionId).isEqualTo("action_id_2")
+        assertThat(safetySourceError.safetyEvent).isEqualTo(SAFETY_EVENT)
     }
 
     @Test
     fun createFromParcel_withWriteToParcel_returnsEquivalentObject() {
-        val parcel = Parcel.obtain()
+        val safetySourceError = SafetySourceError(SAFETY_EVENT)
 
-        actionError1.writeToParcel(parcel, /* flags= */ 0)
-        parcel.setDataPosition(0)
-
-        val fromParcel = SafetySourceError.CREATOR.createFromParcel(parcel)
-        parcel.recycle()
-
-        assertThat(fromParcel).isEqualTo(actionError1)
+        assertThatRoundTripReturnsOriginal(safetySourceError, SafetySourceError.CREATOR)
     }
 
     @Test
     fun equals_hashCode_toString_equalByReference_areEqual() {
-        assertThat(actionError1).isEqualTo(actionError1)
-        assertThat(actionError1.hashCode()).isEqualTo(actionError1.hashCode())
-        assertThat(actionError1.toString()).isEqualTo(actionError1.toString())
+        val safetySourceError = SafetySourceError(SAFETY_EVENT)
+
+        assertThatRepresentationsAreEqual(safetySourceError, safetySourceError)
     }
 
     @Test
-    fun equals_hashCode_toString_actionErrors_equalByValue_areEqual() {
-        val actionError = SafetySourceError.Builder(SOURCE_ERROR_TYPE_ACTION_ERROR)
-                .setIssueId("issue_id_1")
-                .setActionId("action_id_1")
-                .build()
-        val equivalentActionError = SafetySourceError.Builder(SOURCE_ERROR_TYPE_ACTION_ERROR)
-                .setIssueId("issue_id_1")
-                .setActionId("action_id_1")
-                .build()
+    fun equals_hashCode_toString_equalByValue_areEqual() {
+        val safetySourceError = SafetySourceError(SAFETY_EVENT)
+        val equivalentSafetySourceError = SafetySourceError(SAFETY_EVENT)
 
-        assertThat(actionError).isEqualTo(equivalentActionError)
-        assertThat(actionError.hashCode()).isEqualTo(equivalentActionError.hashCode())
-        assertThat(actionError.toString()).isEqualTo(equivalentActionError.toString())
+        assertThatRepresentationsAreEqual(safetySourceError, equivalentSafetySourceError)
     }
 
     @Test
-    fun equals_toString_withDifferentIssueIds_areNotEqual() {
-        val actionError = SafetySourceError.Builder(SOURCE_ERROR_TYPE_ACTION_ERROR)
-                .setIssueId("issue_id_1")
-                .setActionId("action_id_1")
-                .build()
-        val differentActionError = SafetySourceError.Builder(SOURCE_ERROR_TYPE_ACTION_ERROR)
-                .setIssueId("issue_id_2")
-                .setActionId("action_id_1")
-                .build()
+    fun equals_toString_withDifferentSafetyEvents_areNotEqual() {
+        val safetySourceError = SafetySourceError(
+                SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED).build())
+        val otherSafetySourceError = SafetySourceError(
+                SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_DEVICE_REBOOTED).build())
 
-        assertThat(actionError).isNotEqualTo(differentActionError)
-        assertThat(actionError.toString()).isNotEqualTo(differentActionError.toString())
+        assertThatRepresentationsAreNotEqual(safetySourceError, otherSafetySourceError)
     }
 
-    @Test
-    fun equals_toString_withDifferentActionIds_areNotEqual() {
-        val actionError = SafetySourceError.Builder(SOURCE_ERROR_TYPE_ACTION_ERROR)
-                .setIssueId("issue_id_1")
-                .setActionId("action_id_1")
-                .build()
-        val differentActionError = SafetySourceError.Builder(SOURCE_ERROR_TYPE_ACTION_ERROR)
-                .setIssueId("issue_id_1")
-                .setActionId("action_id_2")
-                .build()
-
-        assertThat(actionError).isNotEqualTo(differentActionError)
-        assertThat(actionError.toString()).isNotEqualTo(differentActionError.toString())
+    companion object {
+        private val SAFETY_EVENT =
+                SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED).build()
     }
 }
\ No newline at end of file