bug 582644 - IME event remoting, patch for android r=blassey blocking-fennec=2.0a1+
authorJim Chen <nchen@mozilla.com>
Mon, 16 Aug 2010 14:48:32 -0700
changeset 50691 6d383749eacfe5b841450d824da30289162d4634
parent 50690 b967e8b3e927a013d0ed5f183de68a902dc3c2a4
child 50692 be7c2f122492fea7270266dad29d006978b6c5bb
push idunknown
push userunknown
push dateunknown
reviewersblassey
bugs582644
milestone2.0b4pre
bug 582644 - IME event remoting, patch for android r=blassey blocking-fennec=2.0a1+
dom/ipc/TabParent.cpp
widget/public/nsGUIEvent.h
widget/src/android/AndroidBridge.cpp
widget/src/android/nsWindow.cpp
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -66,16 +66,21 @@
 #include "nsIDOMNSHTMLFrameElement.h"
 #include "nsIDialogCreator.h"
 #include "nsThreadUtils.h"
 #include "nsSerializationHelper.h"
 #include "nsIPromptFactory.h"
 #include "nsIContent.h"
 #include "mozilla/unused.h"
 
+#ifdef ANDROID
+#include "AndroidBridge.h"
+using namespace mozilla;
+#endif
+
 using mozilla::ipc::DocumentRendererParent;
 using mozilla::ipc::DocumentRendererShmemParent;
 using mozilla::ipc::DocumentRendererNativeIDParent;
 using mozilla::dom::ContentParent;
 
 // The flags passed by the webProgress notifications are 16 bits shifted
 // from the ones registered by webProgressListeners.
 #define NOTIFY_FLAG_SHIFT 16
@@ -565,17 +570,37 @@ TabParent::RecvAsyncMessage(const nsStri
                             const nsString& aJSON)
 {
   return ReceiveMessage(aMessage, PR_FALSE, aJSON, nsnull);
 }
 
 bool
 TabParent::RecvQueryContentResult(const nsQueryContentEvent& event)
 {
+#ifdef ANDROID
+  if (!event.mSucceeded) {
+    AndroidBridge::Bridge()->ReturnIMEQueryResult(nsnull, 0, 0, 0);
     return true;
+  }
+
+  switch (event.message) {
+  case NS_QUERY_TEXT_CONTENT:
+    AndroidBridge::Bridge()->ReturnIMEQueryResult(
+        event.mReply.mString.get(), event.mReply.mString.Length(), 0, 0);
+    break;
+  case NS_QUERY_SELECTED_TEXT:
+    AndroidBridge::Bridge()->ReturnIMEQueryResult(
+        event.mReply.mString.get(),
+        event.mReply.mString.Length(),
+        event.GetSelectionStart(),
+        event.GetSelectionEnd() - event.GetSelectionStart());
+    break;
+  }
+#endif
+  return true;
 }
 
 bool
 TabParent::ReceiveMessage(const nsString& aMessage,
                           PRBool aSync,
                           const nsString& aJSON,
                           nsTArray<nsString>* aJSONRetVal)
 {
--- a/widget/public/nsGUIEvent.h
+++ b/widget/public/nsGUIEvent.h
@@ -1256,16 +1256,30 @@ public:
   void InitForQueryTextRect(PRUint32 aOffset, PRUint32 aLength)
   {
     NS_ASSERTION(message == NS_QUERY_TEXT_RECT,
                  "wrong initializer is called");
     mInput.mOffset = aOffset;
     mInput.mLength = aLength;
   }
 
+  PRUint32 GetSelectionStart(void) const
+  {
+    NS_ASSERTION(message == NS_QUERY_SELECTED_TEXT,
+                 "not querying selection");
+    return mReply.mOffset + (mReply.mReversed ? mReply.mString.Length() : 0);
+  }
+
+  PRUint32 GetSelectionEnd(void) const
+  {
+    NS_ASSERTION(message == NS_QUERY_SELECTED_TEXT,
+                 "not querying selection");
+    return mReply.mOffset + (mReply.mReversed ? 0 : mReply.mString.Length());
+  }
+
   PRBool mSucceeded;
   PRPackedBool mWasAsync;
   struct {
     PRUint32 mOffset;
     PRUint32 mLength;
   } mInput;
   struct {
     void* mContentsRoot;
--- a/widget/src/android/AndroidBridge.cpp
+++ b/widget/src/android/AndroidBridge.cpp
@@ -32,17 +32,20 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include <android/log.h>
 
+#ifdef MOZ_IPC
 #include "mozilla/dom/ContentChild.h"
+#include "nsXULAppAPI.h"
+#endif
 #include <pthread.h>
 #include <prthread.h>
 #include "nsXPCOMStrings.h"
 
 #include "AndroidBridge.h"
 
 using namespace mozilla;
 
@@ -187,28 +190,34 @@ AndroidBridge::EnsureJNIThread()
 }
 
 void
 AndroidBridge::NotifyIME(int aType, int aState)
 {
     if (sBridge)
         JNI()->CallStaticVoidMethod(sBridge->mGeckoAppShellClass, 
                                     sBridge->jNotifyIME,  aType, aState);
-    else
+#ifdef MOZ_IPC
+    // It's possible that we are in chrome process
+    //  but sBridge is not initialized yet
+    else if (XRE_GetProcessType() == GeckoProcessType_Content)
         mozilla::dom::ContentChild::GetSingleton()->SendNotifyIME(aType, aState);
+#endif
 }
 
 void
 AndroidBridge::NotifyIMEChange(const PRUnichar *aText, PRUint32 aTextLen,
                                int aStart, int aEnd, int aNewEnd)
 {
     if (!sBridge) {
+#ifdef MOZ_IPC
         mozilla::dom::ContentChild::GetSingleton()->
             SendNotifyIMEChange(nsAutoString(aText), aTextLen,
                                 aStart, aEnd, aNewEnd);
+#endif
         return;
     }
 
     jvalue args[4];
     AutoLocalJNIFrame jniFrame(1);
     args[0].l = JNI()->NewString(aText, aTextLen);
     args[1].i = aStart;
     args[2].i = aEnd;
--- a/widget/src/android/nsWindow.cpp
+++ b/widget/src/android/nsWindow.cpp
@@ -1360,21 +1360,21 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *
             
             DispatchEvent(&event);
 
             if (!event.mSucceeded) {
                 ALOGIME("IME:     -> failed");
                 AndroidBridge::Bridge()->ReturnIMEQueryResult(
                     nsnull, 0, 0, 0);
                 return;
+            } else if (!event.mWasAsync) {
+                AndroidBridge::Bridge()->ReturnIMEQueryResult(
+                    event.mReply.mString.get(), 
+                    event.mReply.mString.Length(), 0, 0);
             }
-
-            AndroidBridge::Bridge()->ReturnIMEQueryResult(
-                event.mReply.mString.get(), 
-                event.mReply.mString.Length(), 0, 0);
             //ALOGIME("IME:     -> l=%u", event.mReply.mString.Length());
         }
         return;
     case AndroidGeckoEvent::IME_DELETE_TEXT:
         {   
             ALOGIME("IME: IME_DELETE_TEXT");
             nsContentCommandEvent event(PR_TRUE,
                                         NS_CONTENT_COMMAND_DELETE, this);
@@ -1406,31 +1406,23 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *
             InitEvent(event, nsnull);
             DispatchEvent(&event);
 
             if (!event.mSucceeded) {
                 ALOGIME("IME:     -> failed");
                 AndroidBridge::Bridge()->ReturnIMEQueryResult(
                     nsnull, 0, 0, 0);
                 return;
+            } else if (!event.mWasAsync) {
+                AndroidBridge::Bridge()->ReturnIMEQueryResult(
+                    event.mReply.mString.get(),
+                    event.mReply.mString.Length(), 
+                    event.GetSelectionStart(),
+                    event.GetSelectionEnd() - event.GetSelectionStart());
             }
-
-            int selStart = int(event.mReply.mOffset + 
-                            (event.mReply.mReversed ? 
-                                event.mReply.mString.Length() : 0));
-
-            int selLength = event.mReply.mReversed ?
-                                int(event.mReply.mString.Length()) : 
-                                -int(event.mReply.mString.Length());
-
-            AndroidBridge::Bridge()->ReturnIMEQueryResult(
-                event.mReply.mString.get(),
-                event.mReply.mString.Length(), 
-                selStart, selLength);
-
             //ALOGIME("IME:     -> o=%u, l=%u", event.mReply.mOffset, event.mReply.mString.Length());
         }
         return;
     }
 }
 
 nsWindow *
 nsWindow::FindWindowForPoint(const nsIntPoint& pt)
@@ -1515,20 +1507,19 @@ nsWindow::CancelIMEComposition()
     AndroidBridge::NotifyIME(AndroidBridge::NOTIFY_IME_CANCELCOMPOSITION, 0);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWindow::OnIMEFocusChange(PRBool aFocus)
 {
     ALOGIME("IME: OnIMEFocusChange: f=%d", aFocus);
-    
-    if (AndroidBridge::Bridge())
-        AndroidBridge::NotifyIME(AndroidBridge::NOTIFY_IME_FOCUSCHANGE, 
-                                 int(aFocus));
+
+    AndroidBridge::NotifyIME(AndroidBridge::NOTIFY_IME_FOCUSCHANGE, 
+                             int(aFocus));
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWindow::OnIMETextChange(PRUint32 aStart, PRUint32 aOldEnd, PRUint32 aNewEnd)
 {
     ALOGIME("IME: OnIMETextChange: s=%d, oe=%d, ne=%d",
             aStart, aOldEnd, aNewEnd);