Bug 1452278 - Part 1 - Make macOS nsOSHelperAppService::GetFromTypeAndExtension() not call OS MIME API's in content r=bzbarsky,froydnj

Add a new nsExternalHelperAppService derived class named nsOSHelperAppServiceChild to be used for the MIME service, external helper app service, and external protocol service interfaces in child processes. nsOSHelperAppServiceChild overrides some methods used to get MIME and external protocol handler information from the OS and implements these methods by remoting the calls to the parent process.

This is necessary because, on Mac, querying the OS for helper application info from sandboxed content processes is unreliable and has buggy side effects.

For now, only use the new class on Mac.

Android and unix file changes r+ by gcp.
Windows files changes r+ by bobowen.
Sync messages review r+ by nfroyd.

MozReview-Commit-ID: 63BiS6VCxfn

Differential Revision: https://phabricator.services.mozilla.com/D15620

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Haik Aftandilian 2019-03-27 22:49:33 +00:00
Родитель c0b388efb1
Коммит 77b79862cf
24 изменённых файлов: 593 добавлений и 140 удалений

Просмотреть файл

@ -71,8 +71,9 @@ Classes = [
'@mozilla.org/uriloader/external-helper-app-service;1',
'@mozilla.org/uriloader/external-protocol-service;1',
],
'type': 'nsOSHelperAppService',
'headers': ['nsOSHelperAppService.h'],
'type': 'nsExternalHelperAppService',
'constructor': 'nsExternalHelperAppService::GetSingleton',
'headers': ['nsExternalHelperAppService.h'],
'init_method': 'Init',
'processes': ProcessSelector.ALLOW_IN_SOCKET_PROCESS,
},

Просмотреть файл

@ -1049,12 +1049,18 @@ description =
description =
[PHandlerService::FillHandlerInfo]
description =
[PHandlerService::ExistsForProtocol]
[PHandlerService::GetMIMEInfoFromOS]
description = Lets unprivileged child processes synchronously get MIME type/handler information from the OS
[PHandlerService::ExistsForProtocolOS]
description = bug 1382323
[PHandlerService::ExistsForProtocol]
description =
[PHandlerService::Exists]
description =
[PHandlerService::GetTypeFromExtension]
description =
[PHandlerService::GetApplicationDescription]
description = Lets unprivileged child processes synchronously get a description of the app that handles a given protocol scheme
[PLayerTransaction::ShutdownSync]
description = bug 1363126
[PClientSource::WorkerSyncPing]

Просмотреть файл

@ -72,4 +72,29 @@ interface nsIMIMEService : nsISupports {
* @param aFileExt File Extension. Can be empty.
*/
AUTF8String getPrimaryExtension(in ACString aMIMEType, in AUTF8String aFileExt);
/*
* Returns an nsIMIMEInfo for the provided MIME type and extension
* obtained from an OS lookup. If no handler is found for the type and
* extension, returns a generic nsIMIMEInfo object. The MIME type and
* extension can be the empty string. When the type and extension don't
* map to the same handler, the semantics/resolution are platform
* specific. See the platform implementations for details.
*
* @param aType The MIME type to get handler information for.
* @param aFileExtension The filename extension to use either alone
* or with the MIME type to get handler information
* for. UTF-8 encoded.
* @param [out] aFound Out param indicating whether a MIMEInfo could
* be found for the provided type and/or extension.
* Set to false when neither extension nor the MIME
* type are mapped to a handler.
* @return A nsIMIMEInfo object. This function must return
* a MIMEInfo object if it can allocate one. The
* only justifiable reason for not returning one is
* an out-of-memory error.
*/
nsIMIMEInfo getMIMEInfoFromOS(in ACString aType,
in ACString aFileExtension,
out boolean aFound);
};

Просмотреть файл

@ -166,6 +166,25 @@ NS_IMETHODIMP ContentHandlerService::FillHandlerInfo(
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;
}
@ -182,6 +201,16 @@ 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) {
@ -208,5 +237,15 @@ NS_IMETHODIMP ContentHandlerService::GetTypeFromExtension(
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

Просмотреть файл

@ -1,3 +1,4 @@
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/Logging.h"
#include "HandlerServiceParent.h"
#include "nsIHandlerService.h"
@ -238,6 +239,31 @@ mozilla::ipc::IPCResult HandlerServiceParent::RecvFillHandlerInfo(
return IPC_OK();
}
mozilla::ipc::IPCResult HandlerServiceParent::RecvGetMIMEInfoFromOS(
const nsCString& aMIMEType, const nsCString& aExtension, nsresult* aRv,
HandlerInfo* aHandlerInfoData, bool* aFound) {
*aFound = false;
nsCOMPtr<nsIMIMEService> mimeService =
do_GetService(NS_MIMESERVICE_CONTRACTID, aRv);
if (NS_WARN_IF(NS_FAILED(*aRv))) {
return IPC_OK();
}
nsCOMPtr<nsIMIMEInfo> mimeInfo;
*aRv = mimeService->GetMIMEInfoFromOS(aMIMEType, aExtension, aFound,
getter_AddRefs(mimeInfo));
if (NS_WARN_IF(NS_FAILED(*aRv))) {
return IPC_OK();
}
if (mimeInfo) {
ContentHandlerService::nsIHandlerInfoToHandlerInfo(mimeInfo,
aHandlerInfoData);
}
return IPC_OK();
}
mozilla::ipc::IPCResult HandlerServiceParent::RecvExists(
const HandlerInfo& aHandlerInfo, bool* exists) {
nsCOMPtr<nsIHandlerInfo> info(WrapHandlerInfo(aHandlerInfo));
@ -247,7 +273,7 @@ mozilla::ipc::IPCResult HandlerServiceParent::RecvExists(
return IPC_OK();
}
mozilla::ipc::IPCResult HandlerServiceParent::RecvExistsForProtocol(
mozilla::ipc::IPCResult HandlerServiceParent::RecvExistsForProtocolOS(
const nsCString& aProtocolScheme, bool* aHandlerExists) {
#ifdef MOZ_WIDGET_GTK
// Check the GNOME registry for a protocol handler
@ -258,11 +284,56 @@ mozilla::ipc::IPCResult HandlerServiceParent::RecvExistsForProtocol(
return IPC_OK();
}
/*
* Check if a handler exists for the provided protocol. Check the datastore
* first and then fallback to checking the OS for a handler.
*/
mozilla::ipc::IPCResult HandlerServiceParent::RecvExistsForProtocol(
const nsCString& aProtocolScheme, bool* aHandlerExists) {
#if defined(XP_MACOSX)
// Check the datastore and fallback to an OS check.
// ExternalProcotolHandlerExists() does the fallback.
nsresult rv;
nsCOMPtr<nsIExternalProtocolService> protoSvc =
do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID, &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
*aHandlerExists = false;
return IPC_OK();
}
rv = protoSvc->ExternalProtocolHandlerExists(aProtocolScheme.get(),
aHandlerExists);
if (NS_WARN_IF(NS_FAILED(rv))) {
*aHandlerExists = false;
}
#else
MOZ_RELEASE_ASSERT(false, "No implementation on this platform.");
*aHandlerExists = false;
#endif
return IPC_OK();
}
mozilla::ipc::IPCResult HandlerServiceParent::RecvGetTypeFromExtension(
const nsCString& aFileExtension, nsCString* type) {
nsresult rv;
nsCOMPtr<nsIHandlerService> handlerSvc =
do_GetService(NS_HANDLERSERVICE_CONTRACTID);
handlerSvc->GetTypeFromExtension(aFileExtension, *type);
do_GetService(NS_HANDLERSERVICE_CONTRACTID, &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
return IPC_OK();
}
rv = handlerSvc->GetTypeFromExtension(aFileExtension, *type);
mozilla::Unused << NS_WARN_IF(NS_FAILED(rv));
return IPC_OK();
}
mozilla::ipc::IPCResult HandlerServiceParent::RecvGetApplicationDescription(
const nsCString& aScheme, nsresult* aRv, nsString* aDescription) {
nsCOMPtr<nsIExternalProtocolService> protoSvc =
do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID);
NS_ASSERTION(protoSvc, "No Helper App Service!");
*aRv = protoSvc->GetApplicationDescription(aScheme, *aDescription);
return IPC_OK();
}

Просмотреть файл

@ -13,19 +13,32 @@ class HandlerServiceParent final : public mozilla::dom::PHandlerServiceParent {
private:
virtual ~HandlerServiceParent();
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
void ActorDestroy(ActorDestroyReason aWhy) override;
virtual mozilla::ipc::IPCResult RecvFillHandlerInfo(
mozilla::ipc::IPCResult RecvFillHandlerInfo(
const HandlerInfo& aHandlerInfoData, const nsCString& aOverrideType,
HandlerInfo* handlerInfoData) override;
virtual mozilla::ipc::IPCResult RecvExists(const HandlerInfo& aHandlerInfo,
bool* exits) override;
virtual mozilla::ipc::IPCResult RecvGetTypeFromExtension(
mozilla::ipc::IPCResult RecvGetMIMEInfoFromOS(const nsCString& aMIMEType,
const nsCString& aExtension,
nsresult* aRv,
HandlerInfo* aHandlerInfoData,
bool* aFound) override;
mozilla::ipc::IPCResult RecvExists(const HandlerInfo& aHandlerInfo,
bool* exists) override;
mozilla::ipc::IPCResult RecvGetTypeFromExtension(
const nsCString& aFileExtension, nsCString* type) override;
virtual mozilla::ipc::IPCResult RecvExistsForProtocol(
mozilla::ipc::IPCResult RecvExistsForProtocolOS(
const nsCString& aProtocolScheme, bool* aHandlerExists) override;
mozilla::ipc::IPCResult RecvExistsForProtocol(
const nsCString& aProtocolScheme, bool* aHandlerExists) override;
mozilla::ipc::IPCResult RecvGetApplicationDescription(
const nsCString& aScheme, nsresult* aRv, nsString* aDescription) override;
};
#endif

Просмотреть файл

@ -31,12 +31,28 @@ parent:
sync FillHandlerInfo(HandlerInfo aHandlerInfoData,
nsCString aOverrideType)
returns (HandlerInfo handlerInfoData);
/*
* Check if an OS handler exists for the given protocol scheme.
*/
sync ExistsForProtocolOS(nsCString aProtocolScheme)
returns (bool exists);
/*
* Check if a handler exists for the given protocol scheme. Check
* the datastore first and then fallback to an OS handler check.
*/
sync ExistsForProtocol(nsCString aProtocolScheme)
returns (bool exists);
sync Exists(HandlerInfo aHandlerInfo)
returns (bool exists);
sync GetTypeFromExtension(nsCString aFileExtension)
returns (nsCString type);
sync GetMIMEInfoFromOS(nsCString aMIMEType, nsCString aExtension)
returns (nsresult rv, HandlerInfo handlerInfoData, bool found);
sync GetApplicationDescription(nsCString aScheme)
returns (nsresult rv, nsString description);
async __delete__();
};

Просмотреть файл

@ -11,8 +11,10 @@ nsOSHelperAppService::nsOSHelperAppService() : nsExternalHelperAppService() {}
nsOSHelperAppService::~nsOSHelperAppService() {}
already_AddRefed<nsIMIMEInfo> nsOSHelperAppService::GetMIMEInfoFromOS(
const nsACString& aMIMEType, const nsACString& aFileExt, bool* aFound) {
nsresult nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aMIMEType,
const nsACString& aFileExt,
bool* aFound,
nsIMIMEInfo** aMIMEInfo) {
RefPtr<nsMIMEInfoAndroid> mimeInfo;
*aFound = false;
if (!aMIMEType.IsEmpty())
@ -26,7 +28,8 @@ already_AddRefed<nsIMIMEInfo> nsOSHelperAppService::GetMIMEInfoFromOS(
// something for us, so we return the empty object.
if (!*aFound) mimeInfo = new nsMIMEInfoAndroid(aMIMEType);
return mimeInfo.forget();
mimeInfo.forget(aMIMEInfo);
return NS_OK;
}
nsresult nsOSHelperAppService::OSProtocolHandlerExists(const char* aScheme,

Просмотреть файл

@ -14,15 +14,16 @@ class nsOSHelperAppService : public nsExternalHelperAppService {
nsOSHelperAppService();
virtual ~nsOSHelperAppService();
virtual already_AddRefed<nsIMIMEInfo> GetMIMEInfoFromOS(
const nsACString& aMIMEType, const nsACString& aFileExt, bool* aFound);
nsresult GetMIMEInfoFromOS(const nsACString& aMIMEType,
const nsACString& aFileExt, bool* aFound,
nsIMIMEInfo** aMIMEInfo) override;
virtual MOZ_MUST_USE nsresult OSProtocolHandlerExists(const char* aScheme,
bool* aExists);
MOZ_MUST_USE nsresult OSProtocolHandlerExists(const char* aScheme,
bool* aExists) override;
NS_IMETHOD GetProtocolHandlerInfoFromOS(const nsACString& aScheme,
bool* found,
nsIHandlerInfo** _retval);
nsIHandlerInfo** _retval) override;
static nsIHandlerApp* CreateAndroidHandlerApp(
const nsAString& aName, const nsAString& aDescription,

Просмотреть файл

@ -26,29 +26,22 @@ class nsOSHelperAppService : public nsExternalHelperAppService {
NS_IMETHOD GetApplicationDescription(const nsACString& aScheme,
nsAString& _retval) override;
// method overrides --> used to hook the mime service into internet config....
NS_IMETHOD GetFromTypeAndExtension(const nsACString& aType,
const nsACString& aFileExt,
nsIMIMEInfo** aMIMEInfo) override;
already_AddRefed<nsIMIMEInfo> GetMIMEInfoFromOS(const nsACString& aMIMEType,
const nsACString& aFileExt,
bool* aFound) override;
nsresult GetMIMEInfoFromOS(const nsACString& aMIMEType,
const nsACString& aFileExt, bool* aFound,
nsIMIMEInfo** aMIMEInfo) override;
NS_IMETHOD GetProtocolHandlerInfoFromOS(const nsACString& aScheme,
bool* found,
nsIHandlerInfo** _retval) override;
// override so we can have a child process sandbox-friendly implementation
bool GetMIMETypeFromOSForExtension(const nsACString& aExtension,
nsACString& aMIMEType) override;
// GetFileTokenForPath must be implemented by each platform.
// platformAppPath --> a platform specific path to an application that we got
// out of the rdf data source. This can be a mac file
// spec, a unix path or a windows path depending on the
// platform
// aFile --> an nsIFile representation of that platform application path.
virtual MOZ_MUST_USE nsresult GetFileTokenForPath(
const char16_t* platformAppPath, nsIFile** aFile) override;
MOZ_MUST_USE nsresult GetFileTokenForPath(const char16_t* platformAppPath,
nsIFile** aFile) override;
MOZ_MUST_USE nsresult OSProtocolHandlerExists(const char* aScheme,
bool* aHandlerExists) override;

Просмотреть файл

@ -58,8 +58,8 @@ nsOSHelperAppService::~nsOSHelperAppService() {}
nsresult nsOSHelperAppService::OSProtocolHandlerExists(const char *aProtocolScheme,
bool *aHandlerExists) {
// CFStringCreateWithBytes() can fail even if we're not out of memory --
// for example if the 'bytes' parameter is something very wierd (like "ÿÿ~"
// aka "\xFF\xFF~"), or possibly if it can't be interpreted as using what's
// for example if the 'bytes' parameter is something very weird (like
// "\xFF\xFF~"), or possibly if it can't be interpreted as using what's
// specified in the 'encoding' parameter. See bug 548719.
CFStringRef schemeString =
::CFStringCreateWithBytes(kCFAllocatorDefault, (const UInt8 *)aProtocolScheme,
@ -197,12 +197,6 @@ nsresult nsOSHelperAppService::GetFileTokenForPath(const char16_t *aPlatformAppP
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
NS_IMETHODIMP nsOSHelperAppService::GetFromTypeAndExtension(const nsACString &aType,
const nsACString &aFileExt,
nsIMIMEInfo **aMIMEInfo) {
return nsExternalHelperAppService::GetFromTypeAndExtension(aType, aFileExt, aMIMEInfo);
}
// Returns the MIME types an application bundle explicitly claims to handle.
// Returns NULL if aAppRef doesn't explicitly claim to handle any MIME types.
// If the return value is non-NULL, the caller is responsible for freeing it.
@ -275,12 +269,11 @@ static CFArrayRef GetMIMETypesHandledByApp(FSRef *aAppRef) {
return mimeTypes;
}
// aMIMEType and aFileExt might not match, If they don't we set *aFound to
// false and return a minimal nsIMIMEInfo structure.
already_AddRefed<nsIMIMEInfo> nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString &aMIMEType,
const nsACString &aFileExt,
bool *aFound) {
nsresult nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString &aMIMEType,
const nsACString &aFileExt, bool *aFound,
nsIMIMEInfo **aMIMEInfo) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSNULL;
MOZ_ASSERT(XRE_IsParentProcess());
*aFound = false;
@ -310,8 +303,8 @@ already_AddRefed<nsIMIMEInfo> nsOSHelperAppService::GetMIMEInfoFromOS(const nsAC
typeIsOctetStream = aMIMEType.LowerCaseEqualsLiteral(APPLICATION_OCTET_STREAM);
CFURLRef appURL = NULL;
// CFStringCreateWithCString() can fail even if we're not out of memory --
// for example if the 'cStr' parameter is something very weird (like "ÿÿ~"
// aka "\xFF\xFF~"), or possibly if it can't be interpreted as using what's
// for example if the 'cStr' parameter is something very weird (like
// "\xFF\xFF~"), or possibly if it can't be interpreted as using what's
// specified in the 'encoding' parameter. See bug 548719.
cfMIMEType = ::CFStringCreateWithCString(NULL, flatType.get(), kCFStringEncodingUTF8);
if (cfMIMEType) {
@ -328,8 +321,8 @@ already_AddRefed<nsIMIMEInfo> nsOSHelperAppService::GetMIMEInfoFromOS(const nsAC
}
if (!aFileExt.IsEmpty()) {
// CFStringCreateWithCString() can fail even if we're not out of memory --
// for example if the 'cStr' parameter is something very wierd (like "ÿÿ~"
// aka "\xFF\xFF~"), or possibly if it can't be interpreted as using what's
// for example if the 'cStr' parameter is something very weird (like
// "\xFF\xFF~"), or possibly if it can't be interpreted as using what's
// specified in the 'encoding' parameter. See bug 548719.
CFStringRef cfExt = ::CFStringCreateWithCString(NULL, flatExt.get(), kCFStringEncodingUTF8);
if (cfExt) {
@ -445,10 +438,11 @@ already_AddRefed<nsIMIMEInfo> nsOSHelperAppService::GetMIMEInfoFromOS(const nsAC
if (typeAppIsDefault || extAppIsDefault) {
if (haveAppForExt) mimeInfoMac->AppendExtension(aFileExt);
nsCOMPtr<nsILocalFileMac> app(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
if (!app) {
nsresult rv;
nsCOMPtr<nsILocalFileMac> app(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv));
if (NS_FAILED(rv)) {
[localPool release];
return nullptr;
return rv;
}
CFStringRef cfAppName = NULL;
@ -516,9 +510,10 @@ already_AddRefed<nsIMIMEInfo> nsOSHelperAppService::GetMIMEInfoFromOS(const nsAC
MOZ_LOG(mLog, LogLevel::Debug, ("OS gave us: type '%s' found '%i'\n", mimeType.get(), *aFound));
[localPool release];
return mimeInfoMac.forget();
mimeInfoMac.forget(aMIMEInfo);
return NS_OK;
NS_OBJC_END_TRY_ABORT_BLOCK_NSNULL;
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
NS_IMETHODIMP
@ -550,31 +545,3 @@ nsOSHelperAppService::GetProtocolHandlerInfoFromOS(const nsACString &aScheme, bo
return NS_OK;
}
/*
* Override GetMIMETypeFromOSForExtension() so that we can proxy requests for
* the MIME type to the parent when we're executing in the child process. If
* we're in the parent process, query the OS directly.
*/
bool nsOSHelperAppService::GetMIMETypeFromOSForExtension(const nsACString &aExtension,
nsACString &aMIMEType) {
if (XRE_IsParentProcess()) {
return nsExternalHelperAppService::GetMIMETypeFromOSForExtension(aExtension, aMIMEType);
}
nsCOMPtr<nsIHandlerService> handlerSvc = do_GetService(NS_HANDLERSERVICE_CONTRACTID);
if (NS_WARN_IF(!handlerSvc)) {
return false;
}
nsresult rv = handlerSvc->GetTypeFromExtension(aExtension, aMIMEType);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
if (aMIMEType.IsEmpty()) {
return false;
}
return true;
}

Просмотреть файл

@ -36,6 +36,8 @@ EXPORTS += [
EXPORTS += [
'ContentHandlerService.h',
'nsExternalHelperAppService.h',
'nsMIMEInfoChild.h',
'nsOSHelperAppServiceChild.h',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
@ -61,6 +63,7 @@ UNIFIED_SOURCES += [
'nsExternalProtocolHandler.cpp',
'nsLocalHandlerApp.cpp',
'nsMIMEInfoImpl.cpp',
'nsOSHelperAppServiceChild.cpp',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':

Просмотреть файл

@ -43,6 +43,8 @@
#include "nsAutoPtr.h"
#include "nsIMutableArray.h"
#include "nsIRedirectHistoryEntry.h"
#include "nsOSHelperAppService.h"
#include "nsOSHelperAppServiceChild.h"
// used to access our datastore of user-configured helper applications
#include "nsIHandlerService.h"
@ -105,6 +107,7 @@
# include "FennecJNIWrappers.h"
#endif
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/Preferences.h"
#include "mozilla/ipc/URIUtils.h"
@ -573,6 +576,32 @@ static const nsDefaultMimeTypeEntry nonDecodableExtensions[] = {
{APPLICATION_COMPRESS, "z"},
{APPLICATION_GZIP, "svgz"}};
static StaticRefPtr<nsExternalHelperAppService> sExtHelperAppSvcSingleton;
/**
* On Mac child processes, return an nsOSHelperAppServiceChild for remoting
* OS calls to the parent process. On all other platforms use
* nsOSHelperAppService.
*/
/* static */
already_AddRefed<nsExternalHelperAppService>
nsExternalHelperAppService::GetSingleton() {
if (!sExtHelperAppSvcSingleton) {
#ifdef XP_MACOSX
if (XRE_IsParentProcess()) {
sExtHelperAppSvcSingleton = new nsOSHelperAppService();
} else {
sExtHelperAppSvcSingleton = new nsOSHelperAppServiceChild();
}
#else
sExtHelperAppSvcSingleton = new nsOSHelperAppService();
#endif /* XP_MACOSX */
ClearOnShutdown(&sExtHelperAppSvcSingleton);
}
return do_AddRef(sExtHelperAppSvcSingleton);
}
NS_IMPL_ISUPPORTS(nsExternalHelperAppService, nsIExternalHelperAppService,
nsPIExternalAppLauncher, nsIExternalProtocolService,
nsIMIMEService, nsIObserver, nsISupportsWeakReference)
@ -2483,7 +2512,11 @@ NS_IMETHODIMP nsExternalHelperAppService::GetFromTypeAndExtension(
// (1) Ask the OS for a mime info
bool found;
*_retval = GetMIMEInfoFromOS(typeToUse, aFileExt, &found).take();
nsresult rv = GetMIMEInfoFromOS(typeToUse, aFileExt, &found, _retval);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
LOG(("OS gave back 0x%p - found: %i\n", *_retval, found));
// If we got no mimeinfo, something went wrong. Probably lack of memory.
if (!*_retval) return NS_ERROR_OUT_OF_MEMORY;
@ -2491,7 +2524,6 @@ NS_IMETHODIMP nsExternalHelperAppService::GetFromTypeAndExtension(
// (2) Now, let's see if we can find something in our datastore
// This will not overwrite the OS information that interests us
// (i.e. default application, default app. description)
nsresult rv;
nsCOMPtr<nsIHandlerService> handlerSvc =
do_GetService(NS_HANDLERSERVICE_CONTRACTID);
if (handlerSvc) {
@ -2796,7 +2828,17 @@ bool nsExternalHelperAppService::GetTypeFromExtras(const nsACString& aExtension,
bool nsExternalHelperAppService::GetMIMETypeFromOSForExtension(
const nsACString& aExtension, nsACString& aMIMEType) {
bool found = false;
nsCOMPtr<nsIMIMEInfo> mimeInfo =
GetMIMEInfoFromOS(EmptyCString(), aExtension, &found);
return found && mimeInfo && NS_SUCCEEDED(mimeInfo->GetMIMEType(aMIMEType));
nsCOMPtr<nsIMIMEInfo> mimeInfo;
nsresult rv = GetMIMEInfoFromOS(EmptyCString(), aExtension, &found,
getter_AddRefs(mimeInfo));
return NS_SUCCEEDED(rv) && found && mimeInfo &&
NS_SUCCEEDED(mimeInfo->GetMIMEType(aMIMEType));
}
nsresult nsExternalHelperAppService::GetMIMEInfoFromOS(
const nsACString& aMIMEType, const nsACString& aFileExt, bool* aFound,
nsIMIMEInfo** aMIMEInfo) {
*aMIMEInfo = nullptr;
*aFound = false;
return NS_ERROR_NOT_IMPLEMENTED;
}

Просмотреть файл

@ -67,25 +67,6 @@ class nsExternalHelperAppService : public nsIExternalHelperAppService,
*/
MOZ_MUST_USE nsresult Init();
/**
* Given a mimetype and an extension, looks up a mime info from the OS.
* The mime type is given preference. This function follows the same rules
* as nsIMIMEService::GetFromTypeAndExtension.
* This is supposed to be overridden by the platform-specific
* nsOSHelperAppService!
* @param aFileExt The file extension; may be empty. UTF-8 encoded.
* @param [out] aFound
* Should be set to true if the os has a mapping, to
* false otherwise. Must not be null.
* @return A MIMEInfo. This function must return a MIMEInfo object if it
* can allocate one. The only justifiable reason for not
* returning one is an out-of-memory error.
* If null, the value of aFound is unspecified.
*/
virtual already_AddRefed<nsIMIMEInfo> GetMIMEInfoFromOS(
const nsACString& aMIMEType, const nsACString& aFileExt,
bool* aFound) = 0;
/**
* Given a string identifying an application, create an nsIFile representing
* it. This function should look in $PATH for the application.
@ -103,8 +84,7 @@ class nsExternalHelperAppService : public nsIExternalHelperAppService,
virtual nsresult GetFileTokenForPath(const char16_t* platformAppPath,
nsIFile** aFile);
virtual nsresult OSProtocolHandlerExists(const char* aScheme,
bool* aExists) = 0;
NS_IMETHOD OSProtocolHandlerExists(const char* aScheme, bool* aExists) = 0;
/**
* Given an extension, get a MIME type string. If not overridden by
@ -115,6 +95,8 @@ class nsExternalHelperAppService : public nsIExternalHelperAppService,
virtual bool GetMIMETypeFromOSForExtension(const nsACString& aExtension,
nsACString& aMIMEType);
static already_AddRefed<nsExternalHelperAppService> GetSingleton();
protected:
virtual ~nsExternalHelperAppService();

Просмотреть файл

@ -129,5 +129,34 @@ interface nsIHandlerService : nsISupports
*
* @returns whether or not a handler exists
*/
boolean existsForProtocolOS(in ACString aProtocolScheme);
/**
* Whether or not there is a handler in the datastore or OS for
* the specified protocol type. If there is no handler in the datastore,
* falls back to a check for an OS handler.
*
* @param aProtocolScheme scheme to check for support
*
* @returns whether or not a handler exists
*/
boolean existsForProtocol(in ACString aProtocolScheme);
/*
* Fill in a handler info object using information from the OS, taking into
* account the MIME type and file extension. When the OS handler
* for the MIME type and extension match, |aFound| is returned as true. If
* either the MIME type or extension is the empty string and a handler is
* found, |aFound| is returned as true.
*/
void getMIMEInfoFromOS(in nsIHandlerInfo aHandlerInfo,
in ACString aMIMEType,
in ACString aExtension,
out bool aFound);
/*
* Get a description for the application responsible for handling
* the provided protocol.
*/
AString getApplicationDescription(in ACString aProtocolScheme);
};

Просмотреть файл

@ -0,0 +1,49 @@
/* 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/. */
#ifndef nsMIMEInfoChild_h
#define nsMIMEInfoChild_h
#include "nsMIMEInfoImpl.h"
/*
* A platform-generic nsMIMEInfo implementation to be used in child process
* generic code that needs a MIMEInfo with limited functionality.
*/
class nsChildProcessMIMEInfo : public nsMIMEInfoImpl {
public:
explicit nsChildProcessMIMEInfo(const char* aMIMEType = "")
: nsMIMEInfoImpl(aMIMEType) {}
explicit nsChildProcessMIMEInfo(const nsACString& aMIMEType)
: nsMIMEInfoImpl(aMIMEType) {}
nsChildProcessMIMEInfo(const nsACString& aType, HandlerClass aClass)
: nsMIMEInfoImpl(aType, aClass) {}
NS_IMETHOD LaunchWithFile(nsIFile* aFile) override {
return NS_ERROR_NOT_IMPLEMENTED;
};
protected:
virtual MOZ_MUST_USE nsresult LoadUriInternal(nsIURI* aURI) override {
return NS_ERROR_NOT_IMPLEMENTED;
};
#ifdef DEBUG
virtual MOZ_MUST_USE nsresult LaunchDefaultWithFile(nsIFile* aFile) override {
return NS_ERROR_UNEXPECTED;
}
#endif
static MOZ_MUST_USE nsresult OpenApplicationWithURI(nsIFile* aApplication,
const nsCString& aURI) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHOD GetDefaultDescription(nsAString& aDefaultDescription) override {
return NS_ERROR_NOT_IMPLEMENTED;
};
};
#endif

Просмотреть файл

@ -0,0 +1,149 @@
/* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 <sys/types.h>
#include <sys/stat.h>
#include "mozilla/Logging.h"
#include "mozilla/net/NeckoCommon.h"
#include "nsOSHelperAppServiceChild.h"
#include "nsMIMEInfoChild.h"
#include "nsISupports.h"
#include "nsString.h"
#include "nsTArray.h"
#include "nsIURL.h"
#include "nsIFile.h"
#include "nsIHandlerService.h"
#include "nsMimeTypes.h"
#include "nsMIMEInfoImpl.h"
#include "nsIStringBundle.h"
#include "nsIPromptService.h"
#include "nsMemory.h"
#include "nsCRT.h"
#include "nsEmbedCID.h"
#undef LOG
#define LOG(args) \
MOZ_LOG(nsExternalHelperAppService::mLog, mozilla::LogLevel::Info, args)
#undef LOG_ERR
#define LOG_ERR(args) \
MOZ_LOG(nsExternalHelperAppService::mLog, mozilla::LogLevel::Error, args)
#undef LOG_ENABLED
#define LOG_ENABLED() \
MOZ_LOG_TEST(nsExternalHelperAppService::mLog, mozilla::LogLevel::Info)
nsresult nsOSHelperAppServiceChild::ExternalProtocolHandlerExists(
const char* aProtocolScheme, bool* aHandlerExists) {
nsresult rv;
nsCOMPtr<nsIHandlerService> handlerSvc =
do_GetService(NS_HANDLERSERVICE_CONTRACTID, &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
LOG_ERR(("nsOSHelperAppServiceChild error: no handler service"));
return rv;
}
nsAutoCString scheme(aProtocolScheme);
*aHandlerExists = false;
rv = handlerSvc->ExistsForProtocol(scheme, aHandlerExists);
LOG(
("nsOSHelperAppServiceChild::OSProtocolHandlerExists(): "
"protocol: %s, result: %" PRId32,
aProtocolScheme, static_cast<uint32_t>(rv)));
mozilla::Unused << NS_WARN_IF(NS_FAILED(rv));
return rv;
}
nsresult nsOSHelperAppServiceChild::OSProtocolHandlerExists(const char* aScheme,
bool* aExists) {
// Use ExternalProtocolHandlerExists() which includes the
// OS-level check and remotes the call to the parent process.
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsOSHelperAppServiceChild::GetApplicationDescription(const nsACString& aScheme,
nsAString& aRetVal) {
nsresult rv;
nsCOMPtr<nsIHandlerService> handlerSvc =
do_GetService(NS_HANDLERSERVICE_CONTRACTID, &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
LOG_ERR(("nsOSHelperAppServiceChild error: no handler service"));
return rv;
}
rv = handlerSvc->GetApplicationDescription(aScheme, aRetVal);
LOG(
("nsOSHelperAppServiceChild::GetApplicationDescription(): "
"scheme: %s, result: %" PRId32 ", description: %s",
PromiseFlatCString(aScheme).get(), static_cast<uint32_t>(rv),
NS_ConvertUTF16toUTF8(aRetVal).get()));
mozilla::Unused << NS_WARN_IF(NS_FAILED(rv));
return rv;
}
NS_IMETHODIMP
nsOSHelperAppServiceChild::GetMIMEInfoFromOS(const nsACString& aMIMEType,
const nsACString& aFileExt,
bool* aFound,
nsIMIMEInfo** aMIMEInfo) {
RefPtr<nsChildProcessMIMEInfo> mimeInfo =
new nsChildProcessMIMEInfo(aMIMEType);
nsCOMPtr<nsIHandlerService> handlerSvc =
do_GetService(NS_HANDLERSERVICE_CONTRACTID);
if (handlerSvc) {
nsresult rv =
handlerSvc->GetMIMEInfoFromOS(mimeInfo, aMIMEType, aFileExt, aFound);
LOG(
("nsOSHelperAppServiceChild::GetMIMEInfoFromOS(): "
"MIME type: %s, extension: %s, result: %" PRId32,
PromiseFlatCString(aMIMEType).get(),
PromiseFlatCString(aFileExt).get(), static_cast<uint32_t>(rv)));
mozilla::Unused << NS_WARN_IF(NS_FAILED(rv));
if (NS_FAILED(rv)) {
return rv;
}
} else {
LOG_ERR(("nsOSHelperAppServiceChild error: no handler service"));
*aFound = false;
}
mimeInfo.forget(aMIMEInfo);
return NS_OK;
}
NS_IMETHODIMP
nsOSHelperAppServiceChild::GetProtocolHandlerInfoFromOS(
const nsACString& aScheme, bool* aFound, nsIHandlerInfo** aRetVal) {
MOZ_ASSERT(!aScheme.IsEmpty(), "No scheme was specified!");
nsresult rv =
OSProtocolHandlerExists(PromiseFlatCString(aScheme).get(), aFound);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsChildProcessMIMEInfo* handlerInfo =
new nsChildProcessMIMEInfo(aScheme, nsMIMEInfoBase::eProtocolInfo);
NS_ENSURE_TRUE(handlerInfo, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(*aRetVal = handlerInfo);
if (!*aFound) {
// Code that calls this requires an object no matter whether the OS has
// something for us, so we return the empty object.
return NS_OK;
}
nsAutoString description;
rv = GetApplicationDescription(aScheme, description);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "GetApplicationDescription failed");
handlerInfo->SetDefaultDescription(description);
return NS_OK;
}
nsresult nsOSHelperAppServiceChild::GetFileTokenForPath(
const char16_t* platformAppPath, nsIFile** aFile) {
return NS_ERROR_NOT_IMPLEMENTED;
}

Просмотреть файл

@ -0,0 +1,46 @@
/* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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/. */
#ifndef nsOSHelperAppServiceChild_h__
#define nsOSHelperAppServiceChild_h__
#include "nsExternalHelperAppService.h"
class nsIMIMEInfo;
/*
* Provides a generic implementation of the nsExternalHelperAppService
* platform-specific methods by remoting calls to the parent process.
* Only provides implementations for the methods needed in unprivileged
* child processes.
*/
class nsOSHelperAppServiceChild : public nsExternalHelperAppService {
public:
nsOSHelperAppServiceChild() : nsExternalHelperAppService(){};
virtual ~nsOSHelperAppServiceChild() = default;
NS_IMETHOD GetProtocolHandlerInfoFromOS(const nsACString& aScheme,
bool* found,
nsIHandlerInfo** _retval) override;
nsresult GetFileTokenForPath(const char16_t* platformAppPath,
nsIFile** aFile) override;
NS_IMETHOD ExternalProtocolHandlerExists(const char* aProtocolScheme,
bool* aHandlerExists) override;
NS_IMETHOD OSProtocolHandlerExists(const char* aScheme,
bool* aExists) override;
NS_IMETHOD GetApplicationDescription(const nsACString& aScheme,
nsAString& aRetVal) override;
NS_IMETHOD GetMIMEInfoFromOS(const nsACString& aMIMEType,
const nsACString& aFileExt, bool* aFound,
nsIMIMEInfo** aMIMEInfo) override;
};
#endif // nsOSHelperAppServiceChild_h__

Просмотреть файл

@ -29,9 +29,9 @@ class nsOSHelperAppService final : public nsExternalHelperAppService {
NS_IMETHOD GetFromTypeAndExtension(const nsACString& aType,
const nsACString& aFileExt,
nsIMIMEInfo** aMIMEInfo);
already_AddRefed<nsIMIMEInfo> GetMIMEInfoFromOS(const nsACString& aMIMEType,
const nsACString& aFileExt,
bool* aFound);
NS_IMETHOD GetMIMEInfoFromOS(const nsACString& aMIMEType,
const nsACString& aFileExt, bool* aFound,
nsIMIMEInfo** aMIMEInfo) override;
NS_IMETHOD GetProtocolHandlerInfoFromOS(const nsACString& aScheme,
bool* found,
nsIHandlerInfo** _retval);
@ -45,7 +45,8 @@ class nsOSHelperAppService final : public nsExternalHelperAppService {
virtual nsresult GetFileTokenForPath(const char16_t* platformAppPath,
nsIFile** aFile);
nsresult OSProtocolHandlerExists(const char* aScheme, bool* aHandlerExists);
nsresult OSProtocolHandlerExists(const char* aScheme,
bool* aHandlerExists) override;
};
#endif // nsOSHelperAppService_h__

Просмотреть файл

@ -32,15 +32,16 @@ nsOSHelperAppService::GetFromTypeAndExtension(const nsACString& aType, const nsA
return nsExternalHelperAppService::GetFromTypeAndExtension(aType, aFileExt, aMIMEInfo);
}
already_AddRefed<nsIMIMEInfo> nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aMIMEType,
const nsACString& aFileExt,
bool* aFound) {
NS_IMETHODIMP nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aMIMEType,
const nsACString& aFileExt, bool* aFound,
nsIMIMEInfo** aMIMEInfo) {
*aMIMEInfo = nullptr;
*aFound = false;
return nullptr;
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsOSHelperAppService::GetProtocolHandlerInfoFromOS(const nsACString& aScheme, bool* found,
nsOSHelperAppService::GetProtocolHandlerInfoFromOS(const char* aScheme, bool* found,
nsIHandlerInfo** _retval) {
*found = false;
return NS_OK;

Просмотреть файл

@ -1039,8 +1039,8 @@ nsresult nsOSHelperAppService::OSProtocolHandlerExists(
nsCOMPtr<nsIHandlerService> handlerSvc =
do_GetService(NS_HANDLERSERVICE_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv) && handlerSvc) {
rv = handlerSvc->ExistsForProtocol(nsCString(aProtocolScheme),
aHandlerExists);
rv = handlerSvc->ExistsForProtocolOS(nsCString(aProtocolScheme),
aHandlerExists);
}
}
@ -1324,8 +1324,10 @@ already_AddRefed<nsMIMEInfoBase> nsOSHelperAppService::GetFromType(
return mimeInfo.forget();
}
already_AddRefed<nsIMIMEInfo> nsOSHelperAppService::GetMIMEInfoFromOS(
const nsACString& aType, const nsACString& aFileExt, bool* aFound) {
nsresult nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aType,
const nsACString& aFileExt,
bool* aFound,
nsIMIMEInfo** aMIMEInfo) {
*aFound = true;
RefPtr<nsMIMEInfoBase> retval;
// Fallback to lookup by extension when generic 'application/octet-stream'
@ -1339,14 +1341,18 @@ already_AddRefed<nsIMIMEInfo> nsOSHelperAppService::GetMIMEInfoFromOS(
RefPtr<nsMIMEInfoBase> miByExt =
GetFromExtension(PromiseFlatCString(aFileExt));
// If we had no extension match, but a type match, use that
if (!miByExt && retval) return retval.forget();
if (!miByExt && retval) {
retval.forget(aMIMEInfo);
return NS_OK;
}
// If we had an extension match but no type match, set the mimetype and use
// it
if (!retval && miByExt) {
if (!aType.IsEmpty()) miByExt->SetMIMEType(aType);
miByExt.swap(retval);
return retval.forget();
retval.forget(aMIMEInfo);
return NS_OK;
}
// If we got nothing, make a new mimeinfo
if (!retval) {
@ -1356,7 +1362,8 @@ already_AddRefed<nsIMIMEInfo> nsOSHelperAppService::GetMIMEInfoFromOS(
if (!aFileExt.IsEmpty()) retval->AppendExtension(aFileExt);
}
return retval.forget();
retval.forget(aMIMEInfo);
return NS_OK;
}
// Copy the attributes of retval (mimeinfo from type) onto miByExt, to
@ -1369,7 +1376,8 @@ already_AddRefed<nsIMIMEInfo> nsOSHelperAppService::GetMIMEInfoFromOS(
miByExt.swap(retval);
}
return retval.forget();
retval.forget(aMIMEInfo);
return NS_OK;
}
NS_IMETHODIMP

Просмотреть файл

@ -24,9 +24,9 @@ class nsOSHelperAppService : public nsExternalHelperAppService {
virtual ~nsOSHelperAppService();
// method overrides for mime.types and mime.info look up steps
already_AddRefed<nsIMIMEInfo> GetMIMEInfoFromOS(const nsACString& aMimeType,
const nsACString& aFileExt,
bool* aFound) override;
NS_IMETHOD GetMIMEInfoFromOS(const nsACString& aMimeType,
const nsACString& aFileExt, bool* aFound,
nsIMIMEInfo** aMIMEInfo) override;
NS_IMETHOD GetProtocolHandlerInfoFromOS(const nsACString& aScheme,
bool* found,
nsIHandlerInfo** _retval) override;

Просмотреть файл

@ -376,8 +376,10 @@ already_AddRefed<nsMIMEInfoWin> nsOSHelperAppService::GetByExtension(
return mimeInfo.forget();
}
already_AddRefed<nsIMIMEInfo> nsOSHelperAppService::GetMIMEInfoFromOS(
const nsACString& aMIMEType, const nsACString& aFileExt, bool* aFound) {
NS_IMETHODIMP
nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aMIMEType,
const nsACString& aFileExt,
bool* aFound, nsIMIMEInfo** aMIMEInfo) {
*aFound = true;
const nsCString& flatType = PromiseFlatCString(aMIMEType);
@ -430,9 +432,13 @@ already_AddRefed<nsIMIMEInfo> nsOSHelperAppService::GetMIMEInfoFromOS(
RefPtr<nsMIMEInfoWin> miByExt =
GetByExtension(NS_ConvertUTF8toUTF16(aFileExt), flatType.get());
LOG(("Ext. lookup for '%s' found 0x%p\n", flatExt.get(), miByExt.get()));
if (!miByExt && mi) return mi.forget();
if (!miByExt && mi) {
mi.forget(aMIMEInfo);
return NS_OK;
}
if (miByExt && !mi) {
return miByExt.forget();
miByExt.forget(aMIMEInfo);
return NS_OK;
}
if (!miByExt && !mi) {
*aFound = false;
@ -441,7 +447,8 @@ already_AddRefed<nsIMIMEInfo> nsOSHelperAppService::GetMIMEInfoFromOS(
mi->AppendExtension(aFileExt);
}
return mi.forget();
mi.forget(aMIMEInfo);
return NS_OK;
}
// if we get here, mi has no default app. copy from extension lookup.
@ -451,7 +458,8 @@ already_AddRefed<nsIMIMEInfo> nsOSHelperAppService::GetMIMEInfoFromOS(
mi->SetDefaultDescription(desc);
}
return mi.forget();
mi.forget(aMIMEInfo);
return NS_OK;
}
NS_IMETHODIMP

Просмотреть файл

@ -31,16 +31,16 @@ class nsOSHelperAppService : public nsExternalHelperAppService {
virtual ~nsOSHelperAppService();
// override nsIExternalProtocolService methods
nsresult OSProtocolHandlerExists(const char* aProtocolScheme,
bool* aHandlerExists);
NS_IMETHOD OSProtocolHandlerExists(const char* aProtocolScheme,
bool* aHandlerExists) override;
nsresult LoadUriInternal(nsIURI* aURL);
NS_IMETHOD GetApplicationDescription(const nsACString& aScheme,
nsAString& _retval) override;
// method overrides for windows registry look up steps....
already_AddRefed<nsIMIMEInfo> GetMIMEInfoFromOS(const nsACString& aMIMEType,
const nsACString& aFileExt,
bool* aFound);
NS_IMETHOD GetMIMEInfoFromOS(const nsACString& aMIMEType,
const nsACString& aFileExt, bool* aFound,
nsIMIMEInfo** aMIMEInfo) override;
NS_IMETHOD GetProtocolHandlerInfoFromOS(const nsACString& aScheme,
bool* found,
nsIHandlerInfo** _retval);