Bug 1880216 - Migrate Fenix docs into Sphinx. r=owlish,geckoview-reviewers,android...
[gecko.git] / widget / nsBaseClipboard.h
blobffa68d6240d053ecc40e65a70809db4b0ab14230
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef nsBaseClipboard_h__
7 #define nsBaseClipboard_h__
9 #include "mozilla/dom/PContent.h"
10 #include "mozilla/Logging.h"
11 #include "mozilla/MoveOnlyFunction.h"
12 #include "mozilla/Result.h"
13 #include "nsIClipboard.h"
14 #include "nsITransferable.h"
15 #include "nsCOMPtr.h"
17 static mozilla::LazyLogModule sWidgetClipboardLog("WidgetClipboard");
18 #define MOZ_CLIPBOARD_LOG(...) \
19 MOZ_LOG(sWidgetClipboardLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
20 #define MOZ_CLIPBOARD_LOG_ENABLED() \
21 MOZ_LOG_TEST(sWidgetClipboardLog, mozilla::LogLevel::Debug)
23 class nsITransferable;
24 class nsIClipboardOwner;
25 class nsIPrincipal;
26 class nsIWidget;
28 namespace mozilla::dom {
29 class WindowContext;
30 } // namespace mozilla::dom
32 /**
33 * A base clipboard class for all platform, so that they can share the same
34 * implementation.
36 class nsBaseClipboard : public nsIClipboard {
37 public:
38 explicit nsBaseClipboard(
39 const mozilla::dom::ClipboardCapabilities& aClipboardCaps);
41 // nsISupports
42 NS_DECL_ISUPPORTS
44 // nsIClipboard
45 NS_IMETHOD SetData(nsITransferable* aTransferable, nsIClipboardOwner* aOwner,
46 int32_t aWhichClipboard) override final;
47 NS_IMETHOD AsyncSetData(int32_t aWhichClipboard,
48 nsIAsyncClipboardRequestCallback* aCallback,
49 nsIAsyncSetClipboardData** _retval) override final;
50 NS_IMETHOD GetData(
51 nsITransferable* aTransferable, int32_t aWhichClipboard,
52 mozilla::dom::WindowContext* aWindowContext) override final;
53 NS_IMETHOD AsyncGetData(
54 const nsTArray<nsCString>& aFlavorList, int32_t aWhichClipboard,
55 mozilla::dom::WindowContext* aRequestingWindowContext,
56 nsIPrincipal* aRequestingPrincipal,
57 nsIAsyncClipboardGetCallback* aCallback) override final;
58 NS_IMETHOD GetDataSnapshotSync(
59 const nsTArray<nsCString>& aFlavorList, int32_t aWhichClipboard,
60 mozilla::dom::WindowContext* aRequestingWindowContext,
61 nsIAsyncGetClipboardData** _retval) override final;
62 NS_IMETHOD EmptyClipboard(int32_t aWhichClipboard) override final;
63 NS_IMETHOD HasDataMatchingFlavors(const nsTArray<nsCString>& aFlavorList,
64 int32_t aWhichClipboard,
65 bool* aOutResult) override final;
66 NS_IMETHOD IsClipboardTypeSupported(int32_t aWhichClipboard,
67 bool* aRetval) override final;
69 void AsyncGetDataInternal(
70 const nsTArray<nsCString>& aFlavorList, int32_t aClipboardType,
71 mozilla::dom::WindowContext* aRequestingWindowContext,
72 nsIAsyncClipboardGetCallback* aCallback);
74 using GetDataCallback = mozilla::MoveOnlyFunction<void(nsresult)>;
75 using HasMatchingFlavorsCallback = mozilla::MoveOnlyFunction<void(
76 mozilla::Result<nsTArray<nsCString>, nsresult>)>;
78 protected:
79 virtual ~nsBaseClipboard();
81 // Implement the native clipboard behavior.
82 NS_IMETHOD SetNativeClipboardData(nsITransferable* aTransferable,
83 int32_t aWhichClipboard) = 0;
84 NS_IMETHOD GetNativeClipboardData(nsITransferable* aTransferable,
85 int32_t aWhichClipboard) = 0;
86 virtual void AsyncGetNativeClipboardData(nsITransferable* aTransferable,
87 int32_t aWhichClipboard,
88 GetDataCallback&& aCallback);
89 virtual nsresult EmptyNativeClipboardData(int32_t aWhichClipboard) = 0;
90 virtual mozilla::Result<int32_t, nsresult> GetNativeClipboardSequenceNumber(
91 int32_t aWhichClipboard) = 0;
92 virtual mozilla::Result<bool, nsresult> HasNativeClipboardDataMatchingFlavors(
93 const nsTArray<nsCString>& aFlavorList, int32_t aWhichClipboard) = 0;
94 virtual void AsyncHasNativeClipboardDataMatchingFlavors(
95 const nsTArray<nsCString>& aFlavorList, int32_t aWhichClipboard,
96 HasMatchingFlavorsCallback&& aCallback);
98 void ClearClipboardCache(int32_t aClipboardType);
100 private:
101 void RejectPendingAsyncSetDataRequestIfAny(int32_t aClipboardType);
103 class AsyncSetClipboardData final : public nsIAsyncSetClipboardData {
104 public:
105 NS_DECL_ISUPPORTS
106 NS_DECL_NSIASYNCSETCLIPBOARDDATA
108 AsyncSetClipboardData(int32_t aClipboardType, nsBaseClipboard* aClipboard,
109 nsIAsyncClipboardRequestCallback* aCallback);
111 private:
112 virtual ~AsyncSetClipboardData() = default;
113 bool IsValid() const {
114 // If this request is no longer valid, the callback should be notified.
115 MOZ_ASSERT_IF(!mClipboard, !mCallback);
116 return !!mClipboard;
118 void MaybeNotifyCallback(nsresult aResult);
120 // The clipboard type defined in nsIClipboard.
121 int32_t mClipboardType;
122 // It is safe to use a raw pointer as it will be nullified (by calling
123 // NotifyCallback()) once nsBaseClipboard stops tracking us. This is
124 // also used to indicate whether this request is valid.
125 nsBaseClipboard* mClipboard;
126 // mCallback will be nullified once the callback is notified to ensure the
127 // callback is only notified once.
128 nsCOMPtr<nsIAsyncClipboardRequestCallback> mCallback;
131 class AsyncGetClipboardData final : public nsIAsyncGetClipboardData {
132 public:
133 AsyncGetClipboardData(
134 int32_t aClipboardType, int32_t aSequenceNumber,
135 nsTArray<nsCString>&& aFlavors, bool aFromCache,
136 nsBaseClipboard* aClipboard,
137 mozilla::dom::WindowContext* aRequestingWindowContext);
139 NS_DECL_ISUPPORTS
140 NS_DECL_NSIASYNCGETCLIPBOARDDATA
142 private:
143 virtual ~AsyncGetClipboardData() = default;
144 bool IsValid();
146 // The clipboard type defined in nsIClipboard.
147 const int32_t mClipboardType;
148 // The sequence number associated with the clipboard content for this
149 // request. If it doesn't match with the current sequence number in system
150 // clipboard, this request targets stale data and is deemed invalid.
151 const int32_t mSequenceNumber;
152 // List of available data types for clipboard content.
153 const nsTArray<nsCString> mFlavors;
154 // Data should be read from cache.
155 const bool mFromCache;
156 // This is also used to indicate whether this request is still valid.
157 RefPtr<nsBaseClipboard> mClipboard;
158 // The requesting window, which is used for Content Analysis purposes.
159 RefPtr<mozilla::dom::WindowContext> mRequestingWindowContext;
162 class ClipboardCache final {
163 public:
164 ~ClipboardCache() {
165 // In order to notify the old clipboard owner.
166 Clear();
170 * Clear the cached transferable and notify the original clipboard owner
171 * that it has lost ownership.
173 void Clear();
174 void Update(nsITransferable* aTransferable,
175 nsIClipboardOwner* aClipboardOwner, int32_t aSequenceNumber) {
176 // Clear first to notify the old clipboard owner.
177 Clear();
178 mTransferable = aTransferable;
179 mClipboardOwner = aClipboardOwner;
180 mSequenceNumber = aSequenceNumber;
182 nsITransferable* GetTransferable() const { return mTransferable; }
183 nsIClipboardOwner* GetClipboardOwner() const { return mClipboardOwner; }
184 int32_t GetSequenceNumber() const { return mSequenceNumber; }
185 nsresult GetData(nsITransferable* aTransferable) const;
187 private:
188 nsCOMPtr<nsITransferable> mTransferable;
189 nsCOMPtr<nsIClipboardOwner> mClipboardOwner;
190 int32_t mSequenceNumber = -1;
193 void MaybeRetryGetAvailableFlavors(
194 const nsTArray<nsCString>& aFlavorList, int32_t aWhichClipboard,
195 nsIAsyncClipboardGetCallback* aCallback, int32_t aRetryCount,
196 mozilla::dom::WindowContext* aRequestingWindowContext);
198 // Return clipboard cache if the cached data is valid, otherwise clear the
199 // cached data and returns null.
200 ClipboardCache* GetClipboardCacheIfValid(int32_t aClipboardType);
202 mozilla::Result<nsTArray<nsCString>, nsresult> GetFlavorsFromClipboardCache(
203 int32_t aClipboardType);
204 nsresult GetDataFromClipboardCache(nsITransferable* aTransferable,
205 int32_t aClipboardType);
207 void RequestUserConfirmation(int32_t aClipboardType,
208 const nsTArray<nsCString>& aFlavorList,
209 mozilla::dom::WindowContext* aWindowContext,
210 nsIPrincipal* aRequestingPrincipal,
211 nsIAsyncClipboardGetCallback* aCallback);
213 already_AddRefed<nsIAsyncGetClipboardData>
214 MaybeCreateGetRequestFromClipboardCache(
215 const nsTArray<nsCString>& aFlavorList, int32_t aClipboardType,
216 mozilla::dom::WindowContext* aRequestingWindowContext);
218 // Track the pending request for each clipboard type separately. And only need
219 // to track the latest request for each clipboard type as the prior pending
220 // request will be canceled when a new request is made.
221 RefPtr<AsyncSetClipboardData>
222 mPendingWriteRequests[nsIClipboard::kClipboardTypeCount];
224 mozilla::UniquePtr<ClipboardCache> mCaches[nsIClipboard::kClipboardTypeCount];
225 const mozilla::dom::ClipboardCapabilities mClipboardCaps;
226 bool mIgnoreEmptyNotification = false;
229 #endif // nsBaseClipboard_h__