Bug 1377672 - part3: IMEStateManager::NotifyIME() should ignore notifications and requests which comes from unexpected process r=m_kato,smaug

IME should receive notifications and requests only from proper process.  E.g., IME shouldn't commit composition by a request which came from previous focused process.

This patch makes that IMEStateManager::NotifyIME() takes pointer to TabParent optionally.  If the request or notification came from remote process, it should be non-nullptr.  Then, this makes it ignore notifications and requests from unexpected process.

Note that this patch also touches some gfx headers because they use |ipc::| but compiler is confused at the ambiguousness between |mozilla::ipc::| and |mozilla::dom::ipc::|.

Finally, this patch changes the NS_ASSERTION in IMEHandler::OnDestroyWindow() to MOZ_ASSERT because the orange caused by the NS_ASSERTION was not realized since there was already an intermittent orange bug caused by different NS_ASSERTION.

MozReview-Commit-ID: 9CgKXQRJWmN

--HG--
extra : source : f3b5711908870c5e0e852a399a07e0ae721a12f1
This commit is contained in:
Masayuki Nakano 2017-07-06 00:47:40 +09:00
Родитель c726abb366
Коммит d6e921676c
10 изменённых файлов: 154 добавлений и 122 удалений

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

@ -136,10 +136,23 @@ GetIMEStateSetOpenName(IMEState::Open aOpen)
} }
} }
static bool
IsSameProcess(const TabParent* aTabParent1, const TabParent* aTabParent2)
{
if (aTabParent1 == aTabParent2) {
return true;
}
if (!aTabParent1 != !aTabParent2) {
return false;
}
return aTabParent1->Manager() == aTabParent2->Manager();
}
StaticRefPtr<nsIContent> IMEStateManager::sContent; StaticRefPtr<nsIContent> IMEStateManager::sContent;
StaticRefPtr<nsPresContext> IMEStateManager::sPresContext; StaticRefPtr<nsPresContext> IMEStateManager::sPresContext;
nsIWidget* IMEStateManager::sWidget = nullptr; nsIWidget* IMEStateManager::sWidget = nullptr;
nsIWidget* IMEStateManager::sFocusedIMEWidget = nullptr; nsIWidget* IMEStateManager::sFocusedIMEWidget = nullptr;
StaticRefPtr<TabParent> IMEStateManager::sFocusedIMETabParent;
nsIWidget* IMEStateManager::sActiveInputContextWidget = nullptr; nsIWidget* IMEStateManager::sActiveInputContextWidget = nullptr;
StaticRefPtr<TabParent> IMEStateManager::sActiveTabParent; StaticRefPtr<TabParent> IMEStateManager::sActiveTabParent;
StaticRefPtr<IMEContentObserver> IMEStateManager::sActiveIMEContentObserver; StaticRefPtr<IMEContentObserver> IMEStateManager::sActiveIMEContentObserver;
@ -149,7 +162,6 @@ bool IMEStateManager::sInstalledMenuKeyboardListener = false;
bool IMEStateManager::sIsGettingNewIMEState = false; bool IMEStateManager::sIsGettingNewIMEState = false;
bool IMEStateManager::sCheckForIMEUnawareWebApps = false; bool IMEStateManager::sCheckForIMEUnawareWebApps = false;
bool IMEStateManager::sInputModeSupported = false; bool IMEStateManager::sInputModeSupported = false;
bool IMEStateManager::sRemoteHasFocus = false;
// static // static
void void
@ -226,7 +238,7 @@ IMEStateManager::StopIMEStateManagement()
// the rights to change input context. // the rights to change input context.
if (sTextCompositions && sPresContext) { if (sTextCompositions && sPresContext) {
NotifyIME(REQUEST_TO_COMMIT_COMPOSITION, sPresContext); NotifyIME(REQUEST_TO_COMMIT_COMPOSITION, sPresContext, sActiveTabParent);
} }
sActiveInputContextWidget = nullptr; sActiveInputContextWidget = nullptr;
sPresContext = nullptr; sPresContext = nullptr;
@ -444,7 +456,7 @@ IMEStateManager::OnChangeFocusInternal(nsPresContext* aPresContext,
// If we're deactivating, we shouldn't commit composition forcibly because // If we're deactivating, we shouldn't commit composition forcibly because
// the user may want to continue the composition. // the user may want to continue the composition.
if (aPresContext) { if (aPresContext) {
NotifyIME(REQUEST_TO_COMMIT_COMPOSITION, oldWidget); NotifyIME(REQUEST_TO_COMMIT_COMPOSITION, oldWidget, sFocusedIMETabParent);
} }
} }
@ -478,11 +490,7 @@ IMEStateManager::OnChangeFocusInternal(nsPresContext* aPresContext,
return NS_OK; return NS_OK;
} }
nsIContentParent* currentContentParent = if (sActiveTabParent && !IsSameProcess(sActiveTabParent, newTabParent)) {
sActiveTabParent ? sActiveTabParent->Manager() : nullptr;
nsIContentParent* newContentParent =
newTabParent ? newTabParent->Manager() : nullptr;
if (sActiveTabParent && currentContentParent != newContentParent) {
MOZ_LOG(sISMLog, LogLevel::Debug, MOZ_LOG(sISMLog, LogLevel::Debug,
(" OnChangeFocusInternal(), notifying previous " (" OnChangeFocusInternal(), notifying previous "
"focused child process of parent process or another child process " "focused child process of parent process or another child process "
@ -565,7 +573,8 @@ IMEStateManager::OnChangeFocusInternal(nsPresContext* aPresContext,
// Even if focus isn't changing actually, we should commit current // Even if focus isn't changing actually, we should commit current
// composition here since the IME state is changing. // composition here since the IME state is changing.
if (sPresContext && oldWidget && !focusActuallyChanging) { if (sPresContext && oldWidget && !focusActuallyChanging) {
NotifyIME(REQUEST_TO_COMMIT_COMPOSITION, oldWidget); NotifyIME(REQUEST_TO_COMMIT_COMPOSITION, oldWidget,
sFocusedIMETabParent);
} }
} else if (aAction.mFocusChange == InputContextAction::FOCUS_NOT_CHANGED) { } else if (aAction.mFocusChange == InputContextAction::FOCUS_NOT_CHANGED) {
// If aContent isn't null or aContent is null but editable, somebody gets // If aContent isn't null or aContent is null but editable, somebody gets
@ -923,7 +932,7 @@ IMEStateManager::UpdateIMEState(const IMEState& aNewIMEState,
if (updateIMEState) { if (updateIMEState) {
// commit current composition before modifying IME state. // commit current composition before modifying IME state.
NotifyIME(REQUEST_TO_COMMIT_COMPOSITION, widget); NotifyIME(REQUEST_TO_COMMIT_COMPOSITION, widget, sFocusedIMETabParent);
if (NS_WARN_IF(widget->Destroyed())) { if (NS_WARN_IF(widget->Destroyed())) {
MOZ_LOG(sISMLog, LogLevel::Error, MOZ_LOG(sISMLog, LogLevel::Error,
(" UpdateIMEState(), widget has gone during committing composition")); (" UpdateIMEState(), widget has gone during committing composition"));
@ -1443,25 +1452,29 @@ IMEStateManager::OnCompositionEventDiscarded(
nsresult nsresult
IMEStateManager::NotifyIME(IMEMessage aMessage, IMEStateManager::NotifyIME(IMEMessage aMessage,
nsIWidget* aWidget, nsIWidget* aWidget,
bool aOriginIsRemote) TabParent* aTabParent)
{ {
return IMEStateManager::NotifyIME(IMENotification(aMessage), aWidget, return IMEStateManager::NotifyIME(IMENotification(aMessage), aWidget,
aOriginIsRemote); aTabParent);
} }
// static // static
nsresult nsresult
IMEStateManager::NotifyIME(const IMENotification& aNotification, IMEStateManager::NotifyIME(const IMENotification& aNotification,
nsIWidget* aWidget, nsIWidget* aWidget,
bool aOriginIsRemote) TabParent* aTabParent)
{ {
MOZ_LOG(sISMLog, LogLevel::Info, MOZ_LOG(sISMLog, LogLevel::Info,
("NotifyIME(aNotification={ mMessage=%s }, " ("NotifyIME(aNotification={ mMessage=%s }, "
"aWidget=0x%p, aOriginIsRemote=%s), sFocusedIMEWidget=0x%p, " "aWidget=0x%p, aTabParent=0x%p), sFocusedIMEWidget=0x%p, "
"sRemoteHasFocus=%s", "sActiveTabParent=0x%p, sFocusedIMETabParent=0x%p, "
"IsSameProcess(aTabParent, sActiveTabParent)=%s, "
"IsSameProcess(aTabParent, sFocusedIMETabParent)=%s",
ToChar(aNotification.mMessage), aWidget, ToChar(aNotification.mMessage), aWidget,
GetBoolName(aOriginIsRemote), sFocusedIMEWidget, aTabParent, sFocusedIMEWidget, sActiveTabParent.get(),
GetBoolName(sRemoteHasFocus))); sFocusedIMETabParent.get(),
GetBoolName(IsSameProcess(aTabParent, sActiveTabParent)),
GetBoolName(IsSameProcess(aTabParent, sFocusedIMETabParent))));
if (NS_WARN_IF(!aWidget)) { if (NS_WARN_IF(!aWidget)) {
MOZ_LOG(sISMLog, LogLevel::Error, MOZ_LOG(sISMLog, LogLevel::Error,
@ -1471,61 +1484,58 @@ IMEStateManager::NotifyIME(const IMENotification& aNotification,
switch (aNotification.mMessage) { switch (aNotification.mMessage) {
case NOTIFY_IME_OF_FOCUS: { case NOTIFY_IME_OF_FOCUS: {
// If focus notification comes from a remote process which already lost
// focus, we shouldn't accept the focus notification. Then, following
// notifications from the process will be ignored.
if (NS_WARN_IF(!IsSameProcess(aTabParent, sActiveTabParent))) {
MOZ_ASSERT(aTabParent,
"Why was the input context initialized for a remote process but "
"does this process get IME focus?");
MOZ_LOG(sISMLog, LogLevel::Warning,
(" NotifyIME(), WARNING, the received focus notification is ignored "
"because input context was initialized for %s, perhaps, it came "
"from a busy remote process",
sActiveTabParent ? "another remote process" : "current process"));
return NS_OK;
}
// If there is pending blur notification for current focused IME,
// we should notify IME of blur by ourselves. Then, we should ignore
// following notifications coming from the process.
if (sFocusedIMEWidget) { if (sFocusedIMEWidget) {
if (NS_WARN_IF(!sRemoteHasFocus && !aOriginIsRemote)) { MOZ_ASSERT(sFocusedIMETabParent || aTabParent,
MOZ_LOG(sISMLog, LogLevel::Error, "This case shouldn't be caused by focus move in this process");
(" NotifyIME(), although, this process is "
"getting IME focus but there was focused IME widget"));
} else {
MOZ_LOG(sISMLog, LogLevel::Info,
(" NotifyIME(), tries to notify IME of "
"blur first because remote process's blur notification hasn't "
"been received yet..."));
}
nsCOMPtr<nsIWidget> focusedIMEWidget(sFocusedIMEWidget); nsCOMPtr<nsIWidget> focusedIMEWidget(sFocusedIMEWidget);
sFocusedIMEWidget = nullptr; sFocusedIMEWidget = nullptr;
sRemoteHasFocus = false; sFocusedIMETabParent = nullptr;
focusedIMEWidget->NotifyIME(IMENotification(NOTIFY_IME_OF_BLUR)); focusedIMEWidget->NotifyIME(IMENotification(NOTIFY_IME_OF_BLUR));
} }
sRemoteHasFocus = aOriginIsRemote; sFocusedIMETabParent = aTabParent;
sFocusedIMEWidget = aWidget; sFocusedIMEWidget = aWidget;
nsCOMPtr<nsIWidget> widget(aWidget); nsCOMPtr<nsIWidget> widget(aWidget);
return widget->NotifyIME(aNotification); return widget->NotifyIME(aNotification);
} }
case NOTIFY_IME_OF_BLUR: { case NOTIFY_IME_OF_BLUR: {
if (!sRemoteHasFocus && aOriginIsRemote) { if (!IsSameProcess(aTabParent, sFocusedIMETabParent)) {
MOZ_LOG(sISMLog, LogLevel::Info, MOZ_LOG(sISMLog, LogLevel::Warning,
(" NotifyIME(), received blur notification " (" NotifyIME(), WARNING, the received blur notification is ignored "
"after another one has focus, nothing to do...")); "because it's not from current focused IME process"));
return NS_OK; return NS_OK;
} }
if (NS_WARN_IF(sRemoteHasFocus && !aOriginIsRemote)) { if (!sFocusedIMEWidget) {
MOZ_LOG(sISMLog, LogLevel::Error, MOZ_LOG(sISMLog, LogLevel::Error,
(" NotifyIME(), FAILED, received blur " (" NotifyIME(), WARNING, received blur notification but there is "
"notification from this process but the remote has focus")); "no focused IME widget"));
return NS_OK;
}
if (!sFocusedIMEWidget && aOriginIsRemote) {
MOZ_LOG(sISMLog, LogLevel::Info,
(" NotifyIME(), received blur notification "
"but the remote has already lost focus"));
return NS_OK;
}
if (NS_WARN_IF(!sFocusedIMEWidget)) {
MOZ_LOG(sISMLog, LogLevel::Error,
(" NotifyIME(), FAILED, received blur "
"notification but there is no focused IME widget"));
return NS_OK; return NS_OK;
} }
if (NS_WARN_IF(sFocusedIMEWidget != aWidget)) { if (NS_WARN_IF(sFocusedIMEWidget != aWidget)) {
MOZ_LOG(sISMLog, LogLevel::Error, MOZ_LOG(sISMLog, LogLevel::Warning,
(" NotifyIME(), FAILED, received blur " (" NotifyIME(), WARNING, the received blur notification is ignored "
"notification but there is no focused IME widget")); "because it's not for current focused IME widget"));
return NS_OK; return NS_OK;
} }
nsCOMPtr<nsIWidget> focusedIMEWidget(sFocusedIMEWidget); nsCOMPtr<nsIWidget> focusedIMEWidget(sFocusedIMEWidget);
sFocusedIMEWidget = nullptr; sFocusedIMEWidget = nullptr;
sRemoteHasFocus = false; sFocusedIMETabParent = nullptr;
return focusedIMEWidget->NotifyIME(IMENotification(NOTIFY_IME_OF_BLUR)); return focusedIMEWidget->NotifyIME(IMENotification(NOTIFY_IME_OF_BLUR));
} }
case NOTIFY_IME_OF_SELECTION_CHANGE: case NOTIFY_IME_OF_SELECTION_CHANGE:
@ -1533,30 +1543,22 @@ IMEStateManager::NotifyIME(const IMENotification& aNotification,
case NOTIFY_IME_OF_POSITION_CHANGE: case NOTIFY_IME_OF_POSITION_CHANGE:
case NOTIFY_IME_OF_MOUSE_BUTTON_EVENT: case NOTIFY_IME_OF_MOUSE_BUTTON_EVENT:
case NOTIFY_IME_OF_COMPOSITION_EVENT_HANDLED: { case NOTIFY_IME_OF_COMPOSITION_EVENT_HANDLED: {
if (!sRemoteHasFocus && aOriginIsRemote) { if (!IsSameProcess(aTabParent, sFocusedIMETabParent)) {
MOZ_LOG(sISMLog, LogLevel::Info, MOZ_LOG(sISMLog, LogLevel::Warning,
(" NotifyIME(), received content change " (" NotifyIME(), WARNING, the received content change notification "
"notification from the remote but it's already lost focus")); "is ignored because it's not from current focused IME process"));
return NS_OK;
}
if (NS_WARN_IF(sRemoteHasFocus && !aOriginIsRemote)) {
MOZ_LOG(sISMLog, LogLevel::Error,
(" NotifyIME(), FAILED, received content "
"change notification from this process but the remote has already "
"gotten focus"));
return NS_OK; return NS_OK;
} }
if (!sFocusedIMEWidget) { if (!sFocusedIMEWidget) {
MOZ_LOG(sISMLog, LogLevel::Info, MOZ_LOG(sISMLog, LogLevel::Warning,
(" NotifyIME(), received content change " (" NotifyIME(), WARNING, the received content change notification "
"notification but there is no focused IME widget")); "is ignored because there is no focused IME widget"));
return NS_OK; return NS_OK;
} }
if (NS_WARN_IF(sFocusedIMEWidget != aWidget)) { if (NS_WARN_IF(sFocusedIMEWidget != aWidget)) {
MOZ_LOG(sISMLog, LogLevel::Error, MOZ_LOG(sISMLog, LogLevel::Warning,
(" NotifyIME(), FAILED, received content " (" NotifyIME(), WARNING, the received content change notification "
"change notification for IME which has already lost focus, so, " "is ignored because it's not for current focused IME widget"));
"nothing to do..."));
return NS_OK; return NS_OK;
} }
nsCOMPtr<nsIWidget> widget(aWidget); nsCOMPtr<nsIWidget> widget(aWidget);
@ -1568,26 +1570,35 @@ IMEStateManager::NotifyIME(const IMENotification& aNotification,
break; break;
} }
RefPtr<TextComposition> composition; if (!sTextCompositions) {
if (sTextCompositions) { MOZ_LOG(sISMLog, LogLevel::Info,
composition = sTextCompositions->GetCompositionFor(aWidget); (" NotifyIME(), the request to IME is ignored because "
"there have been no compositions yet"));
return NS_OK;
} }
bool isSynthesizedForTests = RefPtr<TextComposition> composition =
composition && composition->IsSynthesizedForTests(); sTextCompositions->GetCompositionFor(aWidget);
if (!composition) {
MOZ_LOG(sISMLog, LogLevel::Info,
(" NotifyIME(), the request to IME is ignored because "
"there is no active composition"));
return NS_OK;
}
MOZ_LOG(sISMLog, LogLevel::Info, if (!IsSameProcess(aTabParent, composition->GetTabParent())) {
(" NotifyIME(), composition=0x%p, " MOZ_LOG(sISMLog, LogLevel::Warning,
"composition->IsSynthesizedForTests()=%s", (" NotifyIME(), WARNING, the request to IME is ignored because "
composition.get(), GetBoolName(isSynthesizedForTests))); "it does not come from the remote process which has the composition "
"on aWidget"));
return NS_OK;
}
switch (aNotification.mMessage) { switch (aNotification.mMessage) {
case REQUEST_TO_COMMIT_COMPOSITION: case REQUEST_TO_COMMIT_COMPOSITION:
return composition ? return composition->RequestToCommit(aWidget, false);
composition->RequestToCommit(aWidget, false) : NS_OK;
case REQUEST_TO_CANCEL_COMPOSITION: case REQUEST_TO_CANCEL_COMPOSITION:
return composition ? return composition->RequestToCommit(aWidget, true);
composition->RequestToCommit(aWidget, true) : NS_OK;
default: default:
MOZ_CRASH("Unsupported notification"); MOZ_CRASH("Unsupported notification");
} }
@ -1600,11 +1611,11 @@ IMEStateManager::NotifyIME(const IMENotification& aNotification,
nsresult nsresult
IMEStateManager::NotifyIME(IMEMessage aMessage, IMEStateManager::NotifyIME(IMEMessage aMessage,
nsPresContext* aPresContext, nsPresContext* aPresContext,
bool aOriginIsRemote) TabParent* aTabParent)
{ {
MOZ_LOG(sISMLog, LogLevel::Info, MOZ_LOG(sISMLog, LogLevel::Info,
("NotifyIME(aMessage=%s, aPresContext=0x%p, aOriginIsRemote=%s)", ("NotifyIME(aMessage=%s, aPresContext=0x%p, aTabParent=0x%p)",
ToChar(aMessage), aPresContext, GetBoolName(aOriginIsRemote))); ToChar(aMessage), aPresContext, aTabParent));
if (NS_WARN_IF(!CanHandleWith(aPresContext))) { if (NS_WARN_IF(!CanHandleWith(aPresContext))) {
return NS_ERROR_INVALID_ARG; return NS_ERROR_INVALID_ARG;
@ -1617,7 +1628,7 @@ IMEStateManager::NotifyIME(IMEMessage aMessage,
"nsPresContext")); "nsPresContext"));
return NS_ERROR_NOT_AVAILABLE; return NS_ERROR_NOT_AVAILABLE;
} }
return NotifyIME(aMessage, widget, aOriginIsRemote); return NotifyIME(aMessage, widget, aTabParent);
} }
// static // static

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

@ -224,13 +224,13 @@ public:
*/ */
static nsresult NotifyIME(const IMENotification& aNotification, static nsresult NotifyIME(const IMENotification& aNotification,
nsIWidget* aWidget, nsIWidget* aWidget,
bool aOriginIsRemote = false); TabParent* aTabParent = nullptr);
static nsresult NotifyIME(IMEMessage aMessage, static nsresult NotifyIME(IMEMessage aMessage,
nsIWidget* aWidget, nsIWidget* aWidget,
bool aOriginIsRemote = false); TabParent* aTabParent = nullptr);
static nsresult NotifyIME(IMEMessage aMessage, static nsresult NotifyIME(IMEMessage aMessage,
nsPresContext* aPresContext, nsPresContext* aPresContext,
bool aOriginIsRemote = false); TabParent* aTabParent = nullptr);
static nsINode* GetRootEditableNode(nsPresContext* aPresContext, static nsINode* GetRootEditableNode(nsPresContext* aPresContext,
nsIContent* aContent); nsIContent* aContent);
@ -280,11 +280,10 @@ protected:
// sPresContext has gone, we need to clean up some IME state on the widget // sPresContext has gone, we need to clean up some IME state on the widget
// if the widget is available. // if the widget is available.
static nsIWidget* sWidget; static nsIWidget* sWidget;
// sFocusedIMEWidget is, the widget which was sent to "focus" notification // sFocusedIMETabParent is the tab parent, which send "focus" notification to
// from IMEContentObserver and not yet sent "blur" notification. // sFocusedIMEWidget (and didn't yet sent "blur" notification).
// So, if this is not nullptr, the widget needs to receive "blur"
// notification.
static nsIWidget* sFocusedIMEWidget; static nsIWidget* sFocusedIMEWidget;
static StaticRefPtr<TabParent> sFocusedIMETabParent;
// sActiveInputContextWidget is the last widget whose SetInputContext() is // sActiveInputContextWidget is the last widget whose SetInputContext() is
// called. This is important to reduce sync IPC cost with parent process. // called. This is important to reduce sync IPC cost with parent process.
// If IMEStateManager set input context to different widget, PuppetWidget can // If IMEStateManager set input context to different widget, PuppetWidget can
@ -308,7 +307,6 @@ protected:
static bool sIsGettingNewIMEState; static bool sIsGettingNewIMEState;
static bool sCheckForIMEUnawareWebApps; static bool sCheckForIMEUnawareWebApps;
static bool sInputModeSupported; static bool sInputModeSupported;
static bool sRemoteHasFocus;
class MOZ_STACK_CLASS GettingNewIMEStateBlocker final class MOZ_STACK_CLASS GettingNewIMEStateBlocker final
{ {

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

@ -616,7 +616,7 @@ nsresult
TextComposition::NotifyIME(IMEMessage aMessage) TextComposition::NotifyIME(IMEMessage aMessage)
{ {
NS_ENSURE_TRUE(mPresContext, NS_ERROR_NOT_AVAILABLE); NS_ENSURE_TRUE(mPresContext, NS_ERROR_NOT_AVAILABLE);
return IMEStateManager::NotifyIME(aMessage, mPresContext); return IMEStateManager::NotifyIME(aMessage, mPresContext, mTabParent);
} }
void void

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

@ -75,6 +75,11 @@ public:
{ {
return mPresContext ? mPresContext->GetRootWidget() : nullptr; return mPresContext ? mPresContext->GetRootWidget() : nullptr;
} }
// Returns the tab parent which has this composition in its remote process.
TabParent* GetTabParent() const
{
return mTabParent;
}
// Returns true if the composition is started with synthesized event which // Returns true if the composition is started with synthesized event which
// came from nsDOMWindowUtils. // came from nsDOMWindowUtils.
bool IsSynthesizedForTests() const { return mIsSynthesizedForTests; } bool IsSynthesizedForTests() const { return mIsSynthesizedForTests; }

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

@ -143,6 +143,7 @@ TabParent::TabParent(nsIContentParent* aManager,
uint32_t aChromeFlags) uint32_t aChromeFlags)
: TabContext(aContext) : TabContext(aContext)
, mFrameElement(nullptr) , mFrameElement(nullptr)
, mContentCache(*this)
, mRect(0, 0, 0, 0) , mRect(0, 0, 0, 0)
, mDimensions(0, 0) , mDimensions(0, 0)
, mOrientation(0) , mOrientation(0)
@ -1745,7 +1746,7 @@ TabParent::RecvNotifyIMEFocus(const ContentCache& aContentCache,
} }
mContentCache.AssignContent(aContentCache, widget, &aIMENotification); mContentCache.AssignContent(aContentCache, widget, &aIMENotification);
IMEStateManager::NotifyIME(aIMENotification, widget, true); IMEStateManager::NotifyIME(aIMENotification, widget, this);
if (aIMENotification.mMessage == NOTIFY_IME_OF_FOCUS) { if (aIMENotification.mMessage == NOTIFY_IME_OF_FOCUS) {
*aRequests = widget->IMENotificationRequestsRef(); *aRequests = widget->IMENotificationRequestsRef();
@ -1824,7 +1825,7 @@ TabParent::RecvNotifyIMEMouseButtonEvent(
*aConsumedByIME = false; *aConsumedByIME = false;
return IPC_OK(); return IPC_OK();
} }
nsresult rv = IMEStateManager::NotifyIME(aIMENotification, widget, true); nsresult rv = IMEStateManager::NotifyIME(aIMENotification, widget, this);
*aConsumedByIME = rv == NS_SUCCESS_EVENT_CONSUMED; *aConsumedByIME = rv == NS_SUCCESS_EVENT_CONSUMED;
return IPC_OK(); return IPC_OK();
} }

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

@ -27,7 +27,7 @@ class GPUChild;
// GPUProcessHosts are allocated and managed by GPUProcessManager. For all // GPUProcessHosts are allocated and managed by GPUProcessManager. For all
// intents and purposes it is a singleton, though more than one may be allocated // intents and purposes it is a singleton, though more than one may be allocated
// at a time due to its shutdown being asynchronous. // at a time due to its shutdown being asynchronous.
class GPUProcessHost final : public ipc::GeckoChildProcessHost class GPUProcessHost final : public mozilla::ipc::GeckoChildProcessHost
{ {
friend class GPUChild; friend class GPUChild;
@ -121,7 +121,7 @@ private:
DISALLOW_COPY_AND_ASSIGN(GPUProcessHost); DISALLOW_COPY_AND_ASSIGN(GPUProcessHost);
Listener* mListener; Listener* mListener;
ipc::TaskFactory<GPUProcessHost> mTaskFactory; mozilla::ipc::TaskFactory<GPUProcessHost> mTaskFactory;
enum class LaunchPhase { enum class LaunchPhase {
Unlaunched, Unlaunched,

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

@ -99,10 +99,10 @@ public:
bool CreateContentBridges( bool CreateContentBridges(
base::ProcessId aOtherProcess, base::ProcessId aOtherProcess,
ipc::Endpoint<PCompositorManagerChild>* aOutCompositor, mozilla::ipc::Endpoint<PCompositorManagerChild>* aOutCompositor,
ipc::Endpoint<PImageBridgeChild>* aOutImageBridge, mozilla::ipc::Endpoint<PImageBridgeChild>* aOutImageBridge,
ipc::Endpoint<PVRManagerChild>* aOutVRBridge, mozilla::ipc::Endpoint<PVRManagerChild>* aOutVRBridge,
ipc::Endpoint<dom::PVideoDecoderManagerChild>* aOutVideoManager, mozilla::ipc::Endpoint<dom::PVideoDecoderManagerChild>* aOutVideoManager,
nsTArray<uint32_t>* aNamespaces); nsTArray<uint32_t>* aNamespaces);
// This returns a reference to the APZCTreeManager to which // This returns a reference to the APZCTreeManager to which
@ -185,13 +185,13 @@ private:
void OnXPCOMShutdown(); void OnXPCOMShutdown();
bool CreateContentCompositorManager(base::ProcessId aOtherProcess, bool CreateContentCompositorManager(base::ProcessId aOtherProcess,
ipc::Endpoint<PCompositorManagerChild>* aOutEndpoint); mozilla::ipc::Endpoint<PCompositorManagerChild>* aOutEndpoint);
bool CreateContentImageBridge(base::ProcessId aOtherProcess, bool CreateContentImageBridge(base::ProcessId aOtherProcess,
ipc::Endpoint<PImageBridgeChild>* aOutEndpoint); mozilla::ipc::Endpoint<PImageBridgeChild>* aOutEndpoint);
bool CreateContentVRManager(base::ProcessId aOtherProcess, bool CreateContentVRManager(base::ProcessId aOtherProcess,
ipc::Endpoint<PVRManagerChild>* aOutEndpoint); mozilla::ipc::Endpoint<PVRManagerChild>* aOutEndpoint);
void CreateContentVideoDecoderManager(base::ProcessId aOtherProcess, void CreateContentVideoDecoderManager(base::ProcessId aOtherProcess,
ipc::Endpoint<dom::PVideoDecoderManagerChild>* aOutEndPoint); mozilla::ipc::Endpoint<dom::PVideoDecoderManagerChild>* aOutEndPoint);
// Called from RemoteCompositorSession. We track remote sessions so we can // Called from RemoteCompositorSession. We track remote sessions so we can
// notify their owning widgets that the session must be restarted. // notify their owning widgets that the session must be restarted.
@ -258,7 +258,7 @@ private:
bool mDecodeVideoOnGpuProcess = true; bool mDecodeVideoOnGpuProcess = true;
RefPtr<Observer> mObserver; RefPtr<Observer> mObserver;
ipc::TaskFactory<GPUProcessManager> mTaskFactory; mozilla::ipc::TaskFactory<GPUProcessManager> mTaskFactory;
RefPtr<VsyncIOThreadHolder> mVsyncIOThread; RefPtr<VsyncIOThreadHolder> mVsyncIOThread;
uint32_t mNextNamespace; uint32_t mNextNamespace;
uint32_t mIdNamespace; uint32_t mIdNamespace;

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

@ -6,18 +6,21 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ContentCache.h" #include "mozilla/ContentCache.h"
#include "mozilla/IMEStateManager.h" #include "mozilla/IMEStateManager.h"
#include "mozilla/IntegerPrintfMacros.h"
#include "mozilla/Logging.h" #include "mozilla/Logging.h"
#include "mozilla/Move.h"
#include "mozilla/RefPtr.h"
#include "mozilla/SizePrintfMacros.h"
#include "mozilla/TextComposition.h" #include "mozilla/TextComposition.h"
#include "mozilla/TextEvents.h" #include "mozilla/TextEvents.h"
#include "mozilla/dom/TabParent.h"
#include "nsIWidget.h" #include "nsIWidget.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Move.h"
#include "mozilla/IntegerPrintfMacros.h"
#include "mozilla/SizePrintfMacros.h"
namespace mozilla { namespace mozilla {
using namespace dom;
using namespace widget; using namespace widget;
static const char* static const char*
@ -511,8 +514,9 @@ ContentCacheInChild::SetSelection(nsIWidget* aWidget,
* mozilla::ContentCacheInParent * mozilla::ContentCacheInParent
*****************************************************************************/ *****************************************************************************/
ContentCacheInParent::ContentCacheInParent() ContentCacheInParent::ContentCacheInParent(TabParent& aTabParent)
: ContentCache() : ContentCache()
, mTabParent(aTabParent)
, mCommitStringByRequest(nullptr) , mCommitStringByRequest(nullptr)
, mPendingEventsNeedingAck(0) , mPendingEventsNeedingAck(0)
, mCompositionStartInChild(UINT32_MAX) , mCompositionStartInChild(UINT32_MAX)
@ -1234,6 +1238,10 @@ ContentCacheInParent::RequestIMEToCommitComposition(nsIWidget* aWidget,
mCommitStringByRequest = &aCommittedString; mCommitStringByRequest = &aCommittedString;
// TODO: This request may be too late. For example, while the remote process
// was busy, focus may be already changed to the main process and the
// composition has already been canceled by IMEStateManager. So, this
// should check if IME focus is in the TabParent.
aWidget->NotifyIME(IMENotification(aCancel ? REQUEST_TO_CANCEL_COMPOSITION : aWidget->NotifyIME(IMENotification(aCancel ? REQUEST_TO_CANCEL_COMPOSITION :
REQUEST_TO_COMMIT_COMPOSITION)); REQUEST_TO_COMMIT_COMPOSITION));
@ -1274,7 +1282,7 @@ ContentCacheInParent::MaybeNotifyIME(nsIWidget* aWidget,
const IMENotification& aNotification) const IMENotification& aNotification)
{ {
if (!mPendingEventsNeedingAck) { if (!mPendingEventsNeedingAck) {
IMEStateManager::NotifyIME(aNotification, aWidget, true); IMEStateManager::NotifyIME(aNotification, aWidget, &mTabParent);
return; return;
} }
@ -1315,7 +1323,7 @@ ContentCacheInParent::FlushPendingNotifications(nsIWidget* aWidget)
IMENotification notification(mPendingTextChange); IMENotification notification(mPendingTextChange);
if (!aWidget->Destroyed()) { if (!aWidget->Destroyed()) {
mPendingTextChange.Clear(); mPendingTextChange.Clear();
IMEStateManager::NotifyIME(notification, aWidget, true); IMEStateManager::NotifyIME(notification, aWidget, &mTabParent);
} }
} }
@ -1323,7 +1331,7 @@ ContentCacheInParent::FlushPendingNotifications(nsIWidget* aWidget)
IMENotification notification(mPendingSelectionChange); IMENotification notification(mPendingSelectionChange);
if (!aWidget->Destroyed()) { if (!aWidget->Destroyed()) {
mPendingSelectionChange.Clear(); mPendingSelectionChange.Clear();
IMEStateManager::NotifyIME(notification, aWidget, true); IMEStateManager::NotifyIME(notification, aWidget, &mTabParent);
} }
} }
@ -1333,7 +1341,7 @@ ContentCacheInParent::FlushPendingNotifications(nsIWidget* aWidget)
IMENotification notification(mPendingLayoutChange); IMENotification notification(mPendingLayoutChange);
if (!aWidget->Destroyed()) { if (!aWidget->Destroyed()) {
mPendingLayoutChange.Clear(); mPendingLayoutChange.Clear();
IMEStateManager::NotifyIME(notification, aWidget, true); IMEStateManager::NotifyIME(notification, aWidget, &mTabParent);
} }
} }
@ -1343,7 +1351,7 @@ ContentCacheInParent::FlushPendingNotifications(nsIWidget* aWidget)
IMENotification notification(mPendingCompositionUpdate); IMENotification notification(mPendingCompositionUpdate);
if (!aWidget->Destroyed()) { if (!aWidget->Destroyed()) {
mPendingCompositionUpdate.Clear(); mPendingCompositionUpdate.Clear();
IMEStateManager::NotifyIME(notification, aWidget, true); IMEStateManager::NotifyIME(notification, aWidget, &mTabParent);
} }
} }

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

@ -23,6 +23,10 @@ namespace mozilla {
class ContentCacheInParent; class ContentCacheInParent;
namespace dom {
class TabParent;
} // namespace dom
/** /**
* ContentCache stores various information of the child content. * ContentCache stores various information of the child content.
* This class has members which are necessary both in parent process and * This class has members which are necessary both in parent process and
@ -318,7 +322,7 @@ private:
class ContentCacheInParent final : public ContentCache class ContentCacheInParent final : public ContentCache
{ {
public: public:
ContentCacheInParent(); explicit ContentCacheInParent(dom::TabParent& aTabParent);
/** /**
* AssignContent() is called when TabParent receives ContentCache from * AssignContent() is called when TabParent receives ContentCache from
@ -406,6 +410,8 @@ private:
IMENotification mPendingLayoutChange; IMENotification mPendingLayoutChange;
IMENotification mPendingCompositionUpdate; IMENotification mPendingCompositionUpdate;
// mTabParent is owner of the instance.
dom::TabParent& MOZ_NON_OWNING_REF mTabParent;
// This is not nullptr only while the instance is requesting IME to // This is not nullptr only while the instance is requesting IME to
// composition. Then, data value of dispatched composition events should // composition. Then, data value of dispatched composition events should
// be stored into the instance. // be stored into the instance.
@ -432,6 +438,8 @@ private:
// dispatched and set to false when eCompositionCommit(AsIs) is dispatched. // dispatched and set to false when eCompositionCommit(AsIs) is dispatched.
bool mWidgetHasComposition; bool mWidgetHasComposition;
ContentCacheInParent() = delete;
/** /**
* When following methods' aRoundToExistingOffset is true, even if specified * When following methods' aRoundToExistingOffset is true, even if specified
* offset or range is out of bounds, the result is computed with the existing * offset or range is out of bounds, the result is computed with the existing

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

@ -398,8 +398,9 @@ IMEHandler::OnDestroyWindow(nsWindow* aWindow)
// here because TabParent already lost the reference to the nsWindow when // here because TabParent already lost the reference to the nsWindow when
// it receives from the remote process. // it receives from the remote process.
if (sFocusedWindow == aWindow) { if (sFocusedWindow == aWindow) {
NS_ASSERTION(aWindow->GetInputContext().IsOriginContentProcess(), MOZ_ASSERT(aWindow->GetInputContext().IsOriginContentProcess(),
"input context of focused widget should be set from a remote process"); "input context of focused widget should've been set by a remote process "
"if IME focus isn't cleared before destroying the widget");
NotifyIME(aWindow, IMENotification(NOTIFY_IME_OF_BLUR)); NotifyIME(aWindow, IMENotification(NOTIFY_IME_OF_BLUR));
} }