Bug 1890689 apply drift correction to input rate instead of output rate r=pehrsons
[gecko.git] / uriloader / exthandler / HandlerServiceParent.cpp
blob1c83d9628f8ccbffd2d59f5f5b47f87935a4c46a
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 "nsIMIMEService.h"
13 #include "ContentHandlerService.h"
14 #include "nsIExternalProtocolService.h"
15 #include "nsStringEnumerator.h"
16 #include "nsIMutableArray.h"
17 #include "nsCExternalHandlerService.h"
18 #include "nsComponentManagerUtils.h"
19 #include "nsServiceManagerUtils.h"
20 #ifdef MOZ_WIDGET_GTK
21 # include "unix/nsGNOMERegistry.h"
22 #endif
24 using mozilla::dom::ContentHandlerService;
25 using mozilla::dom::HandlerApp;
26 using mozilla::dom::HandlerInfo;
27 using mozilla::dom::RemoteHandlerApp;
29 namespace {
31 class ProxyHandlerInfo final : public nsIHandlerInfo {
32 public:
33 explicit ProxyHandlerInfo(const HandlerInfo& aHandlerInfo);
34 NS_DECL_ISUPPORTS;
35 NS_DECL_NSIHANDLERINFO;
37 nsTArray<nsCString>& Extensions() { return mHandlerInfo.extensions(); }
39 protected:
40 ~ProxyHandlerInfo() {}
41 HandlerInfo mHandlerInfo;
42 nsHandlerInfoAction mPrefAction;
43 nsCOMPtr<nsIMutableArray> mPossibleApps;
46 NS_IMPL_ISUPPORTS(ProxyHandlerInfo, nsIHandlerInfo)
48 ProxyHandlerInfo::ProxyHandlerInfo(const HandlerInfo& aHandlerInfo)
49 : mHandlerInfo(aHandlerInfo),
50 mPrefAction(nsIHandlerInfo::alwaysAsk),
51 mPossibleApps(do_CreateInstance(NS_ARRAY_CONTRACTID)) {
52 for (auto& happ : aHandlerInfo.possibleApplicationHandlers()) {
53 mPossibleApps->AppendElement(new RemoteHandlerApp(happ));
57 /* readonly attribute ACString type; */
58 NS_IMETHODIMP ProxyHandlerInfo::GetType(nsACString& aType) {
59 aType.Assign(mHandlerInfo.type());
60 return NS_OK;
63 /* attribute AString description; */
64 NS_IMETHODIMP ProxyHandlerInfo::GetDescription(nsAString& aDescription) {
65 return NS_ERROR_NOT_IMPLEMENTED;
67 NS_IMETHODIMP ProxyHandlerInfo::SetDescription(const nsAString& aDescription) {
68 return NS_ERROR_NOT_IMPLEMENTED;
71 /* attribute nsIHandlerApp preferredApplicationHandler; */
72 NS_IMETHODIMP ProxyHandlerInfo::GetPreferredApplicationHandler(
73 nsIHandlerApp** aPreferredApplicationHandler) {
74 *aPreferredApplicationHandler =
75 new RemoteHandlerApp(mHandlerInfo.preferredApplicationHandler());
76 NS_IF_ADDREF(*aPreferredApplicationHandler);
77 return NS_OK;
80 NS_IMETHODIMP ProxyHandlerInfo::SetPreferredApplicationHandler(
81 nsIHandlerApp* aApp) {
82 nsString name;
83 nsString detailedDescription;
84 if (aApp) {
85 aApp->GetName(name);
86 aApp->GetDetailedDescription(detailedDescription);
89 mHandlerInfo.preferredApplicationHandler() =
90 HandlerApp(name, detailedDescription);
91 return NS_OK;
94 /* readonly attribute nsIMutableArray possibleApplicationHandlers; */
95 NS_IMETHODIMP ProxyHandlerInfo::GetPossibleApplicationHandlers(
96 nsIMutableArray** aPossibleApplicationHandlers) {
97 *aPossibleApplicationHandlers = mPossibleApps;
98 NS_IF_ADDREF(*aPossibleApplicationHandlers);
99 return NS_OK;
102 /* readonly attribute boolean hasDefaultHandler; */
103 NS_IMETHODIMP ProxyHandlerInfo::GetHasDefaultHandler(bool* aHasDefaultHandler) {
104 return NS_ERROR_NOT_IMPLEMENTED;
107 /* readonly attribute AString defaultDescription; */
108 NS_IMETHODIMP ProxyHandlerInfo::GetDefaultDescription(
109 nsAString& aDefaultDescription) {
110 return NS_ERROR_NOT_IMPLEMENTED;
113 NS_IMETHODIMP ProxyHandlerInfo::GetDefaultExecutable(nsIFile** aExecutable) {
114 return NS_ERROR_NOT_IMPLEMENTED;
117 /* void launchWithURI (in nsIURI aURI,
118 [optional] in BrowsingContext aBrowsingContext); */
119 NS_IMETHODIMP ProxyHandlerInfo::LaunchWithURI(
120 nsIURI* aURI, mozilla::dom::BrowsingContext* aBrowsingContext) {
121 return NS_ERROR_NOT_IMPLEMENTED;
124 /* attribute ProxyHandlerInfoAction preferredAction; */
125 NS_IMETHODIMP ProxyHandlerInfo::GetPreferredAction(
126 nsHandlerInfoAction* aPreferredAction) {
127 *aPreferredAction = mPrefAction;
128 return NS_OK;
130 NS_IMETHODIMP ProxyHandlerInfo::SetPreferredAction(
131 nsHandlerInfoAction aPreferredAction) {
132 mHandlerInfo.preferredAction() = aPreferredAction;
133 mPrefAction = aPreferredAction;
134 return NS_OK;
137 /* attribute boolean alwaysAskBeforeHandling; */
138 NS_IMETHODIMP ProxyHandlerInfo::GetAlwaysAskBeforeHandling(
139 bool* aAlwaysAskBeforeHandling) {
140 *aAlwaysAskBeforeHandling = mHandlerInfo.alwaysAskBeforeHandling();
141 return NS_OK;
143 NS_IMETHODIMP ProxyHandlerInfo::SetAlwaysAskBeforeHandling(
144 bool aAlwaysAskBeforeHandling) {
145 mHandlerInfo.alwaysAskBeforeHandling() = aAlwaysAskBeforeHandling;
146 return NS_OK;
149 class ProxyMIMEInfo : public nsIMIMEInfo {
150 public:
151 NS_DECL_ISUPPORTS
152 NS_DECL_NSIMIMEINFO
153 NS_FORWARD_NSIHANDLERINFO(mProxyHandlerInfo->);
155 explicit ProxyMIMEInfo(const HandlerInfo& aHandlerInfo)
156 : mProxyHandlerInfo(new ProxyHandlerInfo(aHandlerInfo)) {}
158 private:
159 virtual ~ProxyMIMEInfo() {}
160 RefPtr<ProxyHandlerInfo> mProxyHandlerInfo;
162 protected:
163 /* additional members */
166 NS_IMPL_ISUPPORTS(ProxyMIMEInfo, nsIMIMEInfo, nsIHandlerInfo)
168 /* nsIUTF8StringEnumerator getFileExtensions (); */
169 NS_IMETHODIMP ProxyMIMEInfo::GetFileExtensions(
170 nsIUTF8StringEnumerator** _retval) {
171 return NS_NewUTF8StringEnumerator(_retval, &mProxyHandlerInfo->Extensions(),
172 this);
175 /* void setFileExtensions (in AUTF8String aExtensions); */
176 NS_IMETHODIMP ProxyMIMEInfo::SetFileExtensions(const nsACString& aExtensions) {
177 return NS_ERROR_NOT_IMPLEMENTED;
180 /* boolean extensionExists (in AUTF8String aExtension); */
181 NS_IMETHODIMP ProxyMIMEInfo::ExtensionExists(const nsACString& aExtension,
182 bool* _retval) {
183 *_retval = mProxyHandlerInfo->Extensions().Contains(
184 aExtension, nsCaseInsensitiveCStringArrayComparator());
185 return NS_OK;
188 /* void appendExtension (in AUTF8String aExtension); */
189 NS_IMETHODIMP ProxyMIMEInfo::AppendExtension(const nsACString& aExtension) {
190 if (!aExtension.IsEmpty() &&
191 !mProxyHandlerInfo->Extensions().Contains(
192 aExtension, nsCaseInsensitiveCStringArrayComparator())) {
193 mProxyHandlerInfo->Extensions().AppendElement(aExtension);
195 return NS_OK;
198 /* attribute AUTF8String primaryExtension; */
199 NS_IMETHODIMP ProxyMIMEInfo::GetPrimaryExtension(
200 nsACString& aPrimaryExtension) {
201 const auto& extensions = mProxyHandlerInfo->Extensions();
202 if (extensions.IsEmpty()) {
203 aPrimaryExtension.Truncate();
204 return NS_ERROR_FAILURE;
206 aPrimaryExtension = extensions[0];
207 return NS_OK;
210 NS_IMETHODIMP ProxyMIMEInfo::SetPrimaryExtension(
211 const nsACString& aPrimaryExtension) {
212 return NS_ERROR_NOT_IMPLEMENTED;
215 /* readonly attribute ACString MIMEType; */
216 NS_IMETHODIMP ProxyMIMEInfo::GetMIMEType(nsACString& aMIMEType) {
217 return NS_ERROR_NOT_IMPLEMENTED;
220 /* boolean equals (in nsIMIMEInfo aMIMEInfo); */
221 NS_IMETHODIMP ProxyMIMEInfo::Equals(nsIMIMEInfo* aMIMEInfo, bool* _retval) {
222 return NS_ERROR_NOT_IMPLEMENTED;
225 /* readonly attribute nsIArray possibleLocalHandlers; */
226 NS_IMETHODIMP ProxyMIMEInfo::GetPossibleLocalHandlers(
227 nsIArray** aPossibleLocalHandlers) {
228 return NS_ERROR_NOT_IMPLEMENTED;
231 /* void launchWithFile (in nsIFile aFile); */
232 NS_IMETHODIMP ProxyMIMEInfo::LaunchWithFile(nsIFile* aFile) {
233 return NS_ERROR_NOT_IMPLEMENTED;
236 /* boolean isCurrentAppOSDefault(); */
237 NS_IMETHODIMP ProxyMIMEInfo::IsCurrentAppOSDefault(bool* _retval) {
238 return NS_ERROR_NOT_IMPLEMENTED;
241 static already_AddRefed<nsIHandlerInfo> WrapHandlerInfo(
242 const HandlerInfo& aHandlerInfo) {
243 nsCOMPtr<nsIHandlerInfo> info;
244 if (aHandlerInfo.isMIMEInfo()) {
245 info = new ProxyMIMEInfo(aHandlerInfo);
246 } else {
247 info = new ProxyHandlerInfo(aHandlerInfo);
249 return info.forget();
252 } // anonymous namespace
254 HandlerServiceParent::HandlerServiceParent() {}
256 HandlerServiceParent::~HandlerServiceParent() {}
258 mozilla::ipc::IPCResult HandlerServiceParent::RecvFillHandlerInfo(
259 const HandlerInfo& aHandlerInfoData, const nsACString& aOverrideType,
260 HandlerInfo* handlerInfoData) {
261 nsCOMPtr<nsIHandlerInfo> info(WrapHandlerInfo(aHandlerInfoData));
262 nsCOMPtr<nsIHandlerService> handlerSvc =
263 do_GetService(NS_HANDLERSERVICE_CONTRACTID);
264 handlerSvc->FillHandlerInfo(info, aOverrideType);
265 ContentHandlerService::nsIHandlerInfoToHandlerInfo(info, handlerInfoData);
266 return IPC_OK();
269 mozilla::ipc::IPCResult HandlerServiceParent::RecvGetMIMEInfoFromOS(
270 const nsACString& aMIMEType, const nsACString& aExtension, nsresult* aRv,
271 HandlerInfo* aHandlerInfoData, bool* aFound) {
272 *aFound = false;
273 if (aMIMEType.Length() > MAX_MIMETYPE_LENGTH ||
274 aExtension.Length() > MAX_EXT_LENGTH) {
275 *aRv = NS_OK;
276 return IPC_OK();
279 nsCOMPtr<nsIMIMEService> mimeService =
280 do_GetService(NS_MIMESERVICE_CONTRACTID, aRv);
281 if (NS_WARN_IF(NS_FAILED(*aRv))) {
282 return IPC_OK();
285 nsCOMPtr<nsIMIMEInfo> mimeInfo;
286 *aRv = mimeService->GetMIMEInfoFromOS(aMIMEType, aExtension, aFound,
287 getter_AddRefs(mimeInfo));
288 if (NS_WARN_IF(NS_FAILED(*aRv))) {
289 return IPC_OK();
292 if (mimeInfo) {
293 ContentHandlerService::nsIHandlerInfoToHandlerInfo(mimeInfo,
294 aHandlerInfoData);
297 return IPC_OK();
300 mozilla::ipc::IPCResult HandlerServiceParent::RecvExists(
301 const HandlerInfo& aHandlerInfo, bool* exists) {
302 nsCOMPtr<nsIHandlerInfo> info(WrapHandlerInfo(aHandlerInfo));
303 nsCOMPtr<nsIHandlerService> handlerSvc =
304 do_GetService(NS_HANDLERSERVICE_CONTRACTID);
305 handlerSvc->Exists(info, exists);
306 return IPC_OK();
309 mozilla::ipc::IPCResult HandlerServiceParent::RecvExistsForProtocolOS(
310 const nsACString& aProtocolScheme, bool* aHandlerExists) {
311 if (aProtocolScheme.Length() > MAX_SCHEME_LENGTH) {
312 *aHandlerExists = false;
313 return IPC_OK();
315 #ifdef MOZ_WIDGET_GTK
316 // Check the GNOME registry for a protocol handler
317 *aHandlerExists =
318 nsGNOMERegistry::HandlerExists(PromiseFlatCString(aProtocolScheme).get());
319 #else
320 *aHandlerExists = false;
321 #endif
322 return IPC_OK();
326 * Check if a handler exists for the provided protocol. Check the datastore
327 * first and then fallback to checking the OS for a handler.
329 mozilla::ipc::IPCResult HandlerServiceParent::RecvExistsForProtocol(
330 const nsACString& aProtocolScheme, bool* aHandlerExists) {
331 if (aProtocolScheme.Length() > MAX_SCHEME_LENGTH) {
332 *aHandlerExists = false;
333 return IPC_OK();
335 // Check the datastore and fallback to an OS check.
336 // ExternalProcotolHandlerExists() does the fallback.
337 nsresult rv;
338 nsCOMPtr<nsIExternalProtocolService> protoSvc =
339 do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID, &rv);
340 if (NS_WARN_IF(NS_FAILED(rv))) {
341 *aHandlerExists = false;
342 return IPC_OK();
344 rv = protoSvc->ExternalProtocolHandlerExists(
345 PromiseFlatCString(aProtocolScheme).get(), aHandlerExists);
347 if (NS_WARN_IF(NS_FAILED(rv))) {
348 *aHandlerExists = false;
350 return IPC_OK();
353 mozilla::ipc::IPCResult HandlerServiceParent::RecvGetTypeFromExtension(
354 const nsACString& aFileExtension, nsCString* type) {
355 if (aFileExtension.Length() > MAX_EXT_LENGTH) {
356 return IPC_OK();
359 nsresult rv;
360 nsCOMPtr<nsIHandlerService> handlerSvc =
361 do_GetService(NS_HANDLERSERVICE_CONTRACTID, &rv);
362 if (NS_WARN_IF(NS_FAILED(rv))) {
363 return IPC_OK();
366 rv = handlerSvc->GetTypeFromExtension(aFileExtension, *type);
367 mozilla::Unused << NS_WARN_IF(NS_FAILED(rv));
369 return IPC_OK();
372 mozilla::ipc::IPCResult HandlerServiceParent::RecvGetApplicationDescription(
373 const nsACString& aScheme, nsresult* aRv, nsString* aDescription) {
374 if (aScheme.Length() > MAX_SCHEME_LENGTH) {
375 *aRv = NS_ERROR_NOT_AVAILABLE;
376 return IPC_OK();
378 nsCOMPtr<nsIExternalProtocolService> protoSvc =
379 do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID);
380 NS_ASSERTION(protoSvc, "No Helper App Service!");
381 *aRv = protoSvc->GetApplicationDescription(aScheme, *aDescription);
382 return IPC_OK();
385 void HandlerServiceParent::ActorDestroy(ActorDestroyReason aWhy) {}