1 /* 2 * Copyright (C) 2022 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.launcher3.secondarydisplay; 18 19 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; 20 21 import android.content.res.Resources; 22 import android.graphics.Rect; 23 import android.graphics.drawable.Drawable; 24 import android.view.HapticFeedbackConstants; 25 import android.view.View; 26 27 import androidx.annotation.Nullable; 28 29 import com.android.launcher3.AbstractFloatingView; 30 import com.android.launcher3.DragSource; 31 import com.android.launcher3.DropTarget; 32 import com.android.launcher3.R; 33 import com.android.launcher3.accessibility.DragViewStateAnnouncer; 34 import com.android.launcher3.dragndrop.DragController; 35 import com.android.launcher3.dragndrop.DragDriver; 36 import com.android.launcher3.dragndrop.DragOptions; 37 import com.android.launcher3.dragndrop.DragView; 38 import com.android.launcher3.dragndrop.DraggableView; 39 import com.android.launcher3.model.data.ItemInfo; 40 41 /** 42 * Drag controller for Secondary Launcher activity 43 */ 44 public class SecondaryDragController extends DragController<SecondaryDisplayLauncher> { 45 46 private static final boolean PROFILE_DRAWING_DURING_DRAG = false; 47 SecondaryDragController(SecondaryDisplayLauncher secondaryLauncher)48 public SecondaryDragController(SecondaryDisplayLauncher secondaryLauncher) { 49 super(secondaryLauncher); 50 } 51 52 @Override startDrag(@ullable Drawable drawable, @Nullable View view, DraggableView originalView, int dragLayerX, int dragLayerY, DragSource source, ItemInfo dragInfo, Rect dragRegion, float initialDragViewScale, float dragViewScaleOnDrop, DragOptions options)53 protected DragView startDrag(@Nullable Drawable drawable, @Nullable View view, 54 DraggableView originalView, int dragLayerX, int dragLayerY, DragSource source, 55 ItemInfo dragInfo, Rect dragRegion, float initialDragViewScale, 56 float dragViewScaleOnDrop, DragOptions options) { 57 if (PROFILE_DRAWING_DURING_DRAG) { 58 android.os.Debug.startMethodTracing("Launcher"); 59 } 60 mActivity.hideKeyboard(); 61 62 mOptions = options; 63 if (mOptions.simulatedDndStartPoint != null) { 64 mLastTouch.x = mMotionDown.x = mOptions.simulatedDndStartPoint.x; 65 mLastTouch.y = mMotionDown.y = mOptions.simulatedDndStartPoint.y; 66 } 67 68 final int registrationX = mMotionDown.x - dragLayerX; 69 final int registrationY = mMotionDown.y - dragLayerY; 70 71 final int dragRegionLeft = dragRegion == null ? 0 : dragRegion.left; 72 final int dragRegionTop = dragRegion == null ? 0 : dragRegion.top; 73 74 mLastDropTarget = null; 75 76 mDragObject = new DropTarget.DragObject(mActivity.getApplicationContext()); 77 mDragObject.originalView = originalView; 78 79 mIsInPreDrag = mOptions.preDragCondition != null 80 && !mOptions.preDragCondition.shouldStartDrag(0); 81 82 final Resources res = mActivity.getResources(); 83 final float scaleDps = mIsInPreDrag 84 ? res.getDimensionPixelSize(R.dimen.pre_drag_view_scale) : 0f; 85 86 final DragView dragView = mDragObject.dragView = drawable != null 87 ? new SecondaryDragView( 88 mActivity, 89 drawable, 90 registrationX, 91 registrationY, 92 initialDragViewScale, 93 dragViewScaleOnDrop, 94 scaleDps) 95 : new SecondaryDragView( 96 mActivity, 97 view, 98 view.getMeasuredWidth(), 99 view.getMeasuredHeight(), 100 registrationX, 101 registrationY, 102 initialDragViewScale, 103 dragViewScaleOnDrop, 104 scaleDps); 105 dragView.setItemInfo(dragInfo); 106 mDragObject.dragComplete = false; 107 108 mDragObject.xOffset = mMotionDown.x - (dragLayerX + dragRegionLeft); 109 mDragObject.yOffset = mMotionDown.y - (dragLayerY + dragRegionTop); 110 111 mDragDriver = DragDriver.create(this, mOptions, ev -> { 112 }); 113 if (!mOptions.isAccessibleDrag) { 114 mDragObject.stateAnnouncer = DragViewStateAnnouncer.createFor(dragView); 115 } 116 117 mDragObject.dragSource = source; 118 mDragObject.dragInfo = dragInfo; 119 mDragObject.originalDragInfo = mDragObject.dragInfo.makeShallowCopy(); 120 121 if (mOptions.preDragCondition != null) { 122 dragView.setHasDragOffset(mOptions.preDragCondition.getDragOffset().x != 0 || 123 mOptions.preDragCondition.getDragOffset().y != 0); 124 } 125 126 if (dragRegion != null) { 127 dragView.setDragRegion(new Rect(dragRegion)); 128 } 129 130 mActivity.getDragLayer().performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); 131 dragView.show(mLastTouch.x, mLastTouch.y); 132 mDistanceSinceScroll = 0; 133 134 if (!isItemPinnable()) { 135 MAIN_EXECUTOR.post(this:: cancelDrag); 136 } 137 138 if (!mIsInPreDrag) { 139 callOnDragStart(); 140 } else if (mOptions.preDragCondition != null) { 141 mOptions.preDragCondition.onPreDragStart(mDragObject); 142 } 143 144 handleMoveEvent(mLastTouch.x, mLastTouch.y); 145 return dragView; 146 } 147 148 @Override exitDrag()149 protected void exitDrag() { } 150 151 @Override getDefaultDropTarget(int[] dropCoordinates)152 protected DropTarget getDefaultDropTarget(int[] dropCoordinates) { 153 DropTarget target = new DropTarget() { 154 @Override 155 public boolean isDropEnabled() { 156 return true; 157 } 158 159 @Override 160 public void onDrop(DragObject dragObject, DragOptions options) { 161 ((SecondaryDragLayer) mActivity.getDragLayer()).getPinnedAppsAdapter().addPinnedApp( 162 dragObject.dragInfo); 163 dragObject.dragView.remove(); 164 } 165 166 @Override 167 public void onDragEnter(DragObject dragObject) { 168 if (getDistanceDragged() > mActivity.getResources().getDimensionPixelSize( 169 R.dimen.drag_distanceThreshold)) { 170 mActivity.showAppDrawer(false); 171 AbstractFloatingView.closeAllOpenViews(mActivity); 172 } 173 } 174 175 @Override 176 public void onDragOver(DragObject dragObject) { } 177 178 @Override 179 public void onDragExit(DragObject dragObject) { } 180 181 @Override 182 public boolean acceptDrop(DragObject dragObject) { 183 return true; 184 } 185 186 @Override 187 public void prepareAccessibilityDrop() { } 188 189 @Override 190 public void getHitRectRelativeToDragLayer(Rect outRect) { } 191 }; 192 return target; 193 } 194 } 195