Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 16a3825e authored by Jernej Virag's avatar Jernej Virag Committed by Automerger Merge Worker
Browse files

Merge "Remove main thread sendBroadcast calls" into tm-dev am: 10ed7b6d

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

Change-Id: I3db237865d14159fdfc8b7d258bb026b2e027145
parents 34f5be32 10ed7b6d
Loading
Loading
Loading
Loading
+132 −0
Original line number Diff line number Diff line
package com.android.systemui.broadcast

import android.annotation.AnyThread
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.UserHandle
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.util.wakelock.WakeLock
import java.util.concurrent.Executor
import javax.inject.Inject

/**
 * SystemUI master Broadcast sender
 *
 * This class dispatches broadcasts on background thread to avoid synchronous call to binder. Use
 * this class instead of calling [Context.sendBroadcast] directly.
 */
@SysUISingleton
class BroadcastSender @Inject constructor(
    private val context: Context,
    private val wakeLockBuilder: WakeLock.Builder,
    @Background private val bgExecutor: Executor
) {

    private val WAKE_LOCK_TAG = "SysUI:BroadcastSender"
    private val WAKE_LOCK_SEND_REASON = "sendInBackground"

    /**
     * Sends broadcast via [Context.sendBroadcast] on background thread to avoid blocking
     * synchronous binder call.
     */
    @AnyThread
    fun sendBroadcast(intent: Intent) {
        sendInBackground {
            context.sendBroadcast(intent)
        }
    }

    /**
     * Sends broadcast via [Context.sendBroadcast] on background thread to avoid blocking
     * synchronous binder call.
     */
    @AnyThread
    fun sendBroadcast(intent: Intent, receiverPermission: String?) {
        sendInBackground {
            context.sendBroadcast(intent, receiverPermission)
        }
    }

    /**
     * Sends broadcast via [Context.sendBroadcastAsUser] on background thread to avoid blocking
     * synchronous binder call.
     */
    @AnyThread
    fun sendBroadcastAsUser(intent: Intent, userHandle: UserHandle) {
        sendInBackground {
            context.sendBroadcastAsUser(intent, userHandle)
        }
    }

    /**
     * Sends broadcast via [Context.sendBroadcastAsUser] on background thread to avoid blocking
     * synchronous binder call.
     */
    @AnyThread
    fun sendBroadcastAsUser(intent: Intent, userHandle: UserHandle, receiverPermission: String?) {
        sendInBackground {
            context.sendBroadcastAsUser(intent, userHandle, receiverPermission)
        }
    }

    /**
     * Sends broadcast via [Context.sendBroadcastAsUser] on background thread to avoid blocking
     * synchronous binder call.
     */
    @AnyThread
    fun sendBroadcastAsUser(
        intent: Intent,
        userHandle: UserHandle,
        receiverPermission: String?,
        options: Bundle?
    ) {
        sendInBackground {
            context.sendBroadcastAsUser(intent, userHandle, receiverPermission, options)
        }
    }

    /**
     * Sends broadcast via [Context.sendBroadcastAsUser] on background thread to avoid blocking
     * synchronous binder call.
     */
    @AnyThread
    fun sendBroadcastAsUser(
        intent: Intent,
        userHandle: UserHandle,
        receiverPermission: String?,
        appOp: Int
    ) {
        sendInBackground {
            context.sendBroadcastAsUser(intent, userHandle, receiverPermission, appOp)
        }
    }

    /**
     * Sends [Intent.ACTION_CLOSE_SYSTEM_DIALOGS] broadcast to the system.
     */
    @AnyThread
    fun closeSystemDialogs() {
        sendInBackground {
            context.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS))
        }
    }

    /**
     * Dispatches parameter on background executor while holding a wakelock.
     */
    private fun sendInBackground(callable: () -> Unit) {
        val broadcastWakelock = wakeLockBuilder.setTag(WAKE_LOCK_TAG)
                                .setMaxTimeout(5000)
                                .build()
        broadcastWakelock.acquire(WAKE_LOCK_SEND_REASON)
        bgExecutor.execute {
            try {
                callable.invoke()
            } finally {
                broadcastWakelock.release(WAKE_LOCK_SEND_REASON)
            }
        }
    }
}
 No newline at end of file
+9 −3
Original line number Diff line number Diff line
@@ -16,11 +16,11 @@

package com.android.systemui.controls.ui

import android.annotation.AnyThread
import android.annotation.MainThread
import android.app.Dialog
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
import android.database.ContentObserver
@@ -35,6 +35,7 @@ import android.service.controls.actions.FloatAction
import android.util.Log
import android.view.HapticFeedbackConstants
import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.broadcast.BroadcastSender
import com.android.systemui.controls.ControlsMetricsLogger
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
@@ -53,6 +54,7 @@ class ControlActionCoordinatorImpl @Inject constructor(
    private val bgExecutor: DelayableExecutor,
    @Main private val uiExecutor: DelayableExecutor,
    private val activityStarter: ActivityStarter,
    private val broadcastSender: BroadcastSender,
    private val keyguardStateController: KeyguardStateController,
    private val taskViewFactory: Optional<TaskViewFactory>,
    private val controlsMetricsLogger: ControlsMetricsLogger,
@@ -199,11 +201,12 @@ class ControlActionCoordinatorImpl @Inject constructor(
            false
        }

    @AnyThread
    @VisibleForTesting
    fun bouncerOrRun(action: Action, authRequired: Boolean) {
        if (keyguardStateController.isShowing() && authRequired) {
            if (isLocked) {
                context.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS))
                broadcastSender.closeSystemDialogs()

                // pending actions will only run after the control state has been refreshed
                pendingAction = action
@@ -233,7 +236,10 @@ class ControlActionCoordinatorImpl @Inject constructor(
                // make sure the intent is valid before attempting to open the dialog
                if (activities.isNotEmpty() && taskViewFactory.isPresent) {
                    taskViewFactory.get().create(context, uiExecutor, {
                        dialog = DetailDialog(activityContext, it, pendingIntent, cvh).also {
                        dialog = DetailDialog(
                            activityContext, broadcastSender,
                            it, pendingIntent, cvh
                        ).also {
                            it.setOnDismissListener { _ -> dialog = null }
                            it.show()
                        }
+3 −1
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.view.WindowManager
import android.widget.ImageView
import com.android.internal.policy.ScreenDecorationsUtils
import com.android.systemui.R
import com.android.systemui.broadcast.BroadcastSender
import com.android.wm.shell.TaskView

/**
@@ -42,6 +43,7 @@ import com.android.wm.shell.TaskView
 */
class DetailDialog(
    val activityContext: Context,
    val broadcastSender: BroadcastSender,
    val taskView: TaskView,
    val pendingIntent: PendingIntent,
    val cvh: ControlViewHolder
@@ -147,7 +149,7 @@ class DetailDialog(
                // startActivity() below is called.
                removeDetailTask()
                dismiss()
                context.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS))
                broadcastSender.closeSystemDialogs()
                pendingIntent.send()
            }
        }
+7 −3
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ import com.android.settingslib.widget.AdaptiveIcon;
import com.android.systemui.R;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.animation.GhostedViewLaunchAnimatorController;
import com.android.systemui.broadcast.BroadcastSender;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.media.dialog.MediaOutputDialogFactory;
import com.android.systemui.monet.ColorScheme;
@@ -108,6 +109,7 @@ public class MediaControlPanel {
    private SeekBarObserver mSeekBarObserver;
    protected final Executor mBackgroundExecutor;
    private final ActivityStarter mActivityStarter;
    private final BroadcastSender mBroadcastSender;

    private Context mContext;
    private MediaViewHolder mMediaViewHolder;
@@ -142,14 +144,16 @@ public class MediaControlPanel {
     */
    @Inject
    public MediaControlPanel(Context context, @Background Executor backgroundExecutor,
            ActivityStarter activityStarter, MediaViewController mediaViewController,
            SeekBarViewModel seekBarViewModel, Lazy<MediaDataManager> lazyMediaDataManager,
            ActivityStarter activityStarter, BroadcastSender broadcastSender,
            MediaViewController mediaViewController, SeekBarViewModel seekBarViewModel,
            Lazy<MediaDataManager> lazyMediaDataManager,
            MediaOutputDialogFactory mediaOutputDialogFactory,
            MediaCarouselController mediaCarouselController,
            FalsingManager falsingManager, MediaFlags mediaFlags, SystemClock systemClock) {
        mContext = context;
        mBackgroundExecutor = backgroundExecutor;
        mActivityStarter = activityStarter;
        mBroadcastSender = broadcastSender;
        mSeekBarViewModel = seekBarViewModel;
        mMediaViewController = mediaViewController;
        mMediaDataManagerLazy = lazyMediaDataManager;
@@ -898,7 +902,7 @@ public class MediaControlPanel {
                // Dismiss the card Smartspace data through Smartspace trampoline activity.
                mContext.startActivity(dismissIntent);
            } else {
                mContext.sendBroadcast(dismissIntent);
                mBroadcastSender.sendBroadcast(dismissIntent);
            }
        });

+3 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.os.SystemProperties
import android.util.Log
import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.broadcast.BroadcastSender
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.settings.CurrentUserTracker
import com.android.systemui.statusbar.NotificationLockscreenUserManager
@@ -56,6 +57,7 @@ internal val SMARTSPACE_MAX_AGE = SystemProperties
class MediaDataFilter @Inject constructor(
    private val context: Context,
    private val broadcastDispatcher: BroadcastDispatcher,
    private val broadcastSender: BroadcastSender,
    private val lockscreenUserManager: NotificationLockscreenUserManager,
    @Main private val executor: Executor,
    private val systemClock: SystemClock
@@ -249,7 +251,7 @@ class MediaDataFilter @Inject constructor(
                // Dismiss the card Smartspace data through Smartspace trampoline activity.
                context.startActivity(dismissIntent)
            } else {
                context.sendBroadcast(dismissIntent)
                broadcastSender.sendBroadcast(dismissIntent)
            }
            smartspaceMediaData = EMPTY_SMARTSPACE_MEDIA_DATA.copy(
                targetId = smartspaceMediaData.targetId, isValid = smartspaceMediaData.isValid)
Loading