/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * vim:expandtab:shiftwidth=2:tabstop=2:cin: * 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 #include "mozilla/Components.h" #include "mozilla/DBusHelpers.h" #include "nsDBusHandlerApp.h" #include "nsIURI.h" #include "nsIClassInfoImpl.h" #include "nsCOMPtr.h" #include "nsCExternalHandlerService.h" using namespace mozilla; // XXX why does nsMIMEInfoImpl have a threadsafe nsISupports? do we need one // here too? NS_IMPL_CLASSINFO(nsDBusHandlerApp, nullptr, 0, components::DBusHandlerApp::CID()) NS_IMPL_ISUPPORTS_CI(nsDBusHandlerApp, nsIDBusHandlerApp, nsIHandlerApp) //////////////////////////////////////////////////////////////////////////////// //// nsIHandlerApp NS_IMETHODIMP nsDBusHandlerApp::GetName(nsAString& aName) { aName.Assign(mName); return NS_OK; } NS_IMETHODIMP nsDBusHandlerApp::SetName(const nsAString& aName) { mName.Assign(aName); return NS_OK; } NS_IMETHODIMP nsDBusHandlerApp::SetDetailedDescription( const nsAString& aDescription) { mDetailedDescription.Assign(aDescription); return NS_OK; } NS_IMETHODIMP nsDBusHandlerApp::GetDetailedDescription( nsAString& aDescription) { aDescription.Assign(mDetailedDescription); return NS_OK; } NS_IMETHODIMP nsDBusHandlerApp::Equals(nsIHandlerApp* aHandlerApp, bool* _retval) { NS_ENSURE_ARG_POINTER(aHandlerApp); // If the handler app isn't a dbus handler app, then it's not the same app. nsCOMPtr dbusHandlerApp = do_QueryInterface(aHandlerApp); if (!dbusHandlerApp) { *_retval = false; return NS_OK; } nsAutoCString service; nsAutoCString method; nsresult rv = dbusHandlerApp->GetService(service); if (NS_FAILED(rv)) { *_retval = false; return NS_OK; } rv = dbusHandlerApp->GetMethod(method); if (NS_FAILED(rv)) { *_retval = false; return NS_OK; } *_retval = service.Equals(mService) && method.Equals(mMethod); return NS_OK; } NS_IMETHODIMP nsDBusHandlerApp::LaunchWithURI( nsIURI* aURI, mozilla::dom::BrowsingContext* aBrowsingContext) { nsAutoCString spec; nsresult rv = aURI->GetAsciiSpec(spec); NS_ENSURE_SUCCESS(rv, rv); const char* uri = spec.get(); DBusError err; dbus_error_init(&err); mozilla::UniquePtr connection( dbus_bus_get_private(DBUS_BUS_SESSION, &err)); if (dbus_error_is_set(&err)) { dbus_error_free(&err); return NS_ERROR_FAILURE; } if (nullptr == connection) { return NS_ERROR_FAILURE; } dbus_connection_set_exit_on_disconnect(connection.get(), false); RefPtr msg = already_AddRefed(dbus_message_new_method_call( mService.get(), mObjpath.get(), mInterface.get(), mMethod.get())); if (!msg) { return NS_ERROR_FAILURE; } dbus_message_set_no_reply(msg, true); DBusMessageIter iter; dbus_message_iter_init_append(msg, &iter); dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &uri); if (dbus_connection_send(connection.get(), msg, nullptr)) { dbus_connection_flush(connection.get()); } else { return NS_ERROR_FAILURE; } return NS_OK; } //////////////////////////////////////////////////////////////////////////////// //// nsIDBusHandlerApp NS_IMETHODIMP nsDBusHandlerApp::GetService(nsACString& aService) { aService.Assign(mService); return NS_OK; } NS_IMETHODIMP nsDBusHandlerApp::SetService(const nsACString& aService) { mService.Assign(aService); return NS_OK; } NS_IMETHODIMP nsDBusHandlerApp::GetMethod(nsACString& aMethod) { aMethod.Assign(mMethod); return NS_OK; } NS_IMETHODIMP nsDBusHandlerApp::SetMethod(const nsACString& aMethod) { mMethod.Assign(aMethod); return NS_OK; } NS_IMETHODIMP nsDBusHandlerApp::GetDBusInterface(nsACString& aInterface) { aInterface.Assign(mInterface); return NS_OK; } NS_IMETHODIMP nsDBusHandlerApp::SetDBusInterface(const nsACString& aInterface) { mInterface.Assign(aInterface); return NS_OK; } NS_IMETHODIMP nsDBusHandlerApp::GetObjectPath(nsACString& aObjpath) { aObjpath.Assign(mObjpath); return NS_OK; } NS_IMETHODIMP nsDBusHandlerApp::SetObjectPath(const nsACString& aObjpath) { mObjpath.Assign(aObjpath); return NS_OK; }