michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsGNOMERegistry.h" michael@0: #include "nsString.h" michael@0: #include "nsIComponentManager.h" michael@0: #include "nsIFile.h" michael@0: #include "nsMIMEInfoUnix.h" michael@0: #include "nsAutoPtr.h" michael@0: #include "nsIGConfService.h" michael@0: #include "nsIGnomeVFSService.h" michael@0: #include "nsIGIOService.h" michael@0: michael@0: #ifdef MOZ_WIDGET_GTK michael@0: #include michael@0: #include michael@0: #endif michael@0: michael@0: /* static */ bool michael@0: nsGNOMERegistry::HandlerExists(const char *aProtocolScheme) michael@0: { michael@0: nsCOMPtr giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); michael@0: nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); michael@0: if (giovfs) { michael@0: nsCOMPtr app; michael@0: if (NS_FAILED(giovfs->GetAppForURIScheme(nsDependentCString(aProtocolScheme), michael@0: getter_AddRefs(app)))) michael@0: return false; michael@0: else michael@0: return true; michael@0: } else if (gconf) { michael@0: bool isEnabled; michael@0: nsAutoCString handler; michael@0: if (NS_FAILED(gconf->GetAppForProtocol(nsDependentCString(aProtocolScheme), &isEnabled, handler))) michael@0: return false; michael@0: michael@0: return isEnabled; michael@0: } michael@0: michael@0: return false; michael@0: } michael@0: michael@0: // XXX Check HandlerExists() before calling LoadURL. michael@0: // michael@0: // If there is not a registered handler for the protocol, gnome_url_show() michael@0: // falls back to using gnomevfs modules. See bug 389632. We don't want michael@0: // this fallback to happen as we are not sure of the safety of all gnomevfs michael@0: // modules and MIME-default applications. (gnomevfs should be handled in michael@0: // nsGnomeVFSProtocolHandler.) michael@0: michael@0: /* static */ nsresult michael@0: nsGNOMERegistry::LoadURL(nsIURI *aURL) michael@0: { michael@0: nsCOMPtr giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); michael@0: if (giovfs) michael@0: return giovfs->ShowURI(aURL); michael@0: michael@0: nsCOMPtr gnomevfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID); michael@0: if (gnomevfs) michael@0: return gnomevfs->ShowURI(aURL); michael@0: michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: /* static */ void michael@0: nsGNOMERegistry::GetAppDescForScheme(const nsACString& aScheme, michael@0: nsAString& aDesc) michael@0: { michael@0: nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); michael@0: nsCOMPtr giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); michael@0: if (!gconf && !giovfs) michael@0: return; michael@0: michael@0: nsAutoCString name; michael@0: if (giovfs) { michael@0: nsCOMPtr app; michael@0: if (NS_FAILED(giovfs->GetAppForURIScheme(aScheme, getter_AddRefs(app)))) michael@0: return; michael@0: michael@0: app->GetName(name); michael@0: } else { michael@0: bool isEnabled; michael@0: if (NS_FAILED(gconf->GetAppForProtocol(aScheme, &isEnabled, name))) michael@0: return; michael@0: michael@0: if (!name.IsEmpty()) { michael@0: // Try to only provide the executable name, as it is much simpler than with the path and arguments michael@0: int32_t firstSpace = name.FindChar(' '); michael@0: if (firstSpace != kNotFound) { michael@0: name.Truncate(firstSpace); michael@0: int32_t lastSlash = name.RFindChar('/'); michael@0: if (lastSlash != kNotFound) { michael@0: name.Cut(0, lastSlash + 1); michael@0: } michael@0: } michael@0: } michael@0: } michael@0: michael@0: CopyUTF8toUTF16(name, aDesc); michael@0: } michael@0: michael@0: michael@0: /* static */ already_AddRefed michael@0: nsGNOMERegistry::GetFromExtension(const nsACString& aFileExt) michael@0: { michael@0: nsAutoCString mimeType; michael@0: nsCOMPtr giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); michael@0: michael@0: if (giovfs) { michael@0: // Get the MIME type from the extension, then call GetFromType to michael@0: // fill in the MIMEInfo. michael@0: if (NS_FAILED(giovfs->GetMimeTypeFromExtension(aFileExt, mimeType)) || michael@0: mimeType.EqualsLiteral("application/octet-stream")) { michael@0: return nullptr; michael@0: } michael@0: } else { michael@0: /* Fallback to GnomeVFS */ michael@0: nsCOMPtr gnomevfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID); michael@0: if (!gnomevfs) michael@0: return nullptr; michael@0: michael@0: if (NS_FAILED(gnomevfs->GetMimeTypeFromExtension(aFileExt, mimeType)) || michael@0: mimeType.EqualsLiteral("application/octet-stream")) michael@0: return nullptr; michael@0: } michael@0: michael@0: nsRefPtr mi = GetFromType(mimeType); michael@0: if (mi) { michael@0: mi->AppendExtension(aFileExt); michael@0: } michael@0: michael@0: return mi.forget(); michael@0: } michael@0: michael@0: /* static */ already_AddRefed michael@0: nsGNOMERegistry::GetFromType(const nsACString& aMIMEType) michael@0: { michael@0: nsRefPtr mimeInfo = new nsMIMEInfoUnix(aMIMEType); michael@0: NS_ENSURE_TRUE(mimeInfo, nullptr); michael@0: michael@0: nsAutoCString name; michael@0: nsAutoCString description; michael@0: michael@0: nsCOMPtr giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); michael@0: if (giovfs) { michael@0: nsCOMPtr gioHandlerApp; michael@0: if (NS_FAILED(giovfs->GetAppForMimeType(aMIMEType, getter_AddRefs(gioHandlerApp))) || michael@0: !gioHandlerApp) { michael@0: return nullptr; michael@0: } michael@0: gioHandlerApp->GetName(name); michael@0: giovfs->GetDescriptionForMimeType(aMIMEType, description); michael@0: } else { michael@0: /* Fallback to GnomeVFS*/ michael@0: nsCOMPtr gnomevfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID); michael@0: if (!gnomevfs) michael@0: return nullptr; michael@0: michael@0: nsCOMPtr gnomeHandlerApp; michael@0: if (NS_FAILED(gnomevfs->GetAppForMimeType(aMIMEType, getter_AddRefs(gnomeHandlerApp))) || michael@0: !gnomeHandlerApp) { michael@0: return nullptr; michael@0: } michael@0: gnomeHandlerApp->GetName(name); michael@0: gnomevfs->GetDescriptionForMimeType(aMIMEType, description); michael@0: } michael@0: michael@0: mimeInfo->SetDefaultDescription(NS_ConvertUTF8toUTF16(name)); michael@0: mimeInfo->SetPreferredAction(nsIMIMEInfo::useSystemDefault); michael@0: mimeInfo->SetDescription(NS_ConvertUTF8toUTF16(description)); michael@0: michael@0: return mimeInfo.forget(); michael@0: }