Bug 742036 - Part 3: Pass Android's native keycodes to Flash plugin using nsGUIEvent::pluginEvent. r=masayuki,blassey a=blocking-fennec
☠☠ backed out by 029dae90f2cc ☠ ☠
authorChris Peterson <cpeterson@mozilla.com>
Thu, 19 Apr 2012 10:49:31 -0700
changeset 95300 4e26b559d215890bc9b5cc720c9f72b7913779a1
parent 95299 d74da7b4bf106db071ce7657b3b2990146aada9a
child 95301 7ecd07342540a2ca2fd14459064170334a72740e
push id886
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 19:57:52 +0000
treeherdermozilla-beta@bbd8d5efd6d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmasayuki, blassey, blocking-fennec
bugs742036
milestone14.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 742036 - Part 3: Pass Android's native keycodes to Flash plugin using nsGUIEvent::pluginEvent. r=masayuki,blassey a=blocking-fennec
dom/plugins/base/android/Makefile.in
dom/plugins/base/nsPluginInstanceOwner.cpp
widget/android/nsWindow.cpp
widget/android/nsWindow.h
--- a/dom/plugins/base/android/Makefile.in
+++ b/dom/plugins/base/android/Makefile.in
@@ -48,16 +48,17 @@ LIBRARY_NAME	= gkpluginandroid_s
 LIBXUL_LIBRARY   = 1
 FORCE_STATIC_LIB = 1
 EXPORT_LIBRARY = 1
 
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 EXPORTS = \
+  ANPKeyCodes.h \
   android_npapi.h \
   $(NULL)
 
 CPPSRCS += ANPAudio.cpp    \
            ANPEvent.cpp    \
            ANPMatrix.cpp   \
            ANPSystem.cpp   \
            ANPWindow.cpp   \
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -120,17 +120,16 @@ static NS_DEFINE_CID(kAppShellCID, NS_AP
 #include <gdk/gdk.h>
 #include <gdk/gdkx.h>
 #include <gtk/gtk.h>
 #include "gfxXlibNativeRenderer.h"
 #endif
 
 #ifdef MOZ_WIDGET_ANDROID
 #include "ANPBase.h"
-#include "android_npapi.h"
 #include "AndroidBridge.h"
 #include "AndroidMediaLayer.h"
 using namespace mozilla::dom;
 
 #include <android/log.h>
 #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
 #endif
 
@@ -2712,43 +2711,23 @@ nsEventStatus nsPluginInstanceOwner::Pro
           }
       }
       break;
 
     case NS_KEY_EVENT:
      {
        const nsKeyEvent& keyEvent = static_cast<const nsKeyEvent&>(anEvent);
        LOG("Firing NS_KEY_EVENT %d %d\n", keyEvent.keyCode, keyEvent.charCode);
-       
-       int modifiers = 0;
-       if (keyEvent.isShift)
-         modifiers |= kShift_ANPKeyModifier;
-       if (keyEvent.isAlt)
-         modifiers |= kAlt_ANPKeyModifier;
-
-       ANPEvent event;
-       event.inSize = sizeof(ANPEvent);
-       event.eventType = kKey_ANPEventType;
-       event.data.key.nativeCode = keyEvent.keyCode;
-       event.data.key.virtualCode = keyEvent.charCode;
-       event.data.key.modifiers = modifiers;
-       event.data.key.repeatCount = 0;
-       event.data.key.unichar = 0;
-       switch (anEvent.message)
-         {
-         case NS_KEY_DOWN:
-           event.data.key.action = kDown_ANPKeyAction;
-           mInstance->HandleEvent(&event, nsnull);
-           break;
-           
-         case NS_KEY_UP:
-           event.data.key.action = kUp_ANPKeyAction;
-           mInstance->HandleEvent(&event, nsnull);
-           break;
-         }
+       // pluginEvent is initialized by nsWindow::InitKeyEvent().
+       ANPEvent* pluginEvent = reinterpret_cast<ANPEvent*>(keyEvent.pluginEvent);
+       if (pluginEvent) {
+         MOZ_ASSERT(pluginEvent->inSize == sizeof(ANPEvent));
+         MOZ_ASSERT(pluginEvent->eventType == kKey_ANPEventType);
+         mInstance->HandleEvent(pluginEvent, nsnull);
+       }
      }
     }
     rv = nsEventStatus_eConsumeNoDefault;
 #endif
  
   return rv;
 }
 
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -72,16 +72,17 @@ using mozilla::unused;
 #include "BasicLayers.h"
 #include "LayerManagerOGL.h"
 #include "GLContext.h"
 #include "GLContextProvider.h"
 
 #include "nsTArray.h"
 
 #include "AndroidBridge.h"
+#include "android_npapi.h"
 
 #include "imgIEncoder.h"
 
 #include "nsStringGlue.h"
 
 using namespace mozilla;
 using namespace mozilla::widget;
 
@@ -1702,31 +1703,73 @@ static unsigned int ConvertAndroidKeyCod
 
         default:
             ALOG("ConvertAndroidKeyCodeToDOMKeyCode: "
                  "No DOM keycode for Android keycode %d", androidKeyCode);
         return 0;
     }
 }
 
+static void InitPluginEvent(ANPEvent* pluginEvent, ANPKeyActions keyAction,
+                            AndroidGeckoEvent& key)
+{
+    int androidKeyCode = key.KeyCode();
+    PRUint32 domKeyCode = ConvertAndroidKeyCodeToDOMKeyCode(androidKeyCode);
+
+    int modifiers = 0;
+    if (key.IsAltPressed())
+      modifiers |= kAlt_ANPKeyModifier;
+    if (key.IsShiftPressed())
+      modifiers |= kShift_ANPKeyModifier;
+
+    pluginEvent->inSize = sizeof(ANPEvent);
+    pluginEvent->eventType = kKey_ANPEventType;
+    pluginEvent->data.key.action = keyAction;
+    pluginEvent->data.key.nativeCode = androidKeyCode;
+    pluginEvent->data.key.virtualCode = domKeyCode;
+    pluginEvent->data.key.unichar = key.UnicodeChar();
+    pluginEvent->data.key.modifiers = modifiers;
+    pluginEvent->data.key.repeatCount = key.RepeatCount();
+}
+
 void
-nsWindow::InitKeyEvent(nsKeyEvent& event, AndroidGeckoEvent& key)
+nsWindow::InitKeyEvent(nsKeyEvent& event, AndroidGeckoEvent& key,
+                       ANPEvent* pluginEvent)
 {
-    event.keyCode = ConvertAndroidKeyCodeToDOMKeyCode(key.KeyCode());
+    int androidKeyCode = key.KeyCode();
+    PRUint32 domKeyCode = ConvertAndroidKeyCodeToDOMKeyCode(androidKeyCode);
 
-    // Android gives us \n, so filter out some control characters.
-    if (event.message == NS_KEY_PRESS &&
-        key.UnicodeChar() >= ' ') {
-        event.charCode = key.UnicodeChar();
-        if (key.UnicodeChar())
-            event.keyCode = 0;
+    if (event.message == NS_KEY_PRESS) {
+        // Android gives us \n, so filter out some control characters.
+        event.isChar = (key.UnicodeChar() >= ' ');
+        event.charCode = event.isChar ? key.UnicodeChar() : 0;
+        event.keyCode = (event.charCode > 0) ? 0 : domKeyCode;
+        event.pluginEvent = NULL;
+    } else {
+#ifdef DEBUG
+        if (event.message != NS_KEY_DOWN && event.message != NS_KEY_UP) {
+            ALOG("InitKeyEvent: unexpected event.message %d", event.message);
+        }
+#endif // DEBUG
+
+        // Flash will want a pluginEvent for keydown and keyup events.
+        ANPKeyActions action = event.message == NS_KEY_DOWN
+                             ? kDown_ANPKeyAction
+                             : kUp_ANPKeyAction;
+        InitPluginEvent(pluginEvent, action, key);
+
+        event.isChar = false;
+        event.charCode = 0;
+        event.keyCode = domKeyCode;
+        event.pluginEvent = pluginEvent;
     }
-    event.isShift = !!(key.MetaState() & AndroidKeyEvent::META_SHIFT_ON);
+
+    event.isShift = key.IsShiftPressed();
     event.isControl = gMenu;
-    event.isAlt = !!(key.MetaState() & AndroidKeyEvent::META_ALT_ON);
+    event.isAlt = key.IsAltPressed();
     event.isMeta = false;
     event.time = key.Time();
 
     if (gMenu)
         gMenuConsumed = true;
 }
 
 void
@@ -1759,17 +1802,18 @@ nsWindow::HandleSpecialKey(AndroidGeckoE
                 gMenu = true;
                 gMenuConsumed = isLongPress;
                 break;
         }
     } else {
         switch (keyCode) {
             case AndroidKeyEvent::KEYCODE_BACK: {
                 nsKeyEvent pressEvent(true, NS_KEY_PRESS, this);
-                InitKeyEvent(pressEvent, *ae);
+                ANPEvent pluginEvent;
+                InitKeyEvent(pressEvent, *ae, &pluginEvent);
                 DispatchEvent(&pressEvent);
                 return;
             }
             case AndroidKeyEvent::KEYCODE_MENU:
                 gMenu = false;
                 if (!gMenuConsumed) {
                     command = nsGkAtoms::Menu;
                     doCommand = true;
@@ -1829,26 +1873,27 @@ nsWindow::OnKeyEvent(AndroidGeckoEvent *
     case AndroidKeyEvent::KEYCODE_VOLUME_UP:
     case AndroidKeyEvent::KEYCODE_VOLUME_DOWN:
         HandleSpecialKey(ae);
         return;
     }
 
     nsEventStatus status;
     nsKeyEvent event(true, msg, this);
-    InitKeyEvent(event, *ae);
+    ANPEvent pluginEvent;
+    InitKeyEvent(event, *ae, &pluginEvent);
     DispatchEvent(&event, status);
 
     if (Destroyed())
         return;
     if (!firePress)
         return;
 
     nsKeyEvent pressEvent(true, NS_KEY_PRESS, this);
-    InitKeyEvent(pressEvent, *ae);
+    InitKeyEvent(pressEvent, *ae, &pluginEvent);
     if (status == nsEventStatus_eConsumeNoDefault) {
         pressEvent.flags |= NS_EVENT_FLAG_NO_DEFAULT;
     }
 #ifdef DEBUG_ANDROID_WIDGET
     __android_log_print(ANDROID_LOG_INFO, "Gecko", "Dispatching key pressEvent with keyCode %d charCode %d shift %d alt %d sym/ctrl %d metamask %d", pressEvent.keyCode, pressEvent.charCode, pressEvent.isShift, pressEvent.isAlt, pressEvent.isControl, ae->MetaState());
 #endif
     DispatchEvent(&pressEvent);
 }
@@ -1963,20 +2008,21 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *
                 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");
             nsKeyEvent event(true, NS_KEY_PRESS, this);
-            InitEvent(event, nsnull);
+            ANPEvent pluginEvent;
+            InitKeyEvent(event, *ae, &pluginEvent);
             event.keyCode = NS_VK_BACK;
             DispatchEvent(&event);
         }
         return;
     case AndroidGeckoEvent::IME_SET_SELECTION:
         {
             ALOGIME("IME: IME_SET_SELECTION: o=%u, l=%d", ae->Offset(), ae->Count());
 
--- a/widget/android/nsWindow.h
+++ b/widget/android/nsWindow.h
@@ -46,16 +46,18 @@
 #ifdef MOZ_JAVA_COMPOSITOR
 #include "AndroidJavaWrappers.h"
 #include "Layers.h"
 #endif
 
 class gfxASurface;
 class nsIdleService;
 
+struct ANPEvent;
+
 namespace mozilla {
     class AndroidGeckoEvent;
     class AndroidKeyEvent;
 
     namespace layers {
         class CompositorParent;
         class CompositorChild;
     }
@@ -226,17 +228,18 @@ protected:
 
     InputContext mInputContext;
 
     static void DumpWindows();
     static void DumpWindows(const nsTArray<nsWindow*>& wins, int indent = 0);
     static void LogWindow(nsWindow *win, int index, int indent);
 
 private:
-    void InitKeyEvent(nsKeyEvent& event, mozilla::AndroidGeckoEvent& key);
+    void InitKeyEvent(nsKeyEvent& event, mozilla::AndroidGeckoEvent& key,
+                      ANPEvent* pluginEvent);
     bool DispatchMultitouchEvent(nsTouchEvent &event,
                              mozilla::AndroidGeckoEvent *ae);
     void DispatchMotionEvent(nsInputEvent &event,
                              mozilla::AndroidGeckoEvent *ae,
                              const nsIntPoint &refPoint);
     void DispatchGestureEvent(PRUint32 msg, PRUint32 direction, double delta,
                               const nsIntPoint &refPoint, PRUint64 time);
     void HandleSpecialKey(mozilla::AndroidGeckoEvent *ae);