Bug 1916804: Make content analysis DND use getURIForDropEvent a=dmeehan

getURIForDropEvent delegates to getURIForBrowsingContext -- the ground truth for
CA URIs.

This also adds a check that getURIForDropEvent is correctly called in CA tests.
We do not yet test that it returns the right value -- that is future work.

Original Revision: https://phabricator.services.mozilla.com/D222192

Differential Revision: https://phabricator.services.mozilla.com/D227592
This commit is contained in:
David Parks 2024-11-05 15:35:37 +00:00
parent 3752ee37f2
commit c98cc41962
8 changed files with 77 additions and 29 deletions

View file

@ -11,8 +11,10 @@
#include "base/process_util.h"
#include "GMPUtils.h" // ToHexString
#include "mozilla/Components.h"
#include "mozilla/dom/BrowserParent.h"
#include "mozilla/dom/CanonicalBrowsingContext.h"
#include "mozilla/dom/DataTransfer.h"
#include "mozilla/dom/DragEvent.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/WindowGlobalParent.h"
#include "mozilla/Logging.h"
@ -2339,6 +2341,22 @@ NS_IMETHODIMP ContentAnalysis::GetURIForBrowsingContext(
return NS_OK;
}
NS_IMETHODIMP
ContentAnalysis::GetURIForDropEvent(dom::DragEvent* aEvent, nsIURI** aURI) {
MOZ_ASSERT(XRE_IsParentProcess());
*aURI = nullptr;
auto* widgetEvent = aEvent->WidgetEventPtr();
MOZ_ASSERT(widgetEvent);
MOZ_ASSERT(widgetEvent->mClass == eDragEventClass &&
widgetEvent->mMessage == eDrop);
auto* bp =
dom::BrowserParent::GetBrowserParentFromLayersId(widgetEvent->mLayersId);
NS_ENSURE_TRUE(bp, NS_ERROR_FAILURE);
auto* bc = bp->GetBrowsingContext();
NS_ENSURE_TRUE(bc, NS_ERROR_FAILURE);
return GetURIForBrowsingContext(bc, aURI);
}
NS_IMETHODIMP ContentAnalysisCallback::ContentResult(
nsIContentAnalysisResponse* aResponse) {
if (mPromise.isSome()) {

View file

@ -7,6 +7,7 @@
interface nsIURI;
webidl BrowsingContext;
webidl DragEvent;
webidl WindowGlobalParent;
[scriptable, uuid(06e6a60f-3a2b-41fa-a63b-fea7a7f71649)]
@ -309,4 +310,10 @@ interface nsIContentAnalysis : nsISupports
* handles iframes.
*/
nsIURI getURIForBrowsingContext(in BrowsingContext aBrowsingContext);
/**
* Gets the URI to use for the passed-in drop event. This correctly
* handles iframes.
*/
nsIURI getURIForDropEvent(in DragEvent aEvent);
};

View file

@ -24,6 +24,13 @@ let mockCA = {
mightBeActive: true,
caShouldAllow: undefined,
numAnalyzeContentRequestCalls: undefined,
numGetURIForDropEvent: undefined,
getURIForDropEvent(event) {
info(`[${testName}]| Called getURIForDropEvent`);
this.numGetURIForDropEvent += 1;
return this.realCAService.getURIForDropEvent(event);
},
async analyzeContentRequest(_aRequest, _aAutoAcknowledge) {
info(`[${testName}]| Called analyzeContentRequest`);
@ -76,6 +83,7 @@ runTest = async function (
info(testRootName);
testName = testRootName;
mockCA.numAnalyzeContentRequestCalls = 0;
mockCA.numGetURIForDropEvent = 0;
await runDnd(testRootName, sourceBrowsingCxt, targetBrowsingCxt, {
...dndOptions,
});
@ -84,6 +92,11 @@ runTest = async function (
0,
`[${testName}]| AnalyzeContentRequest was not called`
);
is(
mockCA.numGetURIForDropEvent,
0,
`[${testName}]| GetURIForDropEvent was not called`
);
return;
}
@ -93,6 +106,7 @@ runTest = async function (
testName = name;
mockCA.caShouldAllow = caShouldAllow;
mockCA.numAnalyzeContentRequestCalls = 0;
mockCA.numGetURIForDropEvent = 0;
let dropPromise = new Promise(res => {
resolveDropPromise = res;
});
@ -106,5 +120,10 @@ runTest = async function (
1,
`[${testName}]| Called AnalyzeContentRequest once`
);
is(
mockCA.numGetURIForDropEvent,
1,
`[${testName}]| GetURIForDropEvent was called exactly once`
);
}
};

View file

@ -24,6 +24,13 @@ let mockCA = {
mightBeActive: true,
caShouldAllow: undefined,
numAnalyzeContentRequestCalls: undefined,
numGetURIForDropEvent: undefined,
getURIForDropEvent(event) {
info(`[${testName}]| Called getURIForDropEvent`);
this.numGetURIForDropEvent += 1;
return this.realCAService.getURIForDropEvent(event);
},
async analyzeContentRequest(_aRequest, _aAutoAcknowledge) {
info(`[${testName}]| Called analyzeContentRequest`);
@ -76,6 +83,7 @@ runTest = async function (
info(testRootName);
testName = testRootName;
mockCA.numAnalyzeContentRequestCalls = 0;
mockCA.numGetURIForDropEvent = 0;
await runDnd(testRootName, sourceBrowsingCxt, targetBrowsingCxt, {
...dndOptions,
});
@ -84,6 +92,11 @@ runTest = async function (
0,
`[${testName}]| AnalyzeContentRequest was not called`
);
is(
mockCA.numGetURIForDropEvent,
0,
`[${testName}]| GetURIForDropEvent was not called`
);
return;
}
@ -93,6 +106,7 @@ runTest = async function (
testName = name;
mockCA.caShouldAllow = caShouldAllow;
mockCA.numAnalyzeContentRequestCalls = 0;
mockCA.numGetURIForDropEvent = 0;
let dropPromise = new Promise(res => {
resolveDropPromise = res;
});
@ -106,5 +120,10 @@ runTest = async function (
1,
`[${testName}]| Called AnalyzeContentRequest once`
);
is(
mockCA.numGetURIForDropEvent,
1,
`[${testName}]| GetURIForDropEvent was called exactly once`
);
}
};

View file

@ -54,17 +54,24 @@ function mockService(serviceNames, contractId, interfaceObj, mockService) {
/**
* Mock the nsIContentAnalysis service with the object mockCAService.
*
* @param {object} mockCAService
* the service to mock for nsIContentAnalysis
* @returns {object} The newly-mocked service
* @param {object} mockCAServiceTemplate
* the mock nsIContentAnalysis template object
* @returns {object} The newly-mocked service that integrates the template
*/
function mockContentAnalysisService(mockCAService) {
return mockService(
function mockContentAnalysisService(mockCAServiceTemplate) {
let realCAService = SpecialPowers.Cc[
"@mozilla.org/contentanalysis;1"
].getService(SpecialPowers.Ci.nsIContentAnalysis);
let mockCAService = mockService(
["nsIContentAnalysis"],
"@mozilla.org/contentanalysis;1",
Ci.nsIContentAnalysis,
mockCAService
mockCAServiceTemplate
);
if (mockCAService) {
mockCAService.realCAService = realCAService;
}
return mockCAService;
}
/**

View file

@ -239,7 +239,7 @@
{
requestToken: Services.uuid.generateUUID().toString(),
resources: [],
url: dragSession.uriForEvent(event),
url: lazy.contentAnalysis.getURIForDropEvent(event),
windowGlobalParent:
this.browsingContext.currentWindowContext,
...requestFields,

View file

@ -1275,22 +1275,6 @@ nsIWidget* nsBaseDragService::GetWidgetFromWidgetProvider(
return vm->GetRootWidget();
}
NS_IMETHODIMP
nsBaseDragSession::UriForEvent(DragEvent* aEvent, nsIURI** aUri) {
MOZ_ASSERT(XRE_IsParentProcess());
*aUri = nullptr;
auto* widgetEvent = aEvent->WidgetEventPtr();
MOZ_ASSERT(widgetEvent);
auto* bp =
dom::BrowserParent::GetBrowserParentFromLayersId(widgetEvent->mLayersId);
NS_ENSURE_TRUE(bp, NS_ERROR_FAILURE);
auto* bc = bp->GetBrowsingContext();
NS_ENSURE_TRUE(bc, NS_ERROR_FAILURE);
RefPtr<nsIURI> ret = bc->GetCurrentURI();
ret.forget(aUri);
return NS_OK;
}
NS_IMETHODIMP
nsBaseDragSession::SendStoreDropTargetAndDelayEndDragSession(
DragEvent* aEvent) {

View file

@ -215,12 +215,6 @@ interface nsIDragSession : nsISupports
void endDragSession(in boolean aDoneDrag,
[optional] in unsigned long aKeyModifiers);
/**
* Returns the URI that should be used in a content analysis request for
* the given drag event.
*/
nsIURI uriForEvent(in DragEvent event);
/**
* Tell the drag session for the given browser that it
* should store the would-be target of the aEvent (a drop event) and delay