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

Commit 1acaeb5b authored by Winson Chung's avatar Winson Chung
Browse files

Add logging for app drag and drop

- Allow source to specify an instance id for the drag instance
  (we'll create one otherwise if not specified)
- Log start/drop/end as per go/dragdrop_splitscreen_logging

Bug: 191686897
Test: statsd_testdrive -terse 90
Change-Id: I215208777e3627859079abac90520b1772478c5e
parent cc2f80f5
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -124,6 +124,16 @@ public class ClipDescription implements Parcelable {
     */
    public static final String EXTRA_ACTIVITY_OPTIONS = "android.intent.extra.ACTIVITY_OPTIONS";

    /**
     * An instance id used for logging.
     * <p>
     * Type: {@link com.android.internal.logging.InstanceId}
     * </p>
     * @hide
     */
    public static final String EXTRA_LOGGING_INSTANCE_ID =
            "android.intent.extra.LOGGING_INSTANCE_ID";

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(value =
+11 −2
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMA
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;

import android.content.ClipData;
import android.content.ClipDescription;
import android.content.Context;
import android.content.res.Configuration;
@@ -48,6 +49,7 @@ import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;

import com.android.internal.logging.UiEventLogger;
import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.common.DisplayController;
@@ -67,14 +69,17 @@ public class DragAndDropController implements DisplayController.OnDisplaysChange

    private final Context mContext;
    private final DisplayController mDisplayController;
    private final DragAndDropEventLogger mLogger;
    private SplitScreenController mSplitScreen;

    private final SparseArray<PerDisplay> mDisplayDropTargets = new SparseArray<>();
    private final SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction();

    public DragAndDropController(Context context, DisplayController displayController) {
    public DragAndDropController(Context context, DisplayController displayController,
            UiEventLogger uiEventLogger) {
        mContext = context;
        mDisplayController = displayController;
        mLogger = new DragAndDropEventLogger(uiEventLogger);
    }

    public void initialize(Optional<SplitScreenController> splitscreen) {
@@ -179,6 +184,7 @@ public class DragAndDropController implements DisplayController.OnDisplaysChange
                pd.dragLayout.prepare(mDisplayController.getDisplayLayout(displayId),
                        event.getClipData());
                setDropTargetWindowVisibility(pd, View.VISIBLE);
                mLogger.logStart(event);
                break;
            case ACTION_DRAG_ENTERED:
                pd.dragLayout.show();
@@ -198,7 +204,9 @@ public class DragAndDropController implements DisplayController.OnDisplaysChange
            case ACTION_DRAG_ENDED:
                // TODO(b/169894807): Ensure sure it's not possible to get ENDED without DROP
                // or EXITED
                if (!pd.dragLayout.hasDropped()) {
                if (pd.dragLayout.hasDropped()) {
                    mLogger.logDrop();
                } else {
                    pd.activeDragCount--;
                    pd.dragLayout.hide(event, () -> {
                        if (pd.activeDragCount == 0) {
@@ -208,6 +216,7 @@ public class DragAndDropController implements DisplayController.OnDisplaysChange
                        }
                    });
                }
                mLogger.logEnd();
                break;
        }
        return true;
+131 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.wm.shell.draganddrop;

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 android.content.ClipData;
import android.content.ClipDescription;
import android.content.pm.ActivityInfo;
import android.view.DragEvent;

import com.android.internal.logging.InstanceId;
import com.android.internal.logging.InstanceIdSequence;
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;

/**
 * Helper class that to log Drag & Drop UIEvents for a single session, see also go/uievent
 */
public class DragAndDropEventLogger {

    private final UiEventLogger mUiEventLogger;
    // Used to generate instance ids for this drag if one is not provided
    private final InstanceIdSequence mIdSequence;

    // Tracks the current drag session
    private ActivityInfo mActivityInfo;
    private InstanceId mInstanceId;

    public DragAndDropEventLogger(UiEventLogger uiEventLogger) {
        mUiEventLogger = uiEventLogger;
        mIdSequence = new InstanceIdSequence(Integer.MAX_VALUE);
    }

    /**
     * Logs the start of a drag.
     */
    public void logStart(DragEvent event) {
        final ClipDescription description = event.getClipDescription();
        final ClipData data = event.getClipData();
        final ClipData.Item item = data.getItemAt(0);
        mInstanceId = item.getIntent().getParcelableExtra(
                ClipDescription.EXTRA_LOGGING_INSTANCE_ID);
        if (mInstanceId == null) {
            mInstanceId = mIdSequence.newInstanceId();
        }
        mActivityInfo = item.getActivityInfo();
        mUiEventLogger.logWithInstanceId(getStartEnum(description),
                mActivityInfo.applicationInfo.uid,
                mActivityInfo.applicationInfo.packageName, mInstanceId);
    }

    /**
     * Logs a successful drop.
     */
    public void logDrop() {
        mUiEventLogger.logWithInstanceId(DragAndDropUiEventEnum.GLOBAL_APP_DRAG_DROPPED,
                mActivityInfo.applicationInfo.uid,
                mActivityInfo.applicationInfo.packageName, mInstanceId);
    }

    /**
     * Logs the end of a drag.
     */
    public void logEnd() {
        mUiEventLogger.logWithInstanceId(DragAndDropUiEventEnum.GLOBAL_APP_DRAG_END,
                mActivityInfo.applicationInfo.uid,
                mActivityInfo.applicationInfo.packageName, mInstanceId);
    }

    /**
     * Returns the start logging enum for the given drag description.
     */
    private DragAndDropUiEventEnum getStartEnum(ClipDescription description) {
        if (description.hasMimeType(MIMETYPE_APPLICATION_ACTIVITY)) {
            return DragAndDropUiEventEnum.GLOBAL_APP_DRAG_START_ACTIVITY;
        } else if (description.hasMimeType(MIMETYPE_APPLICATION_SHORTCUT)) {
            return DragAndDropUiEventEnum.GLOBAL_APP_DRAG_START_SHORTCUT;
        } else if (description.hasMimeType(MIMETYPE_APPLICATION_TASK)) {
            return DragAndDropUiEventEnum.GLOBAL_APP_DRAG_START_TASK;
        }
        throw new IllegalArgumentException("Not an app drag");
    }

    /**
     * Enums for logging Drag & Drop UiEvents
     */
    public enum DragAndDropUiEventEnum implements UiEventLogger.UiEventEnum {
        @UiEvent(doc = "Starting a global drag and drop of an activity")
        GLOBAL_APP_DRAG_START_ACTIVITY(884),

        @UiEvent(doc = "Starting a global drag and drop of a shortcut")
        GLOBAL_APP_DRAG_START_SHORTCUT(885),

        @UiEvent(doc = "Starting a global drag and drop of a task")
        GLOBAL_APP_DRAG_START_TASK(888),

        @UiEvent(doc = "A global app drag was successfully dropped")
        GLOBAL_APP_DRAG_DROPPED(887),

        @UiEvent(doc = "Ending a global app drag and drop")
        GLOBAL_APP_DRAG_END(886);

        private final int mId;

        DragAndDropUiEventEnum(int id) {
            mId = id;
        }

        @Override
        public int getId() {
            return mId;
        }
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -126,8 +126,8 @@ public abstract class WMShellBaseModule {
    @WMSingleton
    @Provides
    static DragAndDropController provideDragAndDropController(Context context,
            DisplayController displayController) {
        return new DragAndDropController(context, displayController);
            DisplayController displayController, UiEventLogger uiEventLogger) {
        return new DragAndDropController(context, displayController, uiEventLogger);
    }

    @WMSingleton