1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_EXO_DRAG_DROP_OPERATION_H_
#define COMPONENTS_EXO_DRAG_DROP_OPERATION_H_
#include <memory>
#include <string>
#include "base/memory/raw_ptr.h"
#include "base/timer/timer.h"
#include "components/exo/data_device.h"
#include "components/exo/data_offer_observer.h"
#include "components/exo/data_source_observer.h"
#include "components/exo/extended_drag_source.h"
#include "components/exo/surface_observer.h"
#include "components/exo/wm_helper.h"
#include "ui/aura/client/drag_drop_client_observer.h"
#include "ui/base/dragdrop/mojom/drag_drop_types.mojom-forward.h"
#include "ui/gfx/geometry/point_f.h"
class SkBitmap;
namespace ash {
class DragDropController;
} // namespace ash
namespace ui {
class OSExchangeData;
}
namespace exo {
class DataExchangeDelegate;
class ScopedDataSource;
class Surface;
class ScopedSurface;
// This class represents an ongoing drag-drop operation started by an exo
// client. It manages its own lifetime. It will delete itself when the drag
// operation completes, is cancelled, or some vital resource is destroyed
// (e.g. the client deletes the data source used to start the drag operation),
// or if another drag operation races with this one to start and wins.
class DragDropOperation : public DataSourceObserver,
public SurfaceObserver,
public ExtendedDragSource::Observer,
public aura::client::DragDropClientObserver {
public:
// Create an operation for a drag-drop originating from a wayland app.
static base::WeakPtr<DragDropOperation> Create(
DataExchangeDelegate* data_exchange_delegate,
DataSource* source,
Surface* origin,
Surface* icon,
const gfx::PointF& drag_start_point,
ui::mojom::DragEventSource event_source);
DragDropOperation(const DragDropOperation&) = delete;
DragDropOperation& operator=(const DragDropOperation&) = delete;
// Abort the operation if it hasn't been started yet, otherwise do nothing.
void AbortIfPending();
// The drag drop has started.
bool started() const { return started_; }
// DataSourceObserver:
void OnDataSourceDestroying(DataSource* source) override;
// SurfaceObserver:
void OnSurfaceDestroying(Surface* surface) override;
// aura::client::DragDropClientObserver:
void OnDragStarted() override;
void OnDragActionsChanged(int actions) override;
// ExtendedDragSource::Observer:
void OnExtendedDragSourceDestroying(ExtendedDragSource* source) override;
private:
class IconSurface;
// A private constructor and destructor are used to prevent anyone else from
// attempting to manage the lifetime of a DragDropOperation.
DragDropOperation(DataExchangeDelegate* data_exchange_delegate,
DataSource* source,
Surface* origin,
Surface* icon,
const gfx::PointF& drag_start_point,
ui::mojom::DragEventSource event_source);
~DragDropOperation() override;
void OnDragIconCaptured(const SkBitmap& icon_bitmap);
// Called when the focused window is a Lacros window and a source
// DataTransferEndpoint is found in the available MIME types. This
// is currently used to synchronize drag source metadata from
// Lacros to Ash.
void OnDataTransferEndpointRead(const std::string& mime_type,
std::u16string data);
void OnTextRead(const std::string& mime_type, std::u16string data);
void OnHTMLRead(const std::string& mime_type, std::u16string data);
void OnFilenamesRead(DataExchangeDelegate* data_exchange_delegate,
aura::Window* source,
const std::string& mime_type,
const std::vector<uint8_t>& data);
void OnFileContentsRead(const std::string& mime_type,
const base::FilePath& filename,
const std::vector<uint8_t>& data);
void OnWebCustomDataRead(const std::string& mime_type,
const std::vector<uint8_t>& data);
void ScheduleStartDragDropOperation();
// This operation triggers a nested RunLoop, and should not be called
// directly. Use ScheduleStartDragDropOperation instead.
void StartDragDropOperation();
void ResetExtendedDragSource();
std::unique_ptr<ScopedDataSource> source_;
std::unique_ptr<ScopedSurface> icon_;
std::unique_ptr<ScopedSurface> origin_;
gfx::PointF drag_start_point_;
std::unique_ptr<ui::OSExchangeData> os_exchange_data_;
raw_ptr<ash::DragDropController, ExperimentalAsh> drag_drop_controller_;
base::RepeatingClosure counter_;
// Stores whether this object has just started a drag operation. If so, we
// want to ignore the OnDragStarted event, and self destruct the object when
// completed.
bool started_ = false;
bool captured_icon_ = false;
// TODO(crbug.com/994065) This is currently not the actual mime type used by
// the recipient, just an arbitrary one we pick out of the offered types so we
// can report back whether or not the drop can succeed. This may need to
// change in the future.
std::string mime_type_;
ui::mojom::DragEventSource event_source_;
raw_ptr<ExtendedDragSource, ExperimentalAsh> extended_drag_source_;
// TODO(crbug.com/1371493): Remove this once the issue is fixed.
base::OneShotTimer start_drag_drop_timer_;
void DragDataReadTimeout();
base::WeakPtrFactory<DragDropOperation> weak_ptr_factory_{this};
};
} // namespace exo
#endif // COMPONENTS_EXO_DRAG_DROP_OPERATION_H_
|