summaryrefslogtreecommitdiffstats
path: root/uriloader/exthandler/ContentHandlerService.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'uriloader/exthandler/ContentHandlerService.cpp')
-rw-r--r--uriloader/exthandler/ContentHandlerService.cpp263
1 files changed, 263 insertions, 0 deletions
diff --git a/uriloader/exthandler/ContentHandlerService.cpp b/uriloader/exthandler/ContentHandlerService.cpp
new file mode 100644
index 0000000000..599185bcd0
--- /dev/null
+++ b/uriloader/exthandler/ContentHandlerService.cpp
@@ -0,0 +1,263 @@
+/* -*- 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"
+#include "nsMIMEInfoImpl.h"
+#include "nsMIMEInfoChild.h"
+
+using mozilla::dom::ContentChild;
+using mozilla::dom::HandlerInfo;
+using mozilla::dom::PHandlerServiceChild;
+
+namespace mozilla {
+namespace dom {
+
+NS_IMPL_ISUPPORTS(ContentHandlerService, nsIHandlerService)
+
+ContentHandlerService::ContentHandlerService() {}
+
+/* static */ already_AddRefed<nsIHandlerService>
+ContentHandlerService::Create() {
+ if (XRE_IsContentProcess()) {
+ RefPtr service = new ContentHandlerService();
+ if (NS_SUCCEEDED(service->Init())) {
+ return service.forget();
+ }
+ return nullptr;
+ }
+
+ nsCOMPtr<nsIHandlerService> service =
+ do_GetService("@mozilla.org/uriloader/handler-service-parent;1");
+ return service.forget();
+}
+
+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_ERROR_UNEXPECTED;
+ }
+ 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 CopyHandlerInfoTonsIHandlerInfo(
+ 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);
+
+ aHandlerInfo->SetPreferredAction(info.preferredAction());
+ aHandlerInfo->SetAlwaysAskBeforeHandling(info.alwaysAskBeforeHandling());
+
+ 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, aOverrideType, &returnedInfo);
+ CopyHandlerInfoTonsIHandlerInfo(returnedInfo, aHandlerInfo);
+ return NS_OK;
+}
+
+NS_IMETHODIMP ContentHandlerService::GetMIMEInfoFromOS(
+ const nsACString& aMIMEType, const nsACString& aFileExt, bool* aFound,
+ nsIMIMEInfo** aMIMEInfo) {
+ nsresult rv = NS_ERROR_FAILURE;
+ HandlerInfo returnedInfo;
+ if (!mHandlerServiceChild->SendGetMIMEInfoFromOS(aMIMEType, aFileExt, &rv,
+ &returnedInfo, aFound)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ RefPtr<nsChildProcessMIMEInfo> mimeInfo =
+ new nsChildProcessMIMEInfo(returnedInfo.type());
+ CopyHandlerInfoTonsIHandlerInfo(returnedInfo, mimeInfo);
+ mimeInfo.forget(aMIMEInfo);
+ 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(aProtocolScheme,
+ aRetval)) {
+ return NS_ERROR_FAILURE;
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+ContentHandlerService::ExistsForProtocol(const nsACString& aProtocolScheme,
+ bool* aRetval) {
+ if (!mHandlerServiceChild->SendExistsForProtocol(aProtocolScheme, aRetval)) {
+ return NS_ERROR_FAILURE;
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP ContentHandlerService::GetTypeFromExtension(
+ const nsACString& aFileExtension, nsACString& _retval) {
+ _retval.Assign(*mExtToTypeMap.LookupOrInsertWith(aFileExtension, [&] {
+ nsCString type;
+ mHandlerServiceChild->SendGetTypeFromExtension(aFileExtension, &type);
+ return MakeUnique<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