Loading packages/SystemUI/src/com/android/systemui/broadcast/ActionReceiver.kt +3 −3 Original line number Diff line number Diff line Loading @@ -52,7 +52,7 @@ class ActionReceiver( private val userId: Int, private val registerAction: BroadcastReceiver.(IntentFilter) -> Unit, private val unregisterAction: BroadcastReceiver.() -> Unit, private val bgExecutor: Executor, private val workerExecutor: Executor, private val logger: BroadcastDispatcherLogger, private val testPendingRemovalAction: (BroadcastReceiver, Int) -> Boolean ) : BroadcastReceiver(), Dumpable { Loading Loading @@ -112,7 +112,7 @@ class ActionReceiver( val id = index.getAndIncrement() logger.logBroadcastReceived(id, userId, intent) // Immediately return control to ActivityManager bgExecutor.execute { workerExecutor.execute { receiverDatas.forEach { if (it.filter.matchCategories(intent.categories) == null && !testPendingRemovalAction(it.receiver, userId)) { Loading packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt +11 −10 Original line number Diff line number Diff line Loading @@ -34,7 +34,8 @@ import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.BroadcastRunning import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dump.DumpManager import com.android.systemui.settings.UserTracker import java.io.PrintWriter Loading @@ -55,7 +56,6 @@ 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 TAG = "BroadcastDispatcher" private const val DEBUG = true /** * SystemUI master Broadcast Dispatcher. Loading @@ -73,15 +73,16 @@ private const val DEBUG = true @SysUISingleton open class BroadcastDispatcher @Inject constructor( private val context: Context, @Background private val bgLooper: Looper, @Background private val bgExecutor: Executor, @Main private val mainExecutor: Executor, @BroadcastRunning private val broadcastLooper: Looper, @BroadcastRunning private val broadcastExecutor: Executor, private val dumpManager: DumpManager, private val logger: BroadcastDispatcherLogger, private val userTracker: UserTracker, private val removalPendingStore: PendingRemovalStore ) : Dumpable { // Only modify in BG thread // Only modify in BroadcastRunning thread private val receiversByUser = SparseArray<UserBroadcastDispatcher>(20) fun initialize() { Loading Loading @@ -148,7 +149,7 @@ open class BroadcastDispatcher @Inject constructor( val data = ReceiverData( receiver, filter, executor ?: context.mainExecutor, executor ?: mainExecutor, user ?: context.user, permission ) Loading Loading @@ -181,7 +182,7 @@ open class BroadcastDispatcher @Inject constructor( registerReceiver( receiver, filter, bgExecutor, broadcastExecutor, user, flags, permission, Loading Loading @@ -246,8 +247,8 @@ open class BroadcastDispatcher @Inject constructor( UserBroadcastDispatcher( context, userId, bgLooper, bgExecutor, broadcastLooper, broadcastExecutor, logger, removalPendingStore ) Loading @@ -265,7 +266,7 @@ open class BroadcastDispatcher @Inject constructor( ipw.decreaseIndent() } private val handler = object : Handler(bgLooper) { private val handler = object : Handler(broadcastLooper) { override fun handleMessage(msg: Message) { when (msg.what) { Loading packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt +12 −10 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.broadcast import android.annotation.SuppressLint import android.content.BroadcastReceiver import android.content.Context import android.os.Handler Loading Loading @@ -46,8 +47,8 @@ private const val DEBUG = false open class UserBroadcastDispatcher( private val context: Context, private val userId: Int, private val bgLooper: Looper, private val bgExecutor: Executor, private val workerLooper: Looper, private val workerExecutor: Executor, private val logger: BroadcastDispatcherLogger, private val removalPendingStore: PendingRemovalStore ) : Dumpable { Loading @@ -66,9 +67,11 @@ open class UserBroadcastDispatcher( val permission: String? ) private val bgHandler = Handler(bgLooper) private val wrongThreadErrorMsg = "This method should only be called from the worker thread " + "(which is expected to be the BroadcastRunning thread)" private val workerHandler = Handler(workerLooper) // Only modify in BG thread // Only modify in BroadcastRunning thread @VisibleForTesting internal val actionsToActionsReceivers = ArrayMap<ReceiverProperties, ActionReceiver>() private val receiverToActions = ArrayMap<BroadcastReceiver, MutableSet<String>>() Loading Loading @@ -97,8 +100,7 @@ open class UserBroadcastDispatcher( } private fun handleRegisterReceiver(receiverData: ReceiverData, flags: Int) { Preconditions.checkState(bgLooper.isCurrentThread, "This method should only be called from BG thread") Preconditions.checkState(workerLooper.isCurrentThread, wrongThreadErrorMsg) if (DEBUG) Log.w(TAG, "Register receiver: ${receiverData.receiver}") receiverToActions .getOrPut(receiverData.receiver, { ArraySet() }) Loading @@ -113,6 +115,7 @@ open class UserBroadcastDispatcher( logger.logReceiverRegistered(userId, receiverData.receiver, flags) } @SuppressLint("RegisterReceiverViaContextDetector") @VisibleForTesting internal open fun createActionReceiver( action: String, Loading @@ -128,7 +131,7 @@ open class UserBroadcastDispatcher( UserHandle.of(userId), it, permission, bgHandler, workerHandler, flags ) logger.logContextReceiverRegistered(userId, flags, it) Loading @@ -143,15 +146,14 @@ open class UserBroadcastDispatcher( IllegalStateException(e)) } }, bgExecutor, workerExecutor, logger, removalPendingStore::isPendingRemoval ) } private fun handleUnregisterReceiver(receiver: BroadcastReceiver) { Preconditions.checkState(bgLooper.isCurrentThread, "This method should only be called from BG thread") Preconditions.checkState(workerLooper.isCurrentThread, wrongThreadErrorMsg) if (DEBUG) Log.w(TAG, "Unregister receiver: $receiver") receiverToActions.getOrDefault(receiver, mutableSetOf()).forEach { actionsToActionsReceivers.forEach { (key, value) -> Loading packages/SystemUI/src/com/android/systemui/dagger/qualifiers/BroadcastRunning.java 0 → 100644 +30 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 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.dagger.qualifiers; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import javax.inject.Qualifier; @Qualifier @Documented @Retention(RUNTIME) public @interface BroadcastRunning { } packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.java +23 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.os.Process; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.BroadcastRunning; import com.android.systemui.dagger.qualifiers.LongRunning; import com.android.systemui.dagger.qualifiers.Main; Loading @@ -51,6 +52,17 @@ public abstract class SysUIConcurrencyModule { return thread.getLooper(); } /** BroadcastRunning Looper (for sending and receiving broadcasts) */ @Provides @SysUISingleton @BroadcastRunning public static Looper provideBroadcastRunningLooper() { HandlerThread thread = new HandlerThread("BroadcastRunning", Process.THREAD_PRIORITY_BACKGROUND); thread.start(); return thread.getLooper(); } /** Long running tasks Looper */ @Provides @SysUISingleton Loading Loading @@ -83,7 +95,17 @@ public abstract class SysUIConcurrencyModule { } /** * Provide a Long running Executor by default. * Provide a BroadcastRunning Executor (for sending and receiving broadcasts). */ @Provides @SysUISingleton @BroadcastRunning public static Executor provideBroadcastRunningExecutor(@BroadcastRunning Looper looper) { return new ExecutorImpl(looper); } /** * Provide a Long running Executor. */ @Provides @SysUISingleton Loading Loading
packages/SystemUI/src/com/android/systemui/broadcast/ActionReceiver.kt +3 −3 Original line number Diff line number Diff line Loading @@ -52,7 +52,7 @@ class ActionReceiver( private val userId: Int, private val registerAction: BroadcastReceiver.(IntentFilter) -> Unit, private val unregisterAction: BroadcastReceiver.() -> Unit, private val bgExecutor: Executor, private val workerExecutor: Executor, private val logger: BroadcastDispatcherLogger, private val testPendingRemovalAction: (BroadcastReceiver, Int) -> Boolean ) : BroadcastReceiver(), Dumpable { Loading Loading @@ -112,7 +112,7 @@ class ActionReceiver( val id = index.getAndIncrement() logger.logBroadcastReceived(id, userId, intent) // Immediately return control to ActivityManager bgExecutor.execute { workerExecutor.execute { receiverDatas.forEach { if (it.filter.matchCategories(intent.categories) == null && !testPendingRemovalAction(it.receiver, userId)) { Loading
packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt +11 −10 Original line number Diff line number Diff line Loading @@ -34,7 +34,8 @@ import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.BroadcastRunning import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dump.DumpManager import com.android.systemui.settings.UserTracker import java.io.PrintWriter Loading @@ -55,7 +56,6 @@ 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 TAG = "BroadcastDispatcher" private const val DEBUG = true /** * SystemUI master Broadcast Dispatcher. Loading @@ -73,15 +73,16 @@ private const val DEBUG = true @SysUISingleton open class BroadcastDispatcher @Inject constructor( private val context: Context, @Background private val bgLooper: Looper, @Background private val bgExecutor: Executor, @Main private val mainExecutor: Executor, @BroadcastRunning private val broadcastLooper: Looper, @BroadcastRunning private val broadcastExecutor: Executor, private val dumpManager: DumpManager, private val logger: BroadcastDispatcherLogger, private val userTracker: UserTracker, private val removalPendingStore: PendingRemovalStore ) : Dumpable { // Only modify in BG thread // Only modify in BroadcastRunning thread private val receiversByUser = SparseArray<UserBroadcastDispatcher>(20) fun initialize() { Loading Loading @@ -148,7 +149,7 @@ open class BroadcastDispatcher @Inject constructor( val data = ReceiverData( receiver, filter, executor ?: context.mainExecutor, executor ?: mainExecutor, user ?: context.user, permission ) Loading Loading @@ -181,7 +182,7 @@ open class BroadcastDispatcher @Inject constructor( registerReceiver( receiver, filter, bgExecutor, broadcastExecutor, user, flags, permission, Loading Loading @@ -246,8 +247,8 @@ open class BroadcastDispatcher @Inject constructor( UserBroadcastDispatcher( context, userId, bgLooper, bgExecutor, broadcastLooper, broadcastExecutor, logger, removalPendingStore ) Loading @@ -265,7 +266,7 @@ open class BroadcastDispatcher @Inject constructor( ipw.decreaseIndent() } private val handler = object : Handler(bgLooper) { private val handler = object : Handler(broadcastLooper) { override fun handleMessage(msg: Message) { when (msg.what) { Loading
packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt +12 −10 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.broadcast import android.annotation.SuppressLint import android.content.BroadcastReceiver import android.content.Context import android.os.Handler Loading Loading @@ -46,8 +47,8 @@ private const val DEBUG = false open class UserBroadcastDispatcher( private val context: Context, private val userId: Int, private val bgLooper: Looper, private val bgExecutor: Executor, private val workerLooper: Looper, private val workerExecutor: Executor, private val logger: BroadcastDispatcherLogger, private val removalPendingStore: PendingRemovalStore ) : Dumpable { Loading @@ -66,9 +67,11 @@ open class UserBroadcastDispatcher( val permission: String? ) private val bgHandler = Handler(bgLooper) private val wrongThreadErrorMsg = "This method should only be called from the worker thread " + "(which is expected to be the BroadcastRunning thread)" private val workerHandler = Handler(workerLooper) // Only modify in BG thread // Only modify in BroadcastRunning thread @VisibleForTesting internal val actionsToActionsReceivers = ArrayMap<ReceiverProperties, ActionReceiver>() private val receiverToActions = ArrayMap<BroadcastReceiver, MutableSet<String>>() Loading Loading @@ -97,8 +100,7 @@ open class UserBroadcastDispatcher( } private fun handleRegisterReceiver(receiverData: ReceiverData, flags: Int) { Preconditions.checkState(bgLooper.isCurrentThread, "This method should only be called from BG thread") Preconditions.checkState(workerLooper.isCurrentThread, wrongThreadErrorMsg) if (DEBUG) Log.w(TAG, "Register receiver: ${receiverData.receiver}") receiverToActions .getOrPut(receiverData.receiver, { ArraySet() }) Loading @@ -113,6 +115,7 @@ open class UserBroadcastDispatcher( logger.logReceiverRegistered(userId, receiverData.receiver, flags) } @SuppressLint("RegisterReceiverViaContextDetector") @VisibleForTesting internal open fun createActionReceiver( action: String, Loading @@ -128,7 +131,7 @@ open class UserBroadcastDispatcher( UserHandle.of(userId), it, permission, bgHandler, workerHandler, flags ) logger.logContextReceiverRegistered(userId, flags, it) Loading @@ -143,15 +146,14 @@ open class UserBroadcastDispatcher( IllegalStateException(e)) } }, bgExecutor, workerExecutor, logger, removalPendingStore::isPendingRemoval ) } private fun handleUnregisterReceiver(receiver: BroadcastReceiver) { Preconditions.checkState(bgLooper.isCurrentThread, "This method should only be called from BG thread") Preconditions.checkState(workerLooper.isCurrentThread, wrongThreadErrorMsg) if (DEBUG) Log.w(TAG, "Unregister receiver: $receiver") receiverToActions.getOrDefault(receiver, mutableSetOf()).forEach { actionsToActionsReceivers.forEach { (key, value) -> Loading
packages/SystemUI/src/com/android/systemui/dagger/qualifiers/BroadcastRunning.java 0 → 100644 +30 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 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.dagger.qualifiers; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import javax.inject.Qualifier; @Qualifier @Documented @Retention(RUNTIME) public @interface BroadcastRunning { }
packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.java +23 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.os.Process; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.BroadcastRunning; import com.android.systemui.dagger.qualifiers.LongRunning; import com.android.systemui.dagger.qualifiers.Main; Loading @@ -51,6 +52,17 @@ public abstract class SysUIConcurrencyModule { return thread.getLooper(); } /** BroadcastRunning Looper (for sending and receiving broadcasts) */ @Provides @SysUISingleton @BroadcastRunning public static Looper provideBroadcastRunningLooper() { HandlerThread thread = new HandlerThread("BroadcastRunning", Process.THREAD_PRIORITY_BACKGROUND); thread.start(); return thread.getLooper(); } /** Long running tasks Looper */ @Provides @SysUISingleton Loading Loading @@ -83,7 +95,17 @@ public abstract class SysUIConcurrencyModule { } /** * Provide a Long running Executor by default. * Provide a BroadcastRunning Executor (for sending and receiving broadcasts). */ @Provides @SysUISingleton @BroadcastRunning public static Executor provideBroadcastRunningExecutor(@BroadcastRunning Looper looper) { return new ExecutorImpl(looper); } /** * Provide a Long running Executor. */ @Provides @SysUISingleton Loading