Add uievent IDs for QS modes dialog interactions & log them
Adds ModesDialogEventLogger to log these enums and injects it into the ModesDialogViewModel and ModesDialogDelegate to log the operations they each control.
Eldar for new UiEvent IDs: https://eldar.corp.google.com/assessments/756078032/drafts/343683331/sections/review
Bug: 356371233
Test: statsd_testdrive to verify logging, ModesDialogEventLoggerTest, ModesDialogDelegateTest, ModesDialogViewModelTest
Flag: android.app.modes_ui
Change-Id: Id8ef339d0cab29e709c94ff86412d3d6b5f21a85
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java
index 2f4b2efe..39a330d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java
@@ -22,6 +22,7 @@
import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
import static android.service.notification.SystemZenRules.getTriggerDescriptionForScheduleEvent;
import static android.service.notification.SystemZenRules.getTriggerDescriptionForScheduleTime;
+import static android.service.notification.SystemZenRules.PACKAGE_ANDROID;
import static android.service.notification.ZenModeConfig.tryParseCountdownConditionId;
import static android.service.notification.ZenModeConfig.tryParseEventConditionId;
import static android.service.notification.ZenModeConfig.tryParseScheduleConditionId;
@@ -129,7 +130,11 @@
}
public static ZenMode manualDndMode(AutomaticZenRule manualRule, boolean isActive) {
- return new ZenMode(MANUAL_DND_MODE_ID, manualRule,
+ // Manual rule is owned by the system, so we set it here
+ AutomaticZenRule manualRuleWithPkg = new AutomaticZenRule.Builder(manualRule)
+ .setPackage(PACKAGE_ANDROID)
+ .build();
+ return new ZenMode(MANUAL_DND_MODE_ID, manualRuleWithPkg,
isActive ? Status.ENABLED_AND_ACTIVE : Status.ENABLED, true);
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeTest.java
index d9fdcc38..f464247 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeTest.java
@@ -19,6 +19,7 @@
import static android.app.NotificationManager.INTERRUPTION_FILTER_ALARMS;
import static android.app.NotificationManager.INTERRUPTION_FILTER_NONE;
import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
+import static android.service.notification.SystemZenRules.PACKAGE_ANDROID;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
@@ -67,6 +68,7 @@
assertThat(manualMode.canEditNameAndIcon()).isFalse();
assertThat(manualMode.canBeDeleted()).isFalse();
assertThat(manualMode.isActive()).isFalse();
+ assertThat(manualMode.getRule().getPackageName()).isEqualTo(PACKAGE_ANDROID);
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModelTest.kt
index bcad7e7b..54b7d25 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModelTest.kt
@@ -23,6 +23,7 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.settingslib.notification.modes.TestModeBuilder
+import com.android.settingslib.notification.modes.ZenMode
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.testDispatcher
@@ -30,6 +31,7 @@
import com.android.systemui.statusbar.policy.data.repository.fakeZenModeRepository
import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor
import com.android.systemui.statusbar.policy.ui.dialog.mockModesDialogDelegate
+import com.android.systemui.statusbar.policy.ui.dialog.mockModesDialogEventLogger
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -40,6 +42,7 @@
import org.junit.runner.RunWith
import org.mockito.Mockito.clearInvocations
import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.times
import org.mockito.kotlin.verify
@SmallTest
@@ -50,9 +53,16 @@
private val repository = kosmos.fakeZenModeRepository
private val interactor = kosmos.zenModeInteractor
private val mockDialogDelegate = kosmos.mockModesDialogDelegate
+ private val mockDialogEventLogger = kosmos.mockModesDialogEventLogger
private val underTest =
- ModesDialogViewModel(context, interactor, kosmos.testDispatcher, mockDialogDelegate)
+ ModesDialogViewModel(
+ context,
+ interactor,
+ kosmos.testDispatcher,
+ mockDialogDelegate,
+ mockDialogEventLogger
+ )
@Test
fun tiles_filtersOutUserDisabledModes() =
@@ -432,4 +442,84 @@
assertThat(intent.extras?.getString(Settings.EXTRA_AUTOMATIC_ZEN_RULE_ID))
.isEqualTo("B")
}
+
+ @Test
+ fun onClick_logsOnOffEvents() =
+ testScope.runTest {
+ val tiles by collectLastValue(underTest.tiles)
+
+ repository.addModes(
+ listOf(
+ TestModeBuilder.MANUAL_DND_ACTIVE,
+ TestModeBuilder()
+ .setId("id1")
+ .setName("Inactive Mode One")
+ .setActive(false)
+ .setManualInvocationAllowed(true)
+ .build(),
+ TestModeBuilder()
+ .setId("id2")
+ .setName("Active Non-Invokable Mode Two") // but can be turned off by tile
+ .setActive(true)
+ .setManualInvocationAllowed(false)
+ .build(),
+ )
+ )
+ runCurrent()
+
+ assertThat(tiles?.size).isEqualTo(3)
+
+ // Trigger onClick for each tile in sequence
+ tiles?.forEach { it.onClick.invoke() }
+ runCurrent()
+
+ val onModeCaptor = argumentCaptor<ZenMode>()
+ val offModeCaptor = argumentCaptor<ZenMode>()
+
+ // manual mode and mode 2 should have turned off
+ verify(mockDialogEventLogger, times(2)).logModeOff(offModeCaptor.capture())
+ val off0 = offModeCaptor.firstValue
+ assertThat(off0.isManualDnd).isTrue()
+
+ val off1 = offModeCaptor.secondValue
+ assertThat(off1.id).isEqualTo("id2")
+
+ // should also have logged turning mode 1 on
+ verify(mockDialogEventLogger).logModeOn(onModeCaptor.capture())
+ val on = onModeCaptor.lastValue
+ assertThat(on.id).isEqualTo("id1")
+ }
+
+ @Test
+ fun onLongClick_logsSettingsEvents() =
+ testScope.runTest {
+ val tiles by collectLastValue(underTest.tiles)
+
+ repository.addModes(
+ listOf(
+ TestModeBuilder.MANUAL_DND_ACTIVE,
+ TestModeBuilder()
+ .setId("id1")
+ .setName("Inactive Mode One")
+ .setActive(false)
+ .setManualInvocationAllowed(true)
+ .build(),
+ )
+ )
+ runCurrent()
+
+ assertThat(tiles?.size).isEqualTo(2)
+ val modeCaptor = argumentCaptor<ZenMode>()
+
+ // long click manual DND and then automatic mode
+ tiles?.forEach { it.onLongClick.invoke() }
+ runCurrent()
+
+ verify(mockDialogEventLogger, times(2)).logModeSettings(modeCaptor.capture())
+ val manualMode = modeCaptor.firstValue
+ assertThat(manualMode.isManualDnd).isTrue()
+
+ val automaticMode = modeCaptor.lastValue
+ assertThat(automaticMode.id).isEqualTo("id1")
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSModesEvent.kt b/packages/SystemUI/src/com/android/systemui/qs/QSModesEvent.kt
new file mode 100644
index 0000000..1891c41
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSModesEvent.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2024 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 com.android.systemui.qs
+
+import com.android.internal.logging.UiEvent
+import com.android.internal.logging.UiEventLogger
+
+/** Events of user interactions with modes from the QS Modes dialog. {@see ModesDialogViewModel} */
+enum class QSModesEvent(private val _id: Int) : UiEventLogger.UiEventEnum {
+ @UiEvent(doc = "User turned manual Do Not Disturb on via modes dialog") QS_MODES_DND_ON(1870),
+ @UiEvent(doc = "User turned manual Do Not Disturb off via modes dialog") QS_MODES_DND_OFF(1871),
+ @UiEvent(doc = "User opened mode settings from the Do Not Disturb tile in the modes dialog")
+ QS_MODES_DND_SETTINGS(1872),
+ @UiEvent(doc = "User turned automatic mode on via modes dialog") QS_MODES_MODE_ON(1873),
+ @UiEvent(doc = "User turned automatic mode off via modes dialog") QS_MODES_MODE_OFF(1874),
+ @UiEvent(doc = "User opened mode settings from a mode tile in the modes dialog")
+ QS_MODES_MODE_SETTINGS(1875),
+ @UiEvent(doc = "User clicked on Settings from the modes dialog") QS_MODES_SETTINGS(1876),
+ @UiEvent(doc = "User clicked on Do Not Disturb tile, opening the time selection dialog")
+ QS_MODES_DURATION_DIALOG(1879);
+
+ override fun getId() = _id
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegate.kt
index 8aa989f..4f7749b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegate.kt
@@ -57,6 +57,7 @@
private val activityStarter: ActivityStarter,
// Using a provider to avoid a circular dependency.
private val viewModel: Provider<ModesDialogViewModel>,
+ private val dialogEventLogger: ModesDialogEventLogger,
@Main private val mainCoroutineContext: CoroutineContext,
) : SystemUIDialog.Delegate {
// NOTE: This should only be accessed/written from the main thread.
@@ -102,7 +103,9 @@
)
}
- private fun openSettings(dialog: SystemUIDialog) {
+ @VisibleForTesting
+ fun openSettings(dialog: SystemUIDialog) {
+ dialogEventLogger.logDialogSettings()
val animationController =
dialogTransitionAnimator.createActivityTransitionController(dialog)
if (animationController == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogEventLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogEventLogger.kt
new file mode 100644
index 0000000..33ed419
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogEventLogger.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2024 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 com.android.systemui.statusbar.policy.ui.dialog
+
+import com.android.internal.logging.UiEventLogger
+import com.android.settingslib.notification.modes.ZenMode
+import com.android.systemui.qs.QSModesEvent
+import javax.inject.Inject
+
+class ModesDialogEventLogger
+@Inject
+constructor(
+ private val uiEventLogger: UiEventLogger,
+) {
+
+ fun logModeOn(mode: ZenMode) {
+ val id =
+ if (mode.isManualDnd) QSModesEvent.QS_MODES_DND_ON else QSModesEvent.QS_MODES_MODE_ON
+ uiEventLogger.log(id, /* uid= */ 0, mode.rule.packageName)
+ }
+
+ fun logModeOff(mode: ZenMode) {
+ val id =
+ if (mode.isManualDnd) QSModesEvent.QS_MODES_DND_OFF else QSModesEvent.QS_MODES_MODE_OFF
+ uiEventLogger.log(id, /* uid= */ 0, mode.rule.packageName)
+ }
+
+ fun logModeSettings(mode: ZenMode) {
+ val id =
+ if (mode.isManualDnd) QSModesEvent.QS_MODES_DND_SETTINGS
+ else QSModesEvent.QS_MODES_MODE_SETTINGS
+ uiEventLogger.log(id, /* uid= */ 0, mode.rule.packageName)
+ }
+
+ fun logOpenDurationDialog(mode: ZenMode) {
+ // should only occur for manual Do Not Disturb.
+ if (!mode.isManualDnd) {
+ return
+ }
+ uiEventLogger.log(QSModesEvent.QS_MODES_DURATION_DIALOG)
+ }
+
+ fun logDialogSettings() {
+ uiEventLogger.log(QSModesEvent.QS_MODES_SETTINGS)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModel.kt
index 44b692f..5772099 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModel.kt
@@ -30,6 +30,7 @@
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.statusbar.policy.domain.interactor.ZenModeInteractor
import com.android.systemui.statusbar.policy.ui.dialog.ModesDialogDelegate
+import com.android.systemui.statusbar.policy.ui.dialog.ModesDialogEventLogger
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.Flow
@@ -49,6 +50,7 @@
zenModeInteractor: ZenModeInteractor,
@Background val bgDispatcher: CoroutineDispatcher,
private val dialogDelegate: ModesDialogDelegate,
+ private val dialogEventLogger: ModesDialogEventLogger,
) {
private val zenDialogMetricsLogger = QSZenModeDialogMetricsLogger(context)
@@ -94,14 +96,17 @@
if (!mode.rule.isEnabled) {
openSettings(mode)
} else if (mode.isActive) {
+ dialogEventLogger.logModeOff(mode)
zenModeInteractor.deactivateMode(mode)
} else {
if (mode.rule.isManualInvocationAllowed) {
if (zenModeInteractor.shouldAskForZenDuration(mode)) {
+ dialogEventLogger.logOpenDurationDialog(mode)
// NOTE: The dialog handles turning on the mode itself.
val dialog = makeZenModeDialog()
dialog.show()
} else {
+ dialogEventLogger.logModeOn(mode)
zenModeInteractor.activateMode(mode)
}
}
@@ -114,6 +119,7 @@
.flowOn(bgDispatcher)
private fun openSettings(mode: ZenMode) {
+ dialogEventLogger.logModeSettings(mode)
val intent: Intent =
Intent(ACTION_AUTOMATIC_ZEN_RULE_SETTINGS)
.putExtra(EXTRA_AUTOMATIC_ZEN_RULE_ID, mode.id)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegateTest.kt
index bf0a39b..06b3b57 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegateTest.kt
@@ -57,6 +57,7 @@
private val activityStarter = kosmos.activityStarter
private val mockDialogTransitionAnimator = kosmos.mockDialogTransitionAnimator
private val mockAnimationController = kosmos.mockActivityTransitionAnimatorController
+ private val mockDialogEventLogger = kosmos.mockModesDialogEventLogger
private lateinit var underTest: ModesDialogDelegate
@Before
@@ -75,6 +76,7 @@
mockDialogTransitionAnimator,
activityStarter,
{ kosmos.modesDialogViewModel },
+ mockDialogEventLogger,
kosmos.mainCoroutineContext,
)
}
@@ -121,4 +123,12 @@
assertThat(underTest.currentDialog).isNull()
}
+
+ @Test
+ fun openSettings_logsEvent() =
+ testScope.runTest {
+ val dialog: SystemUIDialog = mock()
+ underTest.openSettings(dialog)
+ verify(mockDialogEventLogger).logDialogSettings()
+ }
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegateKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegateKosmos.kt
index 99bb479..932e768 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegateKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegateKosmos.kt
@@ -33,6 +33,7 @@
dialogTransitionAnimator,
activityStarter,
{ modesDialogViewModel },
+ modesDialogEventLogger,
mainCoroutineContext,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogEventLoggerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogEventLoggerKosmos.kt
new file mode 100644
index 0000000..24e7a87
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogEventLoggerKosmos.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2024 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 com.android.systemui.statusbar.policy.ui.dialog
+
+import com.android.internal.logging.uiEventLogger
+import com.android.systemui.kosmos.Kosmos
+import org.mockito.kotlin.mock
+
+var Kosmos.modesDialogEventLogger by Kosmos.Fixture { ModesDialogEventLogger(uiEventLogger) }
+var Kosmos.mockModesDialogEventLogger by Kosmos.Fixture { mock<ModesDialogEventLogger>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogEventLoggerTest.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogEventLoggerTest.kt
new file mode 100644
index 0000000..5146f77
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogEventLoggerTest.kt
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2024 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 com.android.systemui.statusbar.policy.ui.dialog
+
+import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.settingslib.notification.modes.TestModeBuilder
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.qs.QSModesEvent
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
[email protected]
+class ModesDialogEventLoggerTest : SysuiTestCase() {
+
+ private val uiEventLogger = UiEventLoggerFake()
+ private val underTest = ModesDialogEventLogger(uiEventLogger)
+
+ @Test
+ fun testLogModeOn_manual() {
+ underTest.logModeOn(TestModeBuilder.MANUAL_DND_INACTIVE)
+
+ assertThat(uiEventLogger.numLogs()).isEqualTo(1)
+ uiEventLogger[0].match(QSModesEvent.QS_MODES_DND_ON, "android")
+ }
+
+ @Test
+ fun testLogModeOff_manual() {
+ underTest.logModeOff(TestModeBuilder.MANUAL_DND_ACTIVE)
+
+ assertThat(uiEventLogger.numLogs()).isEqualTo(1)
+ uiEventLogger[0].match(QSModesEvent.QS_MODES_DND_OFF, "android")
+ }
+
+ @Test
+ fun testLogModeSettings_manual() {
+ underTest.logModeSettings(TestModeBuilder.MANUAL_DND_ACTIVE)
+
+ assertThat(uiEventLogger.numLogs()).isEqualTo(1)
+ uiEventLogger[0].match(QSModesEvent.QS_MODES_DND_SETTINGS, "android")
+ }
+
+ @Test
+ fun testLogModeOn_automatic() {
+ underTest.logModeOn(TestModeBuilder().setActive(true).setPackage("pkg1").build())
+
+ assertThat(uiEventLogger.numLogs()).isEqualTo(1)
+ uiEventLogger[0].match(QSModesEvent.QS_MODES_MODE_ON, "pkg1")
+ }
+
+ @Test
+ fun testLogModeOff_automatic() {
+ underTest.logModeOff(TestModeBuilder().setActive(false).setPackage("pkg2").build())
+
+ assertThat(uiEventLogger.numLogs()).isEqualTo(1)
+ uiEventLogger[0].match(QSModesEvent.QS_MODES_MODE_OFF, "pkg2")
+ }
+
+ @Test
+ fun testLogModeSettings_automatic() {
+ underTest.logModeSettings(TestModeBuilder().setPackage("pkg3").build())
+
+ assertThat(uiEventLogger.numLogs()).isEqualTo(1)
+ uiEventLogger[0].match(QSModesEvent.QS_MODES_MODE_SETTINGS, "pkg3")
+ }
+
+ @Test
+ fun testLogOpenDurationDialog_manual() {
+ underTest.logOpenDurationDialog(TestModeBuilder.MANUAL_DND_INACTIVE)
+
+ assertThat(uiEventLogger.numLogs()).isEqualTo(1)
+ // package not logged for duration dialog as it only applies to manual mode
+ uiEventLogger[0].match(QSModesEvent.QS_MODES_DURATION_DIALOG, null)
+ }
+
+ @Test
+ fun testLogOpenDurationDialog_automatic_doesNotLog() {
+ underTest.logOpenDurationDialog(
+ TestModeBuilder().setActive(false).setPackage("mypkg").build()
+ )
+
+ // ignore calls to open dialog on something other than the manual rule (shouldn't happen)
+ assertThat(uiEventLogger.numLogs()).isEqualTo(0)
+ }
+
+ @Test
+ fun testLogDialogSettings() {
+ underTest.logDialogSettings()
+ assertThat(uiEventLogger.numLogs()).isEqualTo(1)
+ uiEventLogger[0].match(QSModesEvent.QS_MODES_SETTINGS, null)
+ }
+
+ private fun UiEventLoggerFake.FakeUiEvent.match(event: QSModesEvent, modePackage: String?) {
+ assertThat(eventId).isEqualTo(event.id)
+ assertThat(packageName).isEqualTo(modePackage)
+ }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModelKosmos.kt
index 00020f8..3571a73 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModelKosmos.kt
@@ -21,6 +21,7 @@
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor
import com.android.systemui.statusbar.policy.ui.dialog.modesDialogDelegate
+import com.android.systemui.statusbar.policy.ui.dialog.modesDialogEventLogger
import javax.inject.Provider
val Kosmos.modesDialogViewModel: ModesDialogViewModel by
@@ -30,5 +31,6 @@
zenModeInteractor,
testDispatcher,
Provider { modesDialogDelegate }.get(),
+ modesDialogEventLogger,
)
}