diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java index ae7a671f3d54c..96862af59817d 100644 --- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java +++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java @@ -176,6 +176,18 @@ public class LogModule { return factory.create("MediaTttReceiver", 20); } + + /** + * Provides a logging buffer for logs related to the media mute-await connections. See + * {@link com.android.systemui.media.muteawait.MediaMuteAwaitConnectionManager}. + */ + @Provides + @SysUISingleton + @MediaMuteAwaitLog + public static LogBuffer provideMediaMuteAwaitLogBuffer(LogBufferFactory factory) { + return factory.create("MediaMuteAwaitLog", 20); + } + /** Allows logging buffers to be tweaked via adb on debug builds but not on prod builds. */ @Provides @SysUISingleton diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/MediaMuteAwaitLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/MediaMuteAwaitLog.java new file mode 100644 index 0000000000000..c67d8bebe313a --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/log/dagger/MediaMuteAwaitLog.java @@ -0,0 +1,36 @@ +/* + * 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 com.android.systemui.log.dagger; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import com.android.systemui.log.LogBuffer; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; + +import javax.inject.Qualifier; + +/** + * A {@link LogBuffer} for + * {@link com.android.systemui.media.muteawait.MediaMuteAwaitConnectionManager}. + */ +@Qualifier +@Documented +@Retention(RUNTIME) +public @interface MediaMuteAwaitLog { +} diff --git a/packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManager.kt b/packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManager.kt index 2783532aff970..f47954a238900 100644 --- a/packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManager.kt @@ -33,14 +33,13 @@ import java.util.concurrent.Executor * will be notified. * * See [AudioManager.muteAwaitConnection] and b/206614671 for more details. - * - * TODO(b/206614671): Add logging. */ class MediaMuteAwaitConnectionManager constructor( @Main private val mainExecutor: Executor, private val localMediaManager: LocalMediaManager, private val context: Context, - private val deviceIconUtil: DeviceIconUtil + private val deviceIconUtil: DeviceIconUtil, + private val logger: MediaMuteAwaitLogger ) { var currentMutedDevice: AudioDeviceAttributes? = null @@ -48,7 +47,8 @@ class MediaMuteAwaitConnectionManager constructor( val muteAwaitConnectionChangeListener = object : AudioManager.MuteAwaitConnectionCallback() { override fun onMutedUntilConnection(device: AudioDeviceAttributes, mutedUsages: IntArray) { - if (USAGE_MEDIA in mutedUsages) { + logger.logMutedDeviceAdded(device.address, device.name, mutedUsages.hasMedia()) + if (mutedUsages.hasMedia()) { // There should only be one device that's mutedUntilConnection at a time, so we can // safely override any previous value. currentMutedDevice = device @@ -63,7 +63,11 @@ class MediaMuteAwaitConnectionManager constructor( device: AudioDeviceAttributes, mutedUsages: IntArray ) { - if (currentMutedDevice == device && USAGE_MEDIA in mutedUsages) { + val isMostRecentDevice = currentMutedDevice == device + logger.logMutedDeviceRemoved( + device.address, device.name, mutedUsages.hasMedia(), isMostRecentDevice + ) + if (isMostRecentDevice && mutedUsages.hasMedia()) { currentMutedDevice = null localMediaManager.dispatchAboutToConnectDeviceRemoved() } @@ -92,4 +96,6 @@ class MediaMuteAwaitConnectionManager constructor( private fun AudioDeviceAttributes.getIcon(): Drawable { return deviceIconUtil.getIconFromAudioDeviceType(this.type, context) } + + private fun IntArray.hasMedia() = USAGE_MEDIA in this } diff --git a/packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerFactory.kt b/packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerFactory.kt index 118b2dd4dc90d..ffcc1f75f0777 100644 --- a/packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerFactory.kt @@ -30,6 +30,7 @@ import javax.inject.Inject class MediaMuteAwaitConnectionManagerFactory @Inject constructor( private val mediaFlags: MediaFlags, private val context: Context, + private val logger: MediaMuteAwaitLogger, @Main private val mainExecutor: Executor ) { private val deviceIconUtil = DeviceIconUtil() @@ -40,7 +41,7 @@ class MediaMuteAwaitConnectionManagerFactory @Inject constructor( return null } return MediaMuteAwaitConnectionManager( - mainExecutor, localMediaManager, context, deviceIconUtil + mainExecutor, localMediaManager, context, deviceIconUtil, logger ) } } diff --git a/packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitLogger.kt b/packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitLogger.kt new file mode 100644 index 0000000000000..78f4e012da036 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitLogger.kt @@ -0,0 +1,51 @@ +package com.android.systemui.media.muteawait + +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.log.LogBuffer +import com.android.systemui.log.LogLevel +import com.android.systemui.log.dagger.MediaMuteAwaitLog +import javax.inject.Inject + +/** Log messages for [MediaMuteAwaitConnectionManager]. */ +@SysUISingleton +class MediaMuteAwaitLogger @Inject constructor( + @MediaMuteAwaitLog private val buffer: LogBuffer +) { + /** Logs that a muted device has been newly added. */ + fun logMutedDeviceAdded(deviceAddress: String, deviceName: String, hasMediaUsage: Boolean) = + buffer.log( + TAG, + LogLevel.DEBUG, + { + str1 = deviceAddress + str2 = deviceName + bool1 = hasMediaUsage + }, + { + "Muted device added: address=$str1 name=$str2 hasMediaUsage=$bool1" + } + ) + + /** Logs that a muted device has been removed. */ + fun logMutedDeviceRemoved( + deviceAddress: String, + deviceName: String, + hasMediaUsage: Boolean, + isMostRecentDevice: Boolean + ) = buffer.log( + TAG, + LogLevel.DEBUG, + { + str1 = deviceAddress + str2 = deviceName + bool1 = hasMediaUsage + bool2 = isMostRecentDevice + }, + { + "Muted device removed: " + + "address=$str1 name=$str2 hasMediaUsage=$bool1 isMostRecentDevice=$bool2" + } + ) +} + +private const val TAG = "MediaMuteAwait" diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt index 27c039dcf29ca..b09fc558d0501 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt @@ -53,6 +53,8 @@ class MediaMuteAwaitConnectionManagerTest : SysuiTestCase() { private lateinit var deviceIconUtil: DeviceIconUtil @Mock private lateinit var localMediaManager: LocalMediaManager + @Mock + private lateinit var logger: MediaMuteAwaitLogger private lateinit var icon: Drawable @Before @@ -66,7 +68,8 @@ class MediaMuteAwaitConnectionManagerTest : SysuiTestCase() { FakeExecutor(FakeSystemClock()), localMediaManager, context, - deviceIconUtil + deviceIconUtil, + logger ) } @@ -186,6 +189,39 @@ class MediaMuteAwaitConnectionManagerTest : SysuiTestCase() { verify(localMediaManager).dispatchAboutToConnectDeviceRemoved() } + @Test + fun onMutedUntilConnection_isLogged() { + muteAwaitConnectionManager.startListening() + + getMuteAwaitListener().onMutedUntilConnection(DEVICE, intArrayOf(USAGE_MEDIA)) + + verify(logger).logMutedDeviceAdded(DEVICE_ADDRESS, DEVICE_NAME, hasMediaUsage = true) + } + + @Test + fun onUnmutedEvent_notMostRecentDevice_isLogged() { + muteAwaitConnectionManager.startListening() + + getMuteAwaitListener().onUnmutedEvent(EVENT_CONNECTION, DEVICE, intArrayOf(USAGE_MEDIA)) + + verify(logger).logMutedDeviceRemoved( + DEVICE_ADDRESS, DEVICE_NAME, hasMediaUsage = true, isMostRecentDevice = false + ) + } + + @Test + fun onUnmutedEvent_isMostRecentDevice_isLogged() { + muteAwaitConnectionManager.startListening() + val muteAwaitListener = getMuteAwaitListener() + + muteAwaitListener.onMutedUntilConnection(DEVICE, intArrayOf(USAGE_MEDIA)) + muteAwaitListener.onUnmutedEvent(EVENT_CONNECTION, DEVICE, intArrayOf(USAGE_MEDIA)) + + verify(logger).logMutedDeviceRemoved( + DEVICE_ADDRESS, DEVICE_NAME, hasMediaUsage = true, isMostRecentDevice = true + ) + } + private fun getMuteAwaitListener(): AudioManager.MuteAwaitConnectionCallback { val listenerCaptor = ArgumentCaptor.forClass( AudioManager.MuteAwaitConnectionCallback::class.java