data_offer.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef COMPONENTS_EXO_DATA_OFFER_H_
  5. #define COMPONENTS_EXO_DATA_OFFER_H_
  6. #include <cstdint>
  7. #include <string>
  8. #include "base/callback_forward.h"
  9. #include "base/containers/flat_map.h"
  10. #include "base/containers/flat_set.h"
  11. #include "base/files/scoped_file.h"
  12. #include "base/memory/ref_counted.h"
  13. #include "base/observer_list.h"
  14. #include "ui/base/class_property.h"
  15. #include "url/gurl.h"
  16. namespace aura {
  17. class Window;
  18. }
  19. namespace base {
  20. class Pickle;
  21. class RefCountedMemory;
  22. }
  23. namespace ui {
  24. class Clipboard;
  25. class OSExchangeData;
  26. enum class EndpointType;
  27. }
  28. namespace exo {
  29. class DataOfferDelegate;
  30. class DataOfferObserver;
  31. class DataExchangeDelegate;
  32. enum class DndAction;
  33. // Object representing transferred data offered to a client.
  34. class DataOffer final : public ui::PropertyHandler {
  35. public:
  36. using SendDataCallback =
  37. base::OnceCallback<void(scoped_refptr<base::RefCountedMemory>)>;
  38. using AsyncSendDataCallback = base::OnceCallback<void(SendDataCallback)>;
  39. DataOffer(DataOfferDelegate* delegate);
  40. DataOffer(const DataOffer&) = delete;
  41. DataOffer& operator=(const DataOffer&) = delete;
  42. ~DataOffer() override;
  43. void AddObserver(DataOfferObserver* observer);
  44. void RemoveObserver(DataOfferObserver* observer);
  45. // Notifies to the DataOffer that the client can accept |mime type|.
  46. void Accept(const std::string* mime_type);
  47. // Notifies to the DataOffer that the client start receiving data of
  48. // |mime_type|. DataOffer writes the request data to |fd|.
  49. void Receive(const std::string& mime_type, base::ScopedFD fd);
  50. // Notifies to the DataOffer that the client no longer uses the DataOffer
  51. // object.
  52. void Finish();
  53. // Notifies to the DataOffer that possible and preferred drag and drop
  54. // operations selected by the client.
  55. void SetActions(const base::flat_set<DndAction>& dnd_actions,
  56. DndAction preferred_action);
  57. // Sets the dropped data from |data| to the DataOffer object.
  58. // |data_exchange_delegate| will be used to convert paths to handle mount
  59. // points which is mounted in the mount point namespace of client process.
  60. // |target| is the drop target window and can be used to apply the target
  61. // specitic logic to interpret the data. While this function immediately calls
  62. // DataOfferDelegate::OnOffer inside it with found mime types, dropped data
  63. // bytes may be populated asynchronously after this function call. (e.g.
  64. // Asynchronous lookup is required for resolving file system urls.)
  65. void SetDropData(DataExchangeDelegate* data_exchange_delegate,
  66. aura::Window* target,
  67. const ui::OSExchangeData& data);
  68. // Sets the clipboard data from |data| to the DataOffer object.
  69. void SetClipboardData(DataExchangeDelegate* data_exchange_delegate,
  70. const ui::Clipboard& data,
  71. ui::EndpointType endpoint_type);
  72. // Sets the drag and drop actions which is offered by data source to the
  73. // DataOffer object.
  74. void SetSourceActions(const base::flat_set<DndAction>& source_actions);
  75. DndAction dnd_action() const { return dnd_action_; }
  76. bool finished() const { return finished_; }
  77. private:
  78. void OnDataReady(const std::string& mime_type,
  79. base::ScopedFD fd,
  80. scoped_refptr<base::RefCountedMemory> data);
  81. void GetUrlsFromPickle(DataExchangeDelegate* data_exchange_delegate,
  82. aura::Window* target,
  83. const base::Pickle& pickle,
  84. SendDataCallback callback);
  85. void OnPickledUrlsResolved(SendDataCallback callback,
  86. const std::vector<GURL>& urls);
  87. DataOfferDelegate* const delegate_;
  88. // Data for a given mime type may not ever be requested, or may be requested
  89. // more than once. Using callbacks and a cache allows us to delay any
  90. // expensive operations until they are required, and then ensure that they are
  91. // performed at most once. When we offer data for a given mime type we will
  92. // populate |data_callbacks_| with mime type and a callback which will produce
  93. // the required data. On the first request to |Receive()| we remove and invoke
  94. // the callback and set |data_cache_| with null data. When the callback
  95. // completes we populate |data_cache_| with data and fulfill any
  96. // |pending_receive_requests|.
  97. base::flat_map<std::string, AsyncSendDataCallback> data_callbacks_;
  98. base::flat_map<std::string, scoped_refptr<base::RefCountedMemory>>
  99. data_cache_;
  100. std::vector<std::pair<std::string, base::ScopedFD>> pending_receive_requests_;
  101. base::flat_set<DndAction> source_actions_;
  102. DndAction dnd_action_;
  103. base::ObserverList<DataOfferObserver>::Unchecked observers_;
  104. bool finished_;
  105. base::WeakPtrFactory<DataOffer> weak_ptr_factory_{this};
  106. };
  107. class ScopedDataOffer {
  108. public:
  109. ScopedDataOffer(DataOffer* data_offer, DataOfferObserver* observer);
  110. ScopedDataOffer(const ScopedDataOffer&) = delete;
  111. ScopedDataOffer& operator=(const ScopedDataOffer&) = delete;
  112. ~ScopedDataOffer();
  113. DataOffer* get() { return data_offer_; }
  114. private:
  115. DataOffer* const data_offer_;
  116. DataOfferObserver* const observer_;
  117. };
  118. } // namespace exo
  119. #endif // COMPONENTS_EXO_DATA_OFFER_H_