Bug 1700004 - Make FuzzingFunctions::SynthesizeKeyboardEvents synthesize keyboard events in in-process top window rather than active window r=smaug

Currently, it tries to synthesize keyboard events on active window for emulating
user input as far as possible.  However, in the Fission world, it cannot
retrieve active window from a content process for OOP iframe.  And current
behavior does not allow to emulate synthesizing keyboard events in inactive
window which may be caused by 3rd party apps like IME.

Therefore, this patch makes it synthesize keyboard events in in-process top
window from the caller's global object.  If we support synthesizing keyboard
events via main process, we can change the behavior better.  But for now,
this must be enough for the Fuzzing API users.

Differential Revision: https://phabricator.services.mozilla.com/D111040
This commit is contained in:
Masayuki Nakano 2021-04-08 00:11:26 +00:00
parent 9a8efaa32e
commit b8b6c79415
2 changed files with 30 additions and 22 deletions

View File

@ -176,10 +176,9 @@ Modifiers FuzzingFunctions::InactivateModifiers(
}
/* static */
void FuzzingFunctions::SynthesizeKeyboardEvents(const GlobalObject&,
const nsAString& aKeyValue,
const KeyboardEventInit& aDict,
ErrorResult& aRv) {
void FuzzingFunctions::SynthesizeKeyboardEvents(
const GlobalObject& aGlobalObject, const nsAString& aKeyValue,
const KeyboardEventInit& aDict, ErrorResult& aRv) {
// Prepare keyboard event to synthesize first.
uint32_t flags = 0;
// Don't modify the given dictionary since caller may want to modify
@ -268,20 +267,28 @@ void FuzzingFunctions::SynthesizeKeyboardEvents(const GlobalObject&,
event.mKeyNameIndex, maybeNonStandardLocation);
}
// Synthesize keyboard events on focused widget.
nsFocusManager* focusManager = nsFocusManager::GetFocusManager();
if (NS_WARN_IF(!focusManager)) {
// Synthesize keyboard events in a DOM window which is in-process top one.
// For emulating user input, this is better than dispatching the events in
// the caller's DOM window because this approach can test the path redirecting
// the events to focused subdocument too. However, for now, we cannot
// dispatch it via another process without big changes. Therefore, we should
// use in-process top window instead. If you need to test the path in the
// parent process to, please file a feature request bug.
nsCOMPtr<nsPIDOMWindowInner> windowInner =
do_QueryInterface(aGlobalObject.GetAsSupports());
if (!windowInner) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return;
}
nsPIDOMWindowOuter* activeWindow = focusManager->GetActiveWindow();
if (NS_WARN_IF(!activeWindow)) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
nsPIDOMWindowOuter* inProcessTopWindowOuter =
windowInner->GetInProcessScriptableTop();
if (NS_WARN_IF(!inProcessTopWindowOuter)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsIDocShell* docShell = activeWindow->GetDocShell();
nsIDocShell* docShell = inProcessTopWindowOuter->GetDocShell();
if (NS_WARN_IF(!docShell)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
@ -299,9 +306,9 @@ void FuzzingFunctions::SynthesizeKeyboardEvents(const GlobalObject&,
return;
}
nsCOMPtr<nsPIDOMWindowInner> activeWindowInner =
activeWindow->EnsureInnerWindow();
if (NS_WARN_IF(!activeWindowInner)) {
nsCOMPtr<nsPIDOMWindowInner> inProcessTopWindowInner =
inProcessTopWindowOuter->EnsureInnerWindow();
if (NS_WARN_IF(!inProcessTopWindowInner)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
@ -309,7 +316,7 @@ void FuzzingFunctions::SynthesizeKeyboardEvents(const GlobalObject&,
RefPtr<TextInputProcessor> textInputProcessor = new TextInputProcessor();
bool beganInputTransaction = false;
aRv = textInputProcessor->BeginInputTransactionForFuzzing(
activeWindowInner, nullptr, &beganInputTransaction);
inProcessTopWindowInner, nullptr, &beganInputTransaction);
if (NS_WARN_IF(aRv.Failed())) {
return;
}

View File

@ -42,13 +42,14 @@ interface FuzzingFunctions {
/**
* synthesizeKeyboardEvents() synthesizes a set of "keydown",
* "keypress" (only when it's necessary) and "keyup" events on focused
* widget. This is currently not aware of APZ since this dispatches the
* events into focused PresShell in current process. I.e., dispatched
* events won't be handled by some default action handlers which are only
* in the main process. Note that this does not allow to synthesize
* keyboard events if this is called from a keyboard event or composition
* event listener.
* "keypress" (only when it's necessary) and "keyup" events in top DOM window
* in current process (and the synthesized events will be retargeted to
* focused window/document/element). I.e, this is currently not dispatched
* via the main process if you call this in a content process. Therefore, in
* the case, some default action handlers which are only in the main process
* will never run. Note that this does not allow to synthesize keyboard
* events if this is called from a keyboard event or composition event
* listener.
*
* @param aKeyValue If you want to synthesize non-printable key
* events, you need to set one of key values