[DO NOT MERGE] Fix BroadcastDispatcher registering with CURRENT am: e771b7529e

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/11792343

Change-Id: Ia1d89c5e65915027359b1e6d4b2abdc8c26bf24d
This commit is contained in:
Fabian Kozynski
2020-06-11 19:22:03 +00:00
committed by Automerger Merge Worker
6 changed files with 62 additions and 24 deletions

View File

@@ -62,7 +62,7 @@ Acquire the dispatcher by using `@Inject` to obtain a `BroadcastDispatcher`. The
* @param executor An executor to dispatch [BroadcastReceiver.onReceive]. Pass null to use an
* executor in the main thread (default).
* @param user A user handle to determine which broadcast should be dispatched to this receiver.
* By default, it is the current user.
* By default, it is the user of the context (system user in SystemUI).
* @throws IllegalArgumentException if the filter has other constraints that are not actions or
* categories or the filter has no actions.
*/

View File

@@ -16,8 +16,10 @@
package com.android.systemui.broadcast
import android.app.ActivityManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Handler
import android.os.HandlerExecutor
@@ -29,14 +31,10 @@ import android.util.SparseArray
import com.android.internal.annotations.VisibleForTesting
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.Main
import com.android.systemui.dump.DumpManager
import java.io.FileDescriptor
import java.io.PrintWriter
import java.util.concurrent.Executor
import javax.inject.Inject
import javax.inject.Singleton
data class ReceiverData(
val receiver: BroadcastReceiver,
@@ -48,6 +46,8 @@ data class ReceiverData(
private const val MSG_ADD_RECEIVER = 0
private const val MSG_REMOVE_RECEIVER = 1
private const val MSG_REMOVE_RECEIVER_FOR_USER = 2
private const val MSG_USER_SWITCH = 3
private const val MSG_SET_STARTING_USER = 99
private const val TAG = "BroadcastDispatcher"
private const val DEBUG = true
@@ -62,21 +62,27 @@ private const val DEBUG = true
* permissions, schemes, data types, data authorities or priority different than 0.
* Cannot be used for getting sticky broadcasts (either as return of registering or as re-delivery).
*/
@Singleton
open class BroadcastDispatcher @Inject constructor (
open class BroadcastDispatcher constructor (
private val context: Context,
@Main private val mainHandler: Handler,
@Background private val bgLooper: Looper,
dumpManager: DumpManager,
private val bgLooper: Looper,
private val dumpManager: DumpManager,
private val logger: BroadcastDispatcherLogger
) : Dumpable {
) : Dumpable, BroadcastReceiver() {
// Only modify in BG thread
private val receiversByUser = SparseArray<UserBroadcastDispatcher>(20)
init {
// TODO: Don't do this in the constructor
fun initialize() {
dumpManager.registerDumpable(javaClass.name, this)
handler.sendEmptyMessage(MSG_SET_STARTING_USER)
registerReceiver(this, IntentFilter(Intent.ACTION_USER_SWITCHED), null, UserHandle.ALL)
}
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == Intent.ACTION_USER_SWITCHED) {
val user = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL)
handler.obtainMessage(MSG_USER_SWITCH, user, 0).sendToTarget()
}
}
/**
@@ -88,7 +94,7 @@ open class BroadcastDispatcher @Inject constructor (
* have at least one action.
* @param handler A handler to dispatch [BroadcastReceiver.onReceive].
* @param user A user handle to determine which broadcast should be dispatched to this receiver.
* By default, it is the current user.
* By default, it is the user of the context (system user in SystemUI).
* @throws IllegalArgumentException if the filter has other constraints that are not actions or
* categories or the filter has no actions.
*/
@@ -114,7 +120,7 @@ open class BroadcastDispatcher @Inject constructor (
* @param executor An executor to dispatch [BroadcastReceiver.onReceive]. Pass null to use an
* executor in the main thread (default).
* @param user A user handle to determine which broadcast should be dispatched to this receiver.
* By default, it is the current user.
* By default, it is the user of the context (system user in SystemUI).
* @throws IllegalArgumentException if the filter has other constraints that are not actions or
* categories or the filter has no actions.
*/
@@ -171,6 +177,7 @@ open class BroadcastDispatcher @Inject constructor (
override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
pw.println("Broadcast dispatcher:")
pw.println(" Current user: ${handler.currentUser}")
for (index in 0 until receiversByUser.size()) {
pw.println(" User ${receiversByUser.keyAt(index)}")
receiversByUser.valueAt(index).dump(fd, pw, args)
@@ -178,6 +185,8 @@ open class BroadcastDispatcher @Inject constructor (
}
private val handler = object : Handler(bgLooper) {
var currentUser = UserHandle.USER_SYSTEM
override fun handleMessage(msg: Message) {
when (msg.what) {
MSG_ADD_RECEIVER -> {
@@ -185,7 +194,7 @@ open class BroadcastDispatcher @Inject constructor (
// If the receiver asked to be registered under the current user, we register
// under the actual current user.
val userId = if (data.user.identifier == UserHandle.USER_CURRENT) {
context.userId
currentUser
} else {
data.user.identifier
}
@@ -208,6 +217,13 @@ open class BroadcastDispatcher @Inject constructor (
receiversByUser.get(msg.arg1)?.unregisterReceiver(msg.obj as BroadcastReceiver)
}
MSG_USER_SWITCH -> {
currentUser = msg.arg1
}
MSG_SET_STARTING_USER -> {
currentUser = ActivityManager.getCurrentUser()
}
else -> super.handleMessage(msg)
}
}

View File

@@ -25,6 +25,7 @@ import android.hardware.display.AmbientDisplayConfiguration;
import android.hardware.display.NightDisplayListener;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.ServiceManager;
import android.util.DisplayMetrics;
import android.view.Choreographer;
@@ -39,9 +40,12 @@ import com.android.internal.util.NotificationMessagingUtil;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.Prefs;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.AlwaysOnDisplayPolicy;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.plugins.PluginInitializerImpl;
import com.android.systemui.shared.plugins.PluginManager;
@@ -178,6 +182,21 @@ public class DependencyProvider {
return ActivityManagerWrapper.getInstance();
}
/** Provides and initializes the {#link BroadcastDispatcher} for SystemUI */
@Singleton
@Provides
public BroadcastDispatcher providesBroadcastDispatcher(
Context context,
@Background Looper backgroundLooper,
DumpManager dumpManager,
BroadcastDispatcherLogger logger
) {
BroadcastDispatcher bD =
new BroadcastDispatcher(context, backgroundLooper, dumpManager, logger);
bD.initialize();
return bD;
}
@Singleton
@Provides
public DevicePolicyManagerWrapper provideDevicePolicyManagerWrapper() {

View File

@@ -73,8 +73,8 @@ public abstract class SysuiTestCase {
public void SysuiSetup() throws Exception {
SystemUIFactory.createFromConfig(mContext);
mDependency = new TestableDependency(mContext);
mFakeBroadcastDispatcher = new FakeBroadcastDispatcher(mContext, mock(Handler.class),
mock(Looper.class), mock(DumpManager.class), mock(BroadcastDispatcherLogger.class));
mFakeBroadcastDispatcher = new FakeBroadcastDispatcher(mContext, mock(Looper.class),
mock(DumpManager.class), mock(BroadcastDispatcherLogger.class));
mRealInstrumentation = InstrumentationRegistry.getInstrumentation();
Instrumentation inst = spy(mRealInstrumentation);

View File

@@ -18,6 +18,7 @@ package com.android.systemui.broadcast
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Handler
import android.os.Looper
@@ -96,7 +97,6 @@ class BroadcastDispatcherTest : SysuiTestCase() {
broadcastDispatcher = TestBroadcastDispatcher(
mockContext,
Handler(testableLooper.looper),
testableLooper.looper,
mock(DumpManager::class.java),
logger,
@@ -177,7 +177,12 @@ class BroadcastDispatcherTest : SysuiTestCase() {
@Test
fun testRegisterCurrentAsActualUser() {
setUserMock(mockContext, user1)
val intent = Intent(Intent.ACTION_USER_SWITCHED).apply {
putExtra(Intent.EXTRA_USER_HANDLE, user1.identifier)
}
broadcastDispatcher.onReceive(mockContext, intent)
testableLooper.processAllMessages()
broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
mockHandler, UserHandle.CURRENT)
@@ -240,12 +245,11 @@ class BroadcastDispatcherTest : SysuiTestCase() {
private class TestBroadcastDispatcher(
context: Context,
mainHandler: Handler,
bgLooper: Looper,
dumpManager: DumpManager,
logger: BroadcastDispatcherLogger,
var mockUBRMap: Map<Int, UserBroadcastDispatcher>
) : BroadcastDispatcher(context, mainHandler, bgLooper, dumpManager, logger) {
) : BroadcastDispatcher(context, bgLooper, dumpManager, logger) {
override fun createUBRForUser(userId: Int): UserBroadcastDispatcher {
return mockUBRMap.getOrDefault(userId, mock(UserBroadcastDispatcher::class.java))
}

View File

@@ -30,11 +30,10 @@ import java.util.concurrent.Executor
class FakeBroadcastDispatcher(
context: SysuiTestableContext,
handler: Handler,
looper: Looper,
dumpManager: DumpManager,
logger: BroadcastDispatcherLogger
) : BroadcastDispatcher(context, handler, looper, dumpManager, logger) {
) : BroadcastDispatcher(context, looper, dumpManager, logger) {
private val registeredReceivers = ArraySet<BroadcastReceiver>()