summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Fabian Kozynski <kozynski@google.com> 2020-06-08 11:14:58 -0400
committer Fabian Kozynski <kozynski@google.com> 2020-06-11 16:27:46 +0000
commit34f899a8493044356a93d36843b92726908dd3e9 (patch)
tree4bf4c9203a4a21c5262de35813ab91d15d0b033f
parente8d82057f8cfac91864fae151447fd1071bd6fe1 (diff)
Fix BroadcastDispatcher registering with CURRENT
When a BroadcastReceiver is registered with UserHandle.CURRENT, the current user should be obtained. This has to be cached in order to not call ActivityManager every time. As it is done in the initializer the initial value caching will happen before any other BroadcastReceiver is actually registered. The caching and updating is all done in the background thread. Also, remove unnecessary dependency. Test: manual Test: atest BroadcastDispatcher Fixes: 158298581 Change-Id: Idfd2dc65f9079c57e971250aa7b0aef222da5af5
-rw-r--r--packages/SystemUI/docs/broadcasts.md2
-rw-r--r--packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt46
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java19
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt3
6 files changed, 62 insertions, 24 deletions
diff --git a/packages/SystemUI/docs/broadcasts.md b/packages/SystemUI/docs/broadcasts.md
index 6c8488b332c2..8ec20f5689ff 100644
--- a/packages/SystemUI/docs/broadcasts.md
+++ b/packages/SystemUI/docs/broadcasts.md
@@ -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.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
index d61de0623fe8..67c0c620f136 100644
--- a/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
+++ b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
@@ -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)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
index 6dbb1e933fbd..45e47228e16a 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
@@ -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;
@@ -40,9 +41,12 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.Prefs;
import com.android.systemui.accessibility.ModeSwitchesController;
+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;
@@ -185,6 +189,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() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
index aa3f91a22208..713aef9e8a91 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
@@ -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);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
index 86ddb209f321..4ed284ede634 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
@@ -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))
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt
index 6e982e26b8cb..09a091689a23 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt
@@ -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>()