| Index: content/browser/browser_plugin/browser_plugin_guest.cc
 | 
| diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc
 | 
| index 543a63c7359b4c74796686fd5f7cf24f1bb4c4ef..e8d16c8a513df9a032066b07e72030e96c4a62c0 100644
 | 
| --- a/content/browser/browser_plugin/browser_plugin_guest.cc
 | 
| +++ b/content/browser/browser_plugin/browser_plugin_guest.cc
 | 
| @@ -91,6 +91,9 @@ BrowserPluginGuest::BrowserPluginGuest(bool has_render_view,
 | 
|        last_input_flags_(0),
 | 
|        last_can_compose_inline_(true),
 | 
|        guest_proxy_routing_id_(MSG_ROUTING_NONE),
 | 
| +      last_drag_status_(blink::WebDragStatusUnknown),
 | 
| +      seen_embedder_system_drag_ended_(false),
 | 
| +      seen_embedder_drag_source_ended_at_(false),
 | 
|        delegate_(delegate),
 | 
|        weak_ptr_factory_(this) {
 | 
|    DCHECK(web_contents);
 | 
| @@ -417,12 +420,45 @@ void BrowserPluginGuest::DragSourceEndedAt(int client_x, int client_y,
 | 
|      int screen_x, int screen_y, blink::WebDragOperation operation) {
 | 
|    web_contents()->GetRenderViewHost()->DragSourceEndedAt(client_x, client_y,
 | 
|        screen_x, screen_y, operation);
 | 
| +  seen_embedder_drag_source_ended_at_ = true;
 | 
| +  EndSystemDragIfApplicable();
 | 
|  }
 | 
|  
 | 
| -void BrowserPluginGuest::EndSystemDrag() {
 | 
| -  RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>(
 | 
| -      GetWebContents()->GetRenderViewHost());
 | 
| -  guest_rvh->DragSourceSystemDragEnded();
 | 
| +void BrowserPluginGuest::EndSystemDragIfApplicable() {
 | 
| +  // Ideally we'd want either WebDragStatusDrop or WebDragStatusLeave...
 | 
| +  // Call guest RVH->DragSourceSystemDragEnded() correctly on the guest where
 | 
| +  // the drag was initiated. Calling DragSourceSystemDragEnded() correctly
 | 
| +  // means we call it in all cases and also make sure we only call it once.
 | 
| +  // This ensures that the input state of the guest stays correct, otherwise
 | 
| +  // it will go stale and won't accept any further input events.
 | 
| +  //
 | 
| +  // The strategy used here to call DragSourceSystemDragEnded() on the RVH
 | 
| +  // is when the following conditions are met:
 | 
| +  //   a. Embedder has seen SystemDragEnded()
 | 
| +  //   b. Embedder has seen DragSourceEndedAt()
 | 
| +  //   c. The guest has seen some drag status update other than
 | 
| +  //      WebDragStatusUnknown. Note that this step should ideally be done
 | 
| +  //      differently: The guest has seen at least one of
 | 
| +  //      {WebDragStatusOver, WebDragStatusDrop}. However, if a user drags
 | 
| +  //      a source quickly outside of <webview> bounds, then the
 | 
| +  //      BrowserPluginGuest never sees any of these drag status updates,
 | 
| +  //      there we just check whether we've seen any drag status update or
 | 
| +  //      not.
 | 
| +  if (last_drag_status_ != blink::WebDragStatusOver &&
 | 
| +      seen_embedder_drag_source_ended_at_ && seen_embedder_system_drag_ended_) {
 | 
| +    RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>(
 | 
| +        GetWebContents()->GetRenderViewHost());
 | 
| +    guest_rvh->DragSourceSystemDragEnded();
 | 
| +
 | 
| +    last_drag_status_ = blink::WebDragStatusUnknown;
 | 
| +    seen_embedder_system_drag_ended_ = false;
 | 
| +    seen_embedder_drag_source_ended_at_ = false;
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +void BrowserPluginGuest::EmbedderSystemDragEnded() {
 | 
| +  seen_embedder_system_drag_ended_ = true;
 | 
| +  EndSystemDragIfApplicable();
 | 
|  }
 | 
|  
 | 
|  void BrowserPluginGuest::SendQueuedMessages() {
 | 
| @@ -649,11 +685,12 @@ void BrowserPluginGuest::OnDragStatusUpdate(int browser_plugin_instance_id,
 | 
|        break;
 | 
|      case blink::WebDragStatusDrop:
 | 
|        host->DragTargetDrop(location, location, 0);
 | 
| -      EndSystemDrag();
 | 
|        break;
 | 
|      case blink::WebDragStatusUnknown:
 | 
|        NOTREACHED();
 | 
|    }
 | 
| +  last_drag_status_ = drag_status;
 | 
| +  EndSystemDragIfApplicable();
 | 
|  }
 | 
|  
 | 
|  void BrowserPluginGuest::OnExecuteEditCommand(int browser_plugin_instance_id,
 | 
| 
 |