summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/volume/CsdWarningDialogTest.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/CsdWarningDialog.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialogPlugin.kt36
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogPluginComponent.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/factory/VolumeDialogPluginComponentFactory.kt26
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/module/VolumeDialogPluginModule.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogCsdWarningInteractor.kt55
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogStateInteractor.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/shared/model/CsdWarningConfigModel.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/shared/model/VolumeDialogCsdWarningModel.kt29
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/shared/model/VolumeDialogStateModel.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogPluginViewModel.kt9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java4
15 files changed, 228 insertions, 32 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/CsdWarningDialogTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/CsdWarningDialogTest.java
index bebf1cfa86e7..ac4ef06cd53a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/CsdWarningDialogTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/CsdWarningDialogTest.java
@@ -18,16 +18,13 @@ package com.android.systemui.volume;
import static android.media.AudioManager.CSD_WARNING_DOSE_REACHED_1X;
import static android.media.AudioManager.CSD_WARNING_DOSE_REPEATED_5X;
-
import static com.google.common.truth.Truth.assertThat;
-
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Intent;
@@ -48,13 +45,12 @@ import com.android.systemui.plugins.VolumeDialog;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;
-import com.google.common.collect.ImmutableList;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.Collections;
import java.util.List;
import java.util.Optional;
@@ -69,8 +65,8 @@ public class CsdWarningDialogTest extends SysuiTestCase {
private CsdWarningDialog mDialog;
private static final String DISMISS_CSD_NOTIFICATION =
"com.android.systemui.volume.DISMISS_CSD_NOTIFICATION";
- private final Optional<ImmutableList<CsdWarningAction>> mEmptyActions =
- Optional.of(ImmutableList.of());
+ private final Optional<List<CsdWarningAction>> mEmptyActions =
+ Optional.of(Collections.emptyList());
@Before
public void setup() {
@@ -84,7 +80,7 @@ public class CsdWarningDialogTest extends SysuiTestCase {
@Test
public void create1XCsdDialogAndWait_sendsNotification() {
- FakeExecutor executor = new FakeExecutor(new FakeSystemClock());
+ FakeExecutor executor = new FakeExecutor(new FakeSystemClock());
// instantiate directly instead of via factory; we don't want executor to be @Background
mDialog = new CsdWarningDialog(CSD_WARNING_DOSE_REACHED_1X, mContext,
mAudioManager, mNotificationManager, executor, null,
@@ -102,7 +98,7 @@ public class CsdWarningDialogTest extends SysuiTestCase {
@Test
public void create5XCsdDialogAndWait_willSendNotification() {
- FakeExecutor executor = new FakeExecutor(new FakeSystemClock());
+ FakeExecutor executor = new FakeExecutor(new FakeSystemClock());
mDialog = new CsdWarningDialog(CSD_WARNING_DOSE_REPEATED_5X, mContext,
mAudioManager, mNotificationManager, executor, null,
mEmptyActions,
@@ -122,7 +118,7 @@ public class CsdWarningDialogTest extends SysuiTestCase {
.setPackage(mContext.getPackageName());
mDialog = new CsdWarningDialog(CSD_WARNING_DOSE_REPEATED_5X, mContext,
mAudioManager, mNotificationManager, executor, null,
- Optional.of(ImmutableList.of(new CsdWarningAction("Undo", undoIntent, false))),
+ Optional.of(List.of(new CsdWarningAction("Undo", undoIntent, false))),
mFakeBroadcastDispatcher);
when(mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC)).thenReturn(25);
@@ -149,7 +145,7 @@ public class CsdWarningDialogTest extends SysuiTestCase {
.setPackage(mContext.getPackageName());
mDialog = new CsdWarningDialog(CSD_WARNING_DOSE_REPEATED_5X, mContext,
mAudioManager, mNotificationManager, executor, null,
- Optional.of(ImmutableList.of(new CsdWarningAction("Undo", undoIntent, false))),
+ Optional.of(List.of(new CsdWarningAction("Undo", undoIntent, false))),
mFakeBroadcastDispatcher);
Intent dismissIntent = new Intent(DISMISS_CSD_NOTIFICATION)
.setPackage(mContext.getPackageName());
diff --git a/packages/SystemUI/src/com/android/systemui/volume/CsdWarningDialog.java b/packages/SystemUI/src/com/android/systemui/volume/CsdWarningDialog.java
index a63660ba2804..5c439262b02c 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/CsdWarningDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/CsdWarningDialog.java
@@ -46,14 +46,13 @@ import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.util.NotificationChannels;
import com.android.systemui.util.concurrency.DelayableExecutor;
-import com.google.common.collect.ImmutableList;
+import java.util.List;
+import java.util.Optional;
import dagger.assisted.Assisted;
import dagger.assisted.AssistedFactory;
import dagger.assisted.AssistedInject;
-import java.util.Optional;
-
/**
* A class that implements the three Computed Sound Dose-related warnings defined in
* {@link AudioManager}:
@@ -108,7 +107,7 @@ public class CsdWarningDialog extends SystemUIDialog
private long mShowTime;
@VisibleForTesting public int mCachedMediaStreamVolume;
- private Optional<ImmutableList<CsdWarningAction>> mActionIntents;
+ private Optional<List<CsdWarningAction>> mActionIntents;
private final BroadcastDispatcher mBroadcastDispatcher;
/**
@@ -120,7 +119,7 @@ public class CsdWarningDialog extends SystemUIDialog
CsdWarningDialog create(
int csdWarning,
Runnable onCleanup,
- Optional<ImmutableList<CsdWarningAction>> actionIntents);
+ Optional<List<CsdWarningAction>> actionIntents);
}
@AssistedInject
@@ -131,7 +130,7 @@ public class CsdWarningDialog extends SystemUIDialog
NotificationManager notificationManager,
@Background DelayableExecutor delayableExecutor,
@Assisted Runnable onCleanup,
- @Assisted Optional<ImmutableList<CsdWarningAction>> actionIntents,
+ @Assisted Optional<List<CsdWarningAction>> actionIntents,
BroadcastDispatcher broadcastDispatcher) {
super(context);
mCsdWarning = csdWarning;
@@ -350,7 +349,7 @@ public class CsdWarningDialog extends SystemUIDialog
if (Flags.sounddoseCustomization()
&& mActionIntents.isPresent()
&& !mActionIntents.get().isEmpty()) {
- ImmutableList<CsdWarningAction> actionIntentsList = mActionIntents.get();
+ List<CsdWarningAction> actionIntentsList = mActionIntents.get();
for (CsdWarningAction action : actionIntentsList) {
if (action.getLabel() == null || action.getIntent() == null) {
Log.w(TAG, "Null action intent received. Skipping addition to notification");
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index a4e46f667329..ae063b416dca 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -31,7 +31,6 @@ import static android.view.View.INVISIBLE;
import static android.view.View.LAYOUT_DIRECTION_RTL;
import static android.view.View.VISIBLE;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
-
import static com.android.internal.jank.InteractionJankMonitor.CUJ_VOLUME_CONTROL;
import static com.android.internal.jank.InteractionJankMonitor.Configuration.Builder;
import static com.android.settingslib.flags.Flags.audioSharingDeveloperOption;
@@ -144,18 +143,17 @@ import com.android.systemui.volume.domain.interactor.VolumeDialogInteractor;
import com.android.systemui.volume.domain.interactor.VolumePanelNavigationInteractor;
import com.android.systemui.volume.panel.shared.flag.VolumePanelFlag;
import com.android.systemui.volume.ui.navigation.VolumeNavigator;
-
import com.google.android.msdl.domain.MSDLPlayer;
-import com.google.common.collect.ImmutableList;
-
-import dagger.Lazy;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
+import dagger.Lazy;
+
/**
* Visual presentation of the volume dialog.
*
@@ -326,8 +324,8 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
private final VolumePanelFlag mVolumePanelFlag;
private final VolumeDialogInteractor mInteractor;
// Optional actions for soundDose
- private Optional<ImmutableList<CsdWarningAction>>
- mCsdWarningNotificationActions = Optional.of(ImmutableList.of());
+ private Optional<List<CsdWarningAction>>
+ mCsdWarningNotificationActions = Optional.of(Collections.emptyList());
public VolumeDialogImpl(
Context context,
@@ -2237,7 +2235,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
}
public void setCsdWarningNotificationActionIntents(
- ImmutableList<CsdWarningAction> actionIntent) {
+ List<CsdWarningAction> actionIntent) {
mCsdWarningNotificationActions = Optional.of(actionIntent);
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java b/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
index 2009143859d3..94964bbafbd6 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
@@ -43,13 +43,13 @@ import com.android.systemui.volume.VolumePanelDialogReceiver;
import com.android.systemui.volume.VolumeUI;
import com.android.systemui.volume.dialog.VolumeDialogPlugin;
import com.android.systemui.volume.dialog.dagger.VolumeDialogPluginComponent;
+import com.android.systemui.volume.dialog.dagger.factory.VolumeDialogPluginComponentFactory;
import com.android.systemui.volume.domain.interactor.VolumeDialogInteractor;
import com.android.systemui.volume.domain.interactor.VolumePanelNavigationInteractor;
import com.android.systemui.volume.panel.dagger.VolumePanelComponent;
import com.android.systemui.volume.panel.dagger.factory.VolumePanelComponentFactory;
import com.android.systemui.volume.panel.shared.flag.VolumePanelFlag;
import com.android.systemui.volume.ui.navigation.VolumeNavigator;
-
import com.google.android.msdl.domain.MSDLPlayer;
import dagger.Binds;
@@ -104,6 +104,10 @@ public interface VolumeModule {
@Binds
VolumePanelComponentFactory bindVolumePanelComponentFactory(VolumePanelComponent.Factory impl);
+ @Binds
+ VolumeDialogPluginComponentFactory bindVolumeDialogPluginComponentFactory(
+ VolumeDialogPluginComponent.Factory impl);
+
/** */
@Provides
static VolumeDialog provideVolumeDialog(
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialogPlugin.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialogPlugin.kt
index 5a69be5486a0..938e313771ad 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialogPlugin.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialogPlugin.kt
@@ -22,9 +22,13 @@ import com.android.app.tracing.coroutines.coroutineScopeTraced
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.plugins.VolumeDialog
+import com.android.systemui.volume.CsdWarningAction
+import com.android.systemui.volume.CsdWarningDialog
import com.android.systemui.volume.SafetyWarningDialog
import com.android.systemui.volume.dialog.dagger.VolumeDialogPluginComponent
+import com.android.systemui.volume.dialog.dagger.factory.VolumeDialogPluginComponentFactory
import com.android.systemui.volume.dialog.ui.viewmodel.VolumeDialogPluginViewModel
+import java.util.Optional
import javax.inject.Inject
import kotlin.coroutines.resume
import kotlinx.coroutines.CoroutineScope
@@ -39,7 +43,8 @@ constructor(
@Application private val applicationCoroutineScope: CoroutineScope,
private val context: Context,
private val audioManager: AudioManager,
- private val volumeDialogPluginComponentFactory: VolumeDialogPluginComponent.Factory,
+ private val volumeDialogPluginComponentFactory: VolumeDialogPluginComponentFactory,
+ private val csdWarningDialogFactory: CsdWarningDialog.Factory,
) : VolumeDialog {
private var job: Job? = null
@@ -67,6 +72,16 @@ constructor(
}
}
.launchIn(this)
+
+ viewModel.csdWarning
+ .mapLatest { csdWarning ->
+ if (csdWarning != null) {
+ showCsdWarningDialog(csdWarning, viewModel.csdWarningConfigModel.actions) {
+ viewModel.onCsdWarningDismissed()
+ }
+ }
+ }
+ .launchIn(this)
}
override fun destroy() {
@@ -86,4 +101,23 @@ constructor(
dialog.show()
continuation.invokeOnCancellation { dialog.dismiss() }
}
+
+ private suspend fun showCsdWarningDialog(
+ warning: Int,
+ actions: List<CsdWarningAction>,
+ onDismissed: () -> Unit,
+ ) = suspendCancellableCoroutine { continuation ->
+ val dialog =
+ csdWarningDialogFactory.create(
+ warning,
+ {
+ onDismissed()
+ continuation.resume(Unit)
+ },
+ Optional.of(actions),
+ )
+
+ dialog.show()
+ continuation.invokeOnCancellation { dialog.dismiss() }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogPluginComponent.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogPluginComponent.kt
index 4e0098ccdf99..f0fe4a3b7ffd 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogPluginComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogPluginComponent.kt
@@ -16,6 +16,7 @@
package com.android.systemui.volume.dialog.dagger
+import com.android.systemui.volume.dialog.dagger.factory.VolumeDialogPluginComponentFactory
import com.android.systemui.volume.dialog.dagger.module.VolumeDialogPluginModule
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogPlugin
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogPluginScope
@@ -35,9 +36,9 @@ interface VolumeDialogPluginComponent {
fun viewModel(): VolumeDialogPluginViewModel
@Subcomponent.Factory
- interface Factory {
+ interface Factory : VolumeDialogPluginComponentFactory {
- fun create(
+ override fun create(
@BindsInstance @VolumeDialogPlugin scope: CoroutineScope
): VolumeDialogPluginComponent
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/factory/VolumeDialogPluginComponentFactory.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/factory/VolumeDialogPluginComponentFactory.kt
new file mode 100644
index 000000000000..8edccd525f68
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/factory/VolumeDialogPluginComponentFactory.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2025 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.volume.dialog.dagger.factory
+
+import com.android.systemui.volume.dialog.dagger.VolumeDialogPluginComponent
+import kotlinx.coroutines.CoroutineScope
+
+/** Common interface for all dagger Subcomponent.Factory providing [VolumeDialogPluginComponent]. */
+interface VolumeDialogPluginComponentFactory {
+
+ fun create(scope: CoroutineScope): VolumeDialogPluginComponent
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/module/VolumeDialogPluginModule.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/module/VolumeDialogPluginModule.kt
index cd8cdc8573bd..547c51d1cefd 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/module/VolumeDialogPluginModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/module/VolumeDialogPluginModule.kt
@@ -17,13 +17,22 @@
package com.android.systemui.volume.dialog.dagger.module
import com.android.systemui.volume.dialog.dagger.VolumeDialogComponent
+import com.android.systemui.volume.dialog.shared.model.CsdWarningConfigModel
import com.android.systemui.volume.dialog.utils.VolumeTracer
import com.android.systemui.volume.dialog.utils.VolumeTracerImpl
import dagger.Binds
import dagger.Module
+import dagger.Provides
@Module(subcomponents = [VolumeDialogComponent::class])
interface VolumeDialogPluginModule {
@Binds fun bindVolumeTracer(volumeTracer: VolumeTracerImpl): VolumeTracer
+
+ companion object {
+
+ @Provides
+ fun provideCsdWarningConfigModel(): CsdWarningConfigModel =
+ CsdWarningConfigModel(emptyList())
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogCsdWarningInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogCsdWarningInteractor.kt
new file mode 100644
index 000000000000..ef9def328d15
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogCsdWarningInteractor.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2025 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.volume.dialog.domain.interactor
+
+import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogPluginScope
+import com.android.systemui.volume.dialog.shared.model.VolumeDialogCsdWarningModel
+import javax.inject.Inject
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.map
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@VolumeDialogPluginScope
+class VolumeDialogCsdWarningInteractor
+@Inject
+constructor(private val stateInteractor: VolumeDialogStateInteractor) {
+
+ /** Emits warning when the warning should be visible and null when it shouldn't */
+ val csdWarning: Flow<Int?> =
+ stateInteractor.volumeDialogState
+ .map { it.isShowingCsdWarning }
+ .flatMapLatest { model ->
+ when (model) {
+ is VolumeDialogCsdWarningModel.Visible ->
+ flow {
+ emit(model.warning)
+ delay(model.duration)
+ emit(null)
+ }
+ is VolumeDialogCsdWarningModel.Invisible -> flowOf(null)
+ }
+ }
+
+ fun onCsdWarningDismissed() {
+ stateInteractor.setCsdWarning(VolumeDialogCsdWarningModel.Invisible)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogStateInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogStateInteractor.kt
index 26d2414acec1..b3c92f8cdbb9 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogStateInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogStateInteractor.kt
@@ -23,10 +23,12 @@ import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogPlugin
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogPluginScope
import com.android.systemui.volume.dialog.data.repository.VolumeDialogStateRepository
import com.android.systemui.volume.dialog.domain.model.VolumeDialogEventModel
+import com.android.systemui.volume.dialog.shared.model.VolumeDialogCsdWarningModel
import com.android.systemui.volume.dialog.shared.model.VolumeDialogSafetyWarningModel
import com.android.systemui.volume.dialog.shared.model.VolumeDialogStateModel
import com.android.systemui.volume.dialog.shared.model.VolumeDialogStreamModel
import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.launchIn
@@ -64,6 +66,14 @@ constructor(
is VolumeDialogEventModel.ShowSafetyWarning -> {
setSafetyWarning(VolumeDialogSafetyWarningModel.Visible(event.flags))
}
+ is VolumeDialogEventModel.ShowCsdWarning -> {
+ setCsdWarning(
+ VolumeDialogCsdWarningModel.Visible(
+ warning = event.csdWarning,
+ duration = event.durationMs.milliseconds,
+ )
+ )
+ }
is VolumeDialogEventModel.SubscribedToEvents -> {
volumeDialogController.getState()
}
@@ -81,6 +91,10 @@ constructor(
volumeDialogStateRepository.updateState { it.copy(isShowingSafetyWarning = model) }
}
+ fun setCsdWarning(model: VolumeDialogCsdWarningModel) {
+ volumeDialogStateRepository.updateState { it.copy(isShowingCsdWarning = model) }
+ }
+
/** Returns a copy of [model] filled with the values from [VolumeDialogController.State]. */
private fun VolumeDialogController.State.copyIntoModel(
model: VolumeDialogStateModel
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/shared/model/CsdWarningConfigModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/shared/model/CsdWarningConfigModel.kt
new file mode 100644
index 000000000000..e6741bae6c26
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/shared/model/CsdWarningConfigModel.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2025 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.volume.dialog.shared.model
+
+import com.android.systemui.volume.CsdWarningAction
+
+data class CsdWarningConfigModel(val actions: List<CsdWarningAction>)
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/shared/model/VolumeDialogCsdWarningModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/shared/model/VolumeDialogCsdWarningModel.kt
new file mode 100644
index 000000000000..219af7165534
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/shared/model/VolumeDialogCsdWarningModel.kt
@@ -0,0 +1,29 @@
+/*
+ * 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.volume.dialog.shared.model
+
+import kotlin.time.Duration
+
+/** Models current CSD dialog state. */
+sealed interface VolumeDialogCsdWarningModel {
+
+ /** CSD dialog is visible and has been shown with the [warning] for the [duration]. */
+ data class Visible(val warning: Int, val duration: Duration) : VolumeDialogCsdWarningModel
+
+ /** CSD dialog is invisible. */
+ data object Invisible : VolumeDialogCsdWarningModel
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/shared/model/VolumeDialogStateModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/shared/model/VolumeDialogStateModel.kt
index 838006d0adb2..89456fe2ac75 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/shared/model/VolumeDialogStateModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/shared/model/VolumeDialogStateModel.kt
@@ -23,6 +23,7 @@ data class VolumeDialogStateModel(
val shouldShowA11ySlider: Boolean = false,
val isShowingSafetyWarning: VolumeDialogSafetyWarningModel =
VolumeDialogSafetyWarningModel.Invisible,
+ val isShowingCsdWarning: VolumeDialogCsdWarningModel = VolumeDialogCsdWarningModel.Invisible,
val streamModels: Map<Int, VolumeDialogStreamModel> = mapOf(),
val ringerModeInternal: Int = 0,
val ringerModeExternal: Int = 0,
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogPluginViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogPluginViewModel.kt
index e7a2cf4eff08..1765f0111e08 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogPluginViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogPluginViewModel.kt
@@ -20,9 +20,11 @@ import com.android.systemui.volume.Events
import com.android.systemui.volume.dialog.VolumeDialog
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogPlugin
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogPluginScope
+import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogCsdWarningInteractor
import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogSafetyWarningInteractor
import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogVisibilityInteractor
import com.android.systemui.volume.dialog.shared.VolumeDialogLogger
+import com.android.systemui.volume.dialog.shared.model.CsdWarningConfigModel
import com.android.systemui.volume.dialog.shared.model.VolumeDialogVisibilityModel
import javax.inject.Inject
import javax.inject.Provider
@@ -38,8 +40,10 @@ constructor(
@VolumeDialogPlugin private val coroutineScope: CoroutineScope,
private val dialogVisibilityInteractor: VolumeDialogVisibilityInteractor,
private val dialogSafetyWarningInteractor: VolumeDialogSafetyWarningInteractor,
+ private val dialogCsdWarningInteractor: VolumeDialogCsdWarningInteractor,
private val volumeDialogProvider: Provider<VolumeDialog>,
private val logger: VolumeDialogLogger,
+ val csdWarningConfigModel: CsdWarningConfigModel,
) {
fun launchVolumeDialog() {
@@ -61,11 +65,16 @@ constructor(
}
val isShowingSafetyWarning: Flow<Boolean> = dialogSafetyWarningInteractor.isShowingSafetyWarning
+ val csdWarning: Flow<Int?> = dialogCsdWarningInteractor.csdWarning
fun onSafetyWarningDismissed() {
dialogSafetyWarningInteractor.onSafetyWarningDismissed()
}
+ fun onCsdWarningDismissed() {
+ dialogCsdWarningInteractor.onCsdWarningDismissed()
+ }
+
private fun showDialog() {
volumeDialogProvider
.get()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
index 3007eabba0b8..8d05ea16cfa6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
@@ -16,6 +16,7 @@
package com.android.systemui.volume;
+import java.util.List;
import static android.media.AudioManager.RINGER_MODE_NORMAL;
import static android.media.AudioManager.RINGER_MODE_SILENT;
import static android.media.AudioManager.RINGER_MODE_VIBRATE;
@@ -93,7 +94,6 @@ import com.android.systemui.volume.panel.shared.flag.VolumePanelFlag;
import com.android.systemui.volume.ui.navigation.VolumeNavigator;
import com.google.android.msdl.domain.MSDLPlayer;
-import com.google.common.collect.ImmutableList;
import dagger.Lazy;
@@ -163,7 +163,7 @@ public class VolumeDialogImplTest extends SysuiTestCase {
new CsdWarningDialog.Factory() {
@Override
public CsdWarningDialog create(int warningType, Runnable onCleanup,
- Optional<ImmutableList<CsdWarningAction>> actionIntents) {
+ Optional<List<CsdWarningAction>> actionIntents) {
return mCsdWarningDialog;
}
};