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

Commit 590fb801 authored by Jernej Virag's avatar Jernej Virag
Browse files

Move ClipboardOverlayController broadcast handling to background thread

BroadcastDispatcher and BroadcastSender will handle this on background threads and avoid jank.

Bug: 224545601
Test: Tested ScreenshotView functionality on a physical device
Change-Id: I3b1c0d3f14dc4e1010a2e8754aac57755ce726cc
parent 9519e3c9
Loading
Loading
Loading
Loading
+12 −7
Original line number Diff line number Diff line
@@ -41,7 +41,8 @@ data class ReceiverData(
    val receiver: BroadcastReceiver,
    val filter: IntentFilter,
    val executor: Executor,
    val user: UserHandle
    val user: UserHandle,
    val permission: String? = null
)

private const val MSG_ADD_RECEIVER = 0
@@ -96,16 +97,18 @@ open class BroadcastDispatcher constructor (
     *
     */
    @Deprecated(message = "Replacing Handler for Executor in SystemUI",
            replaceWith = ReplaceWith("registerReceiver(receiver, filter, executor, user)"))
        replaceWith = ReplaceWith("registerReceiver(receiver, filter, executor, user, permission)")
    )
    @JvmOverloads
    open fun registerReceiverWithHandler(
        receiver: BroadcastReceiver,
        filter: IntentFilter,
        handler: Handler,
        user: UserHandle = context.user,
        @Context.RegisterReceiverFlags flags: Int = Context.RECEIVER_EXPORTED
        @Context.RegisterReceiverFlags flags: Int = Context.RECEIVER_EXPORTED,
        permission: String? = null
    ) {
        registerReceiver(receiver, filter, HandlerExecutor(handler), user, flags)
        registerReceiver(receiver, filter, HandlerExecutor(handler), user, flags, permission)
    }

    /**
@@ -130,14 +133,16 @@ open class BroadcastDispatcher constructor (
        filter: IntentFilter,
        executor: Executor? = null,
        user: UserHandle? = null,
        @Context.RegisterReceiverFlags flags: Int = Context.RECEIVER_EXPORTED
        @Context.RegisterReceiverFlags flags: Int = Context.RECEIVER_EXPORTED,
        permission: String? = null,
    ) {
        checkFilter(filter)
        val data = ReceiverData(
                receiver,
                filter,
                executor ?: context.mainExecutor,
                user ?: context.user
                user ?: context.user,
                permission
            )
        this.handler
                .obtainMessage(MSG_ADD_RECEIVER, flags, 0, data)
+25 −9
Original line number Diff line number Diff line
@@ -71,9 +71,16 @@ open class UserBroadcastDispatcher(
        }
    }

    // Used for key in actionsToActionsReceivers
    internal data class ReceiverProperties(
        val action: String,
        val flags: Int,
        val permission: String?
    )

    // Only modify in BG thread
    @VisibleForTesting
    internal val actionsToActionsReceivers = ArrayMap<Pair<String, Int>, ActionReceiver>()
    internal val actionsToActionsReceivers = ArrayMap<ReceiverProperties, ActionReceiver>()
    private val receiverToActions = ArrayMap<BroadcastReceiver, MutableSet<String>>()

    @VisibleForTesting
@@ -106,14 +113,20 @@ open class UserBroadcastDispatcher(
                .addAll(receiverData.filter.actionsIterator()?.asSequence() ?: emptySequence())
        receiverData.filter.actionsIterator().forEach {
            actionsToActionsReceivers
                    .getOrPut(it to flags, { createActionReceiver(it, flags) })
                .getOrPut(
                    ReceiverProperties(it, flags, receiverData.permission),
                    { createActionReceiver(it, receiverData.permission, flags) })
                .addReceiverData(receiverData)
        }
        logger.logReceiverRegistered(userId, receiverData.receiver, flags)
    }

    @VisibleForTesting
    internal open fun createActionReceiver(action: String, flags: Int): ActionReceiver {
    internal open fun createActionReceiver(
        action: String,
        permission: String?,
        flags: Int
    ): ActionReceiver {
        return ActionReceiver(
                action,
                userId,
@@ -122,7 +135,7 @@ open class UserBroadcastDispatcher(
                            this,
                            UserHandle.of(userId),
                            it,
                            null,
                            permission,
                            bgHandler,
                            flags
                    )
@@ -149,7 +162,7 @@ open class UserBroadcastDispatcher(
        if (DEBUG) Log.w(TAG, "Unregister receiver: $receiver")
        receiverToActions.getOrDefault(receiver, mutableSetOf()).forEach {
            actionsToActionsReceivers.forEach { (key, value) ->
                if (key.first == it) {
                if (key.action == it) {
                    value.removeReceiver(receiver)
                }
            }
@@ -160,9 +173,12 @@ open class UserBroadcastDispatcher(

    override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
        pw.indentIfPossible {
            actionsToActionsReceivers.forEach { (actionAndFlags, actionReceiver) ->
                println("(${actionAndFlags.first}: " +
                        "${BroadcastDispatcherLogger.flagToString(actionAndFlags.second)}):")
            actionsToActionsReceivers.forEach { (actionFlagsPerm, actionReceiver) ->
                println(
                    "(${actionFlagsPerm.action}: " +
                        BroadcastDispatcherLogger.flagToString(actionFlagsPerm.flags) +
                        if (actionFlagsPerm.permission == null) "):"
                            else ":${actionFlagsPerm.permission}):")
                actionReceiver.dump(fd, pw, args)
            }
        }
+15 −7
Original line number Diff line number Diff line
@@ -80,6 +80,8 @@ import android.widget.TextView;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.policy.PhoneWindow;
import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.broadcast.BroadcastSender;
import com.android.systemui.screenshot.DraggableConstraintLayout;
import com.android.systemui.screenshot.FloatingWindowUtil;
import com.android.systemui.screenshot.OverlayActionChip;
@@ -105,6 +107,7 @@ public class ClipboardOverlayController {

    private final Context mContext;
    private final UiEventLogger mUiEventLogger;
    private final BroadcastDispatcher mBroadcastDispatcher;
    private final DisplayManager mDisplayManager;
    private final DisplayMetrics mDisplayMetrics;
    private final WindowManager mWindowManager;
@@ -137,8 +140,11 @@ public class ClipboardOverlayController {

    private boolean mBlockAttach = false;

    public ClipboardOverlayController(
            Context context, TimeoutHandler timeoutHandler, UiEventLogger uiEventLogger) {
    public ClipboardOverlayController(Context context,
            BroadcastDispatcher broadcastDispatcher,
            BroadcastSender broadcastSender,
            TimeoutHandler timeoutHandler, UiEventLogger uiEventLogger) {
        mBroadcastDispatcher = broadcastDispatcher;
        mDisplayManager = requireNonNull(context.getSystemService(DisplayManager.class));
        final Context displayContext = context.createDisplayContext(getDefaultDisplay());
        mContext = displayContext.createWindowContext(TYPE_SCREENSHOT, null);
@@ -247,9 +253,9 @@ public class ClipboardOverlayController {
                }
            }
        };
        mContext.registerReceiver(mCloseDialogsReceiver,
                new IntentFilter(ACTION_CLOSE_SYSTEM_DIALOGS));

        mBroadcastDispatcher.registerReceiver(mCloseDialogsReceiver,
                new IntentFilter(ACTION_CLOSE_SYSTEM_DIALOGS));
        mScreenshotReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
@@ -258,14 +264,16 @@ public class ClipboardOverlayController {
                }
            }
        };
        mContext.registerReceiver(mScreenshotReceiver, new IntentFilter(SCREENSHOT_ACTION),
                SELF_PERMISSION, null);

        mBroadcastDispatcher.registerReceiver(mScreenshotReceiver,
                new IntentFilter(SCREENSHOT_ACTION), null, null, Context.RECEIVER_EXPORTED,
                SELF_PERMISSION);
        monitorOutsideTouches();

        Intent copyIntent = new Intent(COPY_OVERLAY_ACTION);
        // Set package name so the system knows it's safe
        copyIntent.setPackage(mContext.getPackageName());
        mContext.sendBroadcast(copyIntent, SELF_PERMISSION);
        broadcastSender.sendBroadcast(copyIntent, SELF_PERMISSION);
    }

    void setClipData(ClipData clipData, String clipSource) {
+12 −3
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.systemui.clipboardoverlay;
import android.content.Context;

import com.android.internal.logging.UiEventLogger;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.broadcast.BroadcastSender;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.screenshot.TimeoutHandler;

@@ -29,17 +31,24 @@ import javax.inject.Inject;
 */
@SysUISingleton
public class ClipboardOverlayControllerFactory {

    private final UiEventLogger mUiEventLogger;
    private final BroadcastDispatcher mBroadcastDispatcher;
    private final BroadcastSender mBroadcastSender;

    @Inject
    public ClipboardOverlayControllerFactory(UiEventLogger uiEventLogger) {
        mUiEventLogger = uiEventLogger;
    public ClipboardOverlayControllerFactory(BroadcastDispatcher broadcastDispatcher,
            BroadcastSender broadcastSender, UiEventLogger uiEventLogger) {
        this.mBroadcastDispatcher = broadcastDispatcher;
        this.mBroadcastSender = broadcastSender;
        this.mUiEventLogger = uiEventLogger;
    }

    /**
     * One new ClipboardOverlayController, coming right up!
     */
    public ClipboardOverlayController create(Context context) {
        return new ClipboardOverlayController(context, new TimeoutHandler(context), mUiEventLogger);
        return new ClipboardOverlayController(context, mBroadcastDispatcher, mBroadcastSender,
                new TimeoutHandler(context), mUiEventLogger);
    }
}
+0 −10
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ import android.view.IWindowManager;
import android.view.LayoutInflater;

import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.util.NotificationMessagingUtil;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
@@ -50,7 +49,6 @@ import com.android.systemui.accessibility.ModeSwitchesController;
import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuController;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger;
import com.android.systemui.clipboardoverlay.ClipboardOverlayControllerFactory;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.AlwaysOnDisplayPolicy;
@@ -293,12 +291,4 @@ public class DependencyProvider {
    public ModeSwitchesController providesModeSwitchesController(Context context) {
        return new ModeSwitchesController(context);
    }

    /***/
    @Provides
    @SysUISingleton
    public ClipboardOverlayControllerFactory provideClipboardOverlayControllerFactory(
            UiEventLogger uiEventLogger) {
        return new ClipboardOverlayControllerFactory(uiEventLogger);
    }
}
Loading