Bug 1855360 - Fix the skip-if syntax. a=bustage-fix
[gecko.git] / widget / nsClipboardProxy.cpp
blob931f9cbbb1c14e1dc159cf95faac61b67cbefbdf
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "nsClipboardProxy.h"
7 #if defined(ACCESSIBILITY) && defined(XP_WIN)
8 # include "mozilla/a11y/Compatibility.h"
9 #endif
10 #include "mozilla/ClipboardReadRequestChild.h"
11 #include "mozilla/ClipboardWriteRequestChild.h"
12 #include "mozilla/dom/ContentChild.h"
13 #include "mozilla/net/CookieJarSettings.h"
14 #include "mozilla/Maybe.h"
15 #include "mozilla/Unused.h"
16 #include "nsArrayUtils.h"
17 #include "nsBaseClipboard.h"
18 #include "nsISupportsPrimitives.h"
19 #include "nsCOMPtr.h"
20 #include "nsComponentManagerUtils.h"
21 #include "nsXULAppAPI.h"
22 #include "nsContentUtils.h"
23 #include "PermissionMessageUtils.h"
25 using namespace mozilla;
26 using namespace mozilla::dom;
28 NS_IMPL_ISUPPORTS(nsClipboardProxy, nsIClipboard, nsIClipboardProxy)
30 nsClipboardProxy::nsClipboardProxy() : mClipboardCaps(false, false, false) {}
32 NS_IMETHODIMP
33 nsClipboardProxy::SetData(nsITransferable* aTransferable,
34 nsIClipboardOwner* anOwner, int32_t aWhichClipboard) {
35 #if defined(ACCESSIBILITY) && defined(XP_WIN)
36 a11y::Compatibility::SuppressA11yForClipboardCopy();
37 #endif
39 ContentChild* child = ContentChild::GetSingleton();
40 IPCTransferable ipcTransferable;
41 nsContentUtils::TransferableToIPCTransferable(aTransferable, &ipcTransferable,
42 false, nullptr);
43 child->SendSetClipboard(std::move(ipcTransferable), aWhichClipboard);
44 return NS_OK;
47 NS_IMETHODIMP nsClipboardProxy::AsyncSetData(
48 int32_t aWhichClipboard, nsIAsyncClipboardRequestCallback* aCallback,
49 nsIAsyncSetClipboardData** _retval) {
50 RefPtr<ClipboardWriteRequestChild> request =
51 MakeRefPtr<ClipboardWriteRequestChild>(aCallback);
52 ContentChild::GetSingleton()->SendPClipboardWriteRequestConstructor(
53 request, aWhichClipboard);
54 request.forget(_retval);
55 return NS_OK;
58 NS_IMETHODIMP
59 nsClipboardProxy::GetData(nsITransferable* aTransferable,
60 int32_t aWhichClipboard) {
61 nsTArray<nsCString> types;
62 aTransferable->FlavorsTransferableCanImport(types);
64 IPCTransferableData transferable;
65 ContentChild::GetSingleton()->SendGetClipboard(types, aWhichClipboard,
66 &transferable);
67 return nsContentUtils::IPCTransferableDataToTransferable(
68 transferable, false /* aAddDataFlavor */, aTransferable,
69 false /* aFilterUnknownFlavors */);
72 namespace {
74 class AsyncGetClipboardDataProxy final : public nsIAsyncGetClipboardData {
75 public:
76 explicit AsyncGetClipboardDataProxy(ClipboardReadRequestChild* aActor)
77 : mActor(aActor) {
78 MOZ_ASSERT(mActor);
81 NS_DECL_ISUPPORTS
82 NS_DECL_NSIASYNCGETCLIPBOARDDATA
84 private:
85 virtual ~AsyncGetClipboardDataProxy() {
86 MOZ_ASSERT(mActor);
87 if (mActor->CanSend()) {
88 PClipboardReadRequestChild::Send__delete__(mActor);
92 RefPtr<ClipboardReadRequestChild> mActor;
95 NS_IMPL_ISUPPORTS(AsyncGetClipboardDataProxy, nsIAsyncGetClipboardData)
97 NS_IMETHODIMP AsyncGetClipboardDataProxy::GetValid(bool* aOutResult) {
98 MOZ_ASSERT(mActor);
99 *aOutResult = mActor->CanSend();
100 return NS_OK;
103 NS_IMETHODIMP AsyncGetClipboardDataProxy::GetFlavorList(
104 nsTArray<nsCString>& aFlavorList) {
105 MOZ_ASSERT(mActor);
106 aFlavorList.AppendElements(mActor->FlavorList());
107 return NS_OK;
110 NS_IMETHODIMP AsyncGetClipboardDataProxy::GetData(
111 nsITransferable* aTransferable,
112 nsIAsyncClipboardRequestCallback* aCallback) {
113 if (!aTransferable || !aCallback) {
114 return NS_ERROR_INVALID_ARG;
117 // Get a list of flavors this transferable can import
118 nsTArray<nsCString> flavors;
119 nsresult rv = aTransferable->FlavorsTransferableCanImport(flavors);
120 if (NS_FAILED(rv)) {
121 return rv;
124 MOZ_ASSERT(mActor);
125 // If the requested flavor is not in the list, throw an error.
126 for (const auto& flavor : flavors) {
127 if (!mActor->FlavorList().Contains(flavor)) {
128 return NS_ERROR_FAILURE;
132 if (!mActor->CanSend()) {
133 return aCallback->OnComplete(NS_ERROR_FAILURE);
136 mActor->SendGetData(flavors)->Then(
137 GetMainThreadSerialEventTarget(), __func__,
138 /* resolve */
139 [self = RefPtr{this}, callback = nsCOMPtr{aCallback},
140 transferable = nsCOMPtr{aTransferable}](
141 const IPCTransferableDataOrError& aIpcTransferableDataOrError) {
142 if (aIpcTransferableDataOrError.type() ==
143 IPCTransferableDataOrError::Tnsresult) {
144 MOZ_ASSERT(NS_FAILED(aIpcTransferableDataOrError.get_nsresult()));
145 callback->OnComplete(aIpcTransferableDataOrError.get_nsresult());
146 return;
149 nsresult rv = nsContentUtils::IPCTransferableDataToTransferable(
150 aIpcTransferableDataOrError.get_IPCTransferableData(),
151 false /* aAddDataFlavor */, transferable,
152 false /* aFilterUnknownFlavors */);
153 if (NS_FAILED(rv)) {
154 callback->OnComplete(rv);
155 return;
158 callback->OnComplete(NS_OK);
160 /* reject */
161 [callback =
162 nsCOMPtr{aCallback}](mozilla::ipc::ResponseRejectReason aReason) {
163 callback->OnComplete(NS_ERROR_FAILURE);
166 return NS_OK;
169 } // namespace
171 NS_IMETHODIMP nsClipboardProxy::AsyncGetData(
172 const nsTArray<nsCString>& aFlavorList, int32_t aWhichClipboard,
173 mozilla::dom::WindowContext* aRequestingWindowContext,
174 nsIPrincipal* aRequestingPrincipal,
175 nsIAsyncClipboardGetCallback* aCallback) {
176 if (!aCallback || !aRequestingPrincipal || aFlavorList.IsEmpty()) {
177 return NS_ERROR_INVALID_ARG;
180 if (!nsIClipboard::IsClipboardTypeSupported(aWhichClipboard)) {
181 MOZ_CLIPBOARD_LOG("%s: clipboard %d is not supported.", __FUNCTION__,
182 aWhichClipboard);
183 return NS_ERROR_FAILURE;
186 ContentChild::GetSingleton()
187 ->SendGetClipboardAsync(aFlavorList, aWhichClipboard,
188 aRequestingWindowContext,
189 WrapNotNull(aRequestingPrincipal))
190 ->Then(
191 GetMainThreadSerialEventTarget(), __func__,
192 /* resolve */
193 [callback = nsCOMPtr{aCallback}](const PClipboardReadRequestOrError&
194 aClipboardReadRequestOrError) {
195 if (aClipboardReadRequestOrError.type() ==
196 PClipboardReadRequestOrError::Tnsresult) {
197 MOZ_ASSERT(
198 NS_FAILED(aClipboardReadRequestOrError.get_nsresult()));
199 callback->OnError(aClipboardReadRequestOrError.get_nsresult());
200 return;
203 auto asyncGetClipboardData = MakeRefPtr<AsyncGetClipboardDataProxy>(
204 static_cast<ClipboardReadRequestChild*>(
205 aClipboardReadRequestOrError.get_PClipboardReadRequest()
206 .AsChild()
207 .get()));
209 callback->OnSuccess(asyncGetClipboardData);
211 /* reject */
212 [callback = nsCOMPtr{aCallback}](
213 mozilla::ipc::ResponseRejectReason aReason) {
214 callback->OnError(NS_ERROR_FAILURE);
216 return NS_OK;
219 NS_IMETHODIMP
220 nsClipboardProxy::EmptyClipboard(int32_t aWhichClipboard) {
221 ContentChild::GetSingleton()->SendEmptyClipboard(aWhichClipboard);
222 return NS_OK;
225 NS_IMETHODIMP
226 nsClipboardProxy::HasDataMatchingFlavors(const nsTArray<nsCString>& aFlavorList,
227 int32_t aWhichClipboard,
228 bool* aHasType) {
229 *aHasType = false;
231 ContentChild::GetSingleton()->SendClipboardHasType(aFlavorList,
232 aWhichClipboard, aHasType);
234 return NS_OK;
237 NS_IMETHODIMP
238 nsClipboardProxy::IsClipboardTypeSupported(int32_t aWhichClipboard,
239 bool* aIsSupported) {
240 switch (aWhichClipboard) {
241 case kGlobalClipboard:
242 // We always support the global clipboard.
243 *aIsSupported = true;
244 return NS_OK;
245 case kSelectionClipboard:
246 *aIsSupported = mClipboardCaps.supportsSelectionClipboard();
247 return NS_OK;
248 case kFindClipboard:
249 *aIsSupported = mClipboardCaps.supportsFindClipboard();
250 return NS_OK;
251 case kSelectionCache:
252 *aIsSupported = mClipboardCaps.supportsSelectionCache();
253 return NS_OK;
256 *aIsSupported = false;
257 return NS_OK;
260 void nsClipboardProxy::SetCapabilities(
261 const ClipboardCapabilities& aClipboardCaps) {
262 mClipboardCaps = aClipboardCaps;