Code: void DragController::PerformDrag(DragData* drag_data, LocalFrame& local_root) {
  DCHECK(drag_data);
  document_under_mouse_ =
      local_root.DocumentAtPoint(LayoutPoint(drag_data->ClientPosition()));
  std::unique_ptr<UserGestureIndicator> gesture = Frame::NotifyUserActivation(
      document_under_mouse_ ? document_under_mouse_->GetFrame() : nullptr,
      UserGestureToken::kNewGesture);
  if ((drag_destination_action_ & kDragDestinationActionDHTML) &&
      document_is_handling_drag_) {
    bool prevented_default = false;
    if (local_root.View()) {
      DataTransfer* data_transfer =
          CreateDraggingDataTransfer(kDataTransferReadable, drag_data);
      data_transfer->SetSourceOperation(
          drag_data->DraggingSourceOperationMask());
      EventHandler& event_handler = local_root.GetEventHandler();
      prevented_default = event_handler.PerformDragAndDrop(
                              CreateMouseEvent(drag_data), data_transfer) !=
                          WebInputEventResult::kNotHandled;
      if (!prevented_default) {
        const LayoutPoint point = local_root.View()->RootFrameToContents(
            LayoutPoint(drag_data->ClientPosition()));
        const HitTestResult result = event_handler.HitTestResultAtPoint(point);
        prevented_default |=
            IsHTMLPlugInElement(*result.InnerNode()) &&
            ToHTMLPlugInElement(result.InnerNode())->CanProcessDrag();
      }

      data_transfer->SetAccessPolicy(kDataTransferNumb);
    }
    if (prevented_default) {
      document_under_mouse_ = nullptr;
      CancelDrag();
      return;
    }
  }

  if ((drag_destination_action_ & kDragDestinationActionEdit) &&
      ConcludeEditDrag(drag_data)) {
    document_under_mouse_ = nullptr;
    return;
  }

  document_under_mouse_ = nullptr;

  if (OperationForLoad(drag_data, local_root) != kDragOperationNone) {
    if (page_->GetSettings().GetNavigateOnDragDrop()) {
      ResourceRequest resource_request(drag_data->AsURL());
       resource_request.SetRequestorOrigin(
           SecurityOrigin::Create(KURL(drag_data->AsURL())));
       page_->MainFrame()->Navigate(FrameLoadRequest(nullptr, resource_request));
     }
 
    local_root.GetEventHandler().ClearDragState();
  }
}

Commit Message: Move user activation check to RemoteFrame::Navigate's callers.

Currently RemoteFrame::Navigate is the user of
Frame::HasTransientUserActivation that passes a RemoteFrame*, and
it seems wrong because the user activation (user gesture) needed by
the navigation should belong to the LocalFrame that initiated the
navigation.

Follow-up CLs after this one will update UserActivation code in
Frame to take a LocalFrame* instead of a Frame*, and get rid of
redundant IPCs.

Bug: 811414
Change-Id: I771c1694043edb54374a44213d16715d9c7da704
Reviewed-on: https://chromium-review.googlesource.com/914736
Commit-Queue: Mustaq Ahmed <mustaq@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#536728}
CWE ID: CWE-190
void DragController::PerformDrag(DragData* drag_data, LocalFrame& local_root) {
  DCHECK(drag_data);
  document_under_mouse_ =
      local_root.DocumentAtPoint(LayoutPoint(drag_data->ClientPosition()));
  std::unique_ptr<UserGestureIndicator> gesture = Frame::NotifyUserActivation(
      document_under_mouse_ ? document_under_mouse_->GetFrame() : nullptr,
      UserGestureToken::kNewGesture);
  if ((drag_destination_action_ & kDragDestinationActionDHTML) &&
      document_is_handling_drag_) {
    bool prevented_default = false;
    if (local_root.View()) {
      DataTransfer* data_transfer =
          CreateDraggingDataTransfer(kDataTransferReadable, drag_data);
      data_transfer->SetSourceOperation(
          drag_data->DraggingSourceOperationMask());
      EventHandler& event_handler = local_root.GetEventHandler();
      prevented_default = event_handler.PerformDragAndDrop(
                              CreateMouseEvent(drag_data), data_transfer) !=
                          WebInputEventResult::kNotHandled;
      if (!prevented_default) {
        const LayoutPoint point = local_root.View()->RootFrameToContents(
            LayoutPoint(drag_data->ClientPosition()));
        const HitTestResult result = event_handler.HitTestResultAtPoint(point);
        prevented_default |=
            IsHTMLPlugInElement(*result.InnerNode()) &&
            ToHTMLPlugInElement(result.InnerNode())->CanProcessDrag();
      }

      data_transfer->SetAccessPolicy(kDataTransferNumb);
    }
    if (prevented_default) {
      document_under_mouse_ = nullptr;
      CancelDrag();
      return;
    }
  }

  if ((drag_destination_action_ & kDragDestinationActionEdit) &&
      ConcludeEditDrag(drag_data)) {
    document_under_mouse_ = nullptr;
    return;
  }

  document_under_mouse_ = nullptr;

  if (OperationForLoad(drag_data, local_root) != kDragOperationNone) {
    if (page_->GetSettings().GetNavigateOnDragDrop()) {
      ResourceRequest resource_request(drag_data->AsURL());
       resource_request.SetRequestorOrigin(
           SecurityOrigin::Create(KURL(drag_data->AsURL())));
      resource_request.SetHasUserGesture(Frame::HasTransientUserActivation(
          document_under_mouse_ ? document_under_mouse_->GetFrame() : nullptr));
       page_->MainFrame()->Navigate(FrameLoadRequest(nullptr, resource_request));
     }
 
    local_root.GetEventHandler().ClearDragState();
  }
}
