blob: dc27df1909dbae06a24f43fd8b5ce5b3fdb87a2d [file] [log] [blame]
/*
* 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.launcher3.taskbar;
import android.content.ClipDescription;
import android.graphics.Point;
import android.view.DragEvent;
import android.view.View;
import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.model.data.ItemInfo;
import java.util.UUID;
/**
* Listens to system drag and drop events initated by the Taskbar, and forwards them to Launcher's
* internal DragController to move Hotseat items.
*/
public class TaskbarDragListener implements View.OnDragListener {
private static final String MIME_TYPE_PREFIX = "com.android.launcher3.taskbar.drag_and_drop/";
private final BaseQuickstepLauncher mLauncher;
private final ItemInfo mDraggedItem;
// Randomly generated id used to verify the drag event.
private final String mId;
// Initialized in init().
DragLayer mDragLayer;
/**
* @param draggedItem The info of the item that was long clicked, which we will use to find
* the equivalent match on Hotseat to drag internally.
*/
public TaskbarDragListener(BaseQuickstepLauncher launcher, ItemInfo draggedItem) {
mLauncher = launcher;
mDraggedItem = draggedItem;
mId = UUID.randomUUID().toString();
}
protected void init(DragLayer dragLayer) {
mDragLayer = dragLayer;
mDragLayer.setOnDragListener(this);
// Temporarily disable haptics, as system will already play one when drag and drop starts.
mDragLayer.setHapticFeedbackEnabled(false);
}
private void cleanup() {
mDragLayer.setOnDragListener(null);
mLauncher.setNextWorkspaceDragOptions(null);
mDragLayer.setHapticFeedbackEnabled(true);
}
/**
* Returns a randomly generated id used to verify the drag event.
*/
protected String getMimeType() {
return MIME_TYPE_PREFIX + mId;
}
@Override
public boolean onDrag(View dragLayer, DragEvent dragEvent) {
ClipDescription clipDescription = dragEvent.getClipDescription();
if (dragEvent.getAction() == DragEvent.ACTION_DRAG_STARTED) {
if (clipDescription == null || !clipDescription.hasMimeType(getMimeType())) {
// We didn't initiate this drag, ignore.
cleanup();
return false;
}
View hotseatView = mLauncher.getHotseat().getFirstItemMatch(
(info, view) -> info == mDraggedItem);
if (hotseatView == null) {
cleanup();
return false;
}
DragOptions dragOptions = new DragOptions();
dragOptions.simulatedDndStartPoint = new Point((int) dragEvent.getX(),
(int) dragEvent.getY());
mLauncher.setNextWorkspaceDragOptions(dragOptions);
hotseatView.performLongClick();
} else if (dragEvent.getAction() == DragEvent.ACTION_DRAG_ENDED) {
cleanup();
}
return mLauncher.getDragController().onDragEvent(dragEvent);
}
}