Bug 1728955: part 8) Refactor `DisplayErrCode` in Windows' `nsClipboard`. r=masayuki
[gecko.git] / uriloader / exthandler / ExternalHelperAppParent.cpp
blob1a88e54df7021fb9d0ff9a25cb39c7db004bd892
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/DebugOnly.h"
9 #include "ExternalHelperAppParent.h"
10 #include "nsIContent.h"
11 #include "nsCExternalHandlerService.h"
12 #include "nsIExternalHelperAppService.h"
13 #include "mozilla/dom/ContentParent.h"
14 #include "mozilla/dom/Element.h"
15 #include "mozilla/dom/BrowserParent.h"
16 #include "nsStringStream.h"
17 #include "mozilla/ipc/URIUtils.h"
18 #include "nsNetUtil.h"
19 #include "mozilla/dom/Document.h"
20 #include "mozilla/dom/CanonicalBrowsingContext.h"
21 #include "mozilla/dom/WindowGlobalParent.h"
22 #include "nsQueryObject.h"
24 #include "mozilla/Unused.h"
26 using namespace mozilla::ipc;
28 namespace mozilla {
29 namespace dom {
31 NS_IMPL_ISUPPORTS_INHERITED(ExternalHelperAppParent, nsHashPropertyBag,
32 nsIRequest, nsIChannel, nsIMultiPartChannel,
33 nsIPrivateBrowsingChannel, nsIResumableChannel,
34 nsIStreamListener, nsIExternalHelperAppParent)
36 ExternalHelperAppParent::ExternalHelperAppParent(
37 nsIURI* uri, const int64_t& aContentLength, const bool& aWasFileChannel,
38 const nsCString& aContentDispositionHeader,
39 const uint32_t& aContentDispositionHint,
40 const nsString& aContentDispositionFilename)
41 : mURI(uri),
42 mPending(false),
43 mIPCClosed(false),
44 mLoadFlags(0),
45 mStatus(NS_OK),
46 mCanceled(false),
47 mContentLength(aContentLength),
48 mWasFileChannel(aWasFileChannel) {
49 mContentDispositionHeader = aContentDispositionHeader;
50 if (!mContentDispositionHeader.IsEmpty()) {
51 NS_GetFilenameFromDisposition(mContentDispositionFilename,
52 mContentDispositionHeader);
53 mContentDisposition =
54 NS_GetContentDispositionFromHeader(mContentDispositionHeader, this);
55 } else {
56 mContentDisposition = aContentDispositionHint;
57 mContentDispositionFilename = aContentDispositionFilename;
61 void ExternalHelperAppParent::Init(
62 const Maybe<mozilla::net::LoadInfoArgs>& aLoadInfoArgs,
63 const nsCString& aMimeContentType, const bool& aForceSave,
64 nsIURI* aReferrer, BrowsingContext* aContext,
65 const bool& aShouldCloseWindow) {
66 mozilla::ipc::LoadInfoArgsToLoadInfo(aLoadInfoArgs,
67 getter_AddRefs(mLoadInfo));
69 nsCOMPtr<nsIExternalHelperAppService> helperAppService =
70 do_GetService(NS_EXTERNALHELPERAPPSERVICE_CONTRACTID);
71 NS_ASSERTION(helperAppService, "No Helper App Service!");
73 if (aReferrer) {
74 SetPropertyAsInterface(u"docshell.internalReferrer"_ns, aReferrer);
77 if (aContext) {
78 WindowGlobalParent* parent =
79 aContext->Canonical()->GetCurrentWindowGlobal();
80 if (parent) {
81 RefPtr<BrowserParent> browser = parent->GetBrowserParent();
82 if (browser) {
83 bool isPrivate = false;
84 nsCOMPtr<nsILoadContext> loadContext = browser->GetLoadContext();
85 loadContext->GetUsePrivateBrowsing(&isPrivate);
86 SetPrivate(isPrivate);
91 helperAppService->CreateListener(aMimeContentType, this, aContext, aForceSave,
92 nullptr, getter_AddRefs(mListener));
93 if (aShouldCloseWindow) {
94 RefPtr<nsExternalAppHandler> handler = do_QueryObject(mListener);
95 if (handler) {
96 handler->SetShouldCloseWindow();
101 void ExternalHelperAppParent::ActorDestroy(ActorDestroyReason why) {
102 mIPCClosed = true;
105 void ExternalHelperAppParent::Delete() {
106 if (!mIPCClosed) {
107 Unused << Send__delete__(this);
111 mozilla::ipc::IPCResult ExternalHelperAppParent::RecvOnStartRequest(
112 const nsCString& entityID) {
113 mEntityID = entityID;
114 mPending = true;
115 mStatus = mListener->OnStartRequest(this);
116 return IPC_OK();
119 mozilla::ipc::IPCResult ExternalHelperAppParent::RecvOnDataAvailable(
120 const nsCString& data, const uint64_t& offset, const uint32_t& count) {
121 if (NS_FAILED(mStatus)) {
122 return IPC_OK();
125 MOZ_ASSERT(mPending, "must be pending!");
127 nsCOMPtr<nsIInputStream> stringStream;
128 DebugOnly<nsresult> rv = NS_NewByteInputStream(
129 getter_AddRefs(stringStream), Span(data).To(count), NS_ASSIGNMENT_DEPEND);
130 NS_ASSERTION(NS_SUCCEEDED(rv), "failed to create dependent string!");
131 mStatus = mListener->OnDataAvailable(this, stringStream, offset, count);
133 return IPC_OK();
136 mozilla::ipc::IPCResult ExternalHelperAppParent::RecvOnStopRequest(
137 const nsresult& code) {
138 mPending = false;
139 mListener->OnStopRequest(
140 this, (NS_SUCCEEDED(code) && NS_FAILED(mStatus)) ? mStatus : code);
141 Delete();
142 return IPC_OK();
146 // nsIStreamListener
149 NS_IMETHODIMP
150 ExternalHelperAppParent::OnDataAvailable(nsIRequest* request,
151 nsIInputStream* input, uint64_t offset,
152 uint32_t count) {
153 return mListener->OnDataAvailable(request, input, offset, count);
156 NS_IMETHODIMP
157 ExternalHelperAppParent::OnStartRequest(nsIRequest* request) {
158 return mListener->OnStartRequest(request);
161 NS_IMETHODIMP
162 ExternalHelperAppParent::OnStopRequest(nsIRequest* request, nsresult status) {
163 nsresult rv = mListener->OnStopRequest(request, status);
164 Delete();
165 return rv;
168 ExternalHelperAppParent::~ExternalHelperAppParent() {}
171 // nsIRequest implementation...
174 NS_IMETHODIMP
175 ExternalHelperAppParent::GetName(nsACString& aResult) {
176 if (!mURI) {
177 aResult.Truncate();
178 return NS_ERROR_NOT_AVAILABLE;
180 mURI->GetAsciiSpec(aResult);
181 return NS_OK;
184 NS_IMETHODIMP
185 ExternalHelperAppParent::IsPending(bool* aResult) {
186 *aResult = mPending;
187 return NS_OK;
190 NS_IMETHODIMP
191 ExternalHelperAppParent::GetStatus(nsresult* aResult) {
192 *aResult = mStatus;
193 return NS_OK;
196 NS_IMETHODIMP
197 ExternalHelperAppParent::Cancel(nsresult aStatus) {
198 mCanceled = true;
199 mStatus = aStatus;
200 Unused << SendCancel(aStatus);
201 return NS_OK;
204 NS_IMETHODIMP
205 ExternalHelperAppParent::GetCanceled(bool* aCanceled) {
206 *aCanceled = mCanceled;
207 return NS_OK;
210 NS_IMETHODIMP
211 ExternalHelperAppParent::Suspend() { return NS_ERROR_NOT_IMPLEMENTED; }
213 NS_IMETHODIMP
214 ExternalHelperAppParent::Resume() { return NS_ERROR_NOT_IMPLEMENTED; }
217 // nsIChannel implementation
220 NS_IMETHODIMP
221 ExternalHelperAppParent::GetOriginalURI(nsIURI** aURI) {
222 NS_IF_ADDREF(*aURI = mURI);
223 return NS_OK;
226 NS_IMETHODIMP
227 ExternalHelperAppParent::SetOriginalURI(nsIURI* aURI) {
228 return NS_ERROR_NOT_IMPLEMENTED;
231 NS_IMETHODIMP
232 ExternalHelperAppParent::GetURI(nsIURI** aURI) {
233 NS_IF_ADDREF(*aURI = mURI);
234 return NS_OK;
237 NS_IMETHODIMP
238 ExternalHelperAppParent::Open(nsIInputStream** aResult) {
239 return NS_ERROR_NOT_IMPLEMENTED;
242 NS_IMETHODIMP
243 ExternalHelperAppParent::AsyncOpen(nsIStreamListener* aListener) {
244 return NS_ERROR_NOT_IMPLEMENTED;
247 NS_IMETHODIMP
248 ExternalHelperAppParent::GetLoadFlags(nsLoadFlags* aLoadFlags) {
249 *aLoadFlags = mLoadFlags;
250 return NS_OK;
253 NS_IMETHODIMP
254 ExternalHelperAppParent::SetLoadFlags(nsLoadFlags aLoadFlags) {
255 mLoadFlags = aLoadFlags;
256 return NS_OK;
259 NS_IMETHODIMP
260 ExternalHelperAppParent::GetTRRMode(nsIRequest::TRRMode* aTRRMode) {
261 return GetTRRModeImpl(aTRRMode);
264 NS_IMETHODIMP
265 ExternalHelperAppParent::SetTRRMode(nsIRequest::TRRMode aTRRMode) {
266 return SetTRRModeImpl(aTRRMode);
269 NS_IMETHODIMP
270 ExternalHelperAppParent::GetIsDocument(bool* aIsDocument) {
271 return NS_GetIsDocumentChannel(this, aIsDocument);
274 NS_IMETHODIMP
275 ExternalHelperAppParent::GetLoadGroup(nsILoadGroup** aLoadGroup) {
276 *aLoadGroup = nullptr;
277 return NS_OK;
280 NS_IMETHODIMP
281 ExternalHelperAppParent::SetLoadGroup(nsILoadGroup* aLoadGroup) {
282 return NS_ERROR_NOT_IMPLEMENTED;
285 NS_IMETHODIMP
286 ExternalHelperAppParent::GetOwner(nsISupports** aOwner) {
287 *aOwner = nullptr;
288 return NS_OK;
291 NS_IMETHODIMP
292 ExternalHelperAppParent::SetOwner(nsISupports* aOwner) {
293 return NS_ERROR_NOT_IMPLEMENTED;
296 NS_IMETHODIMP
297 ExternalHelperAppParent::GetLoadInfo(nsILoadInfo** aLoadInfo) {
298 NS_IF_ADDREF(*aLoadInfo = mLoadInfo);
299 return NS_OK;
302 NS_IMETHODIMP
303 ExternalHelperAppParent::SetLoadInfo(nsILoadInfo* aLoadInfo) {
304 return NS_ERROR_NOT_IMPLEMENTED;
307 NS_IMETHODIMP
308 ExternalHelperAppParent::GetNotificationCallbacks(
309 nsIInterfaceRequestor** aCallbacks) {
310 *aCallbacks = nullptr;
311 return NS_OK;
314 NS_IMETHODIMP
315 ExternalHelperAppParent::SetNotificationCallbacks(
316 nsIInterfaceRequestor* aCallbacks) {
317 return NS_ERROR_NOT_IMPLEMENTED;
320 NS_IMETHODIMP
321 ExternalHelperAppParent::GetSecurityInfo(nsISupports** aSecurityInfo) {
322 *aSecurityInfo = nullptr;
323 return NS_OK;
326 NS_IMETHODIMP
327 ExternalHelperAppParent::GetContentType(nsACString& aContentType) {
328 aContentType.Truncate();
329 return NS_OK;
332 NS_IMETHODIMP
333 ExternalHelperAppParent::SetContentType(const nsACString& aContentType) {
334 return NS_ERROR_NOT_IMPLEMENTED;
337 NS_IMETHODIMP
338 ExternalHelperAppParent::GetContentCharset(nsACString& aContentCharset) {
339 aContentCharset.Truncate();
340 return NS_OK;
343 NS_IMETHODIMP
344 ExternalHelperAppParent::SetContentCharset(const nsACString& aContentCharset) {
345 return NS_ERROR_NOT_IMPLEMENTED;
348 NS_IMETHODIMP
349 ExternalHelperAppParent::GetContentDisposition(uint32_t* aContentDisposition) {
350 // NB: mContentDisposition may or may not be set to a non UINT32_MAX value in
351 // nsExternalHelperAppService::DoContentContentProcessHelper
352 if (mContentDispositionHeader.IsEmpty() && mContentDisposition == UINT32_MAX)
353 return NS_ERROR_NOT_AVAILABLE;
355 *aContentDisposition = mContentDisposition;
356 return NS_OK;
359 NS_IMETHODIMP
360 ExternalHelperAppParent::SetContentDisposition(uint32_t aContentDisposition) {
361 mContentDisposition = aContentDisposition;
362 return NS_OK;
365 NS_IMETHODIMP
366 ExternalHelperAppParent::GetContentDispositionFilename(
367 nsAString& aContentDispositionFilename) {
368 if (mContentDispositionFilename.IsEmpty()) {
369 return NS_ERROR_NOT_AVAILABLE;
372 aContentDispositionFilename = mContentDispositionFilename;
373 return NS_OK;
376 NS_IMETHODIMP
377 ExternalHelperAppParent::SetContentDispositionFilename(
378 const nsAString& aContentDispositionFilename) {
379 mContentDispositionFilename = aContentDispositionFilename;
380 return NS_OK;
383 NS_IMETHODIMP
384 ExternalHelperAppParent::GetContentDispositionHeader(
385 nsACString& aContentDispositionHeader) {
386 if (mContentDispositionHeader.IsEmpty()) {
387 return NS_ERROR_NOT_AVAILABLE;
390 aContentDispositionHeader = mContentDispositionHeader;
391 return NS_OK;
394 NS_IMETHODIMP
395 ExternalHelperAppParent::GetContentLength(int64_t* aContentLength) {
396 if (mContentLength < 0) {
397 *aContentLength = -1;
398 } else {
399 *aContentLength = mContentLength;
401 return NS_OK;
404 NS_IMETHODIMP
405 ExternalHelperAppParent::SetContentLength(int64_t aContentLength) {
406 mContentLength = aContentLength;
407 return NS_OK;
411 // nsIResumableChannel implementation
414 NS_IMETHODIMP
415 ExternalHelperAppParent::ResumeAt(uint64_t startPos,
416 const nsACString& entityID) {
417 return NS_ERROR_NOT_IMPLEMENTED;
420 NS_IMETHODIMP
421 ExternalHelperAppParent::GetEntityID(nsACString& aEntityID) {
422 aEntityID = mEntityID;
423 return NS_OK;
427 // nsIMultiPartChannel implementation
430 NS_IMETHODIMP
431 ExternalHelperAppParent::GetBaseChannel(nsIChannel** aChannel) {
432 return NS_ERROR_NOT_IMPLEMENTED;
435 NS_IMETHODIMP
436 ExternalHelperAppParent::GetPartID(uint32_t* aPartID) {
437 return NS_ERROR_NOT_IMPLEMENTED;
440 NS_IMETHODIMP
441 ExternalHelperAppParent::GetIsLastPart(bool* aIsLastPart) {
442 return NS_ERROR_NOT_IMPLEMENTED;
445 } // namespace dom
446 } // namespace mozilla