Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8ccc0077 authored by Yu Chao's avatar Yu Chao
Browse files

Add VolumeDialogInteractor to capture the show/dismiss UI events of

VolumeDialog.

Employs the same solution as ag/26288057 -> which is already launched in
nextfood.

Design doc: https://docs.google.com/document/d/1MDbuPjUhivRXIv7KT_rpEHRenRulswB4r5dSE0w40As/edit?resourcekey=0-MBArhSieiSvxGKdno72rWg&tab=t.0

Particularly these sections:
  - https://docs.google.com/document/d/1MDbuPjUhivRXIv7KT_rpEHRenRulswB4r5dSE0w40As/edit?resourcekey=0-MBArhSieiSvxGKdno72rWg&tab=t.0#bookmark=id.ls849lgeygcd
  - https://docs.google.com/document/d/1MDbuPjUhivRXIv7KT_rpEHRenRulswB4r5dSE0w40As/edit?resourcekey=0-MBArhSieiSvxGKdno72rWg&tab=t.0#bookmark=id.w3oa9z68ejlw

Video Demo (built along with ag/27279610 and cl/610618396: https://drive.google.com/corp/drive/my-drive?q=type:video%20parent:0ABR6pTIIQzvDUk9PVA

PRD: https://docs.google.com/document/d/1H1xyxWbplMORctq6dzxupdUhR4QR6BlA9f94c2D1qDs/edit?resourcekey=0--_a01t4kF7RKxqhUVZ9EFA&tab=t.0#heading=h.tfo1a2xtglbv

Test: VolumeDialogRepositoryTest, VolumeDialogInteractorTest, VolumeDialogImplTest and manual tests (i.e. dismiss the volume bar twice with media volume turned down to 0 under normal ringertone mode and see the printed logs)
Bug: 337737048
Flag: com.android.systemui.enable_contextual_tip_for_mute_volume
Change-Id: I8986970f773afdf44d27f6b7177f9e28c13bddb7
parent 1e8d0901
Loading
Loading
Loading
Loading
+7 −1
Original line number Original line Diff line number Diff line
@@ -135,6 +135,7 @@ import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.util.AlphaTintDrawableWrapper;
import com.android.systemui.util.AlphaTintDrawableWrapper;
import com.android.systemui.util.RoundedCornerProgressDrawable;
import com.android.systemui.util.RoundedCornerProgressDrawable;
import com.android.systemui.util.settings.SecureSettings;
import com.android.systemui.util.settings.SecureSettings;
import com.android.systemui.volume.domain.interactor.VolumeDialogInteractor;
import com.android.systemui.volume.domain.interactor.VolumePanelNavigationInteractor;
import com.android.systemui.volume.domain.interactor.VolumePanelNavigationInteractor;
import com.android.systemui.volume.panel.shared.flag.VolumePanelFlag;
import com.android.systemui.volume.panel.shared.flag.VolumePanelFlag;
import com.android.systemui.volume.ui.binder.VolumeDialogMenuIconBinder;
import com.android.systemui.volume.ui.binder.VolumeDialogMenuIconBinder;
@@ -315,6 +316,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
    private final com.android.systemui.util.time.SystemClock mSystemClock;
    private final com.android.systemui.util.time.SystemClock mSystemClock;
    private final VolumeDialogMenuIconBinder mVolumeDialogMenuIconBinder;
    private final VolumeDialogMenuIconBinder mVolumeDialogMenuIconBinder;
    private final VolumePanelFlag mVolumePanelFlag;
    private final VolumePanelFlag mVolumePanelFlag;
    private final VolumeDialogInteractor mInteractor;


    public VolumeDialogImpl(
    public VolumeDialogImpl(
            Context context,
            Context context,
@@ -335,7 +337,8 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
            Lazy<SecureSettings> secureSettings,
            Lazy<SecureSettings> secureSettings,
            VibratorHelper vibratorHelper,
            VibratorHelper vibratorHelper,
            VolumeDialogMenuIconBinder volumeDialogMenuIconBinder,
            VolumeDialogMenuIconBinder volumeDialogMenuIconBinder,
            com.android.systemui.util.time.SystemClock systemClock) {
            com.android.systemui.util.time.SystemClock systemClock,
            VolumeDialogInteractor interactor) {
        mContext =
        mContext =
                new ContextThemeWrapper(context, R.style.volume_dialog_theme);
                new ContextThemeWrapper(context, R.style.volume_dialog_theme);
        mHandler = new H(looper);
        mHandler = new H(looper);
@@ -370,6 +373,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
        mVolumeDialogMenuIconBinder = volumeDialogMenuIconBinder;
        mVolumeDialogMenuIconBinder = volumeDialogMenuIconBinder;
        mDialogTimeoutMillis = DIALOG_TIMEOUT_MILLIS;
        mDialogTimeoutMillis = DIALOG_TIMEOUT_MILLIS;
        mVolumePanelFlag = volumePanelFlag;
        mVolumePanelFlag = volumePanelFlag;
        mInteractor = interactor;


        dumpManager.registerDumpable("VolumeDialogImpl", this);
        dumpManager.registerDumpable("VolumeDialogImpl", this);


@@ -1519,6 +1523,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
        mShowing = true;
        mShowing = true;
        mIsAnimatingDismiss = false;
        mIsAnimatingDismiss = false;
        mDialog.show();
        mDialog.show();
        mInteractor.onDialogShown();
        Events.writeEvent(Events.EVENT_SHOW_DIALOG, reason, keyguardLocked);
        Events.writeEvent(Events.EVENT_SHOW_DIALOG, reason, keyguardLocked);
        mController.notifyVisible(true);
        mController.notifyVisible(true);
        mController.getCaptionsComponentState(false);
        mController.getCaptionsComponentState(false);
@@ -1605,6 +1610,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
        }
        }
        mIsAnimatingDismiss = true;
        mIsAnimatingDismiss = true;
        mDialogView.animate().cancel();
        mDialogView.animate().cancel();
        mInteractor.onDialogDismissed();
        if (mShowing) {
        if (mShowing) {
            mShowing = false;
            mShowing = false;
            // Only logs when the volume dialog visibility is changed.
            // Only logs when the volume dialog visibility is changed.
+5 −2
Original line number Original line Diff line number Diff line
@@ -41,6 +41,7 @@ import com.android.systemui.volume.VolumeDialogImpl;
import com.android.systemui.volume.VolumeDialogModule;
import com.android.systemui.volume.VolumeDialogModule;
import com.android.systemui.volume.VolumePanelDialogReceiver;
import com.android.systemui.volume.VolumePanelDialogReceiver;
import com.android.systemui.volume.VolumeUI;
import com.android.systemui.volume.VolumeUI;
import com.android.systemui.volume.domain.interactor.VolumeDialogInteractor;
import com.android.systemui.volume.domain.interactor.VolumePanelNavigationInteractor;
import com.android.systemui.volume.domain.interactor.VolumePanelNavigationInteractor;
import com.android.systemui.volume.panel.dagger.VolumePanelComponent;
import com.android.systemui.volume.panel.dagger.VolumePanelComponent;
import com.android.systemui.volume.panel.dagger.factory.VolumePanelComponentFactory;
import com.android.systemui.volume.panel.dagger.factory.VolumePanelComponentFactory;
@@ -118,7 +119,8 @@ public interface VolumeModule {
            Lazy<SecureSettings> secureSettings,
            Lazy<SecureSettings> secureSettings,
            VibratorHelper vibratorHelper,
            VibratorHelper vibratorHelper,
            VolumeDialogMenuIconBinder volumeDialogMenuIconBinder,
            VolumeDialogMenuIconBinder volumeDialogMenuIconBinder,
            SystemClock systemClock) {
            SystemClock systemClock,
            VolumeDialogInteractor interactor) {
        VolumeDialogImpl impl = new VolumeDialogImpl(
        VolumeDialogImpl impl = new VolumeDialogImpl(
                context,
                context,
                volumeDialogController,
                volumeDialogController,
@@ -138,7 +140,8 @@ public interface VolumeModule {
                secureSettings,
                secureSettings,
                vibratorHelper,
                vibratorHelper,
                volumeDialogMenuIconBinder,
                volumeDialogMenuIconBinder,
                systemClock);
                systemClock,
                interactor);
        impl.setStreamImportant(AudioManager.STREAM_SYSTEM, false);
        impl.setStreamImportant(AudioManager.STREAM_SYSTEM, false);
        impl.setAutomute(true);
        impl.setAutomute(true);
        impl.setSilentMode(false);
        impl.setSilentMode(false);
+35 −0
Original line number Original line Diff line number Diff line
/*
 * 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.data.repository

import com.android.systemui.dagger.SysUISingleton
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow

/** A repository that encapsulates the states for Volume Dialog. */
@SysUISingleton
class VolumeDialogRepository @Inject constructor() {
    private val _isDialogVisible: MutableStateFlow<Boolean> = MutableStateFlow(false)
    /** Whether the Volume Dialog is visible. */
    val isDialogVisible = _isDialogVisible.asStateFlow()

    /** Sets whether the Volume Dialog is visible. */
    fun setDialogVisibility(isVisible: Boolean) {
        _isDialogVisible.value = isVisible
    }
}
+43 −0
Original line number Original line Diff line number Diff line
/*
 * 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.domain.interactor

import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.volume.data.repository.VolumeDialogRepository
import javax.inject.Inject
import kotlinx.coroutines.flow.StateFlow

/** An interactor that propagates the UI states of the Volume Dialog. */
@SysUISingleton
class VolumeDialogInteractor
@Inject
constructor(
    private val repository: VolumeDialogRepository,
) {
    /** Whether the Volume Dialog is visible. */
    val isDialogVisible: StateFlow<Boolean> = repository.isDialogVisible

    /** Notifies that the Volume Dialog is shown. */
    fun onDialogShown() {
        repository.setDialogVisibility(true)
    }

    /** Notifies that the Volume Dialog has been dismissed. */
    fun onDialogDismissed() {
        repository.setDialogVisibility(false)
    }
}
+14 −1
Original line number Original line Diff line number Diff line
@@ -86,6 +86,7 @@ import com.android.systemui.statusbar.policy.FakeConfigurationController;
import com.android.systemui.util.settings.FakeSettings;
import com.android.systemui.util.settings.FakeSettings;
import com.android.systemui.util.settings.SecureSettings;
import com.android.systemui.util.settings.SecureSettings;
import com.android.systemui.util.time.FakeSystemClock;
import com.android.systemui.util.time.FakeSystemClock;
import com.android.systemui.volume.domain.interactor.VolumeDialogInteractor;
import com.android.systemui.volume.domain.interactor.VolumePanelNavigationInteractor;
import com.android.systemui.volume.domain.interactor.VolumePanelNavigationInteractor;
import com.android.systemui.volume.panel.shared.flag.VolumePanelFlag;
import com.android.systemui.volume.panel.shared.flag.VolumePanelFlag;
import com.android.systemui.volume.ui.binder.VolumeDialogMenuIconBinder;
import com.android.systemui.volume.ui.binder.VolumeDialogMenuIconBinder;
@@ -153,6 +154,8 @@ public class VolumeDialogImplTest extends SysuiTestCase {
    private VolumeDialogMenuIconBinder mVolumeDialogMenuIconBinder;
    private VolumeDialogMenuIconBinder mVolumeDialogMenuIconBinder;
    @Mock
    @Mock
    private VolumePanelFlag mVolumePanelFlag;
    private VolumePanelFlag mVolumePanelFlag;
    @Mock
    private VolumeDialogInteractor mVolumeDialogInteractor;


    private final CsdWarningDialog.Factory mCsdWarningDialogFactory =
    private final CsdWarningDialog.Factory mCsdWarningDialogFactory =
            new CsdWarningDialog.Factory() {
            new CsdWarningDialog.Factory() {
@@ -218,7 +221,8 @@ public class VolumeDialogImplTest extends SysuiTestCase {
                mLazySecureSettings,
                mLazySecureSettings,
                mVibratorHelper,
                mVibratorHelper,
                mVolumeDialogMenuIconBinder,
                mVolumeDialogMenuIconBinder,
                new FakeSystemClock());
                new FakeSystemClock(),
                mVolumeDialogInteractor);
        mDialog.init(0, null);
        mDialog.init(0, null);
        State state = createShellState();
        State state = createShellState();
        mDialog.onStateChangedH(state);
        mDialog.onStateChangedH(state);
@@ -778,6 +782,15 @@ public class VolumeDialogImplTest extends SysuiTestCase {
        assertFalse(foundDnDIcon);
        assertFalse(foundDnDIcon);
    }
    }


    @Test
    public void testInteractor_onShow() {
        mDialog.show(SHOW_REASON_UNKNOWN);
        mTestableLooper.processAllMessages();

        verify(mVolumeDialogInteractor).onDialogShown();
        verify(mVolumeDialogInteractor).onDialogDismissed(); // dismiss by timeout
    }

    /**
    /**
     * @return true if at least one volume row has the DND icon
     * @return true if at least one volume row has the DND icon
     */
     */
Loading