summaryrefslogtreecommitdiffstats
path: root/uriloader/exthandler/ContentHandlerService.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--uriloader/exthandler/ContentHandlerService.cpp248
1 files changed, 248 insertions, 0 deletions
diff --git a/uriloader/exthandler/ContentHandlerService.cpp b/uriloader/exthandler/ContentHandlerService.cpp
new file mode 100644
index 0000000000..96eb6a0cbb
--- /dev/null
+++ b/uriloader/exthandler/ContentHandlerService.cpp
@@ -0,0 +1,248 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ContentHandlerService.h"
+#include "HandlerServiceChild.h"
+#include "ContentChild.h"
+#include "nsIMutableArray.h"
+#include "nsIMIMEInfo.h"
+#include "nsIStringEnumerator.h"
+#include "nsReadableUtils.h"
+
+using mozilla::dom::ContentChild;
+using mozilla::dom::HandlerInfo;
+using mozilla::dom::PHandlerServiceChild;
+
+namespace mozilla {
+namespace dom {
+
+NS_IMPL_ISUPPORTS(ContentHandlerService, nsIHandlerService)
+
+ContentHandlerService::ContentHandlerService() {}
+
+nsresult ContentHandlerService::Init() {
+ if (!XRE_IsContentProcess()) {
+ return NS_ERROR_FAILURE;
+ }
+ ContentChild* cpc = ContentChild::GetSingleton();
+
+ mHandlerServiceChild = new HandlerServiceChild();
+ if (!cpc->SendPHandlerServiceConstructor(mHandlerServiceChild)) {
+ mHandlerServiceChild = nullptr;
+ }
+ return NS_OK;
+}
+
+void ContentHandlerService::nsIHandlerInfoToHandlerInfo(
+ nsIHandlerInfo* aInfo, HandlerInfo* aHandlerInfo) {
+ nsCString type;
+ aInfo->GetType(type);
+ nsCOMPtr<nsIMIMEInfo> mimeInfo = do_QueryInterface(aInfo);
+ bool isMIMEInfo = !!mimeInfo;
+ nsString description;
+ aInfo->GetDescription(description);
+ bool alwaysAskBeforeHandling;
+ aInfo->GetAlwaysAskBeforeHandling(&alwaysAskBeforeHandling);
+ nsCOMPtr<nsIHandlerApp> app;
+ aInfo->GetPreferredApplicationHandler(getter_AddRefs(app));
+ nsString name;
+ nsString detailedDescription;
+ if (app) {
+ app->GetName(name);
+ app->GetDetailedDescription(detailedDescription);
+ }
+ HandlerApp happ(name, detailedDescription);
+ nsTArray<HandlerApp> happs;
+ nsCOMPtr<nsIMutableArray> apps;
+ aInfo->GetPossibleApplicationHandlers(getter_AddRefs(apps));
+ if (apps) {
+ unsigned int length;
+ apps->GetLength(&length);
+ for (unsigned int i = 0; i < length; i++) {
+ apps->QueryElementAt(i, NS_GET_IID(nsIHandlerApp), getter_AddRefs(app));
+ app->GetName(name);
+ app->GetDetailedDescription(detailedDescription);
+ happs.AppendElement(HandlerApp(name, detailedDescription));
+ }
+ }
+
+ nsTArray<nsCString> extensions;
+
+ if (isMIMEInfo) {
+ nsCOMPtr<nsIUTF8StringEnumerator> extensionsIter;
+ mimeInfo->GetFileExtensions(getter_AddRefs(extensionsIter));
+ if (extensionsIter) {
+ bool hasMore = false;
+ while (NS_SUCCEEDED(extensionsIter->HasMore(&hasMore)) && hasMore) {
+ nsAutoCString extension;
+ if (NS_SUCCEEDED(extensionsIter->GetNext(extension))) {
+ extensions.AppendElement(std::move(extension));
+ }
+ }
+ }
+ }
+
+ nsHandlerInfoAction action;
+ aInfo->GetPreferredAction(&action);
+ HandlerInfo info(type, isMIMEInfo, description, alwaysAskBeforeHandling,
+ std::move(extensions), happ, happs, action);
+ *aHandlerInfo = info;
+}
+
+NS_IMETHODIMP RemoteHandlerApp::GetName(nsAString& aName) {
+ aName.Assign(mAppChild.name());
+ return NS_OK;
+}
+
+NS_IMETHODIMP RemoteHandlerApp::SetName(const nsAString& aName) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP RemoteHandlerApp::GetDetailedDescription(
+ nsAString& aDetailedDescription) {
+ aDetailedDescription.Assign(mAppChild.detailedDescription());
+ return NS_OK;
+}
+
+NS_IMETHODIMP RemoteHandlerApp::SetDetailedDescription(
+ const nsAString& aDetailedDescription) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP RemoteHandlerApp::Equals(nsIHandlerApp* aHandlerApp,
+ bool* _retval) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP RemoteHandlerApp::LaunchWithURI(
+ nsIURI* aURI, BrowsingContext* aBrowsingContext) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMPL_ISUPPORTS(RemoteHandlerApp, nsIHandlerApp)
+
+static inline void CopyHanderInfoTonsIHandlerInfo(
+ const HandlerInfo& info, nsIHandlerInfo* aHandlerInfo) {
+ HandlerApp preferredApplicationHandler = info.preferredApplicationHandler();
+ nsCOMPtr<nsIHandlerApp> preferredApp(
+ new RemoteHandlerApp(preferredApplicationHandler));
+ aHandlerInfo->SetPreferredApplicationHandler(preferredApp);
+ nsCOMPtr<nsIMutableArray> possibleHandlers;
+ aHandlerInfo->GetPossibleApplicationHandlers(
+ getter_AddRefs(possibleHandlers));
+ possibleHandlers->AppendElement(preferredApp);
+
+ if (info.isMIMEInfo()) {
+ nsCOMPtr<nsIMIMEInfo> mimeInfo(do_QueryInterface(aHandlerInfo));
+ MOZ_ASSERT(mimeInfo,
+ "parent and child don't agree on whether this is a MIME info");
+ mimeInfo->SetFileExtensions(StringJoin(","_ns, info.extensions()));
+ }
+}
+
+ContentHandlerService::~ContentHandlerService() {}
+
+NS_IMETHODIMP ContentHandlerService::AsyncInit() {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP ContentHandlerService::Enumerate(nsISimpleEnumerator** _retval) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP ContentHandlerService::FillHandlerInfo(
+ nsIHandlerInfo* aHandlerInfo, const nsACString& aOverrideType) {
+ HandlerInfo info, returnedInfo;
+ nsIHandlerInfoToHandlerInfo(aHandlerInfo, &info);
+ mHandlerServiceChild->SendFillHandlerInfo(info, nsCString(aOverrideType),
+ &returnedInfo);
+ CopyHanderInfoTonsIHandlerInfo(returnedInfo, aHandlerInfo);
+ return NS_OK;
+}
+
+NS_IMETHODIMP ContentHandlerService::GetMIMEInfoFromOS(
+ nsIHandlerInfo* aHandlerInfo, const nsACString& aMIMEType,
+ const nsACString& aExtension, bool* aFound) {
+ nsresult rv = NS_ERROR_FAILURE;
+ HandlerInfo returnedInfo;
+ if (!mHandlerServiceChild->SendGetMIMEInfoFromOS(nsCString(aMIMEType),
+ nsCString(aExtension), &rv,
+ &returnedInfo, aFound)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ CopyHanderInfoTonsIHandlerInfo(returnedInfo, aHandlerInfo);
+ return NS_OK;
+}
+
+NS_IMETHODIMP ContentHandlerService::Store(nsIHandlerInfo* aHandlerInfo) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP ContentHandlerService::Exists(nsIHandlerInfo* aHandlerInfo,
+ bool* _retval) {
+ HandlerInfo info;
+ nsIHandlerInfoToHandlerInfo(aHandlerInfo, &info);
+ mHandlerServiceChild->SendExists(info, _retval);
+ return NS_OK;
+}
+
+NS_IMETHODIMP ContentHandlerService::Remove(nsIHandlerInfo* aHandlerInfo) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+ContentHandlerService::ExistsForProtocolOS(const nsACString& aProtocolScheme,
+ bool* aRetval) {
+ if (!mHandlerServiceChild->SendExistsForProtocolOS(nsCString(aProtocolScheme),
+ aRetval)) {
+ return NS_ERROR_FAILURE;
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+ContentHandlerService::ExistsForProtocol(const nsACString& aProtocolScheme,
+ bool* aRetval) {
+ if (!mHandlerServiceChild->SendExistsForProtocol(nsCString(aProtocolScheme),
+ aRetval)) {
+ return NS_ERROR_FAILURE;
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP ContentHandlerService::GetTypeFromExtension(
+ const nsACString& aFileExtension, nsACString& _retval) {
+ nsCString* cachedType = nullptr;
+ if (!!mExtToTypeMap.Get(aFileExtension, &cachedType) && !!cachedType) {
+ _retval.Assign(*cachedType);
+ return NS_OK;
+ }
+ nsCString type;
+ mHandlerServiceChild->SendGetTypeFromExtension(nsCString(aFileExtension),
+ &type);
+ _retval.Assign(type);
+ mExtToTypeMap.Put(nsCString(aFileExtension), new nsCString(type));
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP ContentHandlerService::GetApplicationDescription(
+ const nsACString& aProtocolScheme, nsAString& aRetVal) {
+ nsresult rv = NS_ERROR_FAILURE;
+ nsAutoCString scheme(aProtocolScheme);
+ nsAutoString desc;
+ mHandlerServiceChild->SendGetApplicationDescription(scheme, &rv, &desc);
+ aRetVal.Assign(desc);
+ return rv;
+}
+
+} // namespace dom
+} // namespace mozilla