Loading packages/SystemUI/src/com/android/systemui/media/controls/domain/resume/MediaResumeListener.kt +10 −9 Original line number Diff line number Diff line Loading @@ -80,6 +80,7 @@ constructor( field?.disconnect() field = value } private var currentUserId: Int = context.userId @VisibleForTesting Loading @@ -89,7 +90,7 @@ constructor( if (Intent.ACTION_USER_UNLOCKED == intent.action) { val userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1) if (userId == currentUserId) { loadMediaResumptionControls() backgroundExecutor.execute { loadMediaResumptionControls() } } } } Loading Loading @@ -254,6 +255,7 @@ constructor( if (data.resumeAction == null && !data.hasCheckedForResume && isEligibleForResume) { // TODO also check for a media button receiver intended for restarting (b/154127084) // Set null action to prevent additional attempts to connect backgroundExecutor.execute { mediaDataManager.setResumeAction(key, null) Log.d(TAG, "Checking for service component for " + data.packageName) val pm = context.packageManager Loading @@ -262,7 +264,6 @@ constructor( val inf = resumeInfo?.filter { it.serviceInfo.packageName == data.packageName } if (inf != null && inf.size > 0) { backgroundExecutor.execute { tryUpdateResumptionList(key, inf!!.get(0).componentInfo.componentName) } } Loading packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/resume/MediaResumeListenerTest.kt +33 −26 Original line number Diff line number Diff line Loading @@ -138,6 +138,7 @@ class MediaResumeListenerTest : SysuiTestCase() { whenever(mockContext.packageManager).thenReturn(context.packageManager) whenever(mockContext.contentResolver).thenReturn(context.contentResolver) whenever(mockContext.userId).thenReturn(context.userId) whenever(mockContext.resources).thenReturn(context.resources) whenever(mediaFlags.isRemoteResumeAllowed()).thenReturn(false) executor = FakeExecutor(clock) Loading Loading @@ -210,7 +211,7 @@ class MediaResumeListenerTest : SysuiTestCase() { @Test fun testOnLoad_checksForResume_noService() { // When media data is loaded that has not been checked yet, and does not have a MBS resumeListener.onMediaDataLoaded(KEY, null, data) onMediaDataLoaded(KEY, null, data) // Then we report back to the manager verify(mediaDataManager).setResumeAction(KEY, null) Loading @@ -223,8 +224,7 @@ class MediaResumeListenerTest : SysuiTestCase() { whenever(resumeBrowser.testConnection()).thenAnswer { callbackCaptor.value.onError() } // When media data is loaded that has not been checked yet, and does not have a MBS resumeListener.onMediaDataLoaded(KEY, null, data) executor.runAllReady() onMediaDataLoaded(KEY, null, data) // Then we report back to the manager verify(mediaDataManager).setResumeAction(eq(KEY), eq(null)) Loading @@ -234,7 +234,7 @@ class MediaResumeListenerTest : SysuiTestCase() { fun testOnLoad_localCast_doesNotCheck() { // When media data is loaded that has not been checked yet, and is a local cast val dataCast = data.copy(playbackLocation = MediaData.PLAYBACK_CAST_LOCAL) resumeListener.onMediaDataLoaded(KEY, null, dataCast) onMediaDataLoaded(KEY, null, dataCast, false) // Then we do not take action verify(mediaDataManager, never()).setResumeAction(any(), any()) Loading @@ -244,7 +244,7 @@ class MediaResumeListenerTest : SysuiTestCase() { fun testOnload_remoteCast_doesNotCheck() { // When media data is loaded that has not been checked yet, and is a remote cast val dataRcn = data.copy(playbackLocation = MediaData.PLAYBACK_CAST_REMOTE) resumeListener.onMediaDataLoaded(KEY, null, dataRcn) onMediaDataLoaded(KEY, null, dataRcn, resume = false) // Then we do not take action verify(mediaDataManager, never()).setResumeAction(any(), any()) Loading @@ -257,7 +257,7 @@ class MediaResumeListenerTest : SysuiTestCase() { // When media data is loaded that has not been checked yet, and is a local cast val dataCast = data.copy(playbackLocation = MediaData.PLAYBACK_CAST_LOCAL) resumeListener.onMediaDataLoaded(KEY, null, dataCast) onMediaDataLoaded(KEY, null, dataCast) // Then we report back to the manager verify(mediaDataManager).setResumeAction(KEY, null) Loading @@ -270,7 +270,7 @@ class MediaResumeListenerTest : SysuiTestCase() { // When media data is loaded that has not been checked yet, and is a remote cast val dataRcn = data.copy(playbackLocation = MediaData.PLAYBACK_CAST_REMOTE) resumeListener.onMediaDataLoaded(KEY, null, dataRcn) onMediaDataLoaded(KEY, null, dataRcn, false) // Then we do not take action verify(mediaDataManager, never()).setResumeAction(any(), any()) Loading @@ -288,10 +288,9 @@ class MediaResumeListenerTest : SysuiTestCase() { // When media data is loaded that has not been checked yet, and does have a MBS val dataCopy = data.copy(resumeAction = null, hasCheckedForResume = false) resumeListener.onMediaDataLoaded(KEY, null, dataCopy) onMediaDataLoaded(KEY, null, dataCopy) // Then we test whether the service is valid executor.runAllReady() verify(mediaDataManager).setResumeAction(eq(KEY), eq(null)) verify(resumeBrowser).testConnection() Loading @@ -307,7 +306,7 @@ class MediaResumeListenerTest : SysuiTestCase() { fun testOnLoad_doesNotCheckAgain() { // When a media data is loaded that has been checked already var dataCopy = data.copy(hasCheckedForResume = true) resumeListener.onMediaDataLoaded(KEY, null, dataCopy) onMediaDataLoaded(KEY, null, dataCopy, resume = false) // Then we should not check it again verify(resumeBrowser, never()).testConnection() Loading @@ -320,17 +319,15 @@ class MediaResumeListenerTest : SysuiTestCase() { setUpMbsWithValidResolveInfo() resumeListener.onMediaDataLoaded(KEY, null, data) // We notify the manager to set a null action verify(mediaDataManager).setResumeAction(KEY, null) // If we then get another update from the app before the first check completes assertThat(executor.numPending()).isEqualTo(1) var dataWithCheck = data.copy(hasCheckedForResume = true) resumeListener.onMediaDataLoaded(KEY, null, dataWithCheck) // We do not try to start another check assertThat(executor.numPending()).isEqualTo(1) executor.runAllReady() verify(mediaDataManager).setResumeAction(KEY, null) verify(resumeBrowserFactory, times(1)).create(any(), any(), anyInt()) } @Test Loading Loading @@ -363,6 +360,7 @@ class MediaResumeListenerTest : SysuiTestCase() { resumeListener.userUnlockReceiver.onReceive(context, intent) // Then we should attempt to find recent media for each saved component executor.runAllReady() verify(resumeBrowser, times(3)).findRecentMedia() // Then since the mock service found media, the manager should be informed Loading @@ -382,10 +380,9 @@ class MediaResumeListenerTest : SysuiTestCase() { // When media data is loaded that has not been checked yet, and does have a MBS val dataCopy = data.copy(resumeAction = null, hasCheckedForResume = false) resumeListener.onMediaDataLoaded(KEY, null, dataCopy) onMediaDataLoaded(KEY, null, dataCopy) // Then we test whether the service is valid and set the resume action executor.runAllReady() verify(mediaDataManager).setResumeAction(eq(KEY), eq(null)) verify(resumeBrowser).testConnection() verify(mediaDataManager, times(2)).setResumeAction(eq(KEY), capture(actionCaptor)) Loading Loading @@ -455,6 +452,7 @@ class MediaResumeListenerTest : SysuiTestCase() { resumeListener.userUnlockReceiver.onReceive(mockContext, intent) // We add its resume controls executor.runAllReady() verify(resumeBrowser).findRecentMedia() verify(mediaDataManager) .addResumptionControls(anyInt(), any(), any(), any(), any(), any(), eq(PACKAGE_NAME)) Loading Loading @@ -527,7 +525,7 @@ class MediaResumeListenerTest : SysuiTestCase() { // When media data is loaded that has not been checked yet, and does have a MBS val dataCopy = data.copy(resumeAction = null, hasCheckedForResume = false) resumeListener.onMediaDataLoaded(KEY, null, dataCopy) onMediaDataLoaded(KEY, null, dataCopy) // Then we store the new lastPlayed time verify(sharedPrefsEditor).putString(any(), (capture(componentCaptor))) Loading @@ -546,10 +544,9 @@ class MediaResumeListenerTest : SysuiTestCase() { fun testOnMediaDataLoaded_newKeyDifferent_oldMediaBrowserDisconnected() { setUpMbsWithValidResolveInfo() resumeListener.onMediaDataLoaded(key = KEY, oldKey = null, data) executor.runAllReady() onMediaDataLoaded(key = KEY, oldKey = null, data) resumeListener.onMediaDataLoaded(key = "newKey", oldKey = KEY, data) onMediaDataLoaded(key = "newKey", oldKey = KEY, data) verify(resumeBrowser).disconnect() } Loading @@ -561,8 +558,7 @@ class MediaResumeListenerTest : SysuiTestCase() { // Set up mocks to return with an error whenever(resumeBrowser.testConnection()).thenAnswer { callbackCaptor.value.onError() } resumeListener.onMediaDataLoaded(key = KEY, oldKey = null, data) executor.runAllReady() onMediaDataLoaded(key = KEY, oldKey = null, data) // Ensure we disconnect the browser verify(resumeBrowser).disconnect() Loading @@ -579,8 +575,7 @@ class MediaResumeListenerTest : SysuiTestCase() { callbackCaptor.value.addTrack(description, component, resumeBrowser) } resumeListener.onMediaDataLoaded(key = KEY, oldKey = null, data) executor.runAllReady() onMediaDataLoaded(key = KEY, oldKey = null, data) // Ensure we disconnect the browser verify(resumeBrowser).disconnect() Loading @@ -598,8 +593,7 @@ class MediaResumeListenerTest : SysuiTestCase() { // Load media data that will require us to get the resume action val dataCopy = data.copy(resumeAction = null, hasCheckedForResume = false) resumeListener.onMediaDataLoaded(KEY, null, dataCopy) executor.runAllReady() onMediaDataLoaded(KEY, null, dataCopy) verify(mediaDataManager, times(2)).setResumeAction(eq(KEY), capture(actionCaptor)) // Set up our factory to return a new browser so we can verify we disconnected the old one Loading Loading @@ -634,6 +628,7 @@ class MediaResumeListenerTest : SysuiTestCase() { // When the first user unlocks and we query their recent media userCallbackCaptor.value.onUserChanged(firstUserId, context) resumeListener.userUnlockReceiver.onReceive(context, unlockIntent) executor.runAllReady() whenever(resumeBrowser.userId).thenReturn(userIdCaptor.value) verify(resumeBrowser, times(3)).findRecentMedia() Loading Loading @@ -688,4 +683,16 @@ class MediaResumeListenerTest : SysuiTestCase() { whenever(pm.resolveServiceAsUser(any(), anyInt(), anyInt())).thenReturn(resolveInfo) whenever(pm.getApplicationLabel(any())).thenReturn(PACKAGE_NAME) } private fun onMediaDataLoaded( key: String, oldKey: String?, data: MediaData, resume: Boolean = true ) { resumeListener.onMediaDataLoaded(key, oldKey, data) if (resume) { assertThat(executor.runAllReady()).isEqualTo(1) } } } Loading
packages/SystemUI/src/com/android/systemui/media/controls/domain/resume/MediaResumeListener.kt +10 −9 Original line number Diff line number Diff line Loading @@ -80,6 +80,7 @@ constructor( field?.disconnect() field = value } private var currentUserId: Int = context.userId @VisibleForTesting Loading @@ -89,7 +90,7 @@ constructor( if (Intent.ACTION_USER_UNLOCKED == intent.action) { val userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1) if (userId == currentUserId) { loadMediaResumptionControls() backgroundExecutor.execute { loadMediaResumptionControls() } } } } Loading Loading @@ -254,6 +255,7 @@ constructor( if (data.resumeAction == null && !data.hasCheckedForResume && isEligibleForResume) { // TODO also check for a media button receiver intended for restarting (b/154127084) // Set null action to prevent additional attempts to connect backgroundExecutor.execute { mediaDataManager.setResumeAction(key, null) Log.d(TAG, "Checking for service component for " + data.packageName) val pm = context.packageManager Loading @@ -262,7 +264,6 @@ constructor( val inf = resumeInfo?.filter { it.serviceInfo.packageName == data.packageName } if (inf != null && inf.size > 0) { backgroundExecutor.execute { tryUpdateResumptionList(key, inf!!.get(0).componentInfo.componentName) } } Loading
packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/resume/MediaResumeListenerTest.kt +33 −26 Original line number Diff line number Diff line Loading @@ -138,6 +138,7 @@ class MediaResumeListenerTest : SysuiTestCase() { whenever(mockContext.packageManager).thenReturn(context.packageManager) whenever(mockContext.contentResolver).thenReturn(context.contentResolver) whenever(mockContext.userId).thenReturn(context.userId) whenever(mockContext.resources).thenReturn(context.resources) whenever(mediaFlags.isRemoteResumeAllowed()).thenReturn(false) executor = FakeExecutor(clock) Loading Loading @@ -210,7 +211,7 @@ class MediaResumeListenerTest : SysuiTestCase() { @Test fun testOnLoad_checksForResume_noService() { // When media data is loaded that has not been checked yet, and does not have a MBS resumeListener.onMediaDataLoaded(KEY, null, data) onMediaDataLoaded(KEY, null, data) // Then we report back to the manager verify(mediaDataManager).setResumeAction(KEY, null) Loading @@ -223,8 +224,7 @@ class MediaResumeListenerTest : SysuiTestCase() { whenever(resumeBrowser.testConnection()).thenAnswer { callbackCaptor.value.onError() } // When media data is loaded that has not been checked yet, and does not have a MBS resumeListener.onMediaDataLoaded(KEY, null, data) executor.runAllReady() onMediaDataLoaded(KEY, null, data) // Then we report back to the manager verify(mediaDataManager).setResumeAction(eq(KEY), eq(null)) Loading @@ -234,7 +234,7 @@ class MediaResumeListenerTest : SysuiTestCase() { fun testOnLoad_localCast_doesNotCheck() { // When media data is loaded that has not been checked yet, and is a local cast val dataCast = data.copy(playbackLocation = MediaData.PLAYBACK_CAST_LOCAL) resumeListener.onMediaDataLoaded(KEY, null, dataCast) onMediaDataLoaded(KEY, null, dataCast, false) // Then we do not take action verify(mediaDataManager, never()).setResumeAction(any(), any()) Loading @@ -244,7 +244,7 @@ class MediaResumeListenerTest : SysuiTestCase() { fun testOnload_remoteCast_doesNotCheck() { // When media data is loaded that has not been checked yet, and is a remote cast val dataRcn = data.copy(playbackLocation = MediaData.PLAYBACK_CAST_REMOTE) resumeListener.onMediaDataLoaded(KEY, null, dataRcn) onMediaDataLoaded(KEY, null, dataRcn, resume = false) // Then we do not take action verify(mediaDataManager, never()).setResumeAction(any(), any()) Loading @@ -257,7 +257,7 @@ class MediaResumeListenerTest : SysuiTestCase() { // When media data is loaded that has not been checked yet, and is a local cast val dataCast = data.copy(playbackLocation = MediaData.PLAYBACK_CAST_LOCAL) resumeListener.onMediaDataLoaded(KEY, null, dataCast) onMediaDataLoaded(KEY, null, dataCast) // Then we report back to the manager verify(mediaDataManager).setResumeAction(KEY, null) Loading @@ -270,7 +270,7 @@ class MediaResumeListenerTest : SysuiTestCase() { // When media data is loaded that has not been checked yet, and is a remote cast val dataRcn = data.copy(playbackLocation = MediaData.PLAYBACK_CAST_REMOTE) resumeListener.onMediaDataLoaded(KEY, null, dataRcn) onMediaDataLoaded(KEY, null, dataRcn, false) // Then we do not take action verify(mediaDataManager, never()).setResumeAction(any(), any()) Loading @@ -288,10 +288,9 @@ class MediaResumeListenerTest : SysuiTestCase() { // When media data is loaded that has not been checked yet, and does have a MBS val dataCopy = data.copy(resumeAction = null, hasCheckedForResume = false) resumeListener.onMediaDataLoaded(KEY, null, dataCopy) onMediaDataLoaded(KEY, null, dataCopy) // Then we test whether the service is valid executor.runAllReady() verify(mediaDataManager).setResumeAction(eq(KEY), eq(null)) verify(resumeBrowser).testConnection() Loading @@ -307,7 +306,7 @@ class MediaResumeListenerTest : SysuiTestCase() { fun testOnLoad_doesNotCheckAgain() { // When a media data is loaded that has been checked already var dataCopy = data.copy(hasCheckedForResume = true) resumeListener.onMediaDataLoaded(KEY, null, dataCopy) onMediaDataLoaded(KEY, null, dataCopy, resume = false) // Then we should not check it again verify(resumeBrowser, never()).testConnection() Loading @@ -320,17 +319,15 @@ class MediaResumeListenerTest : SysuiTestCase() { setUpMbsWithValidResolveInfo() resumeListener.onMediaDataLoaded(KEY, null, data) // We notify the manager to set a null action verify(mediaDataManager).setResumeAction(KEY, null) // If we then get another update from the app before the first check completes assertThat(executor.numPending()).isEqualTo(1) var dataWithCheck = data.copy(hasCheckedForResume = true) resumeListener.onMediaDataLoaded(KEY, null, dataWithCheck) // We do not try to start another check assertThat(executor.numPending()).isEqualTo(1) executor.runAllReady() verify(mediaDataManager).setResumeAction(KEY, null) verify(resumeBrowserFactory, times(1)).create(any(), any(), anyInt()) } @Test Loading Loading @@ -363,6 +360,7 @@ class MediaResumeListenerTest : SysuiTestCase() { resumeListener.userUnlockReceiver.onReceive(context, intent) // Then we should attempt to find recent media for each saved component executor.runAllReady() verify(resumeBrowser, times(3)).findRecentMedia() // Then since the mock service found media, the manager should be informed Loading @@ -382,10 +380,9 @@ class MediaResumeListenerTest : SysuiTestCase() { // When media data is loaded that has not been checked yet, and does have a MBS val dataCopy = data.copy(resumeAction = null, hasCheckedForResume = false) resumeListener.onMediaDataLoaded(KEY, null, dataCopy) onMediaDataLoaded(KEY, null, dataCopy) // Then we test whether the service is valid and set the resume action executor.runAllReady() verify(mediaDataManager).setResumeAction(eq(KEY), eq(null)) verify(resumeBrowser).testConnection() verify(mediaDataManager, times(2)).setResumeAction(eq(KEY), capture(actionCaptor)) Loading Loading @@ -455,6 +452,7 @@ class MediaResumeListenerTest : SysuiTestCase() { resumeListener.userUnlockReceiver.onReceive(mockContext, intent) // We add its resume controls executor.runAllReady() verify(resumeBrowser).findRecentMedia() verify(mediaDataManager) .addResumptionControls(anyInt(), any(), any(), any(), any(), any(), eq(PACKAGE_NAME)) Loading Loading @@ -527,7 +525,7 @@ class MediaResumeListenerTest : SysuiTestCase() { // When media data is loaded that has not been checked yet, and does have a MBS val dataCopy = data.copy(resumeAction = null, hasCheckedForResume = false) resumeListener.onMediaDataLoaded(KEY, null, dataCopy) onMediaDataLoaded(KEY, null, dataCopy) // Then we store the new lastPlayed time verify(sharedPrefsEditor).putString(any(), (capture(componentCaptor))) Loading @@ -546,10 +544,9 @@ class MediaResumeListenerTest : SysuiTestCase() { fun testOnMediaDataLoaded_newKeyDifferent_oldMediaBrowserDisconnected() { setUpMbsWithValidResolveInfo() resumeListener.onMediaDataLoaded(key = KEY, oldKey = null, data) executor.runAllReady() onMediaDataLoaded(key = KEY, oldKey = null, data) resumeListener.onMediaDataLoaded(key = "newKey", oldKey = KEY, data) onMediaDataLoaded(key = "newKey", oldKey = KEY, data) verify(resumeBrowser).disconnect() } Loading @@ -561,8 +558,7 @@ class MediaResumeListenerTest : SysuiTestCase() { // Set up mocks to return with an error whenever(resumeBrowser.testConnection()).thenAnswer { callbackCaptor.value.onError() } resumeListener.onMediaDataLoaded(key = KEY, oldKey = null, data) executor.runAllReady() onMediaDataLoaded(key = KEY, oldKey = null, data) // Ensure we disconnect the browser verify(resumeBrowser).disconnect() Loading @@ -579,8 +575,7 @@ class MediaResumeListenerTest : SysuiTestCase() { callbackCaptor.value.addTrack(description, component, resumeBrowser) } resumeListener.onMediaDataLoaded(key = KEY, oldKey = null, data) executor.runAllReady() onMediaDataLoaded(key = KEY, oldKey = null, data) // Ensure we disconnect the browser verify(resumeBrowser).disconnect() Loading @@ -598,8 +593,7 @@ class MediaResumeListenerTest : SysuiTestCase() { // Load media data that will require us to get the resume action val dataCopy = data.copy(resumeAction = null, hasCheckedForResume = false) resumeListener.onMediaDataLoaded(KEY, null, dataCopy) executor.runAllReady() onMediaDataLoaded(KEY, null, dataCopy) verify(mediaDataManager, times(2)).setResumeAction(eq(KEY), capture(actionCaptor)) // Set up our factory to return a new browser so we can verify we disconnected the old one Loading Loading @@ -634,6 +628,7 @@ class MediaResumeListenerTest : SysuiTestCase() { // When the first user unlocks and we query their recent media userCallbackCaptor.value.onUserChanged(firstUserId, context) resumeListener.userUnlockReceiver.onReceive(context, unlockIntent) executor.runAllReady() whenever(resumeBrowser.userId).thenReturn(userIdCaptor.value) verify(resumeBrowser, times(3)).findRecentMedia() Loading Loading @@ -688,4 +683,16 @@ class MediaResumeListenerTest : SysuiTestCase() { whenever(pm.resolveServiceAsUser(any(), anyInt(), anyInt())).thenReturn(resolveInfo) whenever(pm.getApplicationLabel(any())).thenReturn(PACKAGE_NAME) } private fun onMediaDataLoaded( key: String, oldKey: String?, data: MediaData, resume: Boolean = true ) { resumeListener.onMediaDataLoaded(key, oldKey, data) if (resume) { assertThat(executor.runAllReady()).isEqualTo(1) } } }