Bug 389969 - There is no protocol handling dialog. r=cbiesinger, sr=dmose, a=schrep
--- a/netwerk/mime/public/nsIMIMEInfo.idl
+++ b/netwerk/mime/public/nsIMIMEInfo.idl
@@ -100,16 +100,20 @@ interface nsIHandlerInfo : nsISupports {
* preferredAction is how the user specified they would like to handle
* this content type: save to disk, use specified helper app, use OS
* default handler or handle using navigator; possible value constants
* listed below
*/
attribute nsHandlerInfoAction preferredAction;
const long saveToDisk = 0;
+ /**
+ * Used to indicate that we know nothing about what to do with this. You
+ * could consider this to be not initialized.
+ */
const long alwaysAsk = 1;
const long useHelperApp = 2;
const long handleInternally = 3;
const long useSystemDefault = 4;
/**
* alwaysAskBeforeHandling: if true, we should always give the user a
* dialog asking how to dispose of this content.
--- a/uriloader/exthandler/beos/nsOSHelperAppService.cpp
+++ b/uriloader/exthandler/beos/nsOSHelperAppService.cpp
@@ -228,30 +228,36 @@ nsOSHelperAppService::GetMIMEInfoFromOS(
NS_ADDREF(mi);
if (!aFileExt.IsEmpty())
mi->AppendExtension(aFileExt);
return mi;
}
already_AddRefed<nsIHandlerInfo>
-nsOSHelperAppService::GetProtocolInfoFromOS(const nsACString &aScheme)
+nsOSHelperAppService::GetProtocolInfoFromOS(const nsACString &aScheme,
+ PRBool *found)
{
NS_ASSERTION(!aScheme.IsEmpty(), "No scheme was specified!");
- PRBool exists;
nsresult rv = OSProtocolHandlerExists(nsPromiseFlatCString(aScheme).get(),
- &exists);
- if (NS_FAILED(rv) || !exists)
+ found);
+ if (NS_FAILED(rv))
return nsnull;
nsMIMEInfoBeOS *handlerInfo =
new nsMIMEInfoBeOS(aScheme, nsMIMEInfoBase::eProtocolInfo);
NS_ENSURE_TRUE(handlerInfo, nsnull);
NS_ADDREF(handlerInfo);
+ if (!*found) {
+ // Code that calls this requires an object regardless if the OS has
+ // something for us, so we return the empty object.
+ return handlerInfo;
+ }
+
nsAutoString desc;
GetApplicationDescription(aScheme, desc);
handlerInfo->SetDefaultDescription(desc);
return handlerInfo;
}
--- a/uriloader/exthandler/beos/nsOSHelperAppService.h
+++ b/uriloader/exthandler/beos/nsOSHelperAppService.h
@@ -49,17 +49,18 @@ class nsMIMEInfoBeOS;
class nsOSHelperAppService : public nsExternalHelperAppService
{
public:
nsOSHelperAppService();
virtual ~nsOSHelperAppService();
already_AddRefed<nsIMIMEInfo> GetMIMEInfoFromOS(const nsACString& aMIMEType, const nsACString& aFileExt, PRBool *aFound);
- already_AddRefed<nsIHandlerInfo> GetProtocolInfoFromOS(const nsACString &aScheme);
+ already_AddRefed<nsIHandlerInfo> GetProtocolInfoFromOS(const nsACString &aScheme,
+ PRBool *found);
// override nsIExternalProtocolService methods
nsresult OSProtocolHandlerExists(const char * aProtocolScheme, PRBool * aHandlerExists);
protected:
nsresult SetMIMEInfoForType(const char *aMIMEType, nsMIMEInfoBeOS **_retval);
nsresult GetMimeInfoFromExtension(const char *aFileExt, nsMIMEInfoBeOS **_retval);
nsresult GetMimeInfoFromMIMEType(const char *aMIMEType, nsMIMEInfoBeOS **_retval);
--- a/uriloader/exthandler/mac/nsOSHelperAppService.cpp
+++ b/uriloader/exthandler/mac/nsOSHelperAppService.cpp
@@ -311,31 +311,37 @@ nsOSHelperAppService::GetMIMEInfoFromOS(
if (!aFileExt.IsEmpty())
mimeInfo->AppendExtension(aFileExt);
}
return mimeInfo;
}
already_AddRefed<nsIHandlerInfo>
-nsOSHelperAppService::GetProtocolInfoFromOS(const nsACString &aScheme)
+nsOSHelperAppService::GetProtocolInfoFromOS(const nsACString &aScheme,
+ PRBool *found)
{
NS_ASSERTION(!aScheme.IsEmpty(), "No scheme was specified!");
- PRBool exists;
nsresult rv = OSProtocolHandlerExists(nsPromiseFlatCString(aScheme).get(),
- &exists);
- if (NS_FAILED(rv) || !exists)
+ found);
+ if (NS_FAILED(rv))
return nsnull;
nsMIMEInfoMac *handlerInfo =
new nsMIMEInfoMac(aScheme, nsMIMEInfoBase::eProtocolInfo);
NS_ENSURE_TRUE(handlerInfo, nsnull);
NS_ADDREF(handlerInfo);
+ if (!*found) {
+ // Code that calls this requires an object regardless if the OS has
+ // something for us, so we return the empty object.
+ return handlerInfo;
+ }
+
nsAutoString desc;
GetApplicationDescription(aScheme, desc);
handlerInfo->SetDefaultDescription(desc);
return handlerInfo;
}
// we never want to use a hard coded value for the creator and file type for the mac. always look these values up
--- a/uriloader/exthandler/mac/nsOSHelperAppService.h
+++ b/uriloader/exthandler/mac/nsOSHelperAppService.h
@@ -56,17 +56,18 @@ public:
virtual ~nsOSHelperAppService();
// override nsIExternalProtocolService methods
NS_IMETHOD GetApplicationDescription(const nsACString& aScheme, nsAString& _retval);
// method overrides --> used to hook the mime service into internet config....
NS_IMETHOD GetFromTypeAndExtension(const nsACString& aType, const nsACString& aFileExt, nsIMIMEInfo ** aMIMEInfo);
already_AddRefed<nsIMIMEInfo> GetMIMEInfoFromOS(const nsACString& aMIMEType, const nsACString& aFileExt, PRBool * aFound);
- already_AddRefed<nsIHandlerInfo> GetProtocolInfoFromOS(const nsACString &aScheme);
+ already_AddRefed<nsIHandlerInfo> GetProtocolInfoFromOS(const nsACString &aScheme,
+ PRBool *found);
// 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 nsresult GetFileTokenForPath(const PRUnichar * platformAppPath, nsIFile ** aFile);
nsresult OSProtocolHandlerExists(const char * aScheme,
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -1332,31 +1332,37 @@ nsExternalHelperAppService::GetProtocolH
// XXX enterprise customers should be able to turn this support off with a
// single master pref (maybe use one of the "exposed" prefs here?)
// nsIMIMEInfo is a superset of nsIHandlerInfo. Furthermore, nsMimeInfoImpl
// and subclasses have lots of good platform specific-knowledge of local
// applications which we might need later. For now, just use nsMIMEInfoImpl
// instead of implementating a separate nsIHandlerInfo object.
- *aHandlerInfo = GetProtocolInfoFromOS(aScheme).get();
+ PRBool exists;
+ *aHandlerInfo = GetProtocolInfoFromOS(aScheme, &exists).get();
if (!(*aHandlerInfo)) {
// Either it knows nothing, or we ran out of memory
return NS_ERROR_FAILURE;
}
nsresult rv = FillProtoInfoForSchemeFromDS(aScheme, *aHandlerInfo);
if (NS_ERROR_NOT_AVAILABLE == rv) {
// We don't know it, so we always ask the user. By the time we call this
// method, we already have checked if we should open this protocol and ask
// the user, so these defaults are OK.
// XXX this is a bit different than the MIME system, so we may want to look
// into this more in the future.
- (*aHandlerInfo)->SetPreferredAction(nsIHandlerInfo::useSystemDefault);
(*aHandlerInfo)->SetAlwaysAskBeforeHandling(PR_TRUE);
+ // If no OS default existed, we set the preferred action to alwaysAsk. This
+ // really means not initialized to all the code...
+ if (exists)
+ (*aHandlerInfo)->SetPreferredAction(nsIHandlerInfo::useSystemDefault);
+ else
+ (*aHandlerInfo)->SetPreferredAction(nsIHandlerInfo::alwaysAsk);
} else if (NS_FAILED(rv)) {
NS_RELEASE(*aHandlerInfo);
return rv;
}
return NS_OK;
}
--- a/uriloader/exthandler/nsExternalHelperAppService.h
+++ b/uriloader/exthandler/nsExternalHelperAppService.h
@@ -199,17 +199,18 @@ public:
/**
* Given a scheme, looks up the protocol info from the OS. This should be
* overridden by each OS's implementation.
*
* @param aScheme The protocol scheme we are looking for.
* @return An nsIHanderInfo for the protocol.
*/
- virtual already_AddRefed<nsIHandlerInfo> GetProtocolInfoFromOS(const nsACString &aScheme) = 0;
+ virtual already_AddRefed<nsIHandlerInfo> GetProtocolInfoFromOS(const nsACString &aScheme,
+ PRBool *found) = 0;
/**
* Given a string identifying an application, create an nsIFile representing
* it. This function should look in $PATH for the application.
* The base class implementation will first try to interpret platformAppPath
* as an absolute path, and if that fails it will look for a file next to the
* mozilla executable. Subclasses can override this method if they want a
* different behaviour.
--- a/uriloader/exthandler/nsMIMEInfoImpl.cpp
+++ b/uriloader/exthandler/nsMIMEInfoImpl.cpp
@@ -444,17 +444,17 @@ nsMIMEInfoImpl::GetDefaultDescription(ns
}
return NS_OK;
}
NS_IMETHODIMP
nsMIMEInfoImpl::GetHasDefaultHandler(PRBool * _retval)
{
- *_retval = PR_FALSE;
+ *_retval = !mDefaultAppDescription.IsEmpty();
if (mDefaultApplication) {
PRBool exists;
*_retval = NS_SUCCEEDED(mDefaultApplication->Exists(&exists)) && exists;
}
return NS_OK;
}
nsresult
--- a/uriloader/exthandler/unix/nsOSHelperAppService.cpp
+++ b/uriloader/exthandler/unix/nsOSHelperAppService.cpp
@@ -1630,34 +1630,40 @@ nsOSHelperAppService::GetMIMEInfoFromOS(
retval->CopyBasicDataTo(miByExt);
miByExt.swap(retval);
}
return retval;
}
already_AddRefed<nsIHandlerInfo>
-nsOSHelperAppService::GetProtocolInfoFromOS(const nsACString &aScheme)
+nsOSHelperAppService::GetProtocolInfoFromOS(const nsACString &aScheme,
+ PRBool *found)
{
NS_ASSERTION(!aScheme.IsEmpty(), "No scheme was specified!");
// We must check that a registered handler exists so that gnome_url_show
// doesn't fallback to gnomevfs.
// See nsGNOMERegistry::LoadURL and bug 389632.
- PRBool exists;
nsresult rv = OSProtocolHandlerExists(nsPromiseFlatCString(aScheme).get(),
- &exists);
- if (NS_FAILED(rv) || !exists)
+ found);
+ if (NS_FAILED(rv))
return nsnull;
nsMIMEInfoUnix *handlerInfo =
new nsMIMEInfoUnix(aScheme, nsMIMEInfoBase::eProtocolInfo);
NS_ENSURE_TRUE(handlerInfo, nsnull);
NS_ADDREF(handlerInfo);
+ if (!*found) {
+ // Code that calls this requires an object regardless if the OS has
+ // something for us, so we return the empty object.
+ return handlerInfo;
+ }
+
nsAutoString desc;
GetApplicationDescription(aScheme, desc);
handlerInfo->SetDefaultDescription(desc);
return handlerInfo;
}
void
--- a/uriloader/exthandler/unix/nsOSHelperAppService.h
+++ b/uriloader/exthandler/unix/nsOSHelperAppService.h
@@ -56,17 +56,18 @@ class nsOSHelperAppService : public nsEx
public:
nsOSHelperAppService();
virtual ~nsOSHelperAppService();
// method overrides for mime.types and mime.info look up steps
already_AddRefed<nsIMIMEInfo> GetMIMEInfoFromOS(const nsACString& aMimeType,
const nsACString& aFileExt,
PRBool *aFound);
- already_AddRefed<nsIHandlerInfo> GetProtocolInfoFromOS(const nsACString &aScheme);
+ already_AddRefed<nsIHandlerInfo> GetProtocolInfoFromOS(const nsACString &aScheme,
+ PRBool *found);
// override nsIExternalProtocolService methods
nsresult OSProtocolHandlerExists(const char * aProtocolScheme, PRBool * aHandlerExists);
NS_IMETHOD GetApplicationDescription(const nsACString& aScheme, nsAString& _retval);
// 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
--- a/uriloader/exthandler/win/nsOSHelperAppService.cpp
+++ b/uriloader/exthandler/win/nsOSHelperAppService.cpp
@@ -549,30 +549,36 @@ already_AddRefed<nsIMIMEInfo> nsOSHelper
miByExt->GetDefaultDescription(desc);
mi->SetDefaultDescription(desc);
}
return mi;
}
already_AddRefed<nsIHandlerInfo>
-nsOSHelperAppService::GetProtocolInfoFromOS(const nsACString &aScheme)
+nsOSHelperAppService::GetProtocolInfoFromOS(const nsACString &aScheme,
+ PRBool *found)
{
NS_ASSERTION(!aScheme.IsEmpty(), "No scheme was specified!");
- PRBool exists;
nsresult rv = OSProtocolHandlerExists(nsPromiseFlatCString(aScheme).get(),
- &exists);
- if (NS_FAILED(rv) || !exists)
+ found);
+ if (NS_FAILED(rv))
return nsnull;
nsMIMEInfoWin *handlerInfo =
new nsMIMEInfoWin(aScheme, nsMIMEInfoBase::eProtocolInfo);
NS_ENSURE_TRUE(handlerInfo, nsnull);
NS_ADDREF(handlerInfo);
+ if (!*found) {
+ // Code that calls this requires an object regardless if the OS has
+ // something for us, so we return the empty object.
+ return handlerInfo;
+ }
+
nsAutoString desc;
GetApplicationDescription(aScheme, desc);
handlerInfo->SetDefaultDescription(desc);
return handlerInfo;
}
--- a/uriloader/exthandler/win/nsOSHelperAppService.h
+++ b/uriloader/exthandler/win/nsOSHelperAppService.h
@@ -58,17 +58,18 @@ public:
// override nsIExternalProtocolService methods
nsresult OSProtocolHandlerExists(const char * aProtocolScheme, PRBool * aHandlerExists);
nsresult LoadUriInternal(nsIURI * aURL);
NS_IMETHOD GetApplicationDescription(const nsACString& aScheme, nsAString& _retval);
// method overrides for windows registry look up steps....
already_AddRefed<nsIMIMEInfo> GetMIMEInfoFromOS(const nsACString& aMIMEType, const nsACString& aFileExt, PRBool *aFound);
- already_AddRefed<nsIHandlerInfo> GetProtocolInfoFromOS(const nsACString &aScheme);
+ already_AddRefed<nsIHandlerInfo> GetProtocolInfoFromOS(const nsACString &aScheme,
+ PRBool *found);
/** Get the string value of a registry value and store it in result.
* @return PR_TRUE on success, PR_FALSE on failure
*/
static PRBool GetValueString(HKEY hKey, const PRUnichar* pValueName, nsAString& result);
protected:
nsresult GetDefaultAppInfo(const nsAString& aTypeName, nsAString& aDefaultDescription, nsIFile** aDefaultApplication);