Bug 1266683 - Part 2 - Add private browsing mode info to InputContext. r?masayuki draft
authorJan Henning <jh+bugzilla@buttercookie.de>
Sun, 30 Jul 2017 19:45:03 +0200
changeset 641133 1f77a499db05e965a8c558615a95fb4d88578e40
parent 621291 af1b2607f2b30c76d76ed2b93eaadd1507a68935
child 641134 0d39b3e52f4bba436e7ed9567f8a0212d7cf9a21
push id72443
push usermozilla@buttercookie.de
push dateSat, 05 Aug 2017 18:41:28 +0000
reviewersmasayuki
bugs1266683
milestone56.0a1
Bug 1266683 - Part 2 - Add private browsing mode info to InputContext. r?masayuki Android now supports telling an IME that it shouldn't store user-entered content into it's dictionary/language model/etc. and we want to automatically enable this in private browsing. As the code that handles input on Android doesn't have any notion of tabs (and therefore of the difference between normal and private tabs), the best way to get that info across is to retrieve it directly within the IMEStateManager from the corresponding document and store it in the inputContext, which is then passed to Java for Fennec to handle. Implementing this within Gecko also has the benefit that this part of the code can be used by other platforms as well should they want to support similar features in the future. MozReview-Commit-ID: DsxjC4Ma7DR
dom/events/IMEStateManager.cpp
dom/events/IMEStateManager.h
dom/ipc/PBrowser.ipdl
dom/ipc/TabParent.cpp
dom/ipc/TabParent.h
widget/IMEData.h
widget/PuppetWidget.cpp
--- a/dom/events/IMEStateManager.cpp
+++ b/dom/events/IMEStateManager.cpp
@@ -342,17 +342,17 @@ IMEStateManager::OnDestroyPresContext(ns
   DestroyIMEContentObserver();
 
   if (sWidget) {
     IMEState newState = GetNewIMEState(sPresContext, nullptr);
     InputContextAction action(InputContextAction::CAUSE_UNKNOWN,
                               InputContextAction::LOST_FOCUS);
     InputContext::Origin origin =
       sActiveTabParent ? InputContext::ORIGIN_CONTENT : sOrigin;
-    SetIMEState(newState, nullptr, sWidget, action, origin);
+    SetIMEState(newState, nullptr, nullptr, sWidget, action, origin);
   }
   sWidget = nullptr;
   sContent = nullptr;
   sPresContext = nullptr;
   sActiveTabParent = nullptr;
   return NS_OK;
 }
 
@@ -399,17 +399,17 @@ IMEStateManager::OnRemoveContent(nsPresC
 
   // Current IME transaction should commit
   if (sWidget) {
     IMEState newState = GetNewIMEState(sPresContext, nullptr);
     InputContextAction action(InputContextAction::CAUSE_UNKNOWN,
                               InputContextAction::LOST_FOCUS);
     InputContext::Origin origin =
       sActiveTabParent ? InputContext::ORIGIN_CONTENT : sOrigin;
-    SetIMEState(newState, nullptr, sWidget, action, origin);
+    SetIMEState(newState, aPresContext, nullptr, sWidget, action, origin);
   }
 
   sWidget = nullptr;
   sContent = nullptr;
   sPresContext = nullptr;
   sActiveTabParent = nullptr;
 
   return NS_OK;
@@ -629,17 +629,17 @@ IMEStateManager::OnChangeFocusInternal(n
       // focus.
       bool gotFocus = aContent || (newState.mEnabled == IMEState::ENABLED);
       aAction.mFocusChange =
         gotFocus ? InputContextAction::GOT_FOCUS :
                    InputContextAction::LOST_FOCUS;
     }
 
     // Update IME state for new focus widget
-    SetIMEState(newState, aContent, newWidget, aAction,
+    SetIMEState(newState, aPresContext, aContent, newWidget, aAction,
                 newTabParent ? InputContext::ORIGIN_CONTENT : sOrigin);
   }
 
   sActiveTabParent = newTabParent;
   sPresContext = aPresContext;
   sContent = aContent;
 
   // Don't call CreateIMEContentObserver() here except when a plugin gets
@@ -781,17 +781,17 @@ IMEStateManager::OnClickInEditor(nsPresC
   }
 
   InputContextAction::Cause cause =
     aMouseEvent->inputSource == nsIDOMMouseEvent::MOZ_SOURCE_TOUCH ?
       InputContextAction::CAUSE_TOUCH : InputContextAction::CAUSE_MOUSE;
 
   InputContextAction action(cause, InputContextAction::FOCUS_NOT_CHANGED);
   IMEState newState = GetNewIMEState(aPresContext, aContent);
-  SetIMEState(newState, aContent, widget, action, sOrigin);
+  SetIMEState(newState, aPresContext, aContent, widget, action, sOrigin);
 }
 
 // static
 void
 IMEStateManager::OnFocusInEditor(nsPresContext* aPresContext,
                                  nsIContent* aContent,
                                  EditorBase& aEditorBase)
 {
@@ -990,17 +990,17 @@ IMEStateManager::UpdateIMEState(const IM
 
   if (createTextStateManager) {
     DestroyIMEContentObserver();
   }
 
   if (updateIMEState) {
     InputContextAction action(InputContextAction::CAUSE_UNKNOWN,
                               InputContextAction::FOCUS_NOT_CHANGED);
-    SetIMEState(aNewIMEState, aContent, widget, action, sOrigin);
+    SetIMEState(aNewIMEState, presContext, aContent, widget, action, sOrigin);
     if (NS_WARN_IF(widget->Destroyed())) {
       MOZ_LOG(sISMLog, LogLevel::Error,
         ("  UpdateIMEState(), widget has gone during setting input context"));
       return;
     }
   }
 
   if (createTextStateManager) {
@@ -1100,25 +1100,26 @@ void
 IMEStateManager::SetInputContextForChildProcess(
                    TabParent* aTabParent,
                    const InputContext& aInputContext,
                    const InputContextAction& aAction)
 {
   MOZ_LOG(sISMLog, LogLevel::Info,
     ("SetInputContextForChildProcess(aTabParent=0x%p, "
      "aInputContext={ mIMEState={ mEnabled=%s, mOpen=%s }, "
-     "mHTMLInputType=\"%s\", mHTMLInputInputmode=\"%s\", mActionHint=\"%s\" }, "
-     "aAction={ mCause=%s, mAction=%s }), "
+     "mHTMLInputType=\"%s\", mHTMLInputInputmode=\"%s\", mActionHint=\"%s\", "
+     "mInPrivateBrowsing=%s }, aAction={ mCause=%s, mAction=%s }), "
      "sPresContext=0x%p (available: %s), sWidget=0x%p (available: %s), "
      "sActiveTabParent=0x%p",
      aTabParent, GetIMEStateEnabledName(aInputContext.mIMEState.mEnabled),
      GetIMEStateSetOpenName(aInputContext.mIMEState.mOpen),
      NS_ConvertUTF16toUTF8(aInputContext.mHTMLInputType).get(),
      NS_ConvertUTF16toUTF8(aInputContext.mHTMLInputInputmode).get(),
      NS_ConvertUTF16toUTF8(aInputContext.mActionHint).get(),
+     GetBoolName(aInputContext.mInPrivateBrowsing),
      GetActionCauseName(aAction.mCause),
      GetActionFocusChangeName(aAction.mFocusChange),
      sPresContext.get(), GetBoolName(CanHandleWith(sPresContext)),
      sWidget, GetBoolName(sWidget && !sWidget->Destroyed()),
      sActiveTabParent.get()));
 
   if (aTabParent != sActiveTabParent) {
     MOZ_LOG(sISMLog, LogLevel::Error,
@@ -1148,16 +1149,17 @@ IMEStateManager::SetInputContextForChild
   MOZ_ASSERT(aInputContext.mOrigin == InputContext::ORIGIN_CONTENT);
 
   SetInputContext(widget, aInputContext, aAction);
 }
 
 // static
 void
 IMEStateManager::SetIMEState(const IMEState& aState,
+                             nsPresContext* aPresContext,
                              nsIContent* aContent,
                              nsIWidget* aWidget,
                              InputContextAction aAction,
                              InputContext::Origin aOrigin)
 {
   MOZ_LOG(sISMLog, LogLevel::Info,
     ("SetIMEState(aState={ mEnabled=%s, mOpen=%s }, "
      "aContent=0x%p (TabParent=0x%p), aWidget=0x%p, aAction={ mCause=%s, "
@@ -1172,16 +1174,20 @@ IMEStateManager::SetIMEState(const IMESt
   NS_ENSURE_TRUE_VOID(aWidget);
 
   InputContext context;
   context.mIMEState = aState;
   context.mOrigin = aOrigin;
   context.mMayBeIMEUnaware = context.mIMEState.IsEditable() &&
     sCheckForIMEUnawareWebApps && MayBeIMEUnawareWebApp(aContent);
 
+  context.mInPrivateBrowsing =
+    aPresContext &&
+    nsContentUtils::IsInPrivateBrowsing(aPresContext->Document());
+
   if (aContent &&
       aContent->IsAnyOfHTMLElements(nsGkAtoms::input, nsGkAtoms::textarea)) {
     if (!aContent->IsHTMLElement(nsGkAtoms::textarea)) {
       // <input type=number> has an anonymous <input type=text> descendant
       // that gets focus whenever anyone tries to focus the number control. We
       // need to check if aContent is one of those anonymous text controls and,
       // if so, use the number control instead:
       nsIContent* content = aContent;
@@ -1256,24 +1262,26 @@ IMEStateManager::SetIMEState(const IMESt
 void
 IMEStateManager::SetInputContext(nsIWidget* aWidget,
                                  const InputContext& aInputContext,
                                  const InputContextAction& aAction)
 {
   MOZ_LOG(sISMLog, LogLevel::Info,
     ("SetInputContext(aWidget=0x%p, aInputContext={ "
      "mIMEState={ mEnabled=%s, mOpen=%s }, mHTMLInputType=\"%s\", "
-     "mHTMLInputInputmode=\"%s\", mActionHint=\"%s\" }, "
+     "mHTMLInputInputmode=\"%s\", mActionHint=\"%s\", "
+     "mInPrivateBrowsing=%s }, "
      "aAction={ mCause=%s, mAction=%s }), sActiveTabParent=0x%p",
      aWidget,
      GetIMEStateEnabledName(aInputContext.mIMEState.mEnabled),
      GetIMEStateSetOpenName(aInputContext.mIMEState.mOpen),
      NS_ConvertUTF16toUTF8(aInputContext.mHTMLInputType).get(),
      NS_ConvertUTF16toUTF8(aInputContext.mHTMLInputInputmode).get(),
      NS_ConvertUTF16toUTF8(aInputContext.mActionHint).get(),
+     GetBoolName(aInputContext.mInPrivateBrowsing),
      GetActionCauseName(aAction.mCause),
      GetActionFocusChangeName(aAction.mFocusChange),
      sActiveTabParent.get()));
 
   MOZ_RELEASE_ASSERT(aWidget);
 
   nsCOMPtr<nsIWidget> widget(aWidget);
   widget->SetInputContext(aInputContext, aAction);
--- a/dom/events/IMEStateManager.h
+++ b/dom/events/IMEStateManager.h
@@ -255,16 +255,17 @@ public:
    */
   static IMEContentObserver* GetActiveContentObserver();
 
 protected:
   static nsresult OnChangeFocusInternal(nsPresContext* aPresContext,
                                         nsIContent* aContent,
                                         InputContextAction aAction);
   static void SetIMEState(const IMEState &aState,
+                          nsPresContext* aPresContext,
                           nsIContent* aContent,
                           nsIWidget* aWidget,
                           InputContextAction aAction,
                           InputContext::Origin aOrigin);
   static void SetInputContext(nsIWidget* aWidget,
                               const InputContext& aInputContext,
                               const InputContextAction& aAction);
   static IMEState GetNewIMEState(nsPresContext* aPresContext,
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -349,16 +349,17 @@ parent:
     nested(inside_cpow) sync GetInputContext() returns (int32_t IMEEnabled,
                                                         int32_t IMEOpen);
 
     nested(inside_cpow) async SetInputContext(int32_t IMEEnabled,
                                               int32_t IMEOpen,
                                               nsString type,
                                               nsString inputmode,
                                               nsString actionHint,
+                                              bool inPrivateBrowsing,
                                               int32_t cause,
                                               int32_t focusChange);
 
     sync IsParentWindowMainWidgetVisible() returns (bool visible);
 
     /**
      * Set the native cursor.
      * @param value
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -2330,26 +2330,28 @@ TabParent::RecvGetInputContext(int32_t* 
 }
 
 mozilla::ipc::IPCResult
 TabParent::RecvSetInputContext(const int32_t& aIMEEnabled,
                                const int32_t& aIMEOpen,
                                const nsString& aType,
                                const nsString& aInputmode,
                                const nsString& aActionHint,
+                               const bool& aInPrivateBrowsing,
                                const int32_t& aCause,
                                const int32_t& aFocusChange)
 {
   InputContext context;
   context.mIMEState.mEnabled = static_cast<IMEState::Enabled>(aIMEEnabled);
   context.mIMEState.mOpen = static_cast<IMEState::Open>(aIMEOpen);
   context.mHTMLInputType.Assign(aType);
   context.mHTMLInputInputmode.Assign(aInputmode);
   context.mActionHint.Assign(aActionHint);
   context.mOrigin = InputContext::ORIGIN_CONTENT;
+  context.mInPrivateBrowsing = aInPrivateBrowsing;
 
   InputContextAction action(
     static_cast<InputContextAction::Cause>(aCause),
     static_cast<InputContextAction::FocusChange>(aFocusChange));
 
   IMEStateManager::SetInputContextForChildProcess(this, context, action);
 
   return IPC_OK();
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -245,16 +245,17 @@ public:
   virtual mozilla::ipc::IPCResult RecvGetInputContext(int32_t* aIMEEnabled,
                                                       int32_t* aIMEOpen) override;
 
   virtual mozilla::ipc::IPCResult RecvSetInputContext(const int32_t& aIMEEnabled,
                                                       const int32_t& aIMEOpen,
                                                       const nsString& aType,
                                                       const nsString& aInputmode,
                                                       const nsString& aActionHint,
+                                                      const bool& aInPrivateBrowsing,
                                                       const int32_t& aCause,
                                                       const int32_t& aFocusChange) override;
 
 
   // See nsIKeyEventInPluginCallback
   virtual void HandledWindowedPluginKeyEvent(
                  const NativeEventData& aKeyEventData,
                  bool aIsConsumed) override;
--- a/widget/IMEData.h
+++ b/widget/IMEData.h
@@ -266,16 +266,17 @@ struct NativeIMEContext final
   }
 };
 
 struct InputContext final
 {
   InputContext()
     : mOrigin(XRE_IsParentProcess() ? ORIGIN_MAIN : ORIGIN_CONTENT)
     , mMayBeIMEUnaware(false)
+    , mInPrivateBrowsing(false)
   {
   }
 
   bool IsPasswordEditor() const
   {
     return mHTMLInputType.LowerCaseEqualsLiteral("password");
   }
 
@@ -303,16 +304,20 @@ struct InputContext final
   };
   Origin mOrigin;
 
   /* True if the webapp may be unaware of IME events such as input event or
    * composiion events. This enables a key-events-only mode on Android for
    * compatibility with webapps relying on key listeners. */
   bool mMayBeIMEUnaware;
 
+  /* Whether the owning document of the input element has been loaded
+   * in private browsing mode. */
+  bool mInPrivateBrowsing;
+
   bool IsOriginMainProcess() const
   {
     return mOrigin == ORIGIN_MAIN;
   }
 
   bool IsOriginContentProcess() const
   {
     return mOrigin == ORIGIN_CONTENT;
--- a/widget/PuppetWidget.cpp
+++ b/widget/PuppetWidget.cpp
@@ -733,16 +733,17 @@ PuppetWidget::SetInputContext(const Inpu
     return;
   }
   mTabChild->SendSetInputContext(
     static_cast<int32_t>(aContext.mIMEState.mEnabled),
     static_cast<int32_t>(aContext.mIMEState.mOpen),
     aContext.mHTMLInputType,
     aContext.mHTMLInputInputmode,
     aContext.mActionHint,
+    aContext.mInPrivateBrowsing,
     static_cast<int32_t>(aAction.mCause),
     static_cast<int32_t>(aAction.mFocusChange));
 }
 
 InputContext
 PuppetWidget::GetInputContext()
 {
   // XXX Currently, we don't support retrieving IME open state from child