Bug 1728955: part 8) Refactor `DisplayErrCode` in Windows' `nsClipboard`. r=masayuki
[gecko.git] / uriloader / exthandler / HandlerServiceParent.cpp
blob0796c7428b18055c07190c8b64218b2b7822d1cd
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=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/ipc/ProtocolUtils.h"
8 #include "mozilla/Logging.h"
9 #include "HandlerServiceParent.h"
10 #include "nsIHandlerService.h"
11 #include "nsIMIMEInfo.h"
12 #include "ContentHandlerService.h"
13 #include "nsStringEnumerator.h"
14 #ifdef MOZ_WIDGET_GTK
15 # include "unix/nsGNOMERegistry.h"
16 #endif
18 using mozilla::dom::ContentHandlerService;
19 using mozilla::dom::HandlerApp;
20 using mozilla::dom::HandlerInfo;
21 using mozilla::dom::RemoteHandlerApp;
23 namespace {
25 class ProxyHandlerInfo final : public nsIHandlerInfo {
26 public:
27 explicit ProxyHandlerInfo(const HandlerInfo& aHandlerInfo);
28 NS_DECL_ISUPPORTS;
29 NS_DECL_NSIHANDLERINFO;
31 nsTArray<nsCString>& Extensions() { return mHandlerInfo.extensions(); }
33 protected:
34 ~ProxyHandlerInfo() {}
35 HandlerInfo mHandlerInfo;
36 nsHandlerInfoAction mPrefAction;
37 nsCOMPtr<nsIMutableArray> mPossibleApps;
40 NS_IMPL_ISUPPORTS(ProxyHandlerInfo, nsIHandlerInfo)
42 ProxyHandlerInfo::ProxyHandlerInfo(const HandlerInfo& aHandlerInfo)
43 : mHandlerInfo(aHandlerInfo),
44 mPrefAction(nsIHandlerInfo::alwaysAsk),
45 mPossibleApps(do_CreateInstance(NS_ARRAY_CONTRACTID)) {
46 for (auto& happ : aHandlerInfo.possibleApplicationHandlers()) {
47 mPossibleApps->AppendElement(new RemoteHandlerApp(happ));
51 /* readonly attribute ACString type; */
52 NS_IMETHODIMP ProxyHandlerInfo::GetType(nsACString& aType) {
53 aType.Assign(mHandlerInfo.type());
54 return NS_OK;
57 /* attribute AString description; */
58 NS_IMETHODIMP ProxyHandlerInfo::GetDescription(nsAString& aDescription) {
59 return NS_ERROR_NOT_IMPLEMENTED;
61 NS_IMETHODIMP ProxyHandlerInfo::SetDescription(const nsAString& aDescription) {
62 return NS_ERROR_NOT_IMPLEMENTED;
65 /* attribute nsIHandlerApp preferredApplicationHandler; */
66 NS_IMETHODIMP ProxyHandlerInfo::GetPreferredApplicationHandler(
67 nsIHandlerApp** aPreferredApplicationHandler) {
68 *aPreferredApplicationHandler =
69 new RemoteHandlerApp(mHandlerInfo.preferredApplicationHandler());
70 NS_IF_ADDREF(*aPreferredApplicationHandler);
71 return NS_OK;
74 NS_IMETHODIMP ProxyHandlerInfo::SetPreferredApplicationHandler(
75 nsIHandlerApp* aApp) {
76 nsString name;
77 nsString detailedDescription;
78 if (aApp) {
79 aApp->GetName(name);
80 aApp->GetDetailedDescription(detailedDescription);
83 mHandlerInfo.preferredApplicationHandler() =
84 HandlerApp(name, detailedDescription);
85 return NS_OK;
88 /* readonly attribute nsIMutableArray possibleApplicationHandlers; */
89 NS_IMETHODIMP ProxyHandlerInfo::GetPossibleApplicationHandlers(
90 nsIMutableArray** aPossibleApplicationHandlers) {
91 *aPossibleApplicationHandlers = mPossibleApps;
92 NS_IF_ADDREF(*aPossibleApplicationHandlers);
93 return NS_OK;
96 /* readonly attribute boolean hasDefaultHandler; */
97 NS_IMETHODIMP ProxyHandlerInfo::GetHasDefaultHandler(bool* aHasDefaultHandler) {
98 return NS_ERROR_NOT_IMPLEMENTED;
101 /* readonly attribute AString defaultDescription; */
102 NS_IMETHODIMP ProxyHandlerInfo::GetDefaultDescription(
103 nsAString& aDefaultDescription) {
104 return NS_ERROR_NOT_IMPLEMENTED;
107 /* void launchWithURI (in nsIURI aURI,
108 [optional] in BrowsingContext aBrowsingContext); */
109 NS_IMETHODIMP ProxyHandlerInfo::LaunchWithURI(
110 nsIURI* aURI, mozilla::dom::BrowsingContext* aBrowsingContext) {
111 return NS_ERROR_NOT_IMPLEMENTED;
114 /* attribute ProxyHandlerInfoAction preferredAction; */
115 NS_IMETHODIMP ProxyHandlerInfo::GetPreferredAction(
116 nsHandlerInfoAction* aPreferredAction) {
117 *aPreferredAction = mPrefAction;
118 return NS_OK;
120 NS_IMETHODIMP ProxyHandlerInfo::SetPreferredAction(
121 nsHandlerInfoAction aPreferredAction) {
122 mHandlerInfo.preferredAction() = aPreferredAction;
123 mPrefAction = aPreferredAction;
124 return NS_OK;
127 /* attribute boolean alwaysAskBeforeHandling; */
128 NS_IMETHODIMP ProxyHandlerInfo::GetAlwaysAskBeforeHandling(
129 bool* aAlwaysAskBeforeHandling) {
130 *aAlwaysAskBeforeHandling = mHandlerInfo.alwaysAskBeforeHandling();
131 return NS_OK;
133 NS_IMETHODIMP ProxyHandlerInfo::SetAlwaysAskBeforeHandling(
134 bool aAlwaysAskBeforeHandling) {
135 mHandlerInfo.alwaysAskBeforeHandling() = aAlwaysAskBeforeHandling;
136 return NS_OK;
139 class ProxyMIMEInfo : public nsIMIMEInfo {
140 public:
141 NS_DECL_ISUPPORTS
142 NS_DECL_NSIMIMEINFO
143 NS_FORWARD_NSIHANDLERINFO(mProxyHandlerInfo->);
145 explicit ProxyMIMEInfo(const HandlerInfo& aHandlerInfo)
146 : mProxyHandlerInfo(new ProxyHandlerInfo(aHandlerInfo)) {}
148 private:
149 virtual ~ProxyMIMEInfo() {}
150 RefPtr<ProxyHandlerInfo> mProxyHandlerInfo;
152 protected:
153 /* additional members */
156 NS_IMPL_ISUPPORTS(ProxyMIMEInfo, nsIMIMEInfo, nsIHandlerInfo)
158 /* nsIUTF8StringEnumerator getFileExtensions (); */
159 NS_IMETHODIMP ProxyMIMEInfo::GetFileExtensions(
160 nsIUTF8StringEnumerator** _retval) {
161 return NS_NewUTF8StringEnumerator(_retval, &mProxyHandlerInfo->Extensions(),
162 this);
165 /* void setFileExtensions (in AUTF8String aExtensions); */
166 NS_IMETHODIMP ProxyMIMEInfo::SetFileExtensions(const nsACString& aExtensions) {
167 return NS_ERROR_NOT_IMPLEMENTED;
170 /* boolean extensionExists (in AUTF8String aExtension); */
171 NS_IMETHODIMP ProxyMIMEInfo::ExtensionExists(const nsACString& aExtension,
172 bool* _retval) {
173 *_retval = mProxyHandlerInfo->Extensions().Contains(
174 aExtension, nsCaseInsensitiveCStringArrayComparator());
175 return NS_OK;
178 /* void appendExtension (in AUTF8String aExtension); */
179 NS_IMETHODIMP ProxyMIMEInfo::AppendExtension(const nsACString& aExtension) {
180 if (!aExtension.IsEmpty() &&
181 !mProxyHandlerInfo->Extensions().Contains(
182 aExtension, nsCaseInsensitiveCStringArrayComparator())) {
183 mProxyHandlerInfo->Extensions().AppendElement(aExtension);
185 return NS_OK;
188 /* attribute AUTF8String primaryExtension; */
189 NS_IMETHODIMP ProxyMIMEInfo::GetPrimaryExtension(
190 nsACString& aPrimaryExtension) {
191 const auto& extensions = mProxyHandlerInfo->Extensions();
192 if (extensions.IsEmpty()) {
193 aPrimaryExtension.Truncate();
194 return NS_ERROR_FAILURE;
196 aPrimaryExtension = extensions[0];
197 return NS_OK;
200 NS_IMETHODIMP ProxyMIMEInfo::SetPrimaryExtension(
201 const nsACString& aPrimaryExtension) {
202 return NS_ERROR_NOT_IMPLEMENTED;
205 /* readonly attribute ACString MIMEType; */
206 NS_IMETHODIMP ProxyMIMEInfo::GetMIMEType(nsACString& aMIMEType) {
207 return NS_ERROR_NOT_IMPLEMENTED;
210 /* boolean equals (in nsIMIMEInfo aMIMEInfo); */
211 NS_IMETHODIMP ProxyMIMEInfo::Equals(nsIMIMEInfo* aMIMEInfo, bool* _retval) {
212 return NS_ERROR_NOT_IMPLEMENTED;
215 /* readonly attribute nsIArray possibleLocalHandlers; */
216 NS_IMETHODIMP ProxyMIMEInfo::GetPossibleLocalHandlers(
217 nsIArray** aPossibleLocalHandlers) {
218 return NS_ERROR_NOT_IMPLEMENTED;
221 /* void launchWithFile (in nsIFile aFile); */
222 NS_IMETHODIMP ProxyMIMEInfo::LaunchWithFile(nsIFile* aFile) {
223 return NS_ERROR_NOT_IMPLEMENTED;
226 /* boolean isCurrentAppOSDefault(); */
227 NS_IMETHODIMP ProxyMIMEInfo::IsCurrentAppOSDefault(bool* _retval) {
228 return NS_ERROR_NOT_IMPLEMENTED;
231 static already_AddRefed<nsIHandlerInfo> WrapHandlerInfo(
232 const HandlerInfo& aHandlerInfo) {
233 nsCOMPtr<nsIHandlerInfo> info;
234 if (aHandlerInfo.isMIMEInfo()) {
235 info = new ProxyMIMEInfo(aHandlerInfo);
236 } else {
237 info = new ProxyHandlerInfo(aHandlerInfo);
239 return info.forget();
242 } // anonymous namespace
244 HandlerServiceParent::HandlerServiceParent() {}
246 HandlerServiceParent::~HandlerServiceParent() {}
248 mozilla::ipc::IPCResult HandlerServiceParent::RecvFillHandlerInfo(
249 const HandlerInfo& aHandlerInfoData, const nsCString& aOverrideType,
250 HandlerInfo* handlerInfoData) {
251 nsCOMPtr<nsIHandlerInfo> info(WrapHandlerInfo(aHandlerInfoData));
252 nsCOMPtr<nsIHandlerService> handlerSvc =
253 do_GetService(NS_HANDLERSERVICE_CONTRACTID);
254 handlerSvc->FillHandlerInfo(info, aOverrideType);
255 ContentHandlerService::nsIHandlerInfoToHandlerInfo(info, handlerInfoData);
256 return IPC_OK();
259 mozilla::ipc::IPCResult HandlerServiceParent::RecvGetMIMEInfoFromOS(
260 const nsCString& aMIMEType, const nsCString& aExtension, nsresult* aRv,
261 HandlerInfo* aHandlerInfoData, bool* aFound) {
262 *aFound = false;
263 if (aMIMEType.Length() > MAX_MIMETYPE_LENGTH ||
264 aExtension.Length() > MAX_EXT_LENGTH) {
265 *aRv = NS_OK;
266 return IPC_OK();
269 nsCOMPtr<nsIMIMEService> mimeService =
270 do_GetService(NS_MIMESERVICE_CONTRACTID, aRv);
271 if (NS_WARN_IF(NS_FAILED(*aRv))) {
272 return IPC_OK();
275 nsCOMPtr<nsIMIMEInfo> mimeInfo;
276 *aRv = mimeService->GetMIMEInfoFromOS(aMIMEType, aExtension, aFound,
277 getter_AddRefs(mimeInfo));
278 if (NS_WARN_IF(NS_FAILED(*aRv))) {
279 return IPC_OK();
282 if (mimeInfo) {
283 ContentHandlerService::nsIHandlerInfoToHandlerInfo(mimeInfo,
284 aHandlerInfoData);
287 return IPC_OK();
290 mozilla::ipc::IPCResult HandlerServiceParent::RecvExists(
291 const HandlerInfo& aHandlerInfo, bool* exists) {
292 nsCOMPtr<nsIHandlerInfo> info(WrapHandlerInfo(aHandlerInfo));
293 nsCOMPtr<nsIHandlerService> handlerSvc =
294 do_GetService(NS_HANDLERSERVICE_CONTRACTID);
295 handlerSvc->Exists(info, exists);
296 return IPC_OK();
299 mozilla::ipc::IPCResult HandlerServiceParent::RecvExistsForProtocolOS(
300 const nsCString& aProtocolScheme, bool* aHandlerExists) {
301 if (aProtocolScheme.Length() > MAX_SCHEME_LENGTH) {
302 *aHandlerExists = false;
303 return IPC_OK();
305 #ifdef MOZ_WIDGET_GTK
306 // Check the GNOME registry for a protocol handler
307 *aHandlerExists = nsGNOMERegistry::HandlerExists(aProtocolScheme.get());
308 #else
309 *aHandlerExists = false;
310 #endif
311 return IPC_OK();
315 * Check if a handler exists for the provided protocol. Check the datastore
316 * first and then fallback to checking the OS for a handler.
318 mozilla::ipc::IPCResult HandlerServiceParent::RecvExistsForProtocol(
319 const nsCString& aProtocolScheme, bool* aHandlerExists) {
320 if (aProtocolScheme.Length() > MAX_SCHEME_LENGTH) {
321 *aHandlerExists = false;
322 return IPC_OK();
324 #if defined(XP_MACOSX) || defined(XP_WIN)
325 // Check the datastore and fallback to an OS check.
326 // ExternalProcotolHandlerExists() does the fallback.
327 nsresult rv;
328 nsCOMPtr<nsIExternalProtocolService> protoSvc =
329 do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID, &rv);
330 if (NS_WARN_IF(NS_FAILED(rv))) {
331 *aHandlerExists = false;
332 return IPC_OK();
334 rv = protoSvc->ExternalProtocolHandlerExists(aProtocolScheme.get(),
335 aHandlerExists);
337 if (NS_WARN_IF(NS_FAILED(rv))) {
338 *aHandlerExists = false;
340 #else
341 MOZ_RELEASE_ASSERT(false, "No implementation on this platform.");
342 *aHandlerExists = false;
343 #endif
344 return IPC_OK();
347 mozilla::ipc::IPCResult HandlerServiceParent::RecvGetTypeFromExtension(
348 const nsCString& aFileExtension, nsCString* type) {
349 if (aFileExtension.Length() > MAX_EXT_LENGTH) {
350 return IPC_OK();
353 nsresult rv;
354 nsCOMPtr<nsIHandlerService> handlerSvc =
355 do_GetService(NS_HANDLERSERVICE_CONTRACTID, &rv);
356 if (NS_WARN_IF(NS_FAILED(rv))) {
357 return IPC_OK();
360 rv = handlerSvc->GetTypeFromExtension(aFileExtension, *type);
361 mozilla::Unused << NS_WARN_IF(NS_FAILED(rv));
363 return IPC_OK();
366 mozilla::ipc::IPCResult HandlerServiceParent::RecvGetApplicationDescription(
367 const nsCString& aScheme, nsresult* aRv, nsString* aDescription) {
368 if (aScheme.Length() > MAX_SCHEME_LENGTH) {
369 *aRv = NS_ERROR_NOT_AVAILABLE;
370 return IPC_OK();
372 nsCOMPtr<nsIExternalProtocolService> protoSvc =
373 do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID);
374 NS_ASSERTION(protoSvc, "No Helper App Service!");
375 *aRv = protoSvc->GetApplicationDescription(aScheme, *aDescription);
376 return IPC_OK();
379 void HandlerServiceParent::ActorDestroy(ActorDestroyReason aWhy) {}