diff options
| author | 2022-04-18 15:23:49 +0000 | |
|---|---|---|
| committer | 2022-04-18 16:45:29 +0000 | |
| commit | 1f94d22ad894fc0879dbf5d77453af843f10531a (patch) | |
| tree | 3c5e5ab0458e6dfc36e0bbb57a71474cc3ce5063 | |
| parent | 61aa866570b02e2965bf58633524372282f2be8a (diff) | |
[Media] Add logging for NearbyMediaDevicesManager.
Fixes: 219767651
Test: atest NearbyMediaDevicesManagerTest
Change-Id: I3d1952ae30e5d4c3fa0f234f00883dc4b9bc233a
5 files changed, 204 insertions, 7 deletions
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 96862af59817..79ac9e8b0986 100644 --- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java +++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java @@ -188,6 +188,17 @@ public class LogModule { return factory.create("MediaMuteAwaitLog", 20); } + /** + * Provides a logging buffer for logs related to the media mute-await connections. See + * {@link com.android.systemui.media.nearby.NearbyMediaDevicesManager}. + */ + @Provides + @SysUISingleton + @NearbyMediaDevicesLog + public static LogBuffer provideNearbyMediaDevicesLogBuffer(LogBufferFactory factory) { + return factory.create("NearbyMediaDevicesLog", 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/NearbyMediaDevicesLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/NearbyMediaDevicesLog.java new file mode 100644 index 000000000000..b1c6dcfcb13b --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/log/dagger/NearbyMediaDevicesLog.java @@ -0,0 +1,33 @@ +/* + * 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.nearby.NearbyMediaDevicesManager}. */ +@Qualifier +@Documented +@Retention(RUNTIME) +public @interface NearbyMediaDevicesLog { +} diff --git a/packages/SystemUI/src/com/android/systemui/media/nearby/NearbyMediaDevicesLogger.kt b/packages/SystemUI/src/com/android/systemui/media/nearby/NearbyMediaDevicesLogger.kt new file mode 100644 index 000000000000..46b2cc141b3c --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/media/nearby/NearbyMediaDevicesLogger.kt @@ -0,0 +1,51 @@ +package com.android.systemui.media.nearby + +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.log.LogBuffer +import com.android.systemui.log.LogLevel +import com.android.systemui.log.dagger.NearbyMediaDevicesLog +import javax.inject.Inject + +/** Log messages for [NearbyMediaDevicesManager]. */ +@SysUISingleton +class NearbyMediaDevicesLogger @Inject constructor( + @NearbyMediaDevicesLog private val buffer: LogBuffer +) { + /** + * Log that a new provider was registered. + * + * @param numProviders the total number of providers that are currently registered. + */ + fun logProviderRegistered(numProviders: Int) = buffer.log( + TAG, + LogLevel.DEBUG, + { int1 = numProviders }, + { "Provider registered; total providers = $int1" } + ) + + /** + * Log that a new provider was unregistered. + * + * @param numProviders the total number of providers that are currently registered. + */ + fun logProviderUnregistered(numProviders: Int) = buffer.log( + TAG, + LogLevel.DEBUG, + { int1 = numProviders }, + { "Provider unregistered; total providers = $int1" } + ) + + /** + * Log that a provider's binder has died. + * + * @param numProviders the total number of providers that are currently registered. + */ + fun logProviderBinderDied(numProviders: Int) = buffer.log( + TAG, + LogLevel.DEBUG, + { int1 = numProviders }, + { "Provider binder died; total providers = $int1" } + ) +} + +private const val TAG = "NearbyMediaDevices" diff --git a/packages/SystemUI/src/com/android/systemui/media/nearby/NearbyMediaDevicesManager.kt b/packages/SystemUI/src/com/android/systemui/media/nearby/NearbyMediaDevicesManager.kt index 9875ffbaf668..64b772b6a02c 100644 --- a/packages/SystemUI/src/com/android/systemui/media/nearby/NearbyMediaDevicesManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/nearby/NearbyMediaDevicesManager.kt @@ -27,12 +27,11 @@ import javax.inject.Inject * A service that acts as a bridge between (1) external clients that have data on nearby devices * that are able to play media and (2) internal clients (like media Output Switcher) that need data * on these nearby devices. - * - * TODO(b/216313420): Add logging to this class. */ @SysUISingleton class NearbyMediaDevicesManager @Inject constructor( - commandQueue: CommandQueue + commandQueue: CommandQueue, + private val logger: NearbyMediaDevicesLogger ) { private var providers: MutableList<INearbyMediaDevicesProvider> = mutableListOf() private var activeCallbacks: MutableList<INearbyMediaDevicesUpdateCallback> = mutableListOf() @@ -46,13 +45,17 @@ class NearbyMediaDevicesManager @Inject constructor( newProvider.registerNearbyDevicesCallback(it) } providers.add(newProvider) + logger.logProviderRegistered(providers.size) newProvider.asBinder().linkToDeath(deathRecipient, /* flags= */ 0) } override fun unregisterNearbyMediaDevicesProvider( newProvider: INearbyMediaDevicesProvider ) { - providers.remove(newProvider) + val isRemoved = providers.remove(newProvider) + if (isRemoved) { + logger.logProviderUnregistered(providers.size) + } } } @@ -99,6 +102,7 @@ class NearbyMediaDevicesManager @Inject constructor( for (i in providers.size - 1 downTo 0) { if (providers[i].asBinder() == who) { providers.removeAt(i) + logger.logProviderBinderDied(providers.size) break } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/nearby/NearbyMediaDevicesManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/nearby/NearbyMediaDevicesManagerTest.kt index f87a67310ff0..301d887b7474 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/nearby/NearbyMediaDevicesManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/nearby/NearbyMediaDevicesManagerTest.kt @@ -5,13 +5,18 @@ import android.media.INearbyMediaDevicesUpdateCallback import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import android.media.NearbyDevice +import android.os.IBinder import com.android.systemui.statusbar.CommandQueue import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test import org.mockito.ArgumentCaptor import org.mockito.Mock -import org.mockito.Mockito +import org.mockito.Mockito.anyInt +import org.mockito.Mockito.never +import org.mockito.Mockito.reset +import org.mockito.Mockito.times +import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @SmallTest @@ -19,16 +24,18 @@ class NearbyMediaDevicesManagerTest : SysuiTestCase() { private lateinit var manager: NearbyMediaDevicesManager @Mock + private lateinit var logger: NearbyMediaDevicesLogger + @Mock private lateinit var commandQueue: CommandQueue private lateinit var commandQueueCallbacks: CommandQueue.Callbacks @Before fun setUp() { MockitoAnnotations.initMocks(this) - manager = NearbyMediaDevicesManager(commandQueue) + manager = NearbyMediaDevicesManager(commandQueue, logger) val callbackCaptor = ArgumentCaptor.forClass(CommandQueue.Callbacks::class.java) - Mockito.verify(commandQueue).addCallback(callbackCaptor.capture()) + verify(commandQueue).addCallback(callbackCaptor.capture()) commandQueueCallbacks = callbackCaptor.value!! } @@ -128,9 +135,92 @@ class NearbyMediaDevicesManagerTest : SysuiTestCase() { assertThat(provider2.lastRegisteredCallback).isEqualTo(callback) } + @Test + fun providerUnregistered_doesNotReceiveNewCallback() { + val provider = TestProvider() + commandQueueCallbacks.registerNearbyMediaDevicesProvider(provider) + commandQueueCallbacks.unregisterNearbyMediaDevicesProvider(provider) + + val callback = object : INearbyMediaDevicesUpdateCallback.Stub() { + override fun onDevicesUpdated(nearbyDevices: List<NearbyDevice>) {} + } + manager.registerNearbyDevicesCallback(callback) + + assertThat(provider.lastRegisteredCallback).isEqualTo(null) + } + + @Test + fun providerRegistered_isLogged() { + commandQueueCallbacks.registerNearbyMediaDevicesProvider(TestProvider()) + + verify(logger).logProviderRegistered(numProviders = 1) + } + + @Test + fun providerRegisteredTwice_onlyLoggedOnce() { + val provider = TestProvider() + + commandQueueCallbacks.registerNearbyMediaDevicesProvider(provider) + commandQueueCallbacks.registerNearbyMediaDevicesProvider(provider) + + verify(logger, times(1)).logProviderRegistered(numProviders = 1) + } + + @Test + fun multipleProvidersRegistered_isLogged() { + commandQueueCallbacks.registerNearbyMediaDevicesProvider(TestProvider()) + commandQueueCallbacks.registerNearbyMediaDevicesProvider(TestProvider()) + reset(logger) + + commandQueueCallbacks.registerNearbyMediaDevicesProvider(TestProvider()) + + verify(logger).logProviderRegistered(numProviders = 3) + } + + @Test + fun providerUnregistered_isLogged() { + val provider = TestProvider() + commandQueueCallbacks.registerNearbyMediaDevicesProvider(provider) + + commandQueueCallbacks.unregisterNearbyMediaDevicesProvider(provider) + + verify(logger).logProviderUnregistered(numProviders = 0) + } + + @Test + fun multipleProvidersRegisteredThenUnregistered_isLogged() { + val provider = TestProvider() + commandQueueCallbacks.registerNearbyMediaDevicesProvider(provider) + commandQueueCallbacks.registerNearbyMediaDevicesProvider(TestProvider()) + commandQueueCallbacks.registerNearbyMediaDevicesProvider(TestProvider()) + + commandQueueCallbacks.unregisterNearbyMediaDevicesProvider(provider) + + verify(logger).logProviderUnregistered(numProviders = 2) + } + + @Test + fun providerUnregisteredButNeverRegistered_notLogged() { + commandQueueCallbacks.unregisterNearbyMediaDevicesProvider(TestProvider()) + + verify(logger, never()).logProviderRegistered(anyInt()) + } + + @Test + fun providerBinderDied_isLogged() { + val provider = TestProvider() + commandQueueCallbacks.registerNearbyMediaDevicesProvider(provider) + + provider.deathRecipient!!.binderDied(provider) + + verify(logger).logProviderBinderDied(numProviders = 0) + } + private class TestProvider : INearbyMediaDevicesProvider.Stub() { var lastRegisteredCallback: INearbyMediaDevicesUpdateCallback? = null var lastUnregisteredCallback: INearbyMediaDevicesUpdateCallback? = null + var deathRecipient: IBinder.DeathRecipient? = null + override fun registerNearbyDevicesCallback( callback: INearbyMediaDevicesUpdateCallback ) { @@ -142,5 +232,13 @@ class NearbyMediaDevicesManagerTest : SysuiTestCase() { ) { lastUnregisteredCallback = callback } + + override fun asBinder(): IBinder { + return this + } + + override fun linkToDeath(recipient: IBinder.DeathRecipient, flags: Int) { + deathRecipient = recipient + } } } |