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

Commit 76cab65c authored by Winson Chung's avatar Winson Chung
Browse files

Adding some trace tags around system drag and drop

- This CL adds some trace points to better understand drag and drop
  performance.  In particular it adds
  - Client side: startDragAndDrop (trace points for drag shadow drawing,
    call to WM), handleDragEvent (trace points for drag event handling
    for non-LOCATION events)
  - WM side: DragDropController (trace points for dispatching of START,
    DROP, END, and notifying unhandled drops)
  - Shell side: GlobalDragListener (trace points for unhandled drop)

Bug: 308749691
Test: Take a perfetto trace w/ a global drag
Change-Id: Ib9abd414fe67f20ffc3c9dfe261e87ccd8dda766
parent 459ed769
Loading
Loading
Loading
Loading
+38 −29
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.view;
import static android.content.res.Resources.ID_NULL;
import static android.os.Trace.TRACE_TAG_APP;
import static android.os.Trace.TRACE_TAG_VIEW;
import static android.service.autofill.Flags.FLAG_AUTOFILL_CREDMAN_DEV_INTEGRATION;
import static android.view.ContentInfo.SOURCE_DRAG_AND_DROP;
import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH;
@@ -16335,20 +16336,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        ListenerInfo li = mListenerInfo;
        if (li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED) {
            try {
                Trace.traceBegin(Trace.TRACE_TAG_VIEW, "View.onTouchListener#onTouch");
                Trace.traceBegin(TRACE_TAG_VIEW, "View.onTouchListener#onTouch");
                handled = li.mOnTouchListener.onTouch(this, event);
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
                Trace.traceEnd(TRACE_TAG_VIEW);
            }
        }
        if (handled) {
            return true;
        }
        try {
            Trace.traceBegin(Trace.TRACE_TAG_VIEW, "View#onTouchEvent");
            Trace.traceBegin(TRACE_TAG_VIEW, "View#onTouchEvent");
            return onTouchEvent(event);
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
            Trace.traceEnd(TRACE_TAG_VIEW);
        }
    }
@@ -23825,14 +23826,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    public void buildDrawingCache(boolean autoScale) {
        if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0 || (autoScale ?
                mDrawingCache == null : mUnscaledDrawingCache == null)) {
            if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
                Trace.traceBegin(Trace.TRACE_TAG_VIEW,
            if (Trace.isTagEnabled(TRACE_TAG_VIEW)) {
                Trace.traceBegin(TRACE_TAG_VIEW,
                        "buildDrawingCache/SW Layer for " + getClass().getSimpleName());
            }
            try {
                buildDrawingCacheImpl(autoScale);
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
                Trace.traceEnd(TRACE_TAG_VIEW);
            }
        }
    }
@@ -28959,6 +28960,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        surface.copyFrom(surfaceControl);
        IBinder token = null;
        try {
            Trace.traceBegin(TRACE_TAG_VIEW, "startDragAndDrop#drawDragShadow");
            final Canvas canvas = isHardwareAccelerated()
                    ? surface.lockHardwareCanvas()
                    : surface.lockCanvas(null);
@@ -28967,8 +28969,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                shadowBuilder.onDrawShadow(canvas);
            } finally {
                surface.unlockCanvasAndPost(canvas);
                Trace.traceEnd(TRACE_TAG_VIEW);
            }
            Trace.traceBegin(TRACE_TAG_VIEW, "startDragAndDrop#performDrag");
            try {
                token = mAttachInfo.mSession.performDrag(mAttachInfo.mWindow, flags, surfaceControl,
                        root.getLastTouchSource(), root.getLastTouchDeviceId(),
                        root.getLastTouchPointerId(), lastTouchPoint.x, lastTouchPoint.y,
@@ -28981,6 +28986,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                        mAttachInfo.mDragSurface.release();
                    }
                    if (mAttachInfo.mDragData != null) {
                        // Clean up previous drag data intents
                        View.cleanUpPendingIntents(mAttachInfo.mDragData);
                    }
                    mAttachInfo.mDragSurface = surface;
@@ -28994,6 +29000,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                    }
                }
                return token != null;
            } finally {
                Trace.traceEnd(TRACE_TAG_VIEW);
            }
        } catch (Exception e) {
            Log.e(VIEW_LOG_TAG, "Unable to initiate drag", e);
            return false;
+14 −1
Original line number Diff line number Diff line
@@ -21,8 +21,10 @@ import static android.content.pm.ActivityInfo.OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS;
import static android.graphics.HardwareRenderer.SYNC_CONTEXT_IS_STOPPED;
import static android.graphics.HardwareRenderer.SYNC_LOST_SURFACE_REWARD_IF_FOUND;
import static android.os.IInputConstants.INVALID_INPUT_EVENT_ID;
import static android.os.Trace.TRACE_TAG_VIEW;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.DragEvent.ACTION_DRAG_LOCATION;
import static android.view.InputDevice.SOURCE_CLASS_NONE;
import static android.view.InsetsSource.ID_IME;
import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH;
@@ -6464,7 +6466,18 @@ public final class ViewRootImpl implements ViewParent,
                    DragEvent event = (DragEvent) msg.obj;
                    // only present when this app called startDrag()
                    event.mLocalState = mLocalDragState;
                    final boolean traceDragEvent = event.mAction != ACTION_DRAG_LOCATION;
                    try {
                        if (traceDragEvent) {
                            Trace.traceBegin(TRACE_TAG_VIEW,
                                    "c#" + DragEvent.actionToString(event.mAction));
                        }
                        handleDragEvent(event);
                    } finally {
                        if (traceDragEvent) {
                            Trace.traceEnd(TRACE_TAG_VIEW);
                        }
                    }
                } break;
                case MSG_DISPATCH_SYSTEM_UI_VISIBILITY: {
                    handleDispatchSystemUiVisibilityChanged();
+10 −0
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@ package com.android.wm.shell.draganddrop

import android.app.ActivityManager
import android.os.RemoteException
import android.os.Trace
import android.os.Trace.TRACE_TAG_WINDOW_MANAGER
import android.util.Log
import android.view.DragEvent
import android.view.IWindowManager
@@ -27,6 +29,7 @@ import com.android.internal.protolog.common.ProtoLog
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.protolog.ShellProtoLogGroup
import java.util.function.Consumer
import kotlin.random.Random

/**
 * Manages the listener and callbacks for unhandled global drags.
@@ -101,10 +104,15 @@ class GlobalDragListener(

    @VisibleForTesting
    fun onUnhandledDrop(dragEvent: DragEvent, wmCallback: IUnhandledDragCallback) {
        val traceCookie = Random.nextInt()
        Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, "GlobalDragListener.onUnhandledDrop",
            traceCookie);
        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
            "onUnhandledDrop: %s", dragEvent)
        if (callback == null) {
            wmCallback.notifyUnhandledDropComplete(false)
            Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER, "GlobalDragListener.onUnhandledDrop",
                traceCookie);
            return
        }

@@ -112,6 +120,8 @@ class GlobalDragListener(
            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
                "Notifying onUnhandledDrop complete: %b", it)
            wmCallback.notifyUnhandledDropComplete(it)
            Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER, "GlobalDragListener.onUnhandledDrop",
                traceCookie);
        }
    }

+8 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.wm;

import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.View.DRAG_FLAG_GLOBAL;
import static android.view.View.DRAG_FLAG_GLOBAL_SAME_APPLICATION;
import static android.view.View.DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG;
@@ -36,6 +37,7 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.Trace;
import android.util.Slog;
import android.view.Display;
import android.view.DragEvent;
@@ -52,6 +54,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.server.wm.WindowManagerInternal.IDragDropCallback;

import java.util.Objects;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
@@ -386,6 +389,9 @@ class DragDropController {
                    + "(listener=" + mGlobalDragListener + ", flags=" + mDragState.mFlags + ")");
            return false;
        }
        final int traceCookie = new Random().nextInt();
        Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, "DragDropController#notifyUnhandledDrop",
                traceCookie);
        if (DEBUG_DRAG) Slog.d(TAG_WM, "Sending DROP to unhandled listener (" + reason + ")");
        try {
            // Schedule timeout for the unhandled drag listener to call back
@@ -396,6 +402,8 @@ class DragDropController {
                    if (DEBUG_DRAG) Slog.d(TAG_WM, "Unhandled listener finished handling DROP");
                    synchronized (mService.mGlobalLock) {
                        onUnhandledDropCallback(consumedByListener);
                        Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER,
                                "DragDropController#notifyUnhandledDrop", traceCookie);
                    }
                }
            });
+20 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.content.ClipDescription.MIMETYPE_APPLICATION_ACTIVITY;
import static android.content.ClipDescription.MIMETYPE_APPLICATION_SHORTCUT;
import static android.content.ClipDescription.MIMETYPE_APPLICATION_TASK;
import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP;

import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
@@ -49,6 +50,7 @@ import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Slog;
@@ -258,6 +260,7 @@ class DragState {
            }
            mNotifiedWindows.clear();
            mDragInProgress = false;
            Trace.instant(TRACE_TAG_WINDOW_MANAGER, "DragDropController#DRAG_ENDED");
        }

        // Take the cursor back if it has been changed.
@@ -343,6 +346,18 @@ class DragState {
        if (mAnimator != null) {
            return false;
        }
        try {
            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "DragDropController#DROP");
            return reportDropWindowLockInner(token, x, y);
        } finally {
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        }
    }

    private boolean reportDropWindowLockInner(IBinder token, float x, float y) {
        if (mAnimator != null) {
            return false;
        }

        final WindowState touchedWin = mService.mInputToWindowMap.get(token);
        final DragEvent unhandledDropEvent = createDropEvent(x, y, null /* touchedWin */,
@@ -355,10 +370,12 @@ class DragState {
                return true;
            }

            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "DragDropController#noWindow");
            // "drop" outside a valid window -- no recipient to apply a timeout to, and we can send
            // the drag-ended message immediately.
            endDragLocked(false /* consumed */, false /* relinquishDragSurfaceToDropTarget */);
            if (DEBUG_DRAG) Slog.d(TAG_WM, "Drop outside a valid window " + touchedWin);
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
            return false;
        }

@@ -367,6 +384,7 @@ class DragState {
        final IBinder clientToken = touchedWin.mClient.asBinder();
        final DragEvent event = createDropEvent(x, y, touchedWin, false /* includePrivateInfo */);
        try {
            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "DragDropController#dispatchDrop");
            touchedWin.mClient.dispatchDragEvent(event);

            // 5 second timeout for this window to respond to the drop
@@ -380,6 +398,7 @@ class DragState {
            if (MY_PID != touchedWin.mSession.mPid) {
                event.recycle();
            }
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        }
        mToken = clientToken;
        mUnhandledDropEvent = unhandledDropEvent;
@@ -471,6 +490,7 @@ class DragState {
    /* call out to each visible window/session informing it about the drag
     */
    void broadcastDragStartedLocked(final float touchX, final float touchY) {
        Trace.instant(TRACE_TAG_WINDOW_MANAGER, "DragDropController#DRAG_STARTED");
        mOriginalX = mCurrentX = touchX;
        mOriginalY = mCurrentY = touchY;