1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.wm.shell.draganddrop; 18 19 import static android.content.ClipDescription.MIMETYPE_APPLICATION_ACTIVITY; 20 import static android.content.ClipDescription.MIMETYPE_APPLICATION_SHORTCUT; 21 import static android.content.ClipDescription.MIMETYPE_APPLICATION_TASK; 22 23 import android.content.ClipData; 24 import android.content.ClipDescription; 25 import android.content.pm.ActivityInfo; 26 import android.view.DragEvent; 27 28 import androidx.annotation.Nullable; 29 30 import com.android.internal.logging.InstanceId; 31 import com.android.internal.logging.InstanceIdSequence; 32 import com.android.internal.logging.UiEvent; 33 import com.android.internal.logging.UiEventLogger; 34 35 /** 36 * Helper class that to log Drag & Drop UIEvents for a single session, see also go/uievent 37 */ 38 public class DragAndDropEventLogger { 39 40 private final UiEventLogger mUiEventLogger; 41 // Used to generate instance ids for this drag if one is not provided 42 private final InstanceIdSequence mIdSequence; 43 44 // Tracks the current drag session 45 private ActivityInfo mActivityInfo; 46 private InstanceId mInstanceId; 47 DragAndDropEventLogger(UiEventLogger uiEventLogger)48 public DragAndDropEventLogger(UiEventLogger uiEventLogger) { 49 mUiEventLogger = uiEventLogger; 50 mIdSequence = new InstanceIdSequence(Integer.MAX_VALUE); 51 } 52 53 /** 54 * Logs the start of a drag. 55 */ logStart(DragEvent event)56 public InstanceId logStart(DragEvent event) { 57 final ClipDescription description = event.getClipDescription(); 58 final ClipData data = event.getClipData(); 59 final ClipData.Item item = data.getItemAt(0); 60 mInstanceId = item.getIntent().getParcelableExtra( 61 ClipDescription.EXTRA_LOGGING_INSTANCE_ID); 62 if (mInstanceId == null) { 63 mInstanceId = mIdSequence.newInstanceId(); 64 } 65 mActivityInfo = item.getActivityInfo(); 66 log(getStartEnum(description), mActivityInfo); 67 return mInstanceId; 68 } 69 70 /** 71 * Logs a successful drop. 72 */ logDrop()73 public void logDrop() { 74 log(DragAndDropUiEventEnum.GLOBAL_APP_DRAG_DROPPED, mActivityInfo); 75 } 76 77 /** 78 * Logs the end of a drag. 79 */ logEnd()80 public void logEnd() { 81 log(DragAndDropUiEventEnum.GLOBAL_APP_DRAG_END, mActivityInfo); 82 } 83 log(UiEventLogger.UiEventEnum event, @Nullable ActivityInfo activityInfo)84 private void log(UiEventLogger.UiEventEnum event, @Nullable ActivityInfo activityInfo) { 85 mUiEventLogger.logWithInstanceId(event, 86 activityInfo == null ? 0 : activityInfo.applicationInfo.uid, 87 activityInfo == null ? null : activityInfo.applicationInfo.packageName, 88 mInstanceId); 89 } 90 91 /** 92 * Returns the start logging enum for the given drag description. 93 */ getStartEnum(ClipDescription description)94 private DragAndDropUiEventEnum getStartEnum(ClipDescription description) { 95 if (description.hasMimeType(MIMETYPE_APPLICATION_ACTIVITY)) { 96 return DragAndDropUiEventEnum.GLOBAL_APP_DRAG_START_ACTIVITY; 97 } else if (description.hasMimeType(MIMETYPE_APPLICATION_SHORTCUT)) { 98 return DragAndDropUiEventEnum.GLOBAL_APP_DRAG_START_SHORTCUT; 99 } else if (description.hasMimeType(MIMETYPE_APPLICATION_TASK)) { 100 return DragAndDropUiEventEnum.GLOBAL_APP_DRAG_START_TASK; 101 } 102 throw new IllegalArgumentException("Not an app drag"); 103 } 104 105 /** 106 * Enums for logging Drag & Drop UiEvents 107 */ 108 public enum DragAndDropUiEventEnum implements UiEventLogger.UiEventEnum { 109 @UiEvent(doc = "Starting a global drag and drop of an activity") 110 GLOBAL_APP_DRAG_START_ACTIVITY(884), 111 112 @UiEvent(doc = "Starting a global drag and drop of a shortcut") 113 GLOBAL_APP_DRAG_START_SHORTCUT(885), 114 115 @UiEvent(doc = "Starting a global drag and drop of a task") 116 GLOBAL_APP_DRAG_START_TASK(888), 117 118 @UiEvent(doc = "A global app drag was successfully dropped") 119 GLOBAL_APP_DRAG_DROPPED(887), 120 121 @UiEvent(doc = "Ending a global app drag and drop") 122 GLOBAL_APP_DRAG_END(886); 123 124 private final int mId; 125 DragAndDropUiEventEnum(int id)126 DragAndDropUiEventEnum(int id) { 127 mId = id; 128 } 129 130 @Override getId()131 public int getId() { 132 return mId; 133 } 134 } 135 } 136