mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-24 10:45:42 +00:00
47a7f17127
It would be really nice to push all of this back up to the parent or to at least make it asynchronous. I think it should be possible since we control when we send the DOM events, but for the moment this should work. With this patch, I extend ProxyMIMEInfo and HandlerInfo with information about the available extensions for a given MIME type. On Linux, at least, we read the system (in my case GNOME) registry in the child and handlers.json in the parent finally merging them again in the child (in ContentHandlerService::FillHandlerInfo). Even though I was unable to get my mochitest to work, it did work well enough that I could verify that this patch was getting all of the proper extensions to the nsContentAreaDragDrop.cpp code. MozReview-Commit-ID: AR3VayMUiDN --HG-- extra : rebase_source : f9861e46e92fb7e8d297eff3e5d61a3c18912b47
227 lines
6.3 KiB
C++
227 lines
6.3 KiB
C++
#include "ContentHandlerService.h"
|
|
#include "HandlerServiceChild.h"
|
|
#include "ContentChild.h"
|
|
#include "nsIMutableArray.h"
|
|
#include "nsIMIMEInfo.h"
|
|
#include "nsIStringEnumerator.h"
|
|
|
|
using mozilla::dom::ContentChild;
|
|
using mozilla::dom::PHandlerServiceChild;
|
|
using mozilla::dom::HandlerInfo;
|
|
|
|
namespace mozilla {
|
|
namespace dom {
|
|
|
|
NS_IMPL_ISUPPORTS(ContentHandlerService, nsIHandlerService)
|
|
|
|
ContentHandlerService::ContentHandlerService()
|
|
{
|
|
}
|
|
|
|
nsresult
|
|
ContentHandlerService::Init()
|
|
{
|
|
if (!XRE_IsContentProcess()) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
ContentChild* cpc = ContentChild::GetSingleton();
|
|
|
|
mHandlerServiceChild = static_cast<HandlerServiceChild*>(cpc->SendPHandlerServiceConstructor());
|
|
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(Move(extension));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
nsHandlerInfoAction action;
|
|
aInfo->GetPreferredAction(&action);
|
|
HandlerInfo info(type,
|
|
isMIMEInfo,
|
|
description,
|
|
alwaysAskBeforeHandling,
|
|
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, nsIInterfaceRequestor *aWindowContext)
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMPL_ISUPPORTS(RemoteHandlerApp, nsIHandlerApp)
|
|
|
|
static inline void CopyHanderInfoTonsIHandlerInfo(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);
|
|
|
|
if (info.isMIMEInfo()) {
|
|
const auto& fileExtensions = info.extensions();
|
|
bool first = true;
|
|
nsAutoCString extensionsStr;
|
|
for (const auto& extension : fileExtensions) {
|
|
if (!first) {
|
|
extensionsStr.Append(',');
|
|
}
|
|
|
|
extensionsStr.Append(extension);
|
|
first = false;
|
|
}
|
|
|
|
nsCOMPtr<nsIMIMEInfo> mimeInfo(do_QueryInterface(aHandlerInfo));
|
|
MOZ_ASSERT(mimeInfo, "parent and child don't agree on whether this is a MIME info");
|
|
mimeInfo->SetFileExtensions(extensionsStr);
|
|
}
|
|
}
|
|
|
|
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, nsCString(aOverrideType), &returnedInfo);
|
|
CopyHanderInfoTonsIHandlerInfo(returnedInfo, aHandlerInfo);
|
|
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::ExistsForProtocol(const nsACString& aProtocolScheme, bool* aRetval)
|
|
{
|
|
if (!mHandlerServiceChild->SendExistsForProtocol(nsCString(aProtocolScheme), aRetval)) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP ContentHandlerService::GetTypeFromExtension(const nsACString & aFileExtension, nsACString & _retval)
|
|
{
|
|
nsCString* cachedType = nullptr;
|
|
if (!!mExtToTypeMap.Get(aFileExtension, &cachedType) && !!cachedType) {
|
|
_retval.Assign(*cachedType);
|
|
return NS_OK;
|
|
}
|
|
nsCString type;
|
|
mHandlerServiceChild->SendGetTypeFromExtension(nsCString(aFileExtension), &type);
|
|
_retval.Assign(type);
|
|
mExtToTypeMap.Put(nsCString(aFileExtension), new nsCString(type));
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
}
|
|
}
|