Loading android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java +23 −6 Original line number Diff line number Diff line Loading @@ -66,7 +66,6 @@ public class AvrcpTargetService extends ProfileService { // Cover Art Service (Storage + BIP Server) private final AvrcpCoverArtService mAvrcpCoverArtService; private final AdapterService mAdapterService; private final AvrcpVersion mAvrcpVersion; private final MediaPlayerList mMediaPlayerList; private final PlayerSettingsManager mPlayerSettingsManager; Loading Loading @@ -100,12 +99,29 @@ public class AvrcpTargetService extends ProfileService { private static AvrcpTargetService sInstance = null; public AvrcpTargetService(AdapterService adapterService) { this( requireNonNull(adapterService), adapterService.getSystemService(AudioManager.class), AvrcpNativeInterface.getInstance(), new AvrcpVolumeManager( requireNonNull(adapterService), adapterService.getSystemService(AudioManager.class), AvrcpNativeInterface.getInstance()), Looper.myLooper()); } @VisibleForTesting AvrcpTargetService( AdapterService adapterService, AudioManager audioManager, AvrcpNativeInterface nativeInterface, AvrcpVolumeManager volumeManager, Looper looper) { super(requireNonNull(adapterService)); mAdapterService = adapterService; mAudioManager = requireNonNull(getSystemService(AudioManager.class)); mNativeInterface = requireNonNull(AvrcpNativeInterface.getInstance()); mAudioManager = requireNonNull(audioManager); mNativeInterface = requireNonNull(nativeInterface); mMediaPlayerList = new MediaPlayerList(Looper.myLooper(), this); mMediaPlayerList = new MediaPlayerList(looper, this); IntentFilter userFilter = new IntentFilter(); userFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); Loading @@ -119,7 +135,7 @@ public class AvrcpTargetService extends ProfileService { mNativeInterface.init(this); mAvrcpVersion = AvrcpVersion.getCurrentSystemPropertiesValue(); mVolumeManager = new AvrcpVolumeManager(mAdapterService, mAudioManager, mNativeInterface); mVolumeManager = requireNonNull(volumeManager); UserManager userManager = getApplicationContext().getSystemService(UserManager.class); if (userManager.isUserUnlocked()) { Loading Loading @@ -257,6 +273,7 @@ public class AvrcpTargetService extends ProfileService { mPlayerSettingsManager.cleanup(); mMediaPlayerList.cleanup(); mNativeInterface.cleanup(); mVolumeManager.cleanup(); getApplicationContext().unregisterReceiver(mUserUnlockedReceiver); } Loading android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java +5 −0 Original line number Diff line number Diff line Loading @@ -421,6 +421,11 @@ class AvrcpVolumeManager extends AudioDeviceCallback { mDeviceMap.remove(device); } /** Cleans up and unregisters any registered callbacks. */ void cleanup() { mAudioManager.unregisterAudioDeviceCallback(this); } public void dump(StringBuilder sb) { sb.append("AvrcpVolumeManager:\n"); sb.append(" mCurrentDevice: ").append(mCurrentDevice).append("\n"); Loading android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpTargetServiceTest.java +102 −0 Original line number Diff line number Diff line Loading @@ -18,17 +18,41 @@ package com.android.bluetooth.avrcp; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyObject; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.verify; import android.content.Context; import android.content.SharedPreferences; import android.content.res.Resources; import android.media.AudioDeviceCallback; import android.media.AudioManager; import android.media.session.MediaSessionManager; import android.net.Uri; import android.os.UserManager; import android.os.test.TestLooper; import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.TestUtils; import com.android.bluetooth.audio_util.Image; import com.android.bluetooth.audio_util.Metadata; import com.android.bluetooth.btservice.AdapterService; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.List; Loading @@ -37,8 +61,63 @@ import java.util.List; @RunWith(AndroidJUnit4.class) public class AvrcpTargetServiceTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); private @Mock AdapterService mMockAdapterService; private @Mock AudioManager mMockAudioManager; private @Mock AvrcpNativeInterface mMockNativeInterface; private @Mock UserManager mMockUserManager; private @Mock Resources mMockResources; private @Mock SharedPreferences mMockSharedPreferences; private @Mock SharedPreferences.Editor mMockSharedPreferencesEditor; private @Captor ArgumentCaptor<AudioDeviceCallback> mAudioDeviceCb; private MediaSessionManager mMediaSessionManager; private TestLooper mLooper; private static final String TEST_DATA = "-1"; @Before public void setUp() throws Exception { mLooper = new TestLooper(); mLooper.startAutoDispatch(); doReturn(mMockAudioManager) .when(mMockAdapterService) .getSystemService(Context.AUDIO_SERVICE); doReturn(Context.AUDIO_SERVICE) .when(mMockAdapterService) .getSystemServiceName(AudioManager.class); mMediaSessionManager = InstrumentationRegistry.getInstrumentation() .getTargetContext() .getSystemService(MediaSessionManager.class); TestUtils.mockGetSystemService( mMockAdapterService, Context.MEDIA_SESSION_SERVICE, MediaSessionManager.class, mMediaSessionManager); doReturn(mLooper.getNewExecutor()).when(mMockAdapterService).getMainExecutor(); doReturn(mMockAdapterService).when(mMockAdapterService).getApplicationContext(); TestUtils.mockGetSystemService( mMockAdapterService, Context.USER_SERVICE, UserManager.class, mMockUserManager); doReturn(mMockResources).when(mMockAdapterService).getResources(); doReturn(mMockSharedPreferencesEditor).when(mMockSharedPreferences).edit(); doReturn(mMockSharedPreferences) .when(mMockAdapterService) .getSharedPreferences(anyString(), anyInt()); } @After public void tearDown() throws Exception { mLooper.stopAutoDispatchAndIgnoreExceptions(); } @Test public void testQueueUpdateData() { List<Metadata> firstQueue = new ArrayList<Metadata>(); Loading Loading @@ -75,4 +154,27 @@ public class AvrcpTargetServiceTest { Metadata.Builder builder = new Metadata.Builder(); return builder.useDefaults().build(); } @Test public void testServiceInstance() { AvrcpVolumeManager volumeManager = new AvrcpVolumeManager( mMockAdapterService, mMockAudioManager, mMockNativeInterface); AvrcpTargetService service = new AvrcpTargetService( mMockAdapterService, mMockAudioManager, mMockNativeInterface, volumeManager, mLooper.getLooper()); service.start(); verify(mMockAudioManager) .registerAudioDeviceCallback(mAudioDeviceCb.capture(), anyObject()); service.stop(); service.cleanup(); assertThat(mAudioDeviceCb.getValue()).isNotNull(); verify(mMockAudioManager).unregisterAudioDeviceCallback(mAudioDeviceCb.getValue()); } } Loading
android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java +23 −6 Original line number Diff line number Diff line Loading @@ -66,7 +66,6 @@ public class AvrcpTargetService extends ProfileService { // Cover Art Service (Storage + BIP Server) private final AvrcpCoverArtService mAvrcpCoverArtService; private final AdapterService mAdapterService; private final AvrcpVersion mAvrcpVersion; private final MediaPlayerList mMediaPlayerList; private final PlayerSettingsManager mPlayerSettingsManager; Loading Loading @@ -100,12 +99,29 @@ public class AvrcpTargetService extends ProfileService { private static AvrcpTargetService sInstance = null; public AvrcpTargetService(AdapterService adapterService) { this( requireNonNull(adapterService), adapterService.getSystemService(AudioManager.class), AvrcpNativeInterface.getInstance(), new AvrcpVolumeManager( requireNonNull(adapterService), adapterService.getSystemService(AudioManager.class), AvrcpNativeInterface.getInstance()), Looper.myLooper()); } @VisibleForTesting AvrcpTargetService( AdapterService adapterService, AudioManager audioManager, AvrcpNativeInterface nativeInterface, AvrcpVolumeManager volumeManager, Looper looper) { super(requireNonNull(adapterService)); mAdapterService = adapterService; mAudioManager = requireNonNull(getSystemService(AudioManager.class)); mNativeInterface = requireNonNull(AvrcpNativeInterface.getInstance()); mAudioManager = requireNonNull(audioManager); mNativeInterface = requireNonNull(nativeInterface); mMediaPlayerList = new MediaPlayerList(Looper.myLooper(), this); mMediaPlayerList = new MediaPlayerList(looper, this); IntentFilter userFilter = new IntentFilter(); userFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); Loading @@ -119,7 +135,7 @@ public class AvrcpTargetService extends ProfileService { mNativeInterface.init(this); mAvrcpVersion = AvrcpVersion.getCurrentSystemPropertiesValue(); mVolumeManager = new AvrcpVolumeManager(mAdapterService, mAudioManager, mNativeInterface); mVolumeManager = requireNonNull(volumeManager); UserManager userManager = getApplicationContext().getSystemService(UserManager.class); if (userManager.isUserUnlocked()) { Loading Loading @@ -257,6 +273,7 @@ public class AvrcpTargetService extends ProfileService { mPlayerSettingsManager.cleanup(); mMediaPlayerList.cleanup(); mNativeInterface.cleanup(); mVolumeManager.cleanup(); getApplicationContext().unregisterReceiver(mUserUnlockedReceiver); } Loading
android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java +5 −0 Original line number Diff line number Diff line Loading @@ -421,6 +421,11 @@ class AvrcpVolumeManager extends AudioDeviceCallback { mDeviceMap.remove(device); } /** Cleans up and unregisters any registered callbacks. */ void cleanup() { mAudioManager.unregisterAudioDeviceCallback(this); } public void dump(StringBuilder sb) { sb.append("AvrcpVolumeManager:\n"); sb.append(" mCurrentDevice: ").append(mCurrentDevice).append("\n"); Loading
android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpTargetServiceTest.java +102 −0 Original line number Diff line number Diff line Loading @@ -18,17 +18,41 @@ package com.android.bluetooth.avrcp; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyObject; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.verify; import android.content.Context; import android.content.SharedPreferences; import android.content.res.Resources; import android.media.AudioDeviceCallback; import android.media.AudioManager; import android.media.session.MediaSessionManager; import android.net.Uri; import android.os.UserManager; import android.os.test.TestLooper; import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.TestUtils; import com.android.bluetooth.audio_util.Image; import com.android.bluetooth.audio_util.Metadata; import com.android.bluetooth.btservice.AdapterService; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.List; Loading @@ -37,8 +61,63 @@ import java.util.List; @RunWith(AndroidJUnit4.class) public class AvrcpTargetServiceTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); private @Mock AdapterService mMockAdapterService; private @Mock AudioManager mMockAudioManager; private @Mock AvrcpNativeInterface mMockNativeInterface; private @Mock UserManager mMockUserManager; private @Mock Resources mMockResources; private @Mock SharedPreferences mMockSharedPreferences; private @Mock SharedPreferences.Editor mMockSharedPreferencesEditor; private @Captor ArgumentCaptor<AudioDeviceCallback> mAudioDeviceCb; private MediaSessionManager mMediaSessionManager; private TestLooper mLooper; private static final String TEST_DATA = "-1"; @Before public void setUp() throws Exception { mLooper = new TestLooper(); mLooper.startAutoDispatch(); doReturn(mMockAudioManager) .when(mMockAdapterService) .getSystemService(Context.AUDIO_SERVICE); doReturn(Context.AUDIO_SERVICE) .when(mMockAdapterService) .getSystemServiceName(AudioManager.class); mMediaSessionManager = InstrumentationRegistry.getInstrumentation() .getTargetContext() .getSystemService(MediaSessionManager.class); TestUtils.mockGetSystemService( mMockAdapterService, Context.MEDIA_SESSION_SERVICE, MediaSessionManager.class, mMediaSessionManager); doReturn(mLooper.getNewExecutor()).when(mMockAdapterService).getMainExecutor(); doReturn(mMockAdapterService).when(mMockAdapterService).getApplicationContext(); TestUtils.mockGetSystemService( mMockAdapterService, Context.USER_SERVICE, UserManager.class, mMockUserManager); doReturn(mMockResources).when(mMockAdapterService).getResources(); doReturn(mMockSharedPreferencesEditor).when(mMockSharedPreferences).edit(); doReturn(mMockSharedPreferences) .when(mMockAdapterService) .getSharedPreferences(anyString(), anyInt()); } @After public void tearDown() throws Exception { mLooper.stopAutoDispatchAndIgnoreExceptions(); } @Test public void testQueueUpdateData() { List<Metadata> firstQueue = new ArrayList<Metadata>(); Loading Loading @@ -75,4 +154,27 @@ public class AvrcpTargetServiceTest { Metadata.Builder builder = new Metadata.Builder(); return builder.useDefaults().build(); } @Test public void testServiceInstance() { AvrcpVolumeManager volumeManager = new AvrcpVolumeManager( mMockAdapterService, mMockAudioManager, mMockNativeInterface); AvrcpTargetService service = new AvrcpTargetService( mMockAdapterService, mMockAudioManager, mMockNativeInterface, volumeManager, mLooper.getLooper()); service.start(); verify(mMockAudioManager) .registerAudioDeviceCallback(mAudioDeviceCb.capture(), anyObject()); service.stop(); service.cleanup(); assertThat(mAudioDeviceCb.getValue()).isNotNull(); verify(mMockAudioManager).unregisterAudioDeviceCallback(mAudioDeviceCb.getValue()); } }