Merge "Add logs for BroadcastDispatcher" into rvc-dev am: 8b9bfd8d1a am: 90a3e7e5fb
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/11821047 Change-Id: Ibb15ef816f91fa655ef2bb1c406c7692a83fb6fc
This commit is contained in:
@@ -28,12 +28,12 @@ import android.text.TextUtils
|
|||||||
import android.util.SparseArray
|
import android.util.SparseArray
|
||||||
import com.android.internal.annotations.VisibleForTesting
|
import com.android.internal.annotations.VisibleForTesting
|
||||||
import com.android.systemui.Dumpable
|
import com.android.systemui.Dumpable
|
||||||
|
import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger
|
||||||
import com.android.systemui.dagger.qualifiers.Background
|
import com.android.systemui.dagger.qualifiers.Background
|
||||||
import com.android.systemui.dagger.qualifiers.Main
|
import com.android.systemui.dagger.qualifiers.Main
|
||||||
import com.android.systemui.dump.DumpManager
|
import com.android.systemui.dump.DumpManager
|
||||||
import java.io.FileDescriptor
|
import java.io.FileDescriptor
|
||||||
import java.io.PrintWriter
|
import java.io.PrintWriter
|
||||||
import java.lang.IllegalStateException
|
|
||||||
import java.util.concurrent.Executor
|
import java.util.concurrent.Executor
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@@ -67,7 +67,8 @@ open class BroadcastDispatcher @Inject constructor (
|
|||||||
private val context: Context,
|
private val context: Context,
|
||||||
@Main private val mainHandler: Handler,
|
@Main private val mainHandler: Handler,
|
||||||
@Background private val bgLooper: Looper,
|
@Background private val bgLooper: Looper,
|
||||||
dumpManager: DumpManager
|
dumpManager: DumpManager,
|
||||||
|
private val logger: BroadcastDispatcherLogger
|
||||||
) : Dumpable {
|
) : Dumpable {
|
||||||
|
|
||||||
// Only modify in BG thread
|
// Only modify in BG thread
|
||||||
@@ -156,7 +157,7 @@ open class BroadcastDispatcher @Inject constructor (
|
|||||||
/**
|
/**
|
||||||
* Unregister receiver for a particular user.
|
* Unregister receiver for a particular user.
|
||||||
*
|
*
|
||||||
* @param receiver The receiver to unregister. It will be unregistered for all users.
|
* @param receiver The receiver to unregister.
|
||||||
* @param user The user associated to the registered [receiver]. It can be [UserHandle.ALL].
|
* @param user The user associated to the registered [receiver]. It can be [UserHandle.ALL].
|
||||||
*/
|
*/
|
||||||
open fun unregisterReceiverForUser(receiver: BroadcastReceiver, user: UserHandle) {
|
open fun unregisterReceiverForUser(receiver: BroadcastReceiver, user: UserHandle) {
|
||||||
@@ -166,7 +167,7 @@ open class BroadcastDispatcher @Inject constructor (
|
|||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
protected open fun createUBRForUser(userId: Int) =
|
protected open fun createUBRForUser(userId: Int) =
|
||||||
UserBroadcastDispatcher(context, userId, bgLooper)
|
UserBroadcastDispatcher(context, userId, bgLooper, logger)
|
||||||
|
|
||||||
override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
|
override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
|
||||||
pw.println("Broadcast dispatcher:")
|
pw.println("Broadcast dispatcher:")
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import android.util.Log
|
|||||||
import androidx.annotation.VisibleForTesting
|
import androidx.annotation.VisibleForTesting
|
||||||
import com.android.internal.util.Preconditions
|
import com.android.internal.util.Preconditions
|
||||||
import com.android.systemui.Dumpable
|
import com.android.systemui.Dumpable
|
||||||
|
import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger
|
||||||
import java.io.FileDescriptor
|
import java.io.FileDescriptor
|
||||||
import java.io.PrintWriter
|
import java.io.PrintWriter
|
||||||
import java.lang.IllegalArgumentException
|
import java.lang.IllegalArgumentException
|
||||||
@@ -54,7 +55,8 @@ private const val DEBUG = false
|
|||||||
class UserBroadcastDispatcher(
|
class UserBroadcastDispatcher(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val userId: Int,
|
private val userId: Int,
|
||||||
private val bgLooper: Looper
|
private val bgLooper: Looper,
|
||||||
|
private val logger: BroadcastDispatcherLogger
|
||||||
) : BroadcastReceiver(), Dumpable {
|
) : BroadcastReceiver(), Dumpable {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -109,10 +111,12 @@ class UserBroadcastDispatcher(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
val id = if (DEBUG) index.getAndIncrement() else 0
|
val id = index.getAndIncrement()
|
||||||
if (DEBUG) Log.w(TAG, "[$id] Received $intent")
|
if (DEBUG) Log.w(TAG, "[$id] Received $intent")
|
||||||
|
logger.logBroadcastReceived(id, userId, intent)
|
||||||
bgHandler.post(
|
bgHandler.post(
|
||||||
HandleBroadcastRunnable(actionsToReceivers, context, intent, pendingResult, id))
|
HandleBroadcastRunnable(
|
||||||
|
actionsToReceivers, context, intent, pendingResult, id, logger))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -143,6 +147,7 @@ class UserBroadcastDispatcher(
|
|||||||
ArraySet()
|
ArraySet()
|
||||||
}.add(receiverData)
|
}.add(receiverData)
|
||||||
}
|
}
|
||||||
|
logger.logReceiverRegistered(userId, receiverData.receiver)
|
||||||
if (changed) {
|
if (changed) {
|
||||||
createFilterAndRegisterReceiverBG()
|
createFilterAndRegisterReceiverBG()
|
||||||
}
|
}
|
||||||
@@ -163,6 +168,7 @@ class UserBroadcastDispatcher(
|
|||||||
actionsToReceivers.remove(action)
|
actionsToReceivers.remove(action)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
logger.logReceiverUnregistered(userId, receiver)
|
||||||
if (changed) {
|
if (changed) {
|
||||||
createFilterAndRegisterReceiverBG()
|
createFilterAndRegisterReceiverBG()
|
||||||
}
|
}
|
||||||
@@ -187,7 +193,8 @@ class UserBroadcastDispatcher(
|
|||||||
val context: Context,
|
val context: Context,
|
||||||
val intent: Intent,
|
val intent: Intent,
|
||||||
val pendingResult: PendingResult,
|
val pendingResult: PendingResult,
|
||||||
val index: Int
|
val index: Int,
|
||||||
|
val logger: BroadcastDispatcherLogger
|
||||||
) : Runnable {
|
) : Runnable {
|
||||||
override fun run() {
|
override fun run() {
|
||||||
if (DEBUG) Log.w(TAG, "[$index] Dispatching $intent")
|
if (DEBUG) Log.w(TAG, "[$index] Dispatching $intent")
|
||||||
@@ -199,6 +206,7 @@ class UserBroadcastDispatcher(
|
|||||||
it.executor.execute {
|
it.executor.execute {
|
||||||
if (DEBUG) Log.w(TAG,
|
if (DEBUG) Log.w(TAG,
|
||||||
"[$index] Dispatching ${intent.action} to ${it.receiver}")
|
"[$index] Dispatching ${intent.action} to ${it.receiver}")
|
||||||
|
logger.logBroadcastDispatched(index, intent.action, it.receiver)
|
||||||
it.receiver.pendingResult = pendingResult
|
it.receiver.pendingResult = pendingResult
|
||||||
it.receiver.onReceive(context, intent)
|
it.receiver.onReceive(context, intent)
|
||||||
}
|
}
|
||||||
@@ -215,6 +223,7 @@ class UserBroadcastDispatcher(
|
|||||||
if (registered.get()) {
|
if (registered.get()) {
|
||||||
try {
|
try {
|
||||||
context.unregisterReceiver(this@UserBroadcastDispatcher)
|
context.unregisterReceiver(this@UserBroadcastDispatcher)
|
||||||
|
logger.logContextReceiverUnregistered(userId)
|
||||||
} catch (e: IllegalArgumentException) {
|
} catch (e: IllegalArgumentException) {
|
||||||
Log.e(TAG, "Trying to unregister unregistered receiver for user $userId",
|
Log.e(TAG, "Trying to unregister unregistered receiver for user $userId",
|
||||||
IllegalStateException(e))
|
IllegalStateException(e))
|
||||||
@@ -230,6 +239,7 @@ class UserBroadcastDispatcher(
|
|||||||
null,
|
null,
|
||||||
bgHandler)
|
bgHandler)
|
||||||
registered.set(true)
|
registered.set(true)
|
||||||
|
logger.logContextReceiverRegistered(userId, intentFilter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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.broadcast.logging
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.IntentFilter
|
||||||
|
import com.android.systemui.log.LogBuffer
|
||||||
|
import com.android.systemui.log.LogLevel
|
||||||
|
import com.android.systemui.log.LogLevel.DEBUG
|
||||||
|
import com.android.systemui.log.LogLevel.INFO
|
||||||
|
import com.android.systemui.log.LogMessage
|
||||||
|
import com.android.systemui.log.dagger.BroadcastDispatcherLog
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
private const val TAG = "BroadcastDispatcherLog"
|
||||||
|
|
||||||
|
class BroadcastDispatcherLogger @Inject constructor(
|
||||||
|
@BroadcastDispatcherLog private val buffer: LogBuffer
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun logBroadcastReceived(broadcastId: Int, user: Int, intent: Intent) {
|
||||||
|
val intentString = intent.toString()
|
||||||
|
log(INFO, {
|
||||||
|
int1 = broadcastId
|
||||||
|
int2 = user
|
||||||
|
str1 = intentString
|
||||||
|
}, {
|
||||||
|
"[$int1] Broadcast received for user $int2: $str1"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fun logBroadcastDispatched(broadcastId: Int, action: String?, receiver: BroadcastReceiver) {
|
||||||
|
val receiverString = receiver.toString()
|
||||||
|
log(DEBUG, {
|
||||||
|
int1 = broadcastId
|
||||||
|
str1 = action
|
||||||
|
str2 = receiverString
|
||||||
|
}, {
|
||||||
|
"Broadcast $int1 ($str1) dispatched to $str2"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fun logReceiverRegistered(user: Int, receiver: BroadcastReceiver) {
|
||||||
|
val receiverString = receiver.toString()
|
||||||
|
log(INFO, {
|
||||||
|
int1 = user
|
||||||
|
str1 = receiverString
|
||||||
|
}, {
|
||||||
|
"Receiver $str1 registered for user $int1"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fun logReceiverUnregistered(user: Int, receiver: BroadcastReceiver) {
|
||||||
|
val receiverString = receiver.toString()
|
||||||
|
log(INFO, {
|
||||||
|
int1 = user
|
||||||
|
str1 = receiverString
|
||||||
|
}, {
|
||||||
|
"Receiver $str1 unregistered for user $int1"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fun logContextReceiverRegistered(user: Int, filter: IntentFilter) {
|
||||||
|
val actions = filter.actionsIterator().asSequence()
|
||||||
|
.joinToString(separator = ",", prefix = "Actions(", postfix = ")")
|
||||||
|
val categories = if (filter.countCategories() != 0) {
|
||||||
|
filter.categoriesIterator().asSequence()
|
||||||
|
.joinToString(separator = ",", prefix = "Categories(", postfix = ")")
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
log(INFO, {
|
||||||
|
int1 = user
|
||||||
|
str1 = if (categories != "") {
|
||||||
|
"${actions}\n$categories"
|
||||||
|
} else {
|
||||||
|
actions
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"""
|
||||||
|
Receiver registered with Context for user $int1.
|
||||||
|
$str1
|
||||||
|
""".trimIndent()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fun logContextReceiverUnregistered(user: Int) {
|
||||||
|
log(INFO, {
|
||||||
|
int1 = user
|
||||||
|
}, {
|
||||||
|
"Receiver unregistered with Context for user $int1."
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private inline fun log(
|
||||||
|
logLevel: LogLevel,
|
||||||
|
initializer: LogMessage.() -> Unit,
|
||||||
|
noinline printer: LogMessage.() -> String
|
||||||
|
) {
|
||||||
|
buffer.log(TAG, logLevel, initializer, printer)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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 BroadcastDispatcher-related messages. */
|
||||||
|
@Qualifier
|
||||||
|
@Documented
|
||||||
|
@Retention(RUNTIME)
|
||||||
|
public @interface BroadcastDispatcherLog {
|
||||||
|
}
|
||||||
@@ -97,6 +97,18 @@ public class LogModule {
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Provides a logging buffer for {@link com.android.systemui.broadcast.BroadcastDispatcher} */
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@BroadcastDispatcherLog
|
||||||
|
public static LogBuffer provideBroadcastDispatcherLogBuffer(
|
||||||
|
LogcatEchoTracker bufferFilter,
|
||||||
|
DumpManager dumpManager) {
|
||||||
|
LogBuffer buffer = new LogBuffer("BroadcastDispatcherLog", 500, 10, bufferFilter);
|
||||||
|
buffer.attach(dumpManager);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
/** Allows logging buffers to be tweaked via adb on debug builds but not on prod builds. */
|
/** Allows logging buffers to be tweaked via adb on debug builds but not on prod builds. */
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;
|
|||||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||||
import com.android.systemui.broadcast.FakeBroadcastDispatcher;
|
import com.android.systemui.broadcast.FakeBroadcastDispatcher;
|
||||||
|
import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger;
|
||||||
import com.android.systemui.classifier.FalsingManagerFake;
|
import com.android.systemui.classifier.FalsingManagerFake;
|
||||||
import com.android.systemui.dump.DumpManager;
|
import com.android.systemui.dump.DumpManager;
|
||||||
import com.android.systemui.plugins.FalsingManager;
|
import com.android.systemui.plugins.FalsingManager;
|
||||||
@@ -73,7 +74,7 @@ public abstract class SysuiTestCase {
|
|||||||
SystemUIFactory.createFromConfig(mContext);
|
SystemUIFactory.createFromConfig(mContext);
|
||||||
mDependency = new TestableDependency(mContext);
|
mDependency = new TestableDependency(mContext);
|
||||||
mFakeBroadcastDispatcher = new FakeBroadcastDispatcher(mContext, mock(Handler.class),
|
mFakeBroadcastDispatcher = new FakeBroadcastDispatcher(mContext, mock(Handler.class),
|
||||||
mock(Looper.class), mock(DumpManager.class));
|
mock(Looper.class), mock(DumpManager.class), mock(BroadcastDispatcherLogger.class));
|
||||||
|
|
||||||
mRealInstrumentation = InstrumentationRegistry.getInstrumentation();
|
mRealInstrumentation = InstrumentationRegistry.getInstrumentation();
|
||||||
Instrumentation inst = spy(mRealInstrumentation);
|
Instrumentation inst = spy(mRealInstrumentation);
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import android.test.suitebuilder.annotation.SmallTest
|
|||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner
|
||||||
import android.testing.TestableLooper
|
import android.testing.TestableLooper
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger
|
||||||
import com.android.systemui.dump.DumpManager
|
import com.android.systemui.dump.DumpManager
|
||||||
import com.android.systemui.util.concurrency.FakeExecutor
|
import com.android.systemui.util.concurrency.FakeExecutor
|
||||||
import com.android.systemui.util.time.FakeSystemClock
|
import com.android.systemui.util.time.FakeSystemClock
|
||||||
@@ -76,6 +77,8 @@ class BroadcastDispatcherTest : SysuiTestCase() {
|
|||||||
private lateinit var intentFilterOther: IntentFilter
|
private lateinit var intentFilterOther: IntentFilter
|
||||||
@Mock
|
@Mock
|
||||||
private lateinit var mockHandler: Handler
|
private lateinit var mockHandler: Handler
|
||||||
|
@Mock
|
||||||
|
private lateinit var logger: BroadcastDispatcherLogger
|
||||||
|
|
||||||
private lateinit var executor: Executor
|
private lateinit var executor: Executor
|
||||||
|
|
||||||
@@ -96,6 +99,7 @@ class BroadcastDispatcherTest : SysuiTestCase() {
|
|||||||
Handler(testableLooper.looper),
|
Handler(testableLooper.looper),
|
||||||
testableLooper.looper,
|
testableLooper.looper,
|
||||||
mock(DumpManager::class.java),
|
mock(DumpManager::class.java),
|
||||||
|
logger,
|
||||||
mapOf(0 to mockUBRUser0, 1 to mockUBRUser1))
|
mapOf(0 to mockUBRUser0, 1 to mockUBRUser1))
|
||||||
|
|
||||||
// These should be valid filters
|
// These should be valid filters
|
||||||
@@ -239,8 +243,9 @@ class BroadcastDispatcherTest : SysuiTestCase() {
|
|||||||
mainHandler: Handler,
|
mainHandler: Handler,
|
||||||
bgLooper: Looper,
|
bgLooper: Looper,
|
||||||
dumpManager: DumpManager,
|
dumpManager: DumpManager,
|
||||||
|
logger: BroadcastDispatcherLogger,
|
||||||
var mockUBRMap: Map<Int, UserBroadcastDispatcher>
|
var mockUBRMap: Map<Int, UserBroadcastDispatcher>
|
||||||
) : BroadcastDispatcher(context, mainHandler, bgLooper, dumpManager) {
|
) : BroadcastDispatcher(context, mainHandler, bgLooper, dumpManager, logger) {
|
||||||
override fun createUBRForUser(userId: Int): UserBroadcastDispatcher {
|
override fun createUBRForUser(userId: Int): UserBroadcastDispatcher {
|
||||||
return mockUBRMap.getOrDefault(userId, mock(UserBroadcastDispatcher::class.java))
|
return mockUBRMap.getOrDefault(userId, mock(UserBroadcastDispatcher::class.java))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import android.os.UserHandle
|
|||||||
import android.util.ArraySet
|
import android.util.ArraySet
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.android.systemui.SysuiTestableContext
|
import com.android.systemui.SysuiTestableContext
|
||||||
|
import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger
|
||||||
import com.android.systemui.dump.DumpManager
|
import com.android.systemui.dump.DumpManager
|
||||||
import java.util.concurrent.Executor
|
import java.util.concurrent.Executor
|
||||||
|
|
||||||
@@ -31,8 +32,9 @@ class FakeBroadcastDispatcher(
|
|||||||
context: SysuiTestableContext,
|
context: SysuiTestableContext,
|
||||||
handler: Handler,
|
handler: Handler,
|
||||||
looper: Looper,
|
looper: Looper,
|
||||||
dumpManager: DumpManager
|
dumpManager: DumpManager,
|
||||||
) : BroadcastDispatcher(context, handler, looper, dumpManager) {
|
logger: BroadcastDispatcherLogger
|
||||||
|
) : BroadcastDispatcher(context, handler, looper, dumpManager, logger) {
|
||||||
|
|
||||||
private val registeredReceivers = ArraySet<BroadcastReceiver>()
|
private val registeredReceivers = ArraySet<BroadcastReceiver>()
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import android.test.suitebuilder.annotation.SmallTest
|
|||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner
|
||||||
import android.testing.TestableLooper
|
import android.testing.TestableLooper
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger
|
||||||
import com.android.systemui.util.concurrency.FakeExecutor
|
import com.android.systemui.util.concurrency.FakeExecutor
|
||||||
import com.android.systemui.util.time.FakeSystemClock
|
import com.android.systemui.util.time.FakeSystemClock
|
||||||
import junit.framework.Assert.assertEquals
|
import junit.framework.Assert.assertEquals
|
||||||
@@ -40,6 +41,7 @@ import org.mockito.ArgumentMatchers.anyInt
|
|||||||
import org.mockito.ArgumentMatchers.eq
|
import org.mockito.ArgumentMatchers.eq
|
||||||
import org.mockito.Captor
|
import org.mockito.Captor
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
|
import org.mockito.Mockito
|
||||||
import org.mockito.Mockito.anyString
|
import org.mockito.Mockito.anyString
|
||||||
import org.mockito.Mockito.atLeastOnce
|
import org.mockito.Mockito.atLeastOnce
|
||||||
import org.mockito.Mockito.never
|
import org.mockito.Mockito.never
|
||||||
@@ -62,6 +64,8 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
|
|||||||
private val USER_HANDLE = UserHandle.of(USER_ID)
|
private val USER_HANDLE = UserHandle.of(USER_ID)
|
||||||
|
|
||||||
fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()
|
fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()
|
||||||
|
fun <T> any(): T = Mockito.any()
|
||||||
|
fun <T> eq(v: T) = Mockito.eq(v) ?: v
|
||||||
}
|
}
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
@@ -72,6 +76,8 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
|
|||||||
private lateinit var mockContext: Context
|
private lateinit var mockContext: Context
|
||||||
@Mock
|
@Mock
|
||||||
private lateinit var mPendingResult: BroadcastReceiver.PendingResult
|
private lateinit var mPendingResult: BroadcastReceiver.PendingResult
|
||||||
|
@Mock
|
||||||
|
private lateinit var logger: BroadcastDispatcherLogger
|
||||||
|
|
||||||
@Captor
|
@Captor
|
||||||
private lateinit var argumentCaptor: ArgumentCaptor<IntentFilter>
|
private lateinit var argumentCaptor: ArgumentCaptor<IntentFilter>
|
||||||
@@ -91,7 +97,7 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
|
|||||||
fakeExecutor = FakeExecutor(FakeSystemClock())
|
fakeExecutor = FakeExecutor(FakeSystemClock())
|
||||||
|
|
||||||
userBroadcastDispatcher = UserBroadcastDispatcher(
|
userBroadcastDispatcher = UserBroadcastDispatcher(
|
||||||
mockContext, USER_ID, testableLooper.looper)
|
mockContext, USER_ID, testableLooper.looper, logger)
|
||||||
userBroadcastDispatcher.pendingResult = mPendingResult
|
userBroadcastDispatcher.pendingResult = mPendingResult
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,6 +111,13 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
|
|||||||
verify(mockContext, never()).registerReceiverAsUser(any(), any(), any(), anyString(), any())
|
verify(mockContext, never()).registerReceiverAsUser(any(), any(), any(), anyString(), any())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testNotRegisteredOnStart_logging() {
|
||||||
|
testableLooper.processAllMessages()
|
||||||
|
|
||||||
|
verify(logger, never()).logContextReceiverRegistered(anyInt(), any())
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testSingleReceiverRegistered() {
|
fun testSingleReceiverRegistered() {
|
||||||
intentFilter = IntentFilter(ACTION_1)
|
intentFilter = IntentFilter(ACTION_1)
|
||||||
@@ -125,6 +138,18 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
|
|||||||
assertEquals(0, argumentCaptor.value.countCategories())
|
assertEquals(0, argumentCaptor.value.countCategories())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testSingleReceiverRegistered_logging() {
|
||||||
|
intentFilter = IntentFilter(ACTION_1)
|
||||||
|
|
||||||
|
userBroadcastDispatcher.registerReceiver(
|
||||||
|
ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE))
|
||||||
|
testableLooper.processAllMessages()
|
||||||
|
|
||||||
|
verify(logger).logReceiverRegistered(USER_HANDLE.identifier, broadcastReceiver)
|
||||||
|
verify(logger).logContextReceiverRegistered(eq(USER_HANDLE.identifier), any())
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testSingleReceiverUnregistered() {
|
fun testSingleReceiverUnregistered() {
|
||||||
intentFilter = IntentFilter(ACTION_1)
|
intentFilter = IntentFilter(ACTION_1)
|
||||||
@@ -144,6 +169,21 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
|
|||||||
assertFalse(userBroadcastDispatcher.isRegistered())
|
assertFalse(userBroadcastDispatcher.isRegistered())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testSingleReceiverUnregistered_logger() {
|
||||||
|
intentFilter = IntentFilter(ACTION_1)
|
||||||
|
|
||||||
|
userBroadcastDispatcher.registerReceiver(
|
||||||
|
ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE))
|
||||||
|
testableLooper.processAllMessages()
|
||||||
|
|
||||||
|
userBroadcastDispatcher.unregisterReceiver(broadcastReceiver)
|
||||||
|
testableLooper.processAllMessages()
|
||||||
|
|
||||||
|
verify(logger).logReceiverUnregistered(USER_HANDLE.identifier, broadcastReceiver)
|
||||||
|
verify(logger).logContextReceiverUnregistered(USER_HANDLE.identifier)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testFilterHasAllActionsAndCategories_twoReceivers() {
|
fun testFilterHasAllActionsAndCategories_twoReceivers() {
|
||||||
intentFilter = IntentFilter(ACTION_1)
|
intentFilter = IntentFilter(ACTION_1)
|
||||||
@@ -195,6 +235,30 @@ class UserBroadcastDispatcherTest : SysuiTestCase() {
|
|||||||
verify(broadcastReceiverOther).onReceive(mockContext, intent)
|
verify(broadcastReceiverOther).onReceive(mockContext, intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testDispatch_logger() {
|
||||||
|
intentFilter = IntentFilter(ACTION_1)
|
||||||
|
intentFilterOther = IntentFilter(ACTION_2)
|
||||||
|
|
||||||
|
userBroadcastDispatcher.registerReceiver(
|
||||||
|
ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE))
|
||||||
|
userBroadcastDispatcher.registerReceiver(
|
||||||
|
ReceiverData(broadcastReceiverOther, intentFilterOther, fakeExecutor, USER_HANDLE))
|
||||||
|
|
||||||
|
val intent = Intent(ACTION_2)
|
||||||
|
|
||||||
|
userBroadcastDispatcher.onReceive(mockContext, intent)
|
||||||
|
testableLooper.processAllMessages()
|
||||||
|
fakeExecutor.runAllReady()
|
||||||
|
|
||||||
|
val captor = ArgumentCaptor.forClass(Int::class.java)
|
||||||
|
verify(logger)
|
||||||
|
.logBroadcastReceived(captor.capture(), eq(USER_HANDLE.identifier), eq(intent))
|
||||||
|
verify(logger).logBroadcastDispatched(captor.value, ACTION_2, broadcastReceiverOther)
|
||||||
|
verify(logger, never())
|
||||||
|
.logBroadcastDispatched(eq(captor.value), any(), eq(broadcastReceiver))
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testDispatchToCorrectReceiver_differentFiltersSameReceiver() {
|
fun testDispatchToCorrectReceiver_differentFiltersSameReceiver() {
|
||||||
intentFilter = IntentFilter(ACTION_1)
|
intentFilter = IntentFilter(ACTION_1)
|
||||||
|
|||||||
Reference in New Issue
Block a user