no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / widget / nsBaseClipboard.h
blobe1cb9d552baafbe2e20ca8a15ba9343dd684a160
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 nsIWidget;
27 /**
28 * A base clipboard class for all platform, so that they can share the same
29 * implementation.
31 class nsBaseClipboard : public nsIClipboard {
32 public:
33 explicit nsBaseClipboard(
34 const mozilla::dom::ClipboardCapabilities& aClipboardCaps);
36 // nsISupports
37 NS_DECL_ISUPPORTS
39 // nsIClipboard
40 NS_IMETHOD SetData(nsITransferable* aTransferable, nsIClipboardOwner* aOwner,
41 int32_t aWhichClipboard) override final;
42 NS_IMETHOD AsyncSetData(int32_t aWhichClipboard,
43 nsIAsyncClipboardRequestCallback* aCallback,
44 nsIAsyncSetClipboardData** _retval) override final;
45 NS_IMETHOD GetData(nsITransferable* aTransferable,
46 int32_t aWhichClipboard) override final;
47 NS_IMETHOD AsyncGetData(
48 const nsTArray<nsCString>& aFlavorList, int32_t aWhichClipboard,
49 nsIAsyncClipboardGetCallback* aCallback) override final;
50 NS_IMETHOD EmptyClipboard(int32_t aWhichClipboard) override final;
51 NS_IMETHOD HasDataMatchingFlavors(const nsTArray<nsCString>& aFlavorList,
52 int32_t aWhichClipboard,
53 bool* aOutResult) override final;
54 NS_IMETHOD IsClipboardTypeSupported(int32_t aWhichClipboard,
55 bool* aRetval) override final;
57 using GetDataCallback = mozilla::MoveOnlyFunction<void(nsresult)>;
58 using HasMatchingFlavorsCallback = mozilla::MoveOnlyFunction<void(
59 mozilla::Result<nsTArray<nsCString>, nsresult>)>;
61 protected:
62 virtual ~nsBaseClipboard();
64 // Implement the native clipboard behavior.
65 NS_IMETHOD SetNativeClipboardData(nsITransferable* aTransferable,
66 int32_t aWhichClipboard) = 0;
67 NS_IMETHOD GetNativeClipboardData(nsITransferable* aTransferable,
68 int32_t aWhichClipboard) = 0;
69 virtual void AsyncGetNativeClipboardData(nsITransferable* aTransferable,
70 int32_t aWhichClipboard,
71 GetDataCallback&& aCallback);
72 virtual nsresult EmptyNativeClipboardData(int32_t aWhichClipboard) = 0;
73 virtual mozilla::Result<int32_t, nsresult> GetNativeClipboardSequenceNumber(
74 int32_t aWhichClipboard) = 0;
75 virtual mozilla::Result<bool, nsresult> HasNativeClipboardDataMatchingFlavors(
76 const nsTArray<nsCString>& aFlavorList, int32_t aWhichClipboard) = 0;
77 virtual void AsyncHasNativeClipboardDataMatchingFlavors(
78 const nsTArray<nsCString>& aFlavorList, int32_t aWhichClipboard,
79 HasMatchingFlavorsCallback&& aCallback);
81 void ClearClipboardCache(int32_t aClipboardType);
83 private:
84 void RejectPendingAsyncSetDataRequestIfAny(int32_t aClipboardType);
86 class AsyncSetClipboardData final : public nsIAsyncSetClipboardData {
87 public:
88 NS_DECL_ISUPPORTS
89 NS_DECL_NSIASYNCSETCLIPBOARDDATA
91 AsyncSetClipboardData(int32_t aClipboardType, nsBaseClipboard* aClipboard,
92 nsIAsyncClipboardRequestCallback* aCallback);
94 private:
95 virtual ~AsyncSetClipboardData() = default;
96 bool IsValid() const {
97 // If this request is no longer valid, the callback should be notified.
98 MOZ_ASSERT_IF(!mClipboard, !mCallback);
99 return !!mClipboard;
101 void MaybeNotifyCallback(nsresult aResult);
103 // The clipboard type defined in nsIClipboard.
104 int32_t mClipboardType;
105 // It is safe to use a raw pointer as it will be nullified (by calling
106 // NotifyCallback()) once nsBaseClipboard stops tracking us. This is
107 // also used to indicate whether this request is valid.
108 nsBaseClipboard* mClipboard;
109 // mCallback will be nullified once the callback is notified to ensure the
110 // callback is only notified once.
111 nsCOMPtr<nsIAsyncClipboardRequestCallback> mCallback;
114 class AsyncGetClipboardData final : public nsIAsyncGetClipboardData {
115 public:
116 AsyncGetClipboardData(int32_t aClipboardType, int32_t aSequenceNumber,
117 nsTArray<nsCString>&& aFlavors, bool aFromCache,
118 nsBaseClipboard* aClipboard);
120 NS_DECL_ISUPPORTS
121 NS_DECL_NSIASYNCGETCLIPBOARDDATA
123 private:
124 virtual ~AsyncGetClipboardData() = default;
125 bool IsValid();
127 // The clipboard type defined in nsIClipboard.
128 const int32_t mClipboardType;
129 // The sequence number associated with the clipboard content for this
130 // request. If it doesn't match with the current sequence number in system
131 // clipboard, this request targets stale data and is deemed invalid.
132 const int32_t mSequenceNumber;
133 // List of available data types for clipboard content.
134 const nsTArray<nsCString> mFlavors;
135 // Data should be read from cache.
136 const bool mFromCache;
137 // This is also used to indicate whether this request is still valid.
138 RefPtr<nsBaseClipboard> mClipboard;
141 class ClipboardCache final {
142 public:
143 ~ClipboardCache() {
144 // In order to notify the old clipboard owner.
145 Clear();
149 * Clear the cached transferable and notify the original clipboard owner
150 * that it has lost ownership.
152 void Clear();
153 void Update(nsITransferable* aTransferable,
154 nsIClipboardOwner* aClipboardOwner, int32_t aSequenceNumber) {
155 // Clear first to notify the old clipboard owner.
156 Clear();
157 mTransferable = aTransferable;
158 mClipboardOwner = aClipboardOwner;
159 mSequenceNumber = aSequenceNumber;
161 nsITransferable* GetTransferable() const { return mTransferable; }
162 nsIClipboardOwner* GetClipboardOwner() const { return mClipboardOwner; }
163 int32_t GetSequenceNumber() const { return mSequenceNumber; }
164 nsresult GetData(nsITransferable* aTransferable) const;
166 private:
167 nsCOMPtr<nsITransferable> mTransferable;
168 nsCOMPtr<nsIClipboardOwner> mClipboardOwner;
169 int32_t mSequenceNumber = -1;
172 void MaybeRetryGetAvailableFlavors(const nsTArray<nsCString>& aFlavorList,
173 int32_t aWhichClipboard,
174 nsIAsyncClipboardGetCallback* aCallback,
175 int32_t aRetryCount);
177 // Return clipboard cache if the cached data is valid, otherwise clear the
178 // cached data and returns null.
179 ClipboardCache* GetClipboardCacheIfValid(int32_t aClipboardType);
181 mozilla::Result<nsTArray<nsCString>, nsresult> GetFlavorsFromClipboardCache(
182 int32_t aClipboardType);
183 nsresult GetDataFromClipboardCache(nsITransferable* aTransferable,
184 int32_t aClipboardType);
186 // Track the pending request for each clipboard type separately. And only need
187 // to track the latest request for each clipboard type as the prior pending
188 // request will be canceled when a new request is made.
189 RefPtr<AsyncSetClipboardData>
190 mPendingWriteRequests[nsIClipboard::kClipboardTypeCount];
192 mozilla::UniquePtr<ClipboardCache> mCaches[nsIClipboard::kClipboardTypeCount];
193 const mozilla::dom::ClipboardCapabilities mClipboardCaps;
194 bool mIgnoreEmptyNotification = false;
197 #endif // nsBaseClipboard_h__