changing how plugins gain/lose focus.

Previously we were keeping our own state in the UI thread to
determine when to send events to the plugin. This change removes
that logic and uses the document focus to determine when events
are to be sent. This also fixes problems with the plugins
occasionally not receiving lose focus events.

see bug http://b/2033843
diff --git a/WebCore/plugins/PluginView.cpp b/WebCore/plugins/PluginView.cpp
index 811f6be..13d8511 100644
--- a/WebCore/plugins/PluginView.cpp
+++ b/WebCore/plugins/PluginView.cpp
@@ -165,6 +165,10 @@
 #if defined(ANDROID_PLUGINS)
     else if (event->isTouchEvent())
         handleTouchEvent(static_cast<TouchEvent*>(event));
+    else if (event->type() == eventNames().DOMFocusOutEvent)
+        handleFocusEvent(false);
+    else if (event->type() == eventNames().DOMFocusInEvent)
+        handleFocusEvent(true);
 #endif
 #if defined(Q_WS_X11)
     else if (event->type() == eventNames().DOMFocusOutEvent)
diff --git a/WebCore/plugins/PluginView.h b/WebCore/plugins/PluginView.h
index 0fd0d4f..b385d41 100644
--- a/WebCore/plugins/PluginView.h
+++ b/WebCore/plugins/PluginView.h
@@ -289,6 +289,7 @@
 #endif
 
 #ifdef ANDROID_PLUGINS
+        void handleFocusEvent(bool hasFocus);
         void handleTouchEvent(TouchEvent*);
         // called at the end of the base constructor
         void platformInit();
diff --git a/WebCore/plugins/android/PluginViewAndroid.cpp b/WebCore/plugins/android/PluginViewAndroid.cpp
index 0c69cfd..529458b 100644
--- a/WebCore/plugins/android/PluginViewAndroid.cpp
+++ b/WebCore/plugins/android/PluginViewAndroid.cpp
@@ -258,6 +258,20 @@
     return mod;
 }
 
+void PluginView::handleFocusEvent(bool hasFocus)
+{
+    ANPEvent evt;
+    SkANP::InitEvent(&evt, kLifecycle_ANPEventType);
+    evt.data.lifecycle.action = hasFocus ? kGainFocus_ANPLifecycleAction :
+                                           kLoseFocus_ANPLifecycleAction;
+    m_window->sendEvent(evt);
+
+    // redraw the plugin which subsequently invalidates the nav cache
+    IntRect rect = IntRect(m_npWindow.x, m_npWindow.y,
+                           m_npWindow.width, m_npWindow.height);
+    m_window->webViewCore()->contentInvalidate(rect);
+}
+
 void PluginView::handleKeyboardEvent(KeyboardEvent* event)
 {
     if (!m_window->isAcceptingEvent(kKey_ANPEventFlag))
@@ -319,6 +333,9 @@
 
     if (m_plugin->pluginFuncs()->event(m_instance, &evt)) {
         event->setDefaultHandled();
+    } else {
+        // remove the plugin from the document's focus
+        m_parentFrame->document()->focusedNodeRemoved();
     }
 }
 
@@ -498,7 +515,6 @@
     }
 
     m_window->inval(r, true);
-//    android::WebViewCore::getWebViewCore(parent())->contentInvalidate(r);
 }
 
 void PluginView::invalidateRegion(NPRegion region)
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index eb35d44..d31d936 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -1400,33 +1400,6 @@
     return 0;
 }
 
-
-void WebViewCore::updatePluginState(Frame* frame, Node* node, PluginState state) {
-
-    // check that the node and frame pointers are (still) valid
-    if (!frame || !node || !CacheBuilder::validNode(m_mainFrame, frame, node))
-        return;
-
-    // check that the node is a plugin view
-    PluginView* pluginView = nodeIsPlugin(node);
-    if (!pluginView)
-        return;
-
-    // create the event
-    ANPEvent event;
-    SkANP::InitEvent(&event, kLifecycle_ANPEventType);
-
-    if (state == kLoseFocus_PluginState)
-        event.data.lifecycle.action = kLoseFocus_ANPLifecycleAction;
-    else if (state == kGainFocus_PluginState)
-        event.data.lifecycle.action = kGainFocus_ANPLifecycleAction;
-    else
-        return;
-
-    // send the event
-    pluginView->platformPluginWidget()->sendEvent(event);
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 void WebViewCore::moveMouseIfLatest(int moveGeneration,
     WebCore::Frame* frame, int x, int y)
@@ -3000,17 +2973,6 @@
     return GET_NATIVE_VIEW(env, obj)->pictureReady();
 }
 
-static void UpdatePluginState(JNIEnv* env, jobject obj, jint framePtr, jint nodePtr, jint state)
-{
-#ifdef ANDROID_INSTRUMENT
-    TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter);
-#endif
-    WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj);
-    LOG_ASSERT(viewImpl, "viewImpl not set in nativeUpdatePluginState");
-    viewImpl->updatePluginState((WebCore::Frame*) framePtr, (WebCore::Node*) nodePtr,
-                                (PluginState) state);
-}
-
 static void Pause(JNIEnv* env, jobject obj)
 {
     // This is called for the foreground tab when the browser is put to the
@@ -3149,7 +3111,6 @@
     { "nativeResume", "()V", (void*) Resume },
     { "nativeFreeMemory", "()V", (void*) FreeMemory },
     { "nativeSetJsFlags", "(Ljava/lang/String;)V", (void*) SetJsFlags },
-    { "nativeUpdatePluginState", "(III)V", (void*) UpdatePluginState },
     { "nativeUpdateFrameCacheIfLoading", "()V",
         (void*) UpdateFrameCacheIfLoading },
     { "nativeProvideVisitedHistory", "([Ljava/lang/String;)V",
diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h
index 88031d0..a7855b8 100644
--- a/WebKit/android/jni/WebViewCore.h
+++ b/WebKit/android/jni/WebViewCore.h
@@ -63,11 +63,6 @@
 
 namespace android {
 
-    enum PluginState {
-        kGainFocus_PluginState  = 0,
-        kLoseFocus_PluginState  = 1,
-    };
-
     class CachedRoot;
     class ListBoxReply;
 
@@ -366,9 +361,6 @@
         // return the cursorNode if it is a plugin
         Node* cursorNodeIsPlugin();
 
-        // notify the plugin of an update in state
-        void updatePluginState(Frame* frame, Node* node, PluginState state);
-
         // Notify the Java side whether it needs to pass down the touch events
         void needTouchEvents(bool);
 
diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp
index 20e8a70..4b32516 100644
--- a/WebKit/android/nav/WebView.cpp
+++ b/WebKit/android/nav/WebView.cpp
@@ -98,7 +98,6 @@
     jobject     m_obj;
     jmethodID   m_clearTextEntry;
     jmethodID   m_overrideLoading;
-    jmethodID   m_sendPluginState;
     jmethodID   m_scrollBy;
     jmethodID   m_sendMoveMouse;
     jmethodID   m_sendMoveMouseIfLatest;
@@ -128,7 +127,6 @@
     m_javaGlue.m_scrollBy = GetJMethod(env, clazz, "setContentScrollBy", "(IIZ)Z");
     m_javaGlue.m_clearTextEntry = GetJMethod(env, clazz, "clearTextEntry", "()V");
     m_javaGlue.m_overrideLoading = GetJMethod(env, clazz, "overrideLoading", "(Ljava/lang/String;)V");
-    m_javaGlue.m_sendPluginState = GetJMethod(env, clazz, "sendPluginState", "(I)V");
     m_javaGlue.m_sendMoveMouse = GetJMethod(env, clazz, "sendMoveMouse", "(IIII)V");
     m_javaGlue.m_sendMoveMouseIfLatest = GetJMethod(env, clazz, "sendMoveMouseIfLatest", "(Z)V");
     m_javaGlue.m_sendMotionUp = GetJMethod(env, clazz, "sendMotionUp", "(IIIII)V");
@@ -163,10 +161,6 @@
     m_matches = 0;
     m_hasCurrentLocation = false;
     m_isFindPaintSetUp = false;
-    m_pluginReceivesEvents = false; // initialization is the only time this
-                                    // variable should be set directly, all
-                                    // other changes should be made through
-                                    // setPluginReceivesEvents(bool)
 }
 
 ~WebView()
@@ -483,10 +477,9 @@
             " bounds=(%d,%d,w=%d,h=%d)", node->index(), node->nodePointer(),
             bounds.x(), bounds.y(), bounds.width(), bounds.height());
         m_followedLink = false;
-        setPluginReceivesEvents(false);
         return;
     }
-    if (!node->hasCursorRing() || (m_pluginReceivesEvents && node->isPlugin()))
+    if (!node->hasCursorRing() || (node->isPlugin() && node->isFocus()))
         return;
     CursorRing::Flavor flavor = CursorRing::NORMAL_FLAVOR;
     if (!isButton) {
@@ -499,13 +492,12 @@
 #if DEBUG_NAV_UI
         const WebCore::IntRect& ring = (*rings)[0];
         DBG_NAV_LOGD("cursorNode=%d (nodePointer=%p) flavor=%s rings=%d"
-            " (%d, %d, %d, %d) pluginReceivesEvents=%s isPlugin=%s",
+            " (%d, %d, %d, %d) isPlugin=%s",
             node->index(), node->nodePointer(),
             flavor == CursorRing::FAKE_FLAVOR ? "FAKE_FLAVOR" :
             flavor == CursorRing::NORMAL_ANIMATING ? "NORMAL_ANIMATING" :
             flavor == CursorRing::FAKE_ANIMATING ? "FAKE_ANIMATING" : "NORMAL_FLAVOR",
             rings->size(), ring.x(), ring.y(), ring.width(), ring.height(),
-            m_pluginReceivesEvents ? "true" : "false",
             node->isPlugin() ? "true" : "false");
 #endif
     }
@@ -756,7 +748,6 @@
 /* returns true if the key had no effect (neither scrolled nor changed cursor) */
 bool moveCursor(int keyCode, int count, bool ignoreScroll)
 {
-    setPluginReceivesEvents(false);
     CachedRoot* root = getFrameCache(AllowNewer);
     if (!root) {
         DBG_NAV_LOG("!root");
@@ -841,21 +832,6 @@
     return result;
 }
 
-bool pluginEatsNavKey()
-{
-    CachedRoot* root = getFrameCache(DontAllowNewer);
-    if (!root) {
-        DBG_NAV_LOG("!root");
-        return false;
-    }
-    const CachedNode* cursor = root->currentCursor();
-    DBG_NAV_LOGD("cursor=%p isPlugin=%s pluginReceivesEvents=%s",
-        cursor, cursor && cursor->isPlugin() ? "true" : "false",
-        m_pluginReceivesEvents ? "true" : "false");
-    // FIXME: check to see if plugin wants keys
-    return cursor && cursor->isPlugin() && m_pluginReceivesEvents;
-}
-
 void notifyProgressFinished()
 {
     DBG_NAV_LOGD("cursorIsTextInput=%d", cursorIsTextInput(DontAllowNewer));
@@ -975,7 +951,6 @@
             0, x, y);
         viewInvalidate();
         clearTextEntry();
-        setPluginReceivesEvents(false);
         return pageScrolled;
     }
     DBG_NAV_LOGD("CachedNode:%p (%d) x=%d y=%d rx=%d ry=%d", result,
@@ -984,7 +959,6 @@
     updateCursorBounds(root, frame, result);
     root->setCursor(const_cast<CachedFrame*>(frame),
         const_cast<CachedNode*>(result));
-    updatePluginReceivesEvents();
     CachedNodeType type = result->type();
     if (type == NORMAL_CACHEDNODETYPE) {
         sendMotionUp(
@@ -1034,35 +1008,6 @@
         m_hasCurrentLocation = false;
 }
 
-void setPluginReceivesEvents(bool value)
-{
-    if (value == m_pluginReceivesEvents)
-        return;
-
-    //send message to plugin in webkit
-    JNIEnv* env = JSC::Bindings::getJNIEnv();
-    AutoJObject obj = m_javaGlue.object(env);
-    // if it is called during or after DESTROY is handled, the real object of
-    // WebView can be gone. Check before using it.
-    if (!obj.get())
-        return;
-    env->CallVoidMethod(obj.get(), m_javaGlue.m_sendPluginState,
-                        value ? kGainFocus_PluginState : kLoseFocus_PluginState);
-    checkException(env);
-    m_pluginReceivesEvents = value;
-}
-
-void updatePluginReceivesEvents()
-{
-    CachedRoot* root = getFrameCache(DontAllowNewer);
-    if (!root)
-        return;
-    const CachedNode* cursor = root->currentCursor();
-    setPluginReceivesEvents(cursor && cursor->isPlugin());
-    DBG_NAV_LOGD("m_pluginReceivesEvents=%s cursor=%p", m_pluginReceivesEvents
-        ? "true" : "false", cursor);
-}
-
 void setFollowedLink(bool followed)
 {
     if ((m_followedLink = followed) != false) {
@@ -1396,7 +1341,6 @@
     int m_generation; // associate unique ID with sent kit focus to match with ui
     SkPicture* m_navPictureUI;
     bool m_followedLink;
-    bool m_pluginReceivesEvents;
     SkMSec m_ringAnimationEnd;
     // Corresponds to the same-named boolean on the java side.
     bool m_heightCanMeasure;
@@ -1736,6 +1680,12 @@
     return node ? node->isPlugin() : false;
 }
 
+static bool nativeFocusIsPlugin(JNIEnv *env, jobject obj)
+{
+    const CachedNode* node = getFocusNode(env, obj);
+    return node ? node->isPlugin() : false;
+}
+
 static jint nativeFocusNodePointer(JNIEnv *env, jobject obj)
 {
     const CachedNode* node = getFocusNode(env, obj);
@@ -1825,11 +1775,6 @@
     view->setFindIsUp(false);
 }
 
-static void nativeUpdatePluginReceivesEvents(JNIEnv *env, jobject obj)
-{
-    GET_NATIVE_VIEW(env, obj)->updatePluginReceivesEvents();
-}
-
 static void nativeSetFollowedLink(JNIEnv *env, jobject obj, bool followed)
 {
     WebView* view = GET_NATIVE_VIEW(env, obj);
@@ -2008,11 +1953,6 @@
     view->moveSelection(x, y, ex);
 }
 
-static bool nativePluginEatsNavKey(JNIEnv *env, jobject obj)
-{
-    return GET_NATIVE_VIEW(env, obj)->pluginEatsNavKey();
-}
-
 static jobject nativeGetSelection(JNIEnv *env, jobject obj)
 {
     WebView* view = GET_NATIVE_VIEW(env, obj);
@@ -2129,6 +2069,8 @@
         (void*) nativeFocusCandidateText },
     { "nativeFocusCandidateTextSize", "()I",
         (void*) nativeFocusCandidateTextSize },
+    { "nativeFocusIsPlugin", "()Z",
+        (void*) nativeFocusIsPlugin },
     { "nativeFocusNodePointer", "()I",
         (void*) nativeFocusNodePointer },
     { "nativeGetCursorRingBounds", "()Landroid/graphics/Rect;",
@@ -2157,8 +2099,6 @@
         (void*) nativeMoveGeneration },
     { "nativeMoveSelection", "(IIZ)V",
         (void*) nativeMoveSelection },
-    { "nativePluginEatsNavKey", "()Z",
-        (void*) nativePluginEatsNavKey },
     { "nativeRecordButtons", "(ZZZ)V",
         (void*) nativeRecordButtons },
     { "nativeSelectBestAt", "(Landroid/graphics/Rect;)V",
@@ -2177,8 +2117,6 @@
         (void*) nativeUpdateCachedTextfield },
     { "nativeGetBlockLeftEdge", "(IIF)I",
         (void*) nativeGetBlockLeftEdge },
-    { "nativeUpdatePluginReceivesEvents", "()V",
-        (void*) nativeUpdatePluginReceivesEvents }
 };
 
 int register_webview(JNIEnv* env)