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

Commit 3c6c95ed authored by Daichi Hirono's avatar Daichi Hirono
Browse files

Add callback to DragDropController.

The callback allows vendor code to hook drag and drop operations.

Bug: 63914027
Test: Manually drag and drop files between apps, CTS
      CrossAppDragAndDropTests
Change-Id: I33bf907b7c024a485c51bd87d7c4839718ebeb13
parent 77ef9c3c
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.view;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ClipData;
import android.graphics.Rect;
import android.graphics.Region;
import android.hardware.display.DisplayManagerInternal;
@@ -139,6 +140,30 @@ public abstract class WindowManagerInternal {
        public void onHardKeyboardStatusChange(boolean available);
    }

    /**
     * An interface to customize drag and drop behaviors.
     */
    public interface IDragDropCallback {
        /**
         * Called when drag operation is started.
         */
        default boolean performDrag(IWindow window, IBinder dragToken,
                int touchSource, float touchX, float touchY, float thumbCenterX, float thumbCenterY,
                ClipData data) {
            return true;
        }

        /**
         * Called when drop result is reported.
         */
        default void reportDropResult(IWindow window, boolean consumed) {}

        /**
         * Called when drag operation is cancelled.
         */
        default void cancelDragAndDrop(IBinder dragToken) {}
    }

    /**
     * Request that the window manager call
     * {@link DisplayManagerInternal#performTraversalInTransactionFromWindowManager}
@@ -351,4 +376,9 @@ public abstract class WindowManagerInternal {
     * {@param vr2dDisplayId}.
     */
    public abstract void setVr2dDisplayId(int vr2dDisplayId);

    /**
     * Sets callback to DragDropController.
     */
    public abstract void registerDragDropControllerCallback(IDragDropCallback callback);
}
+22 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACT
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;

import android.annotation.NonNull;
import android.content.ClipData;
import android.graphics.PixelFormat;
import android.os.Binder;
@@ -35,6 +36,8 @@ import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.view.View;
import android.view.WindowManagerInternal.IDragDropCallback;
import com.android.internal.util.Preconditions;
import com.android.server.input.InputWindowHandle;

/**
@@ -61,6 +64,7 @@ class DragDropController {

    private WindowManagerService mService;
    private final Handler mHandler;

    /**
     * Lock to preserve the order of state updates.
     * The lock is used to process drag and drop state updates in order without having the window
@@ -94,6 +98,11 @@ class DragDropController {
     */
    private final Object mWriteLock = new Object();

    /**
     * Callback which is used to sync drag state with the vendor-specific code.
     */
    @NonNull private IDragDropCallback mCallback = new IDragDropCallback() {};

    boolean dragDropActiveLocked() {
        return mDragState != null;
    }
@@ -102,6 +111,13 @@ class DragDropController {
        return mDragState.getInputWindowHandle();
    }

    void registerCallback(IDragDropCallback callback) {
        Preconditions.checkNotNull(callback);
        synchronized (mWriteLock) {
            mCallback = callback;
        }
    }

    DragDropController(WindowManagerService service, Looper looper) {
        mService = service;
        mHandler = new DragHandler(service, looper);
@@ -169,6 +185,10 @@ class DragDropController {
        }

        synchronized (mWriteLock) {
            if (!mCallback.performDrag(window, dragToken, touchSource, touchX, touchY, thumbCenterX,
                    thumbCenterY, data)) {
                return false;
            }
            synchronized (mService.mWindowMap) {
                if (mDragState == null) {
                    Slog.w(TAG_WM, "No drag prepared");
@@ -251,6 +271,7 @@ class DragDropController {
        }

        synchronized (mWriteLock) {
            mCallback.reportDropResult(window, consumed);
            synchronized (mService.mWindowMap) {
                if (mDragState == null) {
                    // Most likely the drop recipient ANRed and we ended the drag
@@ -288,6 +309,7 @@ class DragDropController {
        }

        synchronized (mWriteLock) {
            mCallback.cancelDragAndDrop(dragToken);
            synchronized (mService.mWindowMap) {
                if (mDragState == null) {
                    Slog.w(TAG_WM, "cancelDragAndDrop() without prepareDrag()");
+6 −0
Original line number Diff line number Diff line
@@ -125,6 +125,7 @@ import android.app.ActivityThread;
import android.app.AppOpsManager;
import android.app.IActivityManager;
import android.content.BroadcastReceiver;
import android.content.ClipData;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -7441,6 +7442,11 @@ public class WindowManagerService extends IWindowManager.Stub
                mVr2dDisplayId = vr2dDisplayId;
            }
        }

        @Override
        public void registerDragDropControllerCallback(IDragDropCallback callback) {
            mDragDropController.registerCallback(callback);
        }
    }

    void registerAppFreezeListener(AppFreezeListener listener) {