mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
Bug 532738 - Do not open the virtual keyboard on untrusted focus (caused by content page scripts) [r=masayuki]
This commit is contained in:
parent
34bb38d9d1
commit
9d29efb784
@ -89,7 +89,7 @@ nsIMEStateManager::OnDestroyPresContext(nsPresContext* aPresContext)
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget(sPresContext);
|
||||
if (widget) {
|
||||
PRUint32 newState = GetNewIMEState(sPresContext, nsnull);
|
||||
SetIMEState(newState, nsnull, widget);
|
||||
SetIMEState(newState, nsnull, widget, IMEContext::FOCUS_REMOVED);
|
||||
}
|
||||
sContent = nsnull;
|
||||
sPresContext = nsnull;
|
||||
@ -114,7 +114,7 @@ nsIMEStateManager::OnRemoveContent(nsPresContext* aPresContext,
|
||||
if (NS_FAILED(rv))
|
||||
widget->ResetInputState();
|
||||
PRUint32 newState = GetNewIMEState(sPresContext, nsnull);
|
||||
SetIMEState(newState, nsnull, widget);
|
||||
SetIMEState(newState, nsnull, widget, IMEContext::FOCUS_REMOVED);
|
||||
}
|
||||
|
||||
sContent = nsnull;
|
||||
@ -125,7 +125,8 @@ nsIMEStateManager::OnRemoveContent(nsPresContext* aPresContext,
|
||||
|
||||
nsresult
|
||||
nsIMEStateManager::OnChangeFocus(nsPresContext* aPresContext,
|
||||
nsIContent* aContent)
|
||||
nsIContent* aContent,
|
||||
PRUint32 aReason)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPresContext);
|
||||
|
||||
@ -191,7 +192,7 @@ nsIMEStateManager::OnChangeFocus(nsPresContext* aPresContext,
|
||||
|
||||
if (newState != nsIContent::IME_STATUS_NONE) {
|
||||
// Update IME state for new focus widget
|
||||
SetIMEState(newState, aContent, widget);
|
||||
SetIMEState(newState, aContent, widget, aReason);
|
||||
}
|
||||
|
||||
sPresContext = aPresContext;
|
||||
@ -204,7 +205,10 @@ void
|
||||
nsIMEStateManager::OnInstalledMenuKeyboardListener(PRBool aInstalling)
|
||||
{
|
||||
sInstalledMenuKeyboardListener = aInstalling;
|
||||
OnChangeFocus(sPresContext, sContent);
|
||||
|
||||
PRUint32 reason = aInstalling ? IMEContext::FOCUS_MOVED_TO_MENU
|
||||
: IMEContext::FOCUS_MOVED_FROM_MENU;
|
||||
OnChangeFocus(sPresContext, sContent, reason);
|
||||
}
|
||||
|
||||
void
|
||||
@ -236,7 +240,7 @@ nsIMEStateManager::UpdateIMEState(PRUint32 aNewIMEState, nsIContent* aContent)
|
||||
// commit current composition
|
||||
widget->ResetInputState();
|
||||
|
||||
SetIMEState(aNewIMEState, aContent, widget);
|
||||
SetIMEState(aNewIMEState, aContent, widget, IMEContext::EDITOR_STATE_MODIFIED);
|
||||
}
|
||||
|
||||
PRUint32
|
||||
@ -289,7 +293,8 @@ private:
|
||||
void
|
||||
nsIMEStateManager::SetIMEState(PRUint32 aState,
|
||||
nsIContent* aContent,
|
||||
nsIWidget* aWidget)
|
||||
nsIWidget* aWidget,
|
||||
PRUint32 aReason)
|
||||
{
|
||||
if (aState & nsIContent::IME_STATUS_MASK_ENABLED) {
|
||||
if (!aWidget)
|
||||
@ -327,6 +332,12 @@ nsIMEStateManager::SetIMEState(PRUint32 aState,
|
||||
}
|
||||
}
|
||||
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||
context.mReason = aReason | IMEContext::FOCUS_FROM_CONTENT_PROCESS;
|
||||
} else {
|
||||
context.mReason = aReason;
|
||||
}
|
||||
|
||||
aWidget->SetInputMode(context);
|
||||
|
||||
nsContentUtils::AddScriptRunner(new IMEEnabledStateChangedEvent(state));
|
||||
|
@ -59,7 +59,8 @@ public:
|
||||
static nsresult OnRemoveContent(nsPresContext* aPresContext,
|
||||
nsIContent* aContent);
|
||||
static nsresult OnChangeFocus(nsPresContext* aPresContext,
|
||||
nsIContent* aContent);
|
||||
nsIContent* aContent,
|
||||
PRUint32 aReason);
|
||||
static void OnInstalledMenuKeyboardListener(PRBool aInstalling);
|
||||
|
||||
// These two methods manage focus and selection/text observers.
|
||||
@ -90,7 +91,7 @@ public:
|
||||
|
||||
protected:
|
||||
static void SetIMEState(PRUint32 aState, nsIContent* aContent,
|
||||
nsIWidget* aWidget);
|
||||
nsIWidget* aWidget, PRUint32 aReason);
|
||||
static PRUint32 GetNewIMEState(nsPresContext* aPresContext,
|
||||
nsIContent* aContent);
|
||||
|
||||
|
@ -337,6 +337,22 @@ nsFocusManager::GetRedirectedFocus(nsIContent* aContent)
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// static
|
||||
PRUint32
|
||||
nsFocusManager::GetFocusMoveReason(PRUint32 aFlags)
|
||||
{
|
||||
PRUint32 reason = IMEContext::FOCUS_MOVED_UNKNOWN;
|
||||
if (aFlags & nsIFocusManager::FLAG_BYMOUSE) {
|
||||
reason = IMEContext::FOCUS_MOVED_BY_MOUSE;
|
||||
} else if (aFlags & nsIFocusManager::FLAG_BYKEY) {
|
||||
reason = IMEContext::FOCUS_MOVED_BY_KEY;
|
||||
} else if (aFlags & nsIFocusManager::FLAG_BYMOVEFOCUS) {
|
||||
reason = IMEContext::FOCUS_MOVED_BY_MOVEFOCUS;
|
||||
}
|
||||
|
||||
return reason;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFocusManager::GetActiveWindow(nsIDOMWindow** aWindow)
|
||||
{
|
||||
@ -943,7 +959,7 @@ nsFocusManager::WindowHidden(nsIDOMWindow* aWindow)
|
||||
|
||||
nsIMEStateManager::OnTextStateBlur(nsnull, nsnull);
|
||||
if (presShell) {
|
||||
nsIMEStateManager::OnChangeFocus(presShell->GetPresContext(), nsnull);
|
||||
nsIMEStateManager::OnChangeFocus(presShell->GetPresContext(), nsnull, IMEContext::FOCUS_REMOVED);
|
||||
SetCaretVisible(presShell, PR_FALSE, nsnull);
|
||||
}
|
||||
|
||||
@ -1484,7 +1500,7 @@ nsFocusManager::Blur(nsPIDOMWindow* aWindowToClear,
|
||||
// compositionend event won't get fired at the element being blurred.
|
||||
nsIMEStateManager::OnTextStateBlur(nsnull, nsnull);
|
||||
if (mActiveWindow)
|
||||
nsIMEStateManager::OnChangeFocus(presShell->GetPresContext(), nsnull);
|
||||
nsIMEStateManager::OnChangeFocus(presShell->GetPresContext(), nsnull, IMEContext::FOCUS_REMOVED);
|
||||
|
||||
// now adjust the actual focus, by clearing the fields in the focus manager
|
||||
// and in the window.
|
||||
@ -1727,7 +1743,8 @@ nsFocusManager::Focus(nsPIDOMWindow* aWindow,
|
||||
objectFrameWidget->SetFocus(PR_FALSE);
|
||||
}
|
||||
|
||||
nsIMEStateManager::OnChangeFocus(presContext, aContent);
|
||||
PRUint32 reason = GetFocusMoveReason(aFlags);
|
||||
nsIMEStateManager::OnChangeFocus(presContext, aContent, reason);
|
||||
|
||||
// as long as this focus wasn't because a window was raised, update the
|
||||
// commands
|
||||
@ -1743,7 +1760,7 @@ nsFocusManager::Focus(nsPIDOMWindow* aWindow,
|
||||
nsIMEStateManager::OnTextStateFocus(presContext, aContent);
|
||||
} else {
|
||||
nsIMEStateManager::OnTextStateBlur(presContext, nsnull);
|
||||
nsIMEStateManager::OnChangeFocus(presContext, nsnull);
|
||||
nsIMEStateManager::OnChangeFocus(presContext, nsnull, IMEContext::FOCUS_REMOVED);
|
||||
if (!aWindowRaised) {
|
||||
aWindow->UpdateCommands(NS_LITERAL_STRING("focus"));
|
||||
}
|
||||
@ -1766,7 +1783,7 @@ nsFocusManager::Focus(nsPIDOMWindow* aWindow,
|
||||
|
||||
nsPresContext* presContext = presShell->GetPresContext();
|
||||
nsIMEStateManager::OnTextStateBlur(presContext, nsnull);
|
||||
nsIMEStateManager::OnChangeFocus(presContext, nsnull);
|
||||
nsIMEStateManager::OnChangeFocus(presContext, nsnull, IMEContext::FOCUS_REMOVED);
|
||||
|
||||
if (!aWindowRaised)
|
||||
aWindow->UpdateCommands(NS_LITERAL_STRING("focus"));
|
||||
|
@ -123,6 +123,13 @@ public:
|
||||
*/
|
||||
static nsIContent* GetRedirectedFocus(nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* Returns a flag indicating the source and/or reason of the focus change.
|
||||
* This is used to indicate to the IME code if the focus come from a user
|
||||
* input or a script for example.
|
||||
*/
|
||||
static PRUint32 GetFocusMoveReason(PRUint32 aFlags);
|
||||
|
||||
static PRBool sMouseFocusesFormControl;
|
||||
|
||||
protected:
|
||||
|
@ -169,7 +169,7 @@ parent:
|
||||
|
||||
sync GetIMEEnabled() returns (PRUint32 value);
|
||||
|
||||
SetInputMode(PRUint32 value, nsString type, nsString actionHint);
|
||||
SetInputMode(PRUint32 value, nsString type, nsString actionHint, PRUint32 reason);
|
||||
|
||||
sync GetIMEOpenState() returns (PRBool value);
|
||||
|
||||
|
@ -525,7 +525,7 @@ TabParent::RecvGetIMEEnabled(PRUint32* aValue)
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvSetInputMode(const PRUint32& aValue, const nsString& aType, const nsString& aAction)
|
||||
TabParent::RecvSetInputMode(const PRUint32& aValue, const nsString& aType, const nsString& aAction, const PRUint32& aReason)
|
||||
{
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (!widget || !AllowContentIME())
|
||||
@ -535,6 +535,7 @@ TabParent::RecvSetInputMode(const PRUint32& aValue, const nsString& aType, const
|
||||
context.mStatus = aValue;
|
||||
context.mHTMLInputType.Assign(aType);
|
||||
context.mActionHint.Assign(aAction);
|
||||
context.mReason = aReason;
|
||||
widget->SetInputMode(context);
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
|
||||
|
@ -104,7 +104,7 @@ public:
|
||||
virtual bool RecvEndIMEComposition(const PRBool& aCancel,
|
||||
nsString* aComposition);
|
||||
virtual bool RecvGetIMEEnabled(PRUint32* aValue);
|
||||
virtual bool RecvSetInputMode(const PRUint32& aValue, const nsString& aType, const nsString& aAction);
|
||||
virtual bool RecvSetInputMode(const PRUint32& aValue, const nsString& aType, const nsString& aAction, const PRUint32& aReason);
|
||||
virtual bool RecvGetIMEOpenState(PRBool* aValue);
|
||||
virtual bool RecvSetIMEOpenState(const PRBool& aValue);
|
||||
virtual bool RecvGetDPI(float* aValue);
|
||||
|
@ -474,8 +474,9 @@ public class GeckoAppShell
|
||||
if (!mEnable)
|
||||
return;
|
||||
|
||||
if (GeckoApp.surfaceView.mIMEState !=
|
||||
GeckoSurfaceView.IME_STATE_DISABLED)
|
||||
int state = GeckoApp.surfaceView.mIMEState;
|
||||
if (state != GeckoSurfaceView.IME_STATE_DISABLED &&
|
||||
state != GeckoSurfaceView.IME_STATE_PLUGIN)
|
||||
imm.showSoftInput(GeckoApp.surfaceView, 0);
|
||||
else
|
||||
imm.hideSoftInputFromWindow(
|
||||
|
@ -619,6 +619,7 @@ class GeckoSurfaceView
|
||||
public static final int IME_STATE_DISABLED = 0;
|
||||
public static final int IME_STATE_ENABLED = 1;
|
||||
public static final int IME_STATE_PASSWORD = 2;
|
||||
public static final int IME_STATE_PLUGIN = 3;
|
||||
|
||||
GeckoInputConnection inputConnection;
|
||||
KeyListener mKeyListener;
|
||||
|
@ -233,6 +233,29 @@ struct nsIMEUpdatePreference {
|
||||
struct IMEContext {
|
||||
PRUint32 mStatus;
|
||||
|
||||
/* Does the change come from a trusted source */
|
||||
enum {
|
||||
FOCUS_REMOVED = 0x0001,
|
||||
FOCUS_MOVED_UNKNOWN = 0x0002,
|
||||
FOCUS_MOVED_BY_MOVEFOCUS = 0x0004,
|
||||
FOCUS_MOVED_BY_MOUSE = 0x0008,
|
||||
FOCUS_MOVED_BY_KEY = 0x0010,
|
||||
FOCUS_MOVED_TO_MENU = 0x0020,
|
||||
FOCUS_MOVED_FROM_MENU = 0x0040,
|
||||
EDITOR_STATE_MODIFIED = 0x0080,
|
||||
FOCUS_FROM_CONTENT_PROCESS = 0x0100
|
||||
};
|
||||
|
||||
PRBool FocusMovedByUser() const {
|
||||
return (mReason & FOCUS_MOVED_BY_MOUSE) || (mReason & FOCUS_MOVED_BY_KEY);
|
||||
};
|
||||
|
||||
PRBool FocusMovedInContentProcess() const {
|
||||
return (mReason & FOCUS_FROM_CONTENT_PROCESS);
|
||||
};
|
||||
|
||||
PRUint32 mReason;
|
||||
|
||||
/* The type of the input if the input is a html input field */
|
||||
nsString mHTMLInputType;
|
||||
|
||||
|
@ -52,6 +52,7 @@ using mozilla::unused;
|
||||
#include "nsIdleService.h"
|
||||
#include "nsWindow.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIPrefService.h"
|
||||
|
||||
#include "nsRenderingContext.h"
|
||||
#include "nsIDOMSimpleGestureEvent.h"
|
||||
@ -1740,9 +1741,25 @@ nsWindow::ResetInputState()
|
||||
NS_IMETHODIMP
|
||||
nsWindow::SetInputMode(const IMEContext& aContext)
|
||||
{
|
||||
ALOGIME("IME: SetInputMode: s=%d", aContext.mStatus);
|
||||
ALOGIME("IME: SetInputMode: s=%d trusted=%d", aContext.mStatus, aContext.mReason);
|
||||
|
||||
mIMEContext = aContext;
|
||||
|
||||
// Ensure that opening the virtual keyboard is allowed for this specific
|
||||
// IMEContext depending on the content.ime.strict.policy pref
|
||||
if (aContext.mStatus != nsIWidget::IME_STATUS_DISABLED &&
|
||||
aContext.mStatus != nsIWidget::IME_STATUS_PLUGIN) {
|
||||
nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
|
||||
|
||||
PRBool useStrictPolicy = PR_FALSE;
|
||||
if (NS_SUCCEEDED(prefs->GetBoolPref("content.ime.strict_policy", &useStrictPolicy))) {
|
||||
if (useStrictPolicy && !aContext.FocusMovedByUser() &&
|
||||
aContext.FocusMovedInContentProcess()) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AndroidBridge::NotifyIMEEnabled(int(aContext.mStatus), aContext.mHTMLInputType, aContext.mActionHint);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -53,6 +53,7 @@
|
||||
#ifdef MOZ_PLATFORM_MAEMO
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "mozilla/Services.h"
|
||||
#endif
|
||||
|
||||
@ -588,6 +589,22 @@ nsGtkIMModule::SetInputMode(nsWindow* aCaller, const IMEContext* aContext)
|
||||
GtkIMContext *im = GetContext();
|
||||
if (im) {
|
||||
if (IsEnabled()) {
|
||||
// Ensure that opening the virtual keyboard is allowed for this specific
|
||||
// IMEContext depending on the content.ime.strict.policy pref
|
||||
if (mIMEContext.mStatus != nsIWidget::IME_STATUS_DISABLED &&
|
||||
mIMEContext.mStatus != nsIWidget::IME_STATUS_PLUGIN) {
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
|
||||
|
||||
PRBool useStrictPolicy = PR_FALSE;
|
||||
if (NS_SUCCEEDED(prefs->GetBoolPref("content.ime.strict_policy", &useStrictPolicy))) {
|
||||
if (useStrictPolicy && !mIMEContext.FocusMovedByUser() &&
|
||||
mIMEContext.FocusMovedInContentProcess()) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// It is not desired that the hildon's autocomplete mechanism displays
|
||||
// user previous entered passwds, so lets make completions invisible
|
||||
// in these cases.
|
||||
|
@ -398,7 +398,8 @@ NS_IMETHODIMP
|
||||
PuppetWidget::SetInputMode(const IMEContext& aContext)
|
||||
{
|
||||
if (mTabChild &&
|
||||
mTabChild->SendSetInputMode(aContext.mStatus, aContext.mHTMLInputType, aContext.mActionHint))
|
||||
mTabChild->SendSetInputMode(aContext.mStatus, aContext.mHTMLInputType,
|
||||
aContext.mActionHint, aContext.mReason))
|
||||
return NS_OK;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user