Handle onNullBinding

According to the docs, an onNullBinding requires the service to be
manually unbound.
Test: test apk that return null on onBind
Test: atest ControlsProviderLifecycleManager
Fixes: 212286849

Change-Id: I71a59b875bbf9eb411e6e92ddc5a04a7353a46c4
This commit is contained in:
Fabian Kozynski
2022-01-11 11:58:59 -05:00
parent e088b3cb5a
commit d0e683b8f6
2 changed files with 47 additions and 9 deletions

View File

@@ -130,6 +130,12 @@ class ControlsProviderLifecycleManager(
wrapper = null
bindService(false)
}
override fun onNullBinding(name: ComponentName?) {
if (DEBUG) Log.d(TAG, "onNullBinding $name")
wrapper = null
context.unbindService(this)
}
}
private fun handlePendingServiceMethods() {

View File

@@ -17,6 +17,9 @@
package com.android.systemui.controls.controller
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.UserHandle
import android.service.controls.IControlsActionCallback
import android.service.controls.IControlsProvider
@@ -43,6 +46,8 @@ import org.mockito.ArgumentMatchers.eq
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.Mockito.anyInt
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@@ -57,8 +62,6 @@ class ControlsProviderLifecycleManagerTest : SysuiTestCase() {
private lateinit var subscriberService: IControlsSubscriber.Stub
@Mock
private lateinit var service: IControlsProvider.Stub
@Mock
private lateinit var loadCallback: ControlsBindingController.LoadCallback
@Captor
private lateinit var wrapperCaptor: ArgumentCaptor<ControlActionWrapper>
@@ -75,7 +78,7 @@ class ControlsProviderLifecycleManagerTest : SysuiTestCase() {
fun setUp() {
MockitoAnnotations.initMocks(this)
mContext.addMockService(componentName, service)
context.addMockService(componentName, service)
executor = FakeExecutor(FakeSystemClock())
`when`(service.asBinder()).thenCallRealMethod()
`when`(service.queryLocalInterface(ArgumentMatchers.anyString())).thenReturn(service)
@@ -98,7 +101,36 @@ class ControlsProviderLifecycleManagerTest : SysuiTestCase() {
fun testBindService() {
manager.bindService()
executor.runAllReady()
assertTrue(mContext.isBound(componentName))
assertTrue(context.isBound(componentName))
}
@Test
fun testNullBinding() {
val mockContext = mock(Context::class.java)
lateinit var serviceConnection: ServiceConnection
`when`(mockContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer {
val component = (it.arguments[0] as Intent).component
if (component == componentName) {
serviceConnection = it.arguments[1] as ServiceConnection
serviceConnection.onNullBinding(component)
true
} else {
false
}
}
val nullManager = ControlsProviderLifecycleManager(
mockContext,
executor,
actionCallbackService,
UserHandle.of(0),
componentName
)
nullManager.bindService()
executor.runAllReady()
verify(mockContext).unbindService(serviceConnection)
}
@Test
@@ -109,7 +141,7 @@ class ControlsProviderLifecycleManagerTest : SysuiTestCase() {
manager.unbindService()
executor.runAllReady()
assertFalse(mContext.isBound(componentName))
assertFalse(context.isBound(componentName))
}
@Test
@@ -119,7 +151,7 @@ class ControlsProviderLifecycleManagerTest : SysuiTestCase() {
verify(service).load(subscriberService)
assertTrue(mContext.isBound(componentName))
assertTrue(context.isBound(componentName))
}
@Test
@@ -129,7 +161,7 @@ class ControlsProviderLifecycleManagerTest : SysuiTestCase() {
manager.unbindService()
executor.runAllReady()
assertFalse(mContext.isBound(componentName))
assertFalse(context.isBound(componentName))
}
@Test
@@ -162,7 +194,7 @@ class ControlsProviderLifecycleManagerTest : SysuiTestCase() {
manager.maybeBindAndSubscribe(list, subscriberService)
executor.runAllReady()
assertTrue(mContext.isBound(componentName))
assertTrue(context.isBound(componentName))
verify(service).subscribe(list, subscriberService)
}
@@ -173,7 +205,7 @@ class ControlsProviderLifecycleManagerTest : SysuiTestCase() {
manager.maybeBindAndSendAction(controlId, action)
executor.runAllReady()
assertTrue(mContext.isBound(componentName))
assertTrue(context.isBound(componentName))
verify(service).action(eq(controlId), capture(wrapperCaptor),
eq(actionCallbackService))
assertEquals(action, wrapperCaptor.getValue().getWrappedAction())