diff options
12 files changed, 443 insertions, 25 deletions
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 ebb9ce9909bd..594938500aef 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java +++ b/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java @@ -23,6 +23,7 @@ import android.os.Looper; import com.android.internal.jank.InteractionJankMonitor; import com.android.systemui.CoreStartable; +import com.android.systemui.Flags; import com.android.systemui.dump.DumpManager; import com.android.systemui.media.dialog.MediaOutputDialogManager; import com.android.systemui.plugins.VolumeDialog; @@ -40,6 +41,8 @@ import com.android.systemui.volume.VolumeDialogComponent; import com.android.systemui.volume.VolumeDialogImpl; 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.domain.interactor.VolumeDialogInteractor; import com.android.systemui.volume.domain.interactor.VolumePanelNavigationInteractor; import com.android.systemui.volume.panel.dagger.VolumePanelComponent; @@ -66,7 +69,8 @@ import dagger.multibindings.IntoSet; SpatializerModule.class, }, subcomponents = { - VolumePanelComponent.class + VolumePanelComponent.class, + VolumeDialogPluginComponent.class, } ) public interface VolumeModule { @@ -101,6 +105,7 @@ public interface VolumeModule { /** */ @Provides static VolumeDialog provideVolumeDialog( + Lazy<VolumeDialogPlugin> newVolumeDialogProvider, Context context, VolumeDialogController volumeDialogController, AccessibilityManagerWrapper accessibilityManagerWrapper, @@ -118,29 +123,33 @@ public interface VolumeModule { VibratorHelper vibratorHelper, SystemClock systemClock, VolumeDialogInteractor interactor) { - VolumeDialogImpl impl = new VolumeDialogImpl( - context, - volumeDialogController, - accessibilityManagerWrapper, - deviceProvisionedController, - configurationController, - mediaOutputDialogManager, - interactionJankMonitor, - volumePanelNavigationInteractor, - volumeNavigator, - true, /* should listen for jank */ - csdFactory, - devicePostureController, - Looper.getMainLooper(), - volumePanelFlag, - dumpManager, - secureSettings, - vibratorHelper, - systemClock, - interactor); - impl.setStreamImportant(AudioManager.STREAM_SYSTEM, false); - impl.setAutomute(true); - impl.setSilentMode(false); - return impl; + if (Flags.volumeRedesign()) { + return newVolumeDialogProvider.get(); + } else { + VolumeDialogImpl impl = new VolumeDialogImpl( + context, + volumeDialogController, + accessibilityManagerWrapper, + deviceProvisionedController, + configurationController, + mediaOutputDialogManager, + interactionJankMonitor, + volumePanelNavigationInteractor, + volumeNavigator, + true, /* should listen for jank */ + csdFactory, + devicePostureController, + Looper.getMainLooper(), + volumePanelFlag, + dumpManager, + secureSettings, + vibratorHelper, + systemClock, + interactor); + impl.setStreamImportant(AudioManager.STREAM_SYSTEM, false); + impl.setAutomute(true); + impl.setSilentMode(false); + return impl; + } } } diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialog.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialog.kt new file mode 100644 index 000000000000..74e823e9f592 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialog.kt @@ -0,0 +1,34 @@ +/* + * 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 + +import android.app.Dialog +import android.content.Context +import android.os.Bundle +import android.view.ContextThemeWrapper +import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.res.R +import javax.inject.Inject + +class VolumeDialog @Inject constructor(@Application context: Context) : + Dialog(ContextThemeWrapper(context, R.style.volume_dialog_theme)) { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.volume_dialog) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialogPlugin.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialogPlugin.kt new file mode 100644 index 000000000000..a2e81d942ae2 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialogPlugin.kt @@ -0,0 +1,67 @@ +/* + * 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 + +import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.plugins.VolumeDialog +import com.android.systemui.volume.dialog.dagger.VolumeDialogComponent +import com.android.systemui.volume.dialog.dagger.VolumeDialogPluginComponent +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.cancel +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.launch + +class VolumeDialogPlugin +@Inject +constructor( + @Application private val applicationCoroutineScope: CoroutineScope, + private val volumeDialogPluginComponentFactory: VolumeDialogPluginComponent.Factory, +) : VolumeDialog { + + private var volumeDialogPluginComponent: VolumeDialogPluginComponent? = null + private var job: Job? = null + + override fun init(windowType: Int, callback: VolumeDialog.Callback?) { + job = + applicationCoroutineScope.launch { + coroutineScope { + volumeDialogPluginComponent = volumeDialogPluginComponentFactory.create(this) + } + } + } + + private fun showDialog() { + val volumeDialogPluginComponent = + volumeDialogPluginComponent ?: error("Creating dialog before init was called") + volumeDialogPluginComponent.coroutineScope().launch { + coroutineScope { + val volumeDialogComponent: VolumeDialogComponent = + volumeDialogPluginComponent.volumeDialogComponentFactory().create(this) + with(volumeDialogComponent.volumeDialog()) { + setOnDismissListener { volumeDialogComponent.coroutineScope().cancel() } + show() + } + } + } + } + + override fun destroy() { + job?.cancel() + } +} diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogComponent.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogComponent.kt new file mode 100644 index 000000000000..f7ad3205f3dd --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogComponent.kt @@ -0,0 +1,48 @@ +/* + * 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.dagger + +import com.android.systemui.volume.dialog.dagger.scope.VolumeDialog +import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope +import dagger.BindsInstance +import dagger.Subcomponent +import kotlinx.coroutines.CoroutineScope + +/** + * Core Volume Dialog dagger component. It's managed by + * [com.android.systemui.volume.dialog.VolumeDialogPlugin] and lives alongside it. + */ +@VolumeDialogScope +@Subcomponent(modules = []) +interface VolumeDialogComponent { + + /** + * Provides a coroutine scope to use inside [VolumeDialogScope]. + * [com.android.systemui.volume.dialog.VolumeDialogPlugin] manages the lifecycle of this scope. + * It's cancelled when the dialog is disposed. This helps to free occupied resources when volume + * dialog is not shown. + */ + @VolumeDialog fun coroutineScope(): CoroutineScope + + @VolumeDialogScope fun volumeDialog(): com.android.systemui.volume.dialog.VolumeDialog + + @Subcomponent.Factory + interface Factory { + + fun create(@BindsInstance @VolumeDialog scope: CoroutineScope): VolumeDialogComponent + } +} 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 new file mode 100644 index 000000000000..82612a79f6ce --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogPluginComponent.kt @@ -0,0 +1,51 @@ +/* + * 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.dagger + +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 +import dagger.BindsInstance +import dagger.Subcomponent +import kotlinx.coroutines.CoroutineScope + +/** + * Volume Dialog plugin dagger component. It's managed by + * [com.android.systemui.volume.dialog.VolumeDialogPlugin] and lives alongside it. + */ +@VolumeDialogPluginScope +@Subcomponent(modules = [VolumeDialogPluginModule::class]) +interface VolumeDialogPluginComponent { + + /** + * Provides a coroutine scope to use inside [VolumeDialogPluginScope]. + * [com.android.systemui.volume.dialog.VolumeDialogPlugin] manages the lifecycle of this scope. + * It's cancelled when the dialog is disposed. This helps to free occupied resources when volume + * dialog is not shown. + */ + @VolumeDialogPlugin fun coroutineScope(): CoroutineScope + + fun volumeDialogComponentFactory(): VolumeDialogComponent.Factory + + @Subcomponent.Factory + interface Factory { + + fun create( + @BindsInstance @VolumeDialogPlugin 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 new file mode 100644 index 000000000000..3fdf86a923fb --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/module/VolumeDialogPluginModule.kt @@ -0,0 +1,22 @@ +/* + * 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.dagger.module + +import com.android.systemui.volume.dialog.dagger.VolumeDialogComponent +import dagger.Module + +@Module(subcomponents = [VolumeDialogComponent::class]) interface VolumeDialogPluginModule diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/scope/VolumeDialog.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/scope/VolumeDialog.kt new file mode 100644 index 000000000000..34bddb42b891 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/scope/VolumeDialog.kt @@ -0,0 +1,26 @@ +/* + * 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.dagger.scope + +import javax.inject.Qualifier + +/** + * Volume Dialog qualifier. + * + * @see VolumeDialogScope + */ +@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class VolumeDialog diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/scope/VolumeDialogPlugin.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/scope/VolumeDialogPlugin.kt new file mode 100644 index 000000000000..1038c30c1e9f --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/scope/VolumeDialogPlugin.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.dagger.scope + +import javax.inject.Qualifier + +/** + * Volume Dialog plugin qualifier. + * + * @see VolumeDialogPluginScope + */ +@Qualifier +@MustBeDocumented +@Retention(AnnotationRetention.RUNTIME) +annotation class VolumeDialogPlugin diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/scope/VolumeDialogPluginScope.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/scope/VolumeDialogPluginScope.kt new file mode 100644 index 000000000000..6c5f672ba2c1 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/scope/VolumeDialogPluginScope.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.dagger.scope + +import javax.inject.Scope + +/** + * Volume Dialog plugin dependency injection scope. This scope is created alongside Volume Dialog + * plugin is initialized and destroyed alongside it. This is effectively almost similar + * to @Application now. + */ +@MustBeDocumented +@Retention(AnnotationRetention.RUNTIME) +@Scope +annotation class VolumeDialogPluginScope diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/scope/VolumeDialogScope.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/scope/VolumeDialogScope.kt new file mode 100644 index 000000000000..52caa6a42ab4 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/scope/VolumeDialogScope.kt @@ -0,0 +1,25 @@ +/* + * 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.dagger.scope + +import javax.inject.Scope + +/** + * Volume Panel dependency injection scope. This scope is created alongside Volume Panel and + * destroyed when it's lo longer present. + */ +@MustBeDocumented @Retention(AnnotationRetention.RUNTIME) @Scope annotation class VolumeDialogScope diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogViewBinder.kt new file mode 100644 index 000000000000..700225d521c8 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogViewBinder.kt @@ -0,0 +1,45 @@ +/* + * 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.ui.binder + +import android.view.View +import com.android.systemui.lifecycle.WindowLifecycleState +import com.android.systemui.lifecycle.repeatWhenAttached +import com.android.systemui.lifecycle.setSnapshotBinding +import com.android.systemui.lifecycle.viewModel +import com.android.systemui.volume.dialog.ui.viewmodel.VolumeDialogViewModel +import javax.inject.Inject +import kotlinx.coroutines.awaitCancellation + +class VolumeDialogViewBinder +@Inject +constructor(private val volumeDialogViewModelFactory: VolumeDialogViewModel.Factory) { + + suspend fun bind(view: View) { + view.repeatWhenAttached { + view.viewModel( + traceName = "VolumeDialogViewBinder", + minWindowLifecycleState = WindowLifecycleState.ATTACHED, + factory = { volumeDialogViewModelFactory.create() }, + ) { viewModel -> + view.setSnapshotBinding {} + + awaitCancellation() + } + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogViewModel.kt new file mode 100644 index 000000000000..f9e91aee4922 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogViewModel.kt @@ -0,0 +1,33 @@ +/* + * 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.ui.viewmodel + +import com.android.systemui.lifecycle.ExclusiveActivatable +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject + +class VolumeDialogViewModel @AssistedInject constructor() : ExclusiveActivatable() { + + override suspend fun onActivated(): Nothing { + TODO("Not yet implemented") + } + + @AssistedFactory + interface Factory { + fun create(): VolumeDialogViewModel + } +} |