Remove BroadcastReceiver ref on unregister
There were unremoved references in a map in UserBroadcastDispatcher that were not being removed on unregister, leaking objects. Test: atest UserBroadcastDispatcherTest Test: hprof Fixes: 144937054 Change-Id: Icc33a28711eadcd0d566c468f34e76a3913700f3
This commit is contained in:
@@ -28,6 +28,7 @@ import android.util.ArrayMap
|
||||
import android.util.ArraySet
|
||||
import android.util.Log
|
||||
import androidx.annotation.MainThread
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import com.android.internal.util.Preconditions
|
||||
import com.android.systemui.Dumpable
|
||||
import java.io.FileDescriptor
|
||||
@@ -78,6 +79,14 @@ class UserBroadcastDispatcher(
|
||||
private val actionsToReceivers = ArrayMap<String, MutableSet<ReceiverData>>()
|
||||
private val receiverToReceiverData = ArrayMap<BroadcastReceiver, MutableSet<ReceiverData>>()
|
||||
|
||||
@VisibleForTesting
|
||||
internal fun isReceiverReferenceHeld(receiver: BroadcastReceiver): Boolean {
|
||||
return receiverToReceiverData.contains(receiver) ||
|
||||
actionsToReceivers.any {
|
||||
it.value.any { it.receiver == receiver }
|
||||
}
|
||||
}
|
||||
|
||||
// Only call on BG thread as it reads from the maps
|
||||
private fun createFilter(): IntentFilter {
|
||||
Preconditions.checkState(bgHandler.looper.isCurrentThread,
|
||||
@@ -142,7 +151,7 @@ class UserBroadcastDispatcher(
|
||||
if (DEBUG) Log.w(TAG, "Unregister receiver: $receiver")
|
||||
val actions = receiverToReceiverData.getOrElse(receiver) { return }
|
||||
.flatMap { it.filter.actionsIterator().asSequence().asIterable() }.toSet()
|
||||
receiverToReceiverData.get(receiver)?.clear()
|
||||
receiverToReceiverData.remove(receiver)?.clear()
|
||||
var changed = false
|
||||
actions.forEach { action ->
|
||||
actionsToReceivers.get(action)?.removeIf { it.receiver == receiver }
|
||||
|
||||
@@ -77,7 +77,7 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
|
||||
private lateinit var argumentCaptor: ArgumentCaptor<IntentFilter>
|
||||
|
||||
private lateinit var testableLooper: TestableLooper
|
||||
private lateinit var universalBroadcastReceiver: UserBroadcastDispatcher
|
||||
private lateinit var userBroadcastDispatcher: UserBroadcastDispatcher
|
||||
private lateinit var intentFilter: IntentFilter
|
||||
private lateinit var intentFilterOther: IntentFilter
|
||||
private lateinit var handler: Handler
|
||||
@@ -88,9 +88,9 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
|
||||
testableLooper = TestableLooper.get(this)
|
||||
handler = Handler(testableLooper.looper)
|
||||
|
||||
universalBroadcastReceiver = UserBroadcastDispatcher(
|
||||
userBroadcastDispatcher = UserBroadcastDispatcher(
|
||||
mockContext, USER_ID, handler, testableLooper.looper)
|
||||
universalBroadcastReceiver.pendingResult = mPendingResult
|
||||
userBroadcastDispatcher.pendingResult = mPendingResult
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -107,11 +107,11 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
|
||||
fun testSingleReceiverRegistered() {
|
||||
intentFilter = IntentFilter(ACTION_1)
|
||||
|
||||
universalBroadcastReceiver.registerReceiver(
|
||||
userBroadcastDispatcher.registerReceiver(
|
||||
ReceiverData(broadcastReceiver, intentFilter, mockHandler, USER_HANDLE))
|
||||
testableLooper.processAllMessages()
|
||||
|
||||
assertTrue(universalBroadcastReceiver.isRegistered())
|
||||
assertTrue(userBroadcastDispatcher.isRegistered())
|
||||
verify(mockContext).registerReceiverAsUser(
|
||||
any(),
|
||||
eq(USER_HANDLE),
|
||||
@@ -127,19 +127,19 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
|
||||
fun testSingleReceiverUnregistered() {
|
||||
intentFilter = IntentFilter(ACTION_1)
|
||||
|
||||
universalBroadcastReceiver.registerReceiver(
|
||||
userBroadcastDispatcher.registerReceiver(
|
||||
ReceiverData(broadcastReceiver, intentFilter, mockHandler, USER_HANDLE))
|
||||
testableLooper.processAllMessages()
|
||||
reset(mockContext)
|
||||
|
||||
assertTrue(universalBroadcastReceiver.isRegistered())
|
||||
assertTrue(userBroadcastDispatcher.isRegistered())
|
||||
|
||||
universalBroadcastReceiver.unregisterReceiver(broadcastReceiver)
|
||||
userBroadcastDispatcher.unregisterReceiver(broadcastReceiver)
|
||||
testableLooper.processAllMessages()
|
||||
|
||||
verify(mockContext, atLeastOnce()).unregisterReceiver(any())
|
||||
verify(mockContext, never()).registerReceiverAsUser(any(), any(), any(), any(), any())
|
||||
assertFalse(universalBroadcastReceiver.isRegistered())
|
||||
assertFalse(userBroadcastDispatcher.isRegistered())
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -150,13 +150,13 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
|
||||
addCategory(CATEGORY_2)
|
||||
}
|
||||
|
||||
universalBroadcastReceiver.registerReceiver(
|
||||
userBroadcastDispatcher.registerReceiver(
|
||||
ReceiverData(broadcastReceiver, intentFilter, mockHandler, USER_HANDLE))
|
||||
universalBroadcastReceiver.registerReceiver(
|
||||
userBroadcastDispatcher.registerReceiver(
|
||||
ReceiverData(broadcastReceiverOther, intentFilterOther, mockHandler, USER_HANDLE))
|
||||
|
||||
testableLooper.processAllMessages()
|
||||
assertTrue(universalBroadcastReceiver.isRegistered())
|
||||
assertTrue(userBroadcastDispatcher.isRegistered())
|
||||
|
||||
verify(mockContext, times(2)).registerReceiverAsUser(
|
||||
any(),
|
||||
@@ -178,14 +178,14 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
|
||||
intentFilter = IntentFilter(ACTION_1)
|
||||
intentFilterOther = IntentFilter(ACTION_2)
|
||||
|
||||
universalBroadcastReceiver.registerReceiver(
|
||||
userBroadcastDispatcher.registerReceiver(
|
||||
ReceiverData(broadcastReceiver, intentFilter, handler, USER_HANDLE))
|
||||
universalBroadcastReceiver.registerReceiver(
|
||||
userBroadcastDispatcher.registerReceiver(
|
||||
ReceiverData(broadcastReceiverOther, intentFilterOther, handler, USER_HANDLE))
|
||||
|
||||
val intent = Intent(ACTION_2)
|
||||
|
||||
universalBroadcastReceiver.onReceive(mockContext, intent)
|
||||
userBroadcastDispatcher.onReceive(mockContext, intent)
|
||||
testableLooper.processAllMessages()
|
||||
|
||||
verify(broadcastReceiver, never()).onReceive(any(), any())
|
||||
@@ -197,14 +197,14 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
|
||||
intentFilter = IntentFilter(ACTION_1)
|
||||
intentFilterOther = IntentFilter(ACTION_2)
|
||||
|
||||
universalBroadcastReceiver.registerReceiver(
|
||||
userBroadcastDispatcher.registerReceiver(
|
||||
ReceiverData(broadcastReceiver, intentFilter, handler, USER_HANDLE))
|
||||
universalBroadcastReceiver.registerReceiver(
|
||||
userBroadcastDispatcher.registerReceiver(
|
||||
ReceiverData(broadcastReceiver, intentFilterOther, handler, USER_HANDLE))
|
||||
|
||||
val intent = Intent(ACTION_2)
|
||||
|
||||
universalBroadcastReceiver.onReceive(mockContext, intent)
|
||||
userBroadcastDispatcher.onReceive(mockContext, intent)
|
||||
testableLooper.processAllMessages()
|
||||
|
||||
verify(broadcastReceiver).onReceive(mockContext, intent)
|
||||
@@ -217,14 +217,14 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
|
||||
intentFilterOther = IntentFilter(ACTION_1)
|
||||
intentFilterOther.addCategory(CATEGORY_2)
|
||||
|
||||
universalBroadcastReceiver.registerReceiver(
|
||||
userBroadcastDispatcher.registerReceiver(
|
||||
ReceiverData(broadcastReceiver, intentFilter, handler, USER_HANDLE))
|
||||
universalBroadcastReceiver.registerReceiver(
|
||||
userBroadcastDispatcher.registerReceiver(
|
||||
ReceiverData(broadcastReceiverOther, intentFilterOther, handler, USER_HANDLE))
|
||||
|
||||
val intent = Intent(ACTION_1)
|
||||
|
||||
universalBroadcastReceiver.onReceive(mockContext, intent)
|
||||
userBroadcastDispatcher.onReceive(mockContext, intent)
|
||||
testableLooper.processAllMessages()
|
||||
|
||||
verify(broadcastReceiver).onReceive(mockContext, intent)
|
||||
@@ -234,15 +234,32 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
|
||||
@Test
|
||||
fun testPendingResult() {
|
||||
intentFilter = IntentFilter(ACTION_1)
|
||||
universalBroadcastReceiver.registerReceiver(
|
||||
userBroadcastDispatcher.registerReceiver(
|
||||
ReceiverData(broadcastReceiver, intentFilter, handler, USER_HANDLE))
|
||||
|
||||
val intent = Intent(ACTION_1)
|
||||
universalBroadcastReceiver.onReceive(mockContext, intent)
|
||||
userBroadcastDispatcher.onReceive(mockContext, intent)
|
||||
|
||||
testableLooper.processAllMessages()
|
||||
|
||||
verify(broadcastReceiver).onReceive(mockContext, intent)
|
||||
verify(broadcastReceiver).pendingResult = mPendingResult
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testRemoveReceiverReferences() {
|
||||
intentFilter = IntentFilter(ACTION_1)
|
||||
userBroadcastDispatcher.registerReceiver(
|
||||
ReceiverData(broadcastReceiver, intentFilter, handler, USER_HANDLE))
|
||||
|
||||
intentFilterOther = IntentFilter(ACTION_1)
|
||||
intentFilterOther.addAction(ACTION_2)
|
||||
userBroadcastDispatcher.registerReceiver(
|
||||
ReceiverData(broadcastReceiverOther, intentFilterOther, handler, USER_HANDLE))
|
||||
|
||||
userBroadcastDispatcher.unregisterReceiver(broadcastReceiver)
|
||||
testableLooper.processAllMessages()
|
||||
|
||||
assertFalse(userBroadcastDispatcher.isReceiverReferenceHeld(broadcastReceiver))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user