// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/renderer_host/render_widget_host_view_mac.h"

#include <Cocoa/Cocoa.h>
#include <stddef.h>
#include <stdint.h>
#include <tuple>

#include "base/command_line.h"
#include "base/containers/queue.h"
#include "base/mac/mac_util.h"
#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/mac/sdk_forward_declarations.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "components/viz/common/surfaces/child_local_surface_id_allocator.h"
#import "content/app_shim_remote_cocoa/render_widget_host_view_cocoa.h"
#include "content/browser/compositor/image_transport_factory.h"
#include "content/browser/frame_host/render_widget_host_view_guest.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/renderer_host/render_widget_host_delegate.h"
#include "content/browser/renderer_host/text_input_manager.h"
#include "content/common/input_messages.h"
#include "content/common/text_input_state.h"
#include "content/common/view_messages.h"
#include "content/common/widget_messages.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_widget_host_view_mac_delegate.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_utils.h"
#include "content/test/mock_render_widget_host_delegate.h"
#include "content/test/mock_widget_impl.h"
#include "content/test/stub_render_widget_host_owner_delegate.h"
#include "content/test/test_render_view_host.h"
#include "gpu/ipc/common/gpu_messages.h"
#include "gpu/ipc/service/image_transport_surface.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/gtest_mac.h"
#import "third_party/ocmock/OCMock/OCMock.h"
#import "third_party/ocmock/ocmock_extensions.h"
#include "ui/base/cocoa/secure_password_input.h"
#import "ui/base/test/cocoa_helper.h"
#import "ui/base/test/scoped_fake_nswindow_focus.h"
#include "ui/base/ui_base_features.h"
#include "ui/compositor/recyclable_compositor_mac.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/blink/blink_features.h"
#include "ui/events/blink/web_input_event_traits.h"
#include "ui/events/test/cocoa_test_event_utils.h"
#include "ui/gfx/mac/coordinate_conversion.h"
#include "ui/latency/latency_info.h"

using testing::_;

// Helper class with methods used to mock -[NSEvent phase], used by
// |MockScrollWheelEventWithPhase()|.
@interface MockPhaseMethods : NSObject {
}

- (NSEventPhase)phaseNone;
- (NSEventPhase)phaseBegan;
- (NSEventPhase)phaseChanged;
- (NSEventPhase)phaseEnded;
@end

@implementation MockPhaseMethods

- (NSEventPhase)phaseNone {
  return NSEventPhaseNone;
}
- (NSEventPhase)phaseBegan {
  return NSEventPhaseBegan;
}
- (NSEventPhase)phaseChanged {
  return NSEventPhaseChanged;
}
- (NSEventPhase)phaseEnded {
  return NSEventPhaseEnded;
}

@end

@interface MockRenderWidgetHostViewMacDelegate
    : NSObject<RenderWidgetHostViewMacDelegate> {
  BOOL unhandledWheelEventReceived_;
}

@property(nonatomic) BOOL unhandledWheelEventReceived;

@end

@implementation MockRenderWidgetHostViewMacDelegate

@synthesize unhandledWheelEventReceived = unhandledWheelEventReceived_;

- (void)rendererHandledWheelEvent:(const blink::WebMouseWheelEvent&)event
                         consumed:(BOOL)consumed {
  if (!consumed)
    unhandledWheelEventReceived_ = true;
}

- (void)rendererHandledGestureScrollEvent:(const blink::WebGestureEvent&)event
                                 consumed:(BOOL)consumed {
  if (!consumed &&
      event.GetType() == blink::WebInputEvent::kGestureScrollUpdate)
    unhandledWheelEventReceived_ = true;
}

- (void)touchesBeganWithEvent:(NSEvent*)event {}
- (void)touchesMovedWithEvent:(NSEvent*)event {}
- (void)touchesCancelledWithEvent:(NSEvent*)event {}
- (void)touchesEndedWithEvent:(NSEvent*)event {}
- (void)beginGestureWithEvent:(NSEvent*)event {}
- (void)endGestureWithEvent:(NSEvent*)event {}
- (void)rendererHandledOverscrollEvent:(const ui::DidOverscrollParams&)params {
}

@end

@interface FakeTextCheckingResult : NSObject<NSCopying>
@property(readonly) NSRange range;
@property(readonly) NSString* replacementString;
@end

@implementation FakeTextCheckingResult {
  base::scoped_nsobject<NSString> replacementString_;
}
@synthesize range = range_;

+ (FakeTextCheckingResult*)resultWithRange:(NSRange)range
                         replacementString:(NSString*)replacementString {
  FakeTextCheckingResult* result =
      [[[FakeTextCheckingResult alloc] init] autorelease];
  result->range_ = range;
  result->replacementString_.reset([replacementString retain]);
  return result;
}

- (id)copyWithZone:(NSZone*)zone {
  return
      [[FakeTextCheckingResult resultWithRange:self.range
                             replacementString:self.replacementString] retain];
}

- (NSString*)replacementString {
  return replacementString_;
}
@end

@interface FakeSpellChecker : NSObject
@property NSInteger sequenceNumber;
@end

@implementation FakeSpellChecker {
  base::mac::ScopedBlock<void (^)(NSInteger sequenceNumber,
                                  NSArray<NSTextCheckingResult*>* candidates)>
      lastCompletionHandler_;
}
@synthesize sequenceNumber = sequenceNumber_;

- (NSInteger)
requestCandidatesForSelectedRange:(NSRange)selectedRange
                         inString:(NSString*)stringToCheck
                            types:(NSTextCheckingTypes)checkingTypes
                          options:
                              (nullable NSDictionary<NSTextCheckingOptionKey,
                                                     id>*)options
           inSpellDocumentWithTag:(NSInteger)tag
                completionHandler:
                    (void (^__nullable)(NSInteger sequenceNumber,
                                        NSArray<NSTextCheckingResult*>*
                                            candidates))completionHandler
    NS_AVAILABLE_MAC(10_12_2) {
  sequenceNumber_ += 1;
  lastCompletionHandler_.reset([completionHandler copy]);
  return sequenceNumber_;
}

- (base::mac::ScopedBlock<void (^)(NSInteger sequenceNumber,
                                   NSArray<NSTextCheckingResult*>* candidates)>)
    takeCompletionHandler {
  return std::move(lastCompletionHandler_);
}

@end

namespace content {

namespace {

std::string GetMessageNames(
    const MockWidgetInputHandler::MessageVector& events) {
  std::vector<std::string> result;
  for (auto& event : events)
    result.push_back(event->name());
  return base::JoinString(result, " ");
}

blink::WebPointerProperties::PointerType GetPointerType(
    const MockWidgetInputHandler::MessageVector& events) {
  EXPECT_EQ(events.size(), 1U);
  MockWidgetInputHandler::DispatchedEventMessage* event = events[0]->ToEvent();
  if (!event)
    return blink::WebPointerProperties::PointerType::kUnknown;

  if (blink::WebInputEvent::IsMouseEventType(
          event->Event()->web_event->GetType())) {
    return static_cast<const blink::WebMouseEvent*>(
               event->Event()->web_event.get())
        ->pointer_type;
  }

  if (blink::WebInputEvent::IsTouchEventType(
          event->Event()->web_event->GetType())) {
    return static_cast<const blink::WebTouchEvent*>(
               event->Event()->web_event.get())
        ->touches[0]
        .pointer_type;
  }
  return blink::WebPointerProperties::PointerType::kUnknown;
}

NSEvent* MockTabletEventWithParams(CGEventType type,
                                   bool is_entering_proximity,
                                   NSPointingDeviceType device_type) {
  CGEventRef cg_event = CGEventCreate(NULL);
  CGEventSetType(cg_event, type);
  CGEventSetIntegerValueField(cg_event, kCGTabletProximityEventEnterProximity,
                              is_entering_proximity);
  CGEventSetIntegerValueField(cg_event, kCGTabletProximityEventPointerType,
                              device_type);
  NSEvent* event = [NSEvent eventWithCGEvent:cg_event];
  CFRelease(cg_event);
  return event;
}

NSEvent* MockMouseEventWithParams(CGEventType mouse_type,
                                  CGPoint location,
                                  CGMouseButton button,
                                  CGEventMouseSubtype subtype,
                                  bool is_entering_proximity = false,
                                  bool is_pen_tip = false) {
  // CGEvents have their origin at the *top* left screen corner. Converting to
  // an NSEvent, below, flips the location back to bottom left origin.
  CGPoint cg_location =
      CGPointMake(location.x, NSHeight(NSScreen.screens[0].frame) - location.y);
  CGEventRef cg_event =
      CGEventCreateMouseEvent(NULL, mouse_type, cg_location, button);
  CGEventSetIntegerValueField(cg_event, kCGMouseEventSubtype, subtype);
  CGEventSetIntegerValueField(cg_event, kCGTabletProximityEventEnterProximity,
                              is_entering_proximity);
  CGEventSetIntegerValueField(cg_event, kCGTabletEventRotation, 300);
  if (is_pen_tip)
    CGEventSetIntegerValueField(cg_event, kCGTabletEventPointButtons, 1);
  CGEventTimestamp timestamp =
      (ui::EventTimeForNow() - base::TimeTicks()).InMicroseconds() *
      base::Time::kNanosecondsPerMicrosecond;
  CGEventSetTimestamp(cg_event, timestamp);
  NSEvent* event = [NSEvent eventWithCGEvent:cg_event];
  CFRelease(cg_event);
  return event;
}

id MockPinchEvent(NSEventPhase phase, double magnification) {
  id event = [OCMockObject mockForClass:[NSEvent class]];
  NSEventType type = NSEventTypeMagnify;
  NSPoint locationInWindow = NSMakePoint(0, 0);
  CGFloat deltaX = 0;
  CGFloat deltaY = 0;
  NSTimeInterval timestamp = 1;
  NSUInteger modifierFlags = 0;

  [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(type)] type];
  [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(phase)] phase];
  [(NSEvent*)[[event stub]
      andReturnValue:OCMOCK_VALUE(locationInWindow)] locationInWindow];
  [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(deltaX)] deltaX];
  [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(deltaY)] deltaY];
  [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(timestamp)] timestamp];
  [(NSEvent*)[[event stub]
      andReturnValue:OCMOCK_VALUE(modifierFlags)] modifierFlags];
  [(NSEvent*)[[event stub]
      andReturnValue:OCMOCK_VALUE(magnification)] magnification];
  return event;
}

id MockSmartMagnifyEvent() {
  id event = [OCMockObject mockForClass:[NSEvent class]];
  NSEventType type = NSEventTypeSmartMagnify;
  NSPoint locationInWindow = NSMakePoint(0, 0);
  CGFloat deltaX = 0;
  CGFloat deltaY = 0;
  NSTimeInterval timestamp = 1;
  NSUInteger modifierFlags = 0;

  [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(type)] type];
  [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(locationInWindow)]
      locationInWindow];
  [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(deltaX)] deltaX];
  [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(deltaY)] deltaY];
  [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(timestamp)] timestamp];
  [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(modifierFlags)]
      modifierFlags];
  return event;
}

class MockRenderWidgetHostImpl : public RenderWidgetHostImpl {
 public:
  ~MockRenderWidgetHostImpl() override {}

  // Extracts |latency_info| and stores it in |lastWheelEventLatencyInfo|.
  void ForwardWheelEventWithLatencyInfo (
        const blink::WebMouseWheelEvent& wheel_event,
        const ui::LatencyInfo& ui_latency) override {
    RenderWidgetHostImpl::ForwardWheelEventWithLatencyInfo (
        wheel_event, ui_latency);
    lastWheelEventLatencyInfo = ui::LatencyInfo(ui_latency);
  }

  MOCK_METHOD0(Focus, void());
  MOCK_METHOD0(Blur, void());

  ui::LatencyInfo lastWheelEventLatencyInfo;
  static MockRenderWidgetHostImpl* Create(RenderWidgetHostDelegate* delegate,
                                          RenderProcessHost* process,
                                          int32_t routing_id) {
    mojom::WidgetPtr widget;
    std::unique_ptr<MockWidgetImpl> widget_impl =
        std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget));

    return new MockRenderWidgetHostImpl(delegate, process, routing_id,
                                        std::move(widget_impl),
                                        std::move(widget));
  }

  MockWidgetInputHandler* input_handler() {
    return widget_impl_->input_handler();
  }
  MockWidgetInputHandler::MessageVector GetAndResetDispatchedMessages() {
    return input_handler()->GetAndResetDispatchedMessages();
  }

 private:
  MockRenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
                           RenderProcessHost* process,
                           int32_t routing_id,
                           std::unique_ptr<MockWidgetImpl> widget_impl,
                           mojom::WidgetPtr widget)
      : RenderWidgetHostImpl(delegate,
                             process,
                             routing_id,
                             std::move(widget),
                             false),
        widget_impl_(std::move(widget_impl)) {
    set_renderer_initialized(true);
    lastWheelEventLatencyInfo = ui::LatencyInfo();

    ON_CALL(*this, Focus())
        .WillByDefault(
            testing::Invoke(this, &MockRenderWidgetHostImpl::FocusImpl));
    ON_CALL(*this, Blur())
        .WillByDefault(
            testing::Invoke(this, &MockRenderWidgetHostImpl::BlurImpl));
  }

  void FocusImpl() { RenderWidgetHostImpl::Focus(); }
  void BlurImpl() { RenderWidgetHostImpl::Blur(); }

  std::unique_ptr<MockWidgetImpl> widget_impl_;

  DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHostImpl);
};

// Generates the |length| of composition rectangle vector and save them to
// |output|. It starts from |origin| and each rectangle contains |unit_size|.
void GenerateCompositionRectArray(const gfx::Point& origin,
                                  const gfx::Size& unit_size,
                                  size_t length,
                                  const std::vector<size_t>& break_points,
                                  std::vector<gfx::Rect>* output) {
  DCHECK(output);
  output->clear();

  base::queue<int> break_point_queue;
  for (size_t i = 0; i < break_points.size(); ++i)
    break_point_queue.push(break_points[i]);
  break_point_queue.push(length);
  size_t next_break_point = break_point_queue.front();
  break_point_queue.pop();

  gfx::Rect current_rect(origin, unit_size);
  for (size_t i = 0; i < length; ++i) {
    if (i == next_break_point) {
      current_rect.set_x(origin.x());
      current_rect.set_y(current_rect.y() + current_rect.height());
      next_break_point = break_point_queue.front();
      break_point_queue.pop();
    }
    output->push_back(current_rect);
    current_rect.set_x(current_rect.right());
  }
}

gfx::Rect GetExpectedRect(const gfx::Point& origin,
                          const gfx::Size& size,
                          const gfx::Range& range,
                          int line_no) {
  return gfx::Rect(
      origin.x() + range.start() * size.width(),
      origin.y() + line_no * size.height(),
      range.length() * size.width(),
      size.height());
}

// Returns NSScrollWheel event that mocks -phase. |mockPhaseSelector| should
// correspond to a method in |MockPhaseMethods| that returns the desired phase.
NSEvent* MockScrollWheelEventWithPhase(SEL mockPhaseSelector, int32_t delta) {
  CGEventRef cg_event = CGEventCreateScrollWheelEvent(
      nullptr, kCGScrollEventUnitLine, 1, delta, 0);
  CGEventTimestamp timestamp = 0;
  CGEventSetTimestamp(cg_event, timestamp);
  NSEvent* event = [NSEvent eventWithCGEvent:cg_event];
  CFRelease(cg_event);
  method_setImplementation(
      class_getInstanceMethod([NSEvent class], @selector(phase)),
      [MockPhaseMethods instanceMethodForSelector:mockPhaseSelector]);
  return event;
}

NSEvent* MockScrollWheelEventWithMomentumPhase(SEL mockPhaseSelector,
                                               int32_t delta) {
  // Create a fake event with phaseNone. This is for resetting the phase info
  // of CGEventRef.
  MockScrollWheelEventWithPhase(@selector(phaseNone), 0);
  CGEventRef cg_event = CGEventCreateScrollWheelEvent(
      nullptr, kCGScrollEventUnitLine, 1, delta, 0);
  CGEventTimestamp timestamp = 0;
  CGEventSetTimestamp(cg_event, timestamp);
  NSEvent* event = [NSEvent eventWithCGEvent:cg_event];
  CFRelease(cg_event);
  method_setImplementation(
      class_getInstanceMethod([NSEvent class], @selector(momentumPhase)),
      [MockPhaseMethods instanceMethodForSelector:mockPhaseSelector]);
  return event;
}

NSEvent* MockScrollWheelEventWithoutPhase(int32_t delta) {
  return MockScrollWheelEventWithMomentumPhase(@selector(phaseNone), delta);
}

class MockRenderWidgetHostOwnerDelegate
    : public StubRenderWidgetHostOwnerDelegate {
 public:
  MOCK_METHOD1(SetBackgroundOpaque, void(bool opaque));
};

}  // namespace

class RenderWidgetHostViewMacTest : public RenderViewHostImplTestHarness {
 public:
  RenderWidgetHostViewMacTest() : rwhv_mac_(nullptr) {
    mock_clock_.Advance(base::TimeDelta::FromMilliseconds(100));
    ui::SetEventTickClockForTesting(&mock_clock_);
  }

  void SetUp() override {
    RenderViewHostImplTestHarness::SetUp();
    base::test::ScopedFeatureList feature_list;
    feature_list.InitAndEnableFeature(features::kDirectManipulationStylus);

    browser_context_ = std::make_unique<TestBrowserContext>();
    process_host_ =
        std::make_unique<MockRenderProcessHost>(browser_context_.get());
    process_host_->Init();
    host_ = base::WrapUnique(MockRenderWidgetHostImpl::Create(
        &delegate_, process_host_.get(), process_host_->GetNextRoutingID()));
    host_->set_owner_delegate(&mock_owner_delegate_);
    rwhv_mac_ = new RenderWidgetHostViewMac(host_.get(), false);
    rwhv_cocoa_.reset([rwhv_mac_->cocoa_view() retain]);

    window_.reset([[CocoaTestHelperWindow alloc] init]);
    window_.get().pretendIsKeyWindow = YES;
    [[window_ contentView] addSubview:rwhv_cocoa_];
    [rwhv_cocoa_ setFrame:[window_ contentView].bounds];

    base::RunLoop().RunUntilIdle();
    process_host_->sink().ClearMessages();
  }

  void TearDown() override {
    rwhv_cocoa_.reset();
    // RenderWidgetHostImpls with an owner delegate are not expected to be self-
    // deleting.
    host_->ShutdownAndDestroyWidget(/*also_delete=*/false);
    host_.reset();
    process_host_.reset();
    browser_context_.reset();
    RecycleAndWait();
    RenderViewHostImplTestHarness::TearDown();
  }

  void RecycleAndWait() {
    pool_.Recycle();
    base::RunLoop().RunUntilIdle();
    pool_.Recycle();
  }

  void DestroyHostViewRetainCocoaView() {
    test_rvh()->GetWidget()->SetView(nullptr);
    rwhv_mac_->Destroy();
  }

  void ActivateViewWithTextInputManager(RenderWidgetHostViewBase* view,
                                        ui::TextInputType type) {
    TextInputState state;
    state.type = type;
    view->TextInputStateChanged(state);
  }

 protected:
  std::string selected_text() const {
    return base::UTF16ToUTF8(rwhv_mac_->GetTextSelection()->selected_text());
  }

  MockRenderWidgetHostDelegate delegate_;

  std::unique_ptr<TestBrowserContext> browser_context_;
  std::unique_ptr<MockRenderProcessHost> process_host_;
  testing::NiceMock<MockRenderWidgetHostOwnerDelegate> mock_owner_delegate_;
  std::unique_ptr<MockRenderWidgetHostImpl> host_;
  RenderWidgetHostViewMac* rwhv_mac_ = nullptr;
  base::scoped_nsobject<RenderWidgetHostViewCocoa> rwhv_cocoa_;
  base::scoped_nsobject<CocoaTestHelperWindow> window_;

 private:
  // This class isn't derived from PlatformTest.
  base::mac::ScopedNSAutoreleasePool pool_;

  base::SimpleTestTickClock mock_clock_;

  DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewMacTest);
};

TEST_F(RenderWidgetHostViewMacTest, Basic) {
}

TEST_F(RenderWidgetHostViewMacTest, AcceptsFirstResponder) {
  // The RWHVCocoa should normally accept first responder status.
  EXPECT_TRUE([rwhv_cocoa_.get() acceptsFirstResponder]);
}

// This test verifies that RenderWidgetHostViewCocoa's implementation of
// NSTextInputClientConformance conforms to requirements.
TEST_F(RenderWidgetHostViewMacTest, NSTextInputClientConformance) {
  NSRange selectedRange = [rwhv_cocoa_ selectedRange];
  EXPECT_EQ(0u, selectedRange.location);
  EXPECT_EQ(0u, selectedRange.length);

  NSRange actualRange = NSMakeRange(1u, 2u);
  NSAttributedString* actualString = [rwhv_cocoa_
      attributedSubstringForProposedRange:NSMakeRange(NSNotFound, 0u)
                              actualRange:&actualRange];
  EXPECT_EQ(nil, actualString);
  EXPECT_EQ(static_cast<NSUInteger>(NSNotFound), actualRange.location);
  EXPECT_EQ(0u, actualRange.length);

  actualString = [rwhv_cocoa_
      attributedSubstringForProposedRange:NSMakeRange(NSNotFound, 15u)
                              actualRange:&actualRange];
  EXPECT_EQ(nil, actualString);
  EXPECT_EQ(static_cast<NSUInteger>(NSNotFound), actualRange.location);
  EXPECT_EQ(0u, actualRange.length);
}

// Test that NSEvent of private use character won't generate keypress event
// http://crbug.com/459089
TEST_F(RenderWidgetHostViewMacTest, FilterNonPrintableCharacter) {
  // Simulate ctrl+F12, will produce a private use character but shouldn't
  // fire keypress event
  MockWidgetInputHandler::MessageVector events =
      host_->GetAndResetDispatchedMessages();

  EXPECT_EQ(0U, events.size());
  [rwhv_mac_->cocoa_view()
      keyEvent:cocoa_test_event_utils::KeyEventWithKeyCode(
                   0x7B, 0xF70F, NSKeyDown, NSControlKeyMask)];
  base::RunLoop().RunUntilIdle();
  events = host_->GetAndResetDispatchedMessages();

  EXPECT_EQ("RawKeyDown", GetMessageNames(events));

  // Simulate ctrl+delete, will produce a private use character but shouldn't
  // fire keypress event
  process_host_->sink().ClearMessages();
  EXPECT_EQ(0U, process_host_->sink().message_count());
  [rwhv_mac_->cocoa_view()
      keyEvent:cocoa_test_event_utils::KeyEventWithKeyCode(
                   0x2E, 0xF728, NSKeyDown, NSControlKeyMask)];
  base::RunLoop().RunUntilIdle();
  events = host_->GetAndResetDispatchedMessages();
  EXPECT_EQ("RawKeyDown", GetMessageNames(events));

  // Simulate a printable char, should generate keypress event
  [rwhv_mac_->cocoa_view()
      keyEvent:cocoa_test_event_utils::KeyEventWithKeyCode(0x58, 'x', NSKeyDown,
                                                           NSControlKeyMask)];
  base::RunLoop().RunUntilIdle();
  events = host_->GetAndResetDispatchedMessages();
  EXPECT_EQ("RawKeyDown Char", GetMessageNames(events));
}

// Test that invalid |keyCode| shouldn't generate key events.
// https://crbug.com/601964
TEST_F(RenderWidgetHostViewMacTest, InvalidKeyCode) {
  // Simulate "Convert" key on JIS PC keyboard, will generate a |NSFlagsChanged|
  // NSEvent with |keyCode| == 0xFF.
  [rwhv_mac_->cocoa_view() keyEvent:cocoa_test_event_utils::KeyEventWithKeyCode(
                                        0xFF, 0, NSFlagsChanged, 0)];
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0U, host_->GetAndResetDispatchedMessages().size());
}

TEST_F(RenderWidgetHostViewMacTest, GetFirstRectForCharacterRangeCaretCase) {
  const base::string16 kDummyString = base::UTF8ToUTF16("hogehoge");
  const size_t kDummyOffset = 0;

  gfx::Rect caret_rect(10, 11, 0, 10);
  gfx::Range caret_range(0, 0);
  WidgetHostMsg_SelectionBounds_Params params;

  gfx::Rect rect;
  gfx::Range actual_range;
  rwhv_mac_->SelectionChanged(kDummyString, kDummyOffset, caret_range);
  params.anchor_rect = params.focus_rect = caret_rect;
  params.anchor_dir = params.focus_dir = blink::kWebTextDirectionLeftToRight;
  rwhv_mac_->SelectionBoundsChanged(params);
  EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(caret_range, &rect,
                                                             &actual_range));
  EXPECT_EQ(caret_rect, rect);
  EXPECT_EQ(caret_range, gfx::Range(actual_range));

  EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
      gfx::Range(0, 1), &rect, &actual_range));
  EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
      gfx::Range(1, 1), &rect, &actual_range));
  EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
      gfx::Range(2, 3), &rect, &actual_range));

  // Caret moved.
  caret_rect = gfx::Rect(20, 11, 0, 10);
  caret_range = gfx::Range(1, 1);
  params.anchor_rect = params.focus_rect = caret_rect;
  rwhv_mac_->SelectionChanged(kDummyString, kDummyOffset, caret_range);
  rwhv_mac_->SelectionBoundsChanged(params);
  EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(caret_range, &rect,
                                                             &actual_range));
  EXPECT_EQ(caret_rect, rect);
  EXPECT_EQ(caret_range, actual_range);

  EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
      gfx::Range(0, 0), &rect, &actual_range));
  EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
      gfx::Range(1, 2), &rect, &actual_range));
  EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
      gfx::Range(2, 3), &rect, &actual_range));

  // No caret.
  caret_range = gfx::Range(1, 2);
  rwhv_mac_->SelectionChanged(kDummyString, kDummyOffset, caret_range);
  params.anchor_rect = caret_rect;
  params.focus_rect = gfx::Rect(30, 11, 0, 10);
  rwhv_mac_->SelectionBoundsChanged(params);
  EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
      gfx::Range(0, 0), &rect, &actual_range));
  EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
      gfx::Range(0, 1), &rect, &actual_range));
  EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
      gfx::Range(1, 1), &rect, &actual_range));
  EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
      gfx::Range(1, 2), &rect, &actual_range));
  EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
      gfx::Range(2, 2), &rect, &actual_range));
}

TEST_F(RenderWidgetHostViewMacTest, UpdateCompositionSinglelineCase) {
  ActivateViewWithTextInputManager(rwhv_mac_, ui::TEXT_INPUT_TYPE_TEXT);
  const gfx::Point kOrigin(10, 11);
  const gfx::Size kBoundsUnit(10, 20);

  gfx::Rect rect;
  // Make sure not crashing by passing nullptr pointer instead of
  // |actual_range|.
  EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(gfx::Range(0, 0),
                                                              &rect, nullptr));

  // If there are no update from renderer, always returned caret position.
  gfx::Range actual_range;
  EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
      gfx::Range(0, 0), &rect, &actual_range));
  EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
      gfx::Range(0, 1), &rect, &actual_range));
  EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
      gfx::Range(1, 0), &rect, &actual_range));
  EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
      gfx::Range(1, 1), &rect, &actual_range));
  EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
      gfx::Range(1, 2), &rect, &actual_range));

  // If the firstRectForCharacterRange is failed in renderer, empty rect vector
  // is sent. Make sure this does not crash.
  rwhv_mac_->ImeCompositionRangeChanged(gfx::Range(10, 12),
                                        std::vector<gfx::Rect>());
  EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
      gfx::Range(10, 11), &rect, nullptr));

  const int kCompositionLength = 10;
  std::vector<gfx::Rect> composition_bounds;
  const int kCompositionStart = 3;
  const gfx::Range kCompositionRange(kCompositionStart,
                                    kCompositionStart + kCompositionLength);
  GenerateCompositionRectArray(kOrigin,
                               kBoundsUnit,
                               kCompositionLength,
                               std::vector<size_t>(),
                               &composition_bounds);
  rwhv_mac_->ImeCompositionRangeChanged(kCompositionRange, composition_bounds);

  // Out of range requests will return caret position.
  EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
      gfx::Range(0, 0), &rect, &actual_range));
  EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
      gfx::Range(1, 1), &rect, &actual_range));
  EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
      gfx::Range(1, 2), &rect, &actual_range));
  EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
      gfx::Range(2, 2), &rect, &actual_range));
  EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
      gfx::Range(13, 14), &rect, &actual_range));
  EXPECT_FALSE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
      gfx::Range(14, 15), &rect, &actual_range));

  for (int i = 0; i <= kCompositionLength; ++i) {
    for (int j = 0; j <= kCompositionLength - i; ++j) {
      const gfx::Range range(i, i + j);
      const gfx::Rect expected_rect = GetExpectedRect(kOrigin,
                                                      kBoundsUnit,
                                                      range,
                                                      0);
      const gfx::Range request_range = gfx::Range(
          kCompositionStart + range.start(), kCompositionStart + range.end());
      EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
            request_range,
            &rect,
            &actual_range));
      EXPECT_EQ(request_range, actual_range);
      EXPECT_EQ(expected_rect, rect);

      // Make sure not crashing by passing nullptr pointer instead of
      // |actual_range|.
      EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(
          request_range, &rect, nullptr));
    }
  }
}

TEST_F(RenderWidgetHostViewMacTest, UpdateCompositionMultilineCase) {
  ActivateViewWithTextInputManager(rwhv_mac_, ui::TEXT_INPUT_TYPE_TEXT);
  const gfx::Point kOrigin(10, 11);
  const gfx::Size kBoundsUnit(10, 20);
  gfx::Rect rect;

  const int kCompositionLength = 30;
  std::vector<gfx::Rect> composition_bounds;
  const gfx::Range kCompositionRange(0, kCompositionLength);
  // Set breaking point at 10 and 20.
  std::vector<size_t> break_points;
  break_points.push_back(10);
  break_points.push_back(20);
  GenerateCompositionRectArray(kOrigin,
                               kBoundsUnit,
                               kCompositionLength,
                               break_points,
                               &composition_bounds);
  rwhv_mac_->ImeCompositionRangeChanged(kCompositionRange, composition_bounds);

  // Range doesn't contain line breaking point.
  gfx::Range range;
  range = gfx::Range(5, 8);
  gfx::Range actual_range;
  EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(range, &rect,
                                                             &actual_range));
  EXPECT_EQ(range, actual_range);
  EXPECT_EQ(GetExpectedRect(kOrigin, kBoundsUnit, range, 0), rect);
  range = gfx::Range(15, 18);
  EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(range, &rect,
                                                             &actual_range));
  EXPECT_EQ(range, actual_range);
  EXPECT_EQ(GetExpectedRect(kOrigin, kBoundsUnit, gfx::Range(5, 8), 1), rect);
  range = gfx::Range(25, 28);
  EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(range, &rect,
                                                             &actual_range));
  EXPECT_EQ(range, actual_range);
  EXPECT_EQ(GetExpectedRect(kOrigin, kBoundsUnit, gfx::Range(5, 8), 2), rect);

  // Range contains line breaking point.
  range = gfx::Range(8, 12);
  EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(range, &rect,
                                                             &actual_range));
  EXPECT_EQ(gfx::Range(8, 10), actual_range);
  EXPECT_EQ(GetExpectedRect(kOrigin, kBoundsUnit, gfx::Range(8, 10), 0), rect);
  range = gfx::Range(18, 22);
  EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(range, &rect,
                                                             &actual_range));
  EXPECT_EQ(gfx::Range(18, 20), actual_range);
  EXPECT_EQ(GetExpectedRect(kOrigin, kBoundsUnit, gfx::Range(8, 10), 1), rect);

  // Start point is line breaking point.
  range = gfx::Range(10, 12);
  EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(range, &rect,
                                                             &actual_range));
  EXPECT_EQ(gfx::Range(10, 12), actual_range);
  EXPECT_EQ(GetExpectedRect(kOrigin, kBoundsUnit, gfx::Range(0, 2), 1), rect);
  range = gfx::Range(20, 22);
  EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(range, &rect,
                                                             &actual_range));
  EXPECT_EQ(gfx::Range(20, 22), actual_range);
  EXPECT_EQ(GetExpectedRect(kOrigin, kBoundsUnit, gfx::Range(0, 2), 2), rect);

  // End point is line breaking point.
  range = gfx::Range(5, 10);
  EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(range, &rect,
                                                             &actual_range));
  EXPECT_EQ(gfx::Range(5, 10), actual_range);
  EXPECT_EQ(GetExpectedRect(kOrigin, kBoundsUnit, gfx::Range(5, 10), 0), rect);
  range = gfx::Range(15, 20);
  EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(range, &rect,
                                                             &actual_range));
  EXPECT_EQ(gfx::Range(15, 20), actual_range);
  EXPECT_EQ(GetExpectedRect(kOrigin, kBoundsUnit, gfx::Range(5, 10), 1), rect);

  // Start and end point are same line breaking point.
  range = gfx::Range(10, 10);
  EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(range, &rect,
                                                             &actual_range));
  EXPECT_EQ(gfx::Range(10, 10), actual_range);
  EXPECT_EQ(GetExpectedRect(kOrigin, kBoundsUnit, gfx::Range(0, 0), 1), rect);
  range = gfx::Range(20, 20);
  EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(range, &rect,
                                                             &actual_range));
  EXPECT_EQ(gfx::Range(20, 20), actual_range);
  EXPECT_EQ(GetExpectedRect(kOrigin, kBoundsUnit, gfx::Range(0, 0), 2), rect);

  // Start and end point are different line breaking point.
  range = gfx::Range(10, 20);
  EXPECT_TRUE(rwhv_mac_->GetCachedFirstRectForCharacterRange(range, &rect,
                                                             &actual_range));
  EXPECT_EQ(gfx::Range(10, 20), actual_range);
  EXPECT_EQ(GetExpectedRect(kOrigin, kBoundsUnit, gfx::Range(0, 10), 1), rect);
}

// Check that events coming from AppKit via -[NSTextInputClient
// firstRectForCharacterRange:actualRange] are handled in a sane manner if they
// arrive after the C++ RenderWidgetHostView is destroyed.
TEST_F(RenderWidgetHostViewMacTest, CompositionEventAfterDestroy) {
  ActivateViewWithTextInputManager(rwhv_mac_, ui::TEXT_INPUT_TYPE_TEXT);
  const gfx::Rect composition_bounds(0, 0, 30, 40);
  const gfx::Range range(0, 1);
  rwhv_mac_->ImeCompositionRangeChanged(
      range, std::vector<gfx::Rect>(1, composition_bounds));

  NSRange actual_range = NSMakeRange(0, 0);

  NSRect rect = [rwhv_cocoa_ firstRectForCharacterRange:range.ToNSRange()
                                            actualRange:&actual_range];
  EXPECT_EQ(30, rect.size.width);
  EXPECT_EQ(40, rect.size.height);
  EXPECT_EQ(range, gfx::Range(actual_range));

  DestroyHostViewRetainCocoaView();
  actual_range = NSMakeRange(0, 0);
  rect = [rwhv_cocoa_ firstRectForCharacterRange:range.ToNSRange()
                                     actualRange:&actual_range];
  EXPECT_NSEQ(NSZeroRect, rect);
  EXPECT_EQ(gfx::Range(), gfx::Range(actual_range));
}

// Verify that |SetActive()| calls |RenderWidgetHostImpl::Blur()| and
// |RenderWidgetHostImp::Focus()|.
TEST_F(RenderWidgetHostViewMacTest, BlurAndFocusOnSetActive) {
  EXPECT_CALL(*host_, Focus());
  [window_ makeFirstResponder:rwhv_mac_->cocoa_view()];
  testing::Mock::VerifyAndClearExpectations(host_.get());

  EXPECT_CALL(*host_, Blur());
  rwhv_mac_->SetActive(false);
  testing::Mock::VerifyAndClearExpectations(host_.get());

  EXPECT_CALL(*host_, Focus());
  rwhv_mac_->SetActive(true);
  testing::Mock::VerifyAndClearExpectations(host_.get());

  // Unsetting first responder should blur.
  EXPECT_CALL(*host_, Blur());
  [window_ makeFirstResponder:nil];
  testing::Mock::VerifyAndClearExpectations(host_.get());

  // |SetActive()| shoud not focus if view is not first responder.
  EXPECT_CALL(*host_, Focus()).Times(0);
  rwhv_mac_->SetActive(true);
  testing::Mock::VerifyAndClearExpectations(host_.get());
}

TEST_F(RenderWidgetHostViewMacTest, LastWheelEventLatencyInfoExists) {
  process_host_->sink().ClearMessages();

  // Send an initial wheel event for scrolling by 3 lines.
  // Verifies that ui::INPUT_EVENT_LATENCY_UI_COMPONENT is added
  // properly in scrollWheel function.
  NSEvent* wheelEvent1 = MockScrollWheelEventWithPhase(@selector(phaseBegan),3);
  [rwhv_mac_->cocoa_view() scrollWheel:wheelEvent1];
  ASSERT_TRUE(host_->lastWheelEventLatencyInfo.FindLatency(
      ui::INPUT_EVENT_LATENCY_UI_COMPONENT, nullptr));

  // Send a wheel event with phaseEnded.
  // Verifies that ui::INPUT_EVENT_LATENCY_UI_COMPONENT is added
  // properly in shortCircuitScrollWheelEvent function which is called
  // in scrollWheel.
  NSEvent* wheelEvent2 = MockScrollWheelEventWithPhase(@selector(phaseEnded),0);
  [rwhv_mac_->cocoa_view() scrollWheel:wheelEvent2];
  ASSERT_TRUE(host_->lastWheelEventLatencyInfo.FindLatency(
      ui::INPUT_EVENT_LATENCY_UI_COMPONENT, nullptr));
}

TEST_F(RenderWidgetHostViewMacTest, SourceEventTypeExistsInLatencyInfo) {
  process_host_->sink().ClearMessages();

  // Send a wheel event for scrolling by 3 lines.
  // Verifies that SourceEventType exists in forwarded LatencyInfo object.
  NSEvent* wheelEvent = MockScrollWheelEventWithPhase(@selector(phaseBegan), 3);
  [rwhv_mac_->cocoa_view() scrollWheel:wheelEvent];
  ASSERT_TRUE(host_->lastWheelEventLatencyInfo.source_event_type() ==
              ui::SourceEventType::WHEEL);
}

TEST_F(RenderWidgetHostViewMacTest, ScrollWheelEndEventDelivery) {
  // Send an initial wheel event with NSEventPhaseBegan to the view.
  NSEvent* event1 = MockScrollWheelEventWithPhase(@selector(phaseBegan), 0);
  [rwhv_mac_->cocoa_view() scrollWheel:event1];

  // Flush and clear other messages (e.g. begin frames) the RWHVMac also sends.
  base::RunLoop().RunUntilIdle();

  MockWidgetInputHandler::MessageVector events =
      host_->GetAndResetDispatchedMessages();
  EXPECT_EQ("MouseWheel", GetMessageNames(events));
  // Send an ACK for the first wheel event, so that the queue will be flushed.
  events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);

  // Post the NSEventPhaseEnded wheel event to NSApp and check whether the
  // render view receives it.
  NSEvent* event2 = MockScrollWheelEventWithPhase(@selector(phaseEnded), 0);
  [NSApp postEvent:event2 atStart:NO];
  base::RunLoop().RunUntilIdle();
  events = host_->GetAndResetDispatchedMessages();
  // The wheel event with phaseEnded won't be sent to the render view
  // immediately, instead the mouse_wheel_phase_handler will wait for 100ms
  // to see if a wheel event with momentumPhase began arrives or not.
  ASSERT_EQ(0U, events.size());
}

TEST_F(RenderWidgetHostViewMacTest, PointerEventWithEraserType) {
  // Send a NSEvent of NSTabletProximity type which has a device type of eraser.
  NSEvent* event = MockTabletEventWithParams(kCGEventTabletProximity, true,
                                             NSEraserPointingDevice);
  [rwhv_mac_->cocoa_view() tabletEvent:event];
  // Flush and clear other messages (e.g. begin frames) the RWHVMac also sends.
  base::RunLoop().RunUntilIdle();

  event =
      MockMouseEventWithParams(kCGEventMouseMoved, {6, 9}, kCGMouseButtonLeft,
                               kCGEventMouseSubtypeTabletPoint);
  [rwhv_mac_->cocoa_view() mouseEvent:event];
  base::RunLoop().RunUntilIdle();
  MockWidgetInputHandler::MessageVector events =
      host_->GetAndResetDispatchedMessages();
  ASSERT_EQ("MouseMove", GetMessageNames(events));
  EXPECT_EQ(blink::WebPointerProperties::PointerType::kEraser,
            GetPointerType(events));
}

TEST_F(RenderWidgetHostViewMacTest, PointerEventWithPenType) {
  // Send a NSEvent of NSTabletProximity type which has a device type of pen.
  NSEvent* event = MockTabletEventWithParams(kCGEventTabletProximity, true,
                                             NSPenPointingDevice);
  [rwhv_mac_->cocoa_view() tabletEvent:event];
  // Flush and clear other messages (e.g. begin frames) the RWHVMac also sends.
  base::RunLoop().RunUntilIdle();

  event =
      MockMouseEventWithParams(kCGEventMouseMoved, {6, 9}, kCGMouseButtonLeft,
                               kCGEventMouseSubtypeTabletPoint);
  [rwhv_mac_->cocoa_view() mouseEvent:event];
  base::RunLoop().RunUntilIdle();
  MockWidgetInputHandler::MessageVector events =
      host_->GetAndResetDispatchedMessages();
  ASSERT_EQ("MouseMove", GetMessageNames(events));
  EXPECT_EQ(blink::WebPointerProperties::PointerType::kPen,
            GetPointerType(events));
}

TEST_F(RenderWidgetHostViewMacTest, PointerEventWithPenTypeNoTabletEvent) {
  // Send a NSEvent of a mouse type with a subtype of
  // NSTabletProximityEventSubtype, which indicates the input device is a pen.
  NSEvent* event =
      MockMouseEventWithParams(kCGEventMouseMoved, {6, 9}, kCGMouseButtonLeft,
                               kCGEventMouseSubtypeTabletProximity, true);
  [rwhv_mac_->cocoa_view() mouseEvent:event];
  base::RunLoop().RunUntilIdle();
  MockWidgetInputHandler::MessageVector events =
      host_->GetAndResetDispatchedMessages();
  ASSERT_EQ("MouseMove", GetMessageNames(events));
  EXPECT_EQ(blink::WebPointerProperties::PointerType::kPen,
            GetPointerType(events));
  events.clear();

  event = cocoa_test_event_utils::EnterEvent({1, 1}, window_);
  [rwhv_mac_->cocoa_view() mouseEntered:event];
  base::RunLoop().RunUntilIdle();
  events = host_->GetAndResetDispatchedMessages();
  ASSERT_EQ("MouseMove", GetMessageNames(events));
  EXPECT_EQ(blink::WebPointerProperties::PointerType::kPen,
            static_cast<const blink::WebMouseEvent*>(
                events[0]->ToEvent()->Event()->web_event.get())
                ->pointer_type);
}

TEST_F(RenderWidgetHostViewMacTest, PointerEventWithMouseType) {
  // Send a NSEvent of a mouse type.
  NSEvent* event =
      MockMouseEventWithParams(kCGEventMouseMoved, {6, 9}, kCGMouseButtonLeft,
                               kCGEventMouseSubtypeDefault);
  [rwhv_mac_->cocoa_view() mouseEvent:event];
  base::RunLoop().RunUntilIdle();
  MockWidgetInputHandler::MessageVector events =
      host_->GetAndResetDispatchedMessages();
  ASSERT_EQ("MouseMove", GetMessageNames(events));
  EXPECT_EQ(blink::WebPointerProperties::PointerType::kMouse,
            GetPointerType(events));
}

TEST_F(RenderWidgetHostViewMacTest, PointerEventWithPenTypeSendAsTouch) {
  // Send a NSEvent of NSTabletProximity type which has a device type of pen.
  NSEvent* event = MockTabletEventWithParams(kCGEventTabletProximity, true,
                                             NSPenPointingDevice);
  [rwhv_mac_->cocoa_view() tabletEvent:event];
  // Flush and clear other messages (e.g. begin frames) the RWHVMac also sends.
  base::RunLoop().RunUntilIdle();
  static_cast<RenderWidgetHostImpl*>(rwhv_mac_->GetRenderWidgetHost())
      ->input_router()
      ->ForceSetTouchActionAuto();

  event = MockMouseEventWithParams(
      kCGEventLeftMouseDown, {6, 9}, kCGMouseButtonLeft,
      kCGEventMouseSubtypeTabletPoint, false, true);
  [rwhv_mac_->cocoa_view() mouseEvent:event];
  base::RunLoop().RunUntilIdle();
  MockWidgetInputHandler::MessageVector events =
      host_->GetAndResetDispatchedMessages();
  ASSERT_EQ("TouchStart", GetMessageNames(events));
  EXPECT_EQ(blink::WebPointerProperties::PointerType::kPen,
            GetPointerType(events));
  events.clear();
  base::RunLoop().RunUntilIdle();
  events = host_->GetAndResetDispatchedMessages();

  event = MockMouseEventWithParams(
      kCGEventLeftMouseDragged, {16, 29}, kCGMouseButtonLeft,
      kCGEventMouseSubtypeTabletPoint, false, true);
  [rwhv_mac_->cocoa_view() mouseEvent:event];
  base::RunLoop().RunUntilIdle();
  events = host_->GetAndResetDispatchedMessages();
  ASSERT_EQ("TouchMove", GetMessageNames(events));
  EXPECT_EQ(blink::WebPointerProperties::PointerType::kPen,
            GetPointerType(events));

  events.clear();
  base::RunLoop().RunUntilIdle();
  events = host_->GetAndResetDispatchedMessages();

  event = MockMouseEventWithParams(kCGEventLeftMouseUp, {16, 29},
                                   kCGMouseButtonLeft,
                                   kCGEventMouseSubtypeTabletPoint, false);
  [rwhv_mac_->cocoa_view() mouseEvent:event];
  base::RunLoop().RunUntilIdle();
  events = host_->GetAndResetDispatchedMessages();
  ASSERT_EQ("TouchEnd GestureScrollEnd", GetMessageNames(events));
  EXPECT_EQ(blink::WebPointerProperties::PointerType::kPen,
            static_cast<const blink::WebTouchEvent*>(
                events[0]->ToEvent()->Event()->web_event.get())
                ->touches[0]
                .pointer_type);

  events.clear();
  base::RunLoop().RunUntilIdle();
  events = host_->GetAndResetDispatchedMessages();

  event =
      MockMouseEventWithParams(kCGEventLeftMouseDown, {6, 9},
                               kCGMouseButtonLeft, kCGEventMouseSubtypeDefault);
  [rwhv_mac_->cocoa_view() mouseEvent:event];
  base::RunLoop().RunUntilIdle();
  events = host_->GetAndResetDispatchedMessages();
  ASSERT_EQ("MouseDown", GetMessageNames(events));
  EXPECT_EQ(blink::WebPointerProperties::PointerType::kMouse,
            GetPointerType(events));

  events.clear();
  base::RunLoop().RunUntilIdle();
  events = host_->GetAndResetDispatchedMessages();
}

TEST_F(RenderWidgetHostViewMacTest, SendMouseMoveOnShowingContextMenu) {
  rwhv_mac_->SetShowingContextMenu(true);
  base::RunLoop().RunUntilIdle();
  MockWidgetInputHandler::MessageVector events =
      host_->GetAndResetDispatchedMessages();
  ASSERT_EQ("MouseMove", GetMessageNames(events));

  events.clear();

  rwhv_mac_->SetShowingContextMenu(false);
  base::RunLoop().RunUntilIdle();
  events = host_->GetAndResetDispatchedMessages();
  ASSERT_EQ("MouseMove", GetMessageNames(events));
}

TEST_F(RenderWidgetHostViewMacTest,
       IgnoreEmptyUnhandledWheelEventWithWheelGestures) {
  // Add a delegate to the view.
  base::scoped_nsobject<MockRenderWidgetHostViewMacDelegate> view_delegate(
      [[MockRenderWidgetHostViewMacDelegate alloc] init]);
  rwhv_mac_->SetDelegate(view_delegate.get());

  // Send an initial wheel event for scrolling by 3 lines.
  NSEvent* event1 = MockScrollWheelEventWithPhase(@selector(phaseBegan), 3);
  [rwhv_mac_->cocoa_view() scrollWheel:event1];
  base::RunLoop().RunUntilIdle();

  MockWidgetInputHandler::MessageVector events =
      host_->GetAndResetDispatchedMessages();

  ASSERT_EQ("MouseWheel", GetMessageNames(events));

  // Indicate that the wheel event was unhandled.
  events.clear();

  base::RunLoop().RunUntilIdle();
  events = host_->GetAndResetDispatchedMessages();

  // GestureEventQueue allows multiple in-flight events.
  ASSERT_EQ("GestureScrollBegin GestureScrollUpdate", GetMessageNames(events));
  events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);

  events.clear();

  // Check that the view delegate got an unhandled wheel event.
  ASSERT_EQ(YES, view_delegate.get().unhandledWheelEventReceived);
  view_delegate.get().unhandledWheelEventReceived = NO;

  // Send another wheel event, this time for scrolling by 0 lines (empty event).
  NSEvent* event2 = MockScrollWheelEventWithPhase(@selector(phaseChanged), 0);
  [rwhv_mac_->cocoa_view() scrollWheel:event2];
  base::RunLoop().RunUntilIdle();
  events = host_->GetAndResetDispatchedMessages();
  ASSERT_EQ("MouseWheel", GetMessageNames(events));

  events.clear();

  // Check that the view delegate ignored the empty unhandled wheel event.
  ASSERT_EQ(NO, view_delegate.get().unhandledWheelEventReceived);

  // Delete the view while |view_delegate| is still in scope.
  rwhv_cocoa_.reset();
}

// Tests that when view initiated shutdown happens (i.e. RWHView is deleted
// before RWH), we clean up properly and don't leak the RWHVGuest.
TEST_F(RenderWidgetHostViewMacTest, GuestViewDoesNotLeak) {
  int32_t routing_id = process_host_->GetNextRoutingID();

  // Owned by its |cocoa_view()|.
  MockRenderWidgetHostImpl* rwh = MockRenderWidgetHostImpl::Create(
      &delegate_, process_host_.get(), routing_id);
  RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(rwh, true);

  // Add a delegate to the view.
  base::scoped_nsobject<MockRenderWidgetHostViewMacDelegate> view_delegate(
      [[MockRenderWidgetHostViewMacDelegate alloc] init]);
  view->SetDelegate(view_delegate.get());

  base::WeakPtr<RenderWidgetHostViewBase> guest_rwhv_weak =
      (RenderWidgetHostViewGuest::Create(rwh, nullptr, view->GetWeakPtr()))
          ->GetWeakPtr();

  // Remove the cocoa_view() so |view| also goes away before |rwh|.
  {
    base::scoped_nsobject<RenderWidgetHostViewCocoa> rwhv_cocoa;
    rwhv_cocoa.reset([view->cocoa_view() retain]);
  }
  RecycleAndWait();

  // Clean up.
  rwh->ShutdownAndDestroyWidget(true);

  // Let |guest_rwhv_weak| have a chance to delete itself.
  base::RunLoop run_loop;
  base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
                           run_loop.QuitClosure());
  run_loop.Run();

  ASSERT_FALSE(guest_rwhv_weak.get());
}

// Tests setting background transparency. See also (disabled on Mac)
// RenderWidgetHostTest.Background. This test has some additional checks for
// Mac.
TEST_F(RenderWidgetHostViewMacTest, Background) {
  // If no color has been specified then background_color is not set yet.
  ASSERT_FALSE(rwhv_mac_->GetBackgroundColor());

  {
    // Set the color to red. The background is initially assumed to be opaque,
    // so no opacity message change should be sent.
    EXPECT_CALL(mock_owner_delegate_, SetBackgroundOpaque(_)).Times(0);
    rwhv_mac_->SetBackgroundColor(SK_ColorRED);
    EXPECT_EQ(unsigned{SK_ColorRED}, *rwhv_mac_->GetBackgroundColor());
  }
  {
    // Set the color to blue. This should not send an opacity message.
    EXPECT_CALL(mock_owner_delegate_, SetBackgroundOpaque(_)).Times(0);
    rwhv_mac_->SetBackgroundColor(SK_ColorBLUE);
    EXPECT_EQ(unsigned{SK_ColorBLUE}, *rwhv_mac_->GetBackgroundColor());
  }
  {
    // Set the color back to transparent. The background color should now be
    // reported as the default (white), and a transparency change message should
    // be sent.
    EXPECT_CALL(mock_owner_delegate_, SetBackgroundOpaque(false));
    rwhv_mac_->SetBackgroundColor(SK_ColorTRANSPARENT);
    EXPECT_EQ(unsigned{SK_ColorWHITE}, *rwhv_mac_->GetBackgroundColor());
  }
  {
    // Set the color to blue. This should send an opacity message.
    EXPECT_CALL(mock_owner_delegate_, SetBackgroundOpaque(true));
    rwhv_mac_->SetBackgroundColor(SK_ColorBLUE);
    EXPECT_EQ(unsigned{SK_ColorBLUE}, *rwhv_mac_->GetBackgroundColor());
  }
}

// Scrolling with a mouse wheel device on Mac won't give phase information.
// MouseWheelPhaseHandler adds timer based phase information to wheel events
// generated from this type of devices.
TEST_F(RenderWidgetHostViewMacTest, TimerBasedPhaseInfo) {
  rwhv_mac_->set_mouse_wheel_wheel_phase_handler_timeout(
      base::TimeDelta::FromMilliseconds(100));

  // Send a wheel event without phase information for scrolling by 3 lines.
  NSEvent* wheelEvent = MockScrollWheelEventWithoutPhase(3);
  [rwhv_mac_->cocoa_view() scrollWheel:wheelEvent];
  base::RunLoop().RunUntilIdle();
  MockWidgetInputHandler::MessageVector events =
      host_->GetAndResetDispatchedMessages();
  ASSERT_EQ("MouseWheel", GetMessageNames(events));

  events.clear();
  events = host_->GetAndResetDispatchedMessages();
  // Both GSB and GSU will be sent since GestureEventQueue allows multiple
  // in-flight events.
  ASSERT_EQ("GestureScrollBegin GestureScrollUpdate", GetMessageNames(events));
  ASSERT_TRUE(static_cast<const blink::WebGestureEvent*>(
                  events[0]->ToEvent()->Event()->web_event.get())
                  ->data.scroll_begin.synthetic);
  events.clear();

  // Wait for the mouse_wheel_end_dispatch_timer_ to expire, the pending wheel
  // event gets dispatched.
  base::RunLoop run_loop;
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, run_loop.QuitWhenIdleClosure(),
      base::TimeDelta::FromMilliseconds(100));
  run_loop.Run();

  events = host_->GetAndResetDispatchedMessages();
  ASSERT_EQ("MouseWheel GestureScrollEnd", GetMessageNames(events));
  ASSERT_TRUE(static_cast<const blink::WebGestureEvent*>(
                  events[1]->ToEvent()->Event()->web_event.get())
                  ->data.scroll_end.synthetic);
}

// With wheel scroll latching wheel end events are not sent immediately, instead
// we start a timer to see if momentum phase of the scroll starts or not.
TEST_F(RenderWidgetHostViewMacTest,
       WheelWithPhaseEndedIsNotForwardedImmediately) {
  // Initialize the view associated with a MockRenderWidgetHostImpl, rather than
  // the MockRenderProcessHost that is set up by the test harness which mocks
  // out |OnMessageReceived()|.
  TestBrowserContext browser_context;
  MockRenderProcessHost* process_host =
      new MockRenderProcessHost(&browser_context);
  process_host->Init();
  MockRenderWidgetHostDelegate delegate;
  int32_t routing_id = process_host->GetNextRoutingID();
  MockRenderWidgetHostImpl* host =
      MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
  RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
  base::RunLoop().RunUntilIdle();

  // Send an initial wheel event for scrolling by 3 lines.
  NSEvent* wheelEvent1 =
      MockScrollWheelEventWithPhase(@selector(phaseBegan), 3);
  [view->cocoa_view() scrollWheel:wheelEvent1];
  base::RunLoop().RunUntilIdle();
  MockWidgetInputHandler::MessageVector events =
      host->GetAndResetDispatchedMessages();
  ASSERT_EQ("MouseWheel", GetMessageNames(events));

  events.clear();
  events = host->GetAndResetDispatchedMessages();
  // Both GSB and GSU will be sent since GestureEventQueue allows multiple
  // in-flight events.
  ASSERT_EQ("GestureScrollBegin GestureScrollUpdate", GetMessageNames(events));

  // Send a wheel event with phaseEnded. The event will be dropped and the
  // mouse_wheel_end_dispatch_timer_ will start.
  NSEvent* wheelEvent2 =
      MockScrollWheelEventWithPhase(@selector(phaseEnded), 0);
  [view->cocoa_view() scrollWheel:wheelEvent2];
  base::RunLoop().RunUntilIdle();
  events = host->GetAndResetDispatchedMessages();
  ASSERT_EQ(0U, events.size());
  DCHECK(view->HasPendingWheelEndEventForTesting());

  host->ShutdownAndDestroyWidget(true);

  // Wait for the mouse_wheel_end_dispatch_timer_ to expire after host is
  // destroyed. The pending wheel end event won't get dispatched since the
  // render_widget_host_ is null. This waiting confirms that no crash happens
  // because of an attempt to send the pending wheel end event.
  // https://crbug.com/770057
  base::RunLoop run_loop;
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, run_loop.QuitClosure(),
      kMaximumTimeBetweenPhaseEndedAndMomentumPhaseBegan);
  run_loop.Run();
}

TEST_F(RenderWidgetHostViewMacTest,
       WheelWithMomentumPhaseBeganStopsTheWheelEndDispatchTimer) {
  // Initialize the view associated with a MockRenderWidgetHostImpl, rather than
  // the MockRenderProcessHost that is set up by the test harness which mocks
  // out |OnMessageReceived()|.
  TestBrowserContext browser_context;
  MockRenderProcessHost* process_host =
      new MockRenderProcessHost(&browser_context);
  process_host->Init();
  MockRenderWidgetHostDelegate delegate;
  int32_t routing_id = process_host->GetNextRoutingID();
  MockRenderWidgetHostImpl* host =
      MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
  RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
  base::RunLoop().RunUntilIdle();

  // Send an initial wheel event for scrolling by 3 lines.
  NSEvent* wheelEvent1 =
      MockScrollWheelEventWithPhase(@selector(phaseBegan), 3);
  [view->cocoa_view() scrollWheel:wheelEvent1];
  base::RunLoop().RunUntilIdle();
  MockWidgetInputHandler::MessageVector events =
      host->GetAndResetDispatchedMessages();
  ASSERT_EQ("MouseWheel", GetMessageNames(events));

  // Indicate that the wheel event was unhandled.
  events.clear();
  events = host->GetAndResetDispatchedMessages();
  // Both GSB and GSU will be sent since GestureEventQueue allows multiple
  // in-flight events.
  ASSERT_EQ("GestureScrollBegin GestureScrollUpdate", GetMessageNames(events));

  // Send a wheel event with phaseEnded. The event will be dropped and the
  // mouse_wheel_end_dispatch_timer_ will start.
  NSEvent* wheelEvent2 =
      MockScrollWheelEventWithPhase(@selector(phaseEnded), 0);
  [view->cocoa_view() scrollWheel:wheelEvent2];
  base::RunLoop().RunUntilIdle();
  events = host->GetAndResetDispatchedMessages();
  ASSERT_EQ(0U, events.size());
  DCHECK(view->HasPendingWheelEndEventForTesting());

  // Send a wheel event with momentum phase started, this should stop the wheel
  // end dispatch timer.
  NSEvent* wheelEvent3 =
      MockScrollWheelEventWithMomentumPhase(@selector(phaseBegan), 3);
  ASSERT_TRUE(wheelEvent3);
  [view->cocoa_view() scrollWheel:wheelEvent3];
  base::RunLoop().RunUntilIdle();
  events = host->GetAndResetDispatchedMessages();
  ASSERT_EQ("MouseWheel GestureScrollUpdate", GetMessageNames(events));
  DCHECK(!view->HasPendingWheelEndEventForTesting());

  host->ShutdownAndDestroyWidget(true);
}

TEST_F(RenderWidgetHostViewMacTest,
       WheelWithPhaseBeganDispatchesThePendingWheelEnd) {
  // Initialize the view associated with a MockRenderWidgetHostImpl, rather than
  // the MockRenderProcessHost that is set up by the test harness which mocks
  // out |OnMessageReceived()|.
  TestBrowserContext browser_context;
  MockRenderProcessHost* process_host =
      new MockRenderProcessHost(&browser_context);
  process_host->Init();
  MockRenderWidgetHostDelegate delegate;
  int32_t routing_id = process_host->GetNextRoutingID();
  MockRenderWidgetHostImpl* host =
      MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
  RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
  base::RunLoop().RunUntilIdle();

  // Send an initial wheel event for scrolling by 3 lines.
  NSEvent* wheelEvent1 =
      MockScrollWheelEventWithPhase(@selector(phaseBegan), 3);
  [view->cocoa_view() scrollWheel:wheelEvent1];
  base::RunLoop().RunUntilIdle();
  MockWidgetInputHandler::MessageVector events =
      host->GetAndResetDispatchedMessages();
  ASSERT_EQ("MouseWheel", GetMessageNames(events));

  // Indicate that the wheel event was unhandled.
  events.clear();
  // Both GSB and GSU will be sent since GestureEventQueue allows multiple
  // in-flight events.
  events = host->GetAndResetDispatchedMessages();
  ASSERT_EQ("GestureScrollBegin GestureScrollUpdate", GetMessageNames(events));

  // Send a wheel event with phaseEnded. The event will be dropped and the
  // mouse_wheel_end_dispatch_timer_ will start.
  NSEvent* wheelEvent2 =
      MockScrollWheelEventWithPhase(@selector(phaseEnded), 0);
  [view->cocoa_view() scrollWheel:wheelEvent2];
  base::RunLoop().RunUntilIdle();
  events = host->GetAndResetDispatchedMessages();
  ASSERT_EQ(0U, events.size());
  DCHECK(view->HasPendingWheelEndEventForTesting());

  // Send a wheel event with phase started, this should stop the wheel end
  // dispatch timer and dispatch the pending wheel end event for the previous
  // scroll sequence.
  NSEvent* wheelEvent3 =
      MockScrollWheelEventWithPhase(@selector(phaseBegan), 3);
  ASSERT_TRUE(wheelEvent3);
  [view->cocoa_view() scrollWheel:wheelEvent3];
  base::RunLoop().RunUntilIdle();
  events = host->GetAndResetDispatchedMessages();
  ASSERT_EQ("MouseWheel GestureScrollEnd MouseWheel", GetMessageNames(events));
  DCHECK(!view->HasPendingWheelEndEventForTesting());

  host->ShutdownAndDestroyWidget(true);
}

class RenderWidgetHostViewMacPinchTest
    : public RenderWidgetHostViewMacTest,
      public testing::WithParamInterface<bool> {
 public:
  RenderWidgetHostViewMacPinchTest() : async_events_enabled_(GetParam()) {
    if (async_events_enabled_) {
      scoped_feature_list_.InitAndEnableFeature(
          features::kTouchpadAsyncPinchEvents);
    } else {
      scoped_feature_list_.InitAndDisableFeature(
          features::kTouchpadAsyncPinchEvents);
    }
  }

  bool ShouldSendGestureEvents() {
#if defined(MAC_OS_X_VERSION_10_11) && \
    MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_11
    return base::mac::IsAtMostOS10_10();
#endif
    return true;
  }

  void SendBeginPinchEvent() {
    NSEvent* pinchBeginEvent = MockPinchEvent(NSEventPhaseBegan, 0);
    if (ShouldSendGestureEvents())
      [rwhv_cocoa_ beginGestureWithEvent:pinchBeginEvent];
    [rwhv_cocoa_ magnifyWithEvent:pinchBeginEvent];
  }

  void SendEndPinchEvent() {
    NSEvent* pinchEndEvent = MockPinchEvent(NSEventPhaseEnded, 0);
    [rwhv_cocoa_ magnifyWithEvent:pinchEndEvent];
    if (ShouldSendGestureEvents())
      [rwhv_cocoa_ endGestureWithEvent:pinchEndEvent];
  }

  const bool async_events_enabled_;

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
  DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewMacPinchTest);
};

INSTANTIATE_TEST_SUITE_P(, RenderWidgetHostViewMacPinchTest, testing::Bool());

TEST_P(RenderWidgetHostViewMacPinchTest, PinchThresholding) {
  // Do a gesture that crosses the threshold.
  {
    NSEvent* pinchUpdateEvents[3] = {
        MockPinchEvent(NSEventPhaseChanged, 0.25),
        MockPinchEvent(NSEventPhaseChanged, 0.25),
        MockPinchEvent(NSEventPhaseChanged, 0.25),
    };

    SendBeginPinchEvent();
    base::RunLoop().RunUntilIdle();
    MockWidgetInputHandler::MessageVector events =
        host_->GetAndResetDispatchedMessages();

    EXPECT_EQ(0U, events.size());

    // No zoom is sent for the first update event.
    [rwhv_cocoa_ magnifyWithEvent:pinchUpdateEvents[0]];
    base::RunLoop().RunUntilIdle();
    events = host_->GetAndResetDispatchedMessages();
    EXPECT_EQ("MouseWheel", GetMessageNames(events));

    // After acking the synthetic mouse wheel, no GesturePinch events are
    // produced.
    events[0]->ToEvent()->CallCallback(
        INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
    events = host_->GetAndResetDispatchedMessages();
    EXPECT_EQ(0U, events.size());

    // The second update event crosses the threshold of 0.4, and so zoom is no
    // longer disabled.
    [rwhv_cocoa_ magnifyWithEvent:pinchUpdateEvents[1]];
    base::RunLoop().RunUntilIdle();
    events = host_->GetAndResetDispatchedMessages();

    if (async_events_enabled_) {
      EXPECT_EQ("MouseWheel GesturePinchBegin GesturePinchUpdate",
                GetMessageNames(events));
    } else {
      EXPECT_EQ("MouseWheel", GetMessageNames(events));
      // Now acking the synthetic mouse wheel does produce GesturePinch events.
      events[0]->ToEvent()->CallCallback(
          INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
      events = host_->GetAndResetDispatchedMessages();
      EXPECT_EQ("GesturePinchBegin GesturePinchUpdate",
                GetMessageNames(events));
    }

    // The third update still has zoom enabled.
    [rwhv_cocoa_ magnifyWithEvent:pinchUpdateEvents[2]];
    base::RunLoop().RunUntilIdle();
    events = host_->GetAndResetDispatchedMessages();
    if (async_events_enabled_) {
      EXPECT_EQ("MouseWheel GesturePinchUpdate", GetMessageNames(events));
    } else {
      EXPECT_EQ("MouseWheel", GetMessageNames(events));
      events[0]->ToEvent()->CallCallback(
          INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
      events = host_->GetAndResetDispatchedMessages();
      EXPECT_EQ("GesturePinchUpdate", GetMessageNames(events));
    }

    SendEndPinchEvent();
    base::RunLoop().RunUntilIdle();
    events = host_->GetAndResetDispatchedMessages();
    EXPECT_EQ("MouseWheel GesturePinchEnd", GetMessageNames(events));
  }

  // Do a gesture that doesn't cross the threshold, but happens when we're not
  // at page scale factor one, so it should be sent to the renderer.
  {
    NSEvent* pinchUpdateEvent = MockPinchEvent(NSEventPhaseChanged, 0.25);

    rwhv_mac_->page_at_minimum_scale_ = false;

    SendBeginPinchEvent();
    base::RunLoop().RunUntilIdle();
    MockWidgetInputHandler::MessageVector events =
        host_->GetAndResetDispatchedMessages();
    EXPECT_EQ(0U, events.size());

    // Expect that a zoom happen because the time threshold has not passed.
    [rwhv_cocoa_ magnifyWithEvent:pinchUpdateEvent];
    base::RunLoop().RunUntilIdle();
    events = host_->GetAndResetDispatchedMessages();
    EXPECT_EQ("MouseWheel", GetMessageNames(events));
    events[0]->ToEvent()->CallCallback(
        INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
    events = host_->GetAndResetDispatchedMessages();
    EXPECT_EQ("GesturePinchBegin GesturePinchUpdate", GetMessageNames(events));

    SendEndPinchEvent();
    base::RunLoop().RunUntilIdle();
    events = host_->GetAndResetDispatchedMessages();
    EXPECT_EQ("MouseWheel GesturePinchEnd", GetMessageNames(events));
  }

  // Do a gesture again, after the page scale is no longer at one, and ensure
  // that it is thresholded again.
  {
    NSEvent* pinchUpdateEvent = MockPinchEvent(NSEventTypeMagnify, 0.25);

    rwhv_mac_->page_at_minimum_scale_ = true;

    SendBeginPinchEvent();
    base::RunLoop().RunUntilIdle();
    MockWidgetInputHandler::MessageVector events =
        host_->GetAndResetDispatchedMessages();
    EXPECT_EQ(0U, events.size());

    // Get back to zoom one right after the begin event. This should still keep
    // the thresholding in place (it is latched at the begin event).
    rwhv_mac_->page_at_minimum_scale_ = false;

    // Expect that zoom be disabled because the time threshold has passed.
    [rwhv_cocoa_ magnifyWithEvent:pinchUpdateEvent];
    base::RunLoop().RunUntilIdle();
    events = host_->GetAndResetDispatchedMessages();
    EXPECT_EQ("MouseWheel", GetMessageNames(events));

    events[0]->ToEvent()->CallCallback(
        INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
    events = host_->GetAndResetDispatchedMessages();
    EXPECT_EQ(0U, events.size());

    // Since no GesturePinchBegin was sent by the time we reach the pinch end,
    // the GesturePinchBegin and GesturePinchEnd are elided.
    SendEndPinchEvent();
    base::RunLoop().RunUntilIdle();
    events = host_->GetAndResetDispatchedMessages();
    EXPECT_EQ("MouseWheel", GetMessageNames(events));
  }
}

// Tests that the NSEventTypeSmartMagnify event is first offered as a mouse
// wheel event and is then sent as a GestureDoubleTap to invoke the double-tap
// to zoom logic.
TEST_F(RenderWidgetHostViewMacTest, DoubleTapZoom) {
  NSEvent* smartMagnifyEvent = MockSmartMagnifyEvent();
  [rwhv_cocoa_ smartMagnifyWithEvent:smartMagnifyEvent];
  base::RunLoop().RunUntilIdle();

  MockWidgetInputHandler::MessageVector events =
      host_->GetAndResetDispatchedMessages();
  EXPECT_EQ("MouseWheel", GetMessageNames(events));

  events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);

  events = host_->GetAndResetDispatchedMessages();
  EXPECT_EQ("GestureDoubleTap", GetMessageNames(events));
}

// Tests that the NSEventTypeSmartMagnify event may be consumed by a wheel
// listener to prevent the scale change.
TEST_F(RenderWidgetHostViewMacTest, DoubleTapZoomConsumed) {
  NSEvent* smartMagnifyEvent = MockSmartMagnifyEvent();
  [rwhv_cocoa_ smartMagnifyWithEvent:smartMagnifyEvent];
  base::RunLoop().RunUntilIdle();

  MockWidgetInputHandler::MessageVector events =
      host_->GetAndResetDispatchedMessages();
  EXPECT_EQ("MouseWheel", GetMessageNames(events));

  events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);

  events = host_->GetAndResetDispatchedMessages();
  EXPECT_EQ(0U, events.size());
}

TEST_F(RenderWidgetHostViewMacTest, EventLatencyOSMouseWheelHistogram) {
  base::HistogramTester histogram_tester;

  // Send an initial wheel event for scrolling by 3 lines.
  // Verify that Event.Latency.OS.MOUSE_WHEEL histogram is computed properly.
  NSEvent* wheelEvent = MockScrollWheelEventWithPhase(@selector(phaseBegan),3);
  [rwhv_mac_->cocoa_view() scrollWheel:wheelEvent];
  histogram_tester.ExpectTotalCount("Event.Latency.OS.MOUSE_WHEEL", 1);
}

// This test verifies that |selected_text_| is updated accordingly with
// different variations of RWHVMac::SelectChanged updates.
TEST_F(RenderWidgetHostViewMacTest, SelectedText) {
  base::string16 sample_text;
  base::UTF8ToUTF16("hello world!", 12, &sample_text);
  gfx::Range range(6, 11);

  // Send a valid selection for the word 'World'.
  rwhv_mac_->SelectionChanged(sample_text, 0U, range);
  EXPECT_EQ("world", selected_text());

  // Make the range cover some of the text and extend more.
  range.set_end(100);
  rwhv_mac_->SelectionChanged(sample_text, 0U, range);
  EXPECT_EQ("world!", selected_text());

  // Finally, send an empty range. This should clear the selected text.
  range.set_start(100);
  rwhv_mac_->SelectionChanged(sample_text, 0U, range);
  EXPECT_EQ("", selected_text());
}

// This class is used for IME-related unit tests which verify correctness of IME
// for pages with multiple RWHVs.
class InputMethodMacTest : public RenderWidgetHostViewMacTest {
 public:
  InputMethodMacTest() {}
  ~InputMethodMacTest() override {}

  void SetUp() override {
    RenderWidgetHostViewMacTest::SetUp();

    // Initializing a child frame's view.
    child_browser_context_ = std::make_unique<TestBrowserContext>();
    child_process_host_ =
        new MockRenderProcessHost(child_browser_context_.get());
    child_process_host_->Init();
    child_widget_ = MockRenderWidgetHostImpl::Create(
        &delegate_, child_process_host_,
        child_process_host_->GetNextRoutingID());
    child_view_ = new TestRenderWidgetHostView(child_widget_);
    base::RunLoop().RunUntilIdle();
  }

  void TearDown() override {
    child_widget_->ShutdownAndDestroyWidget(true);
    child_browser_context_.reset();
    RenderWidgetHostViewMacTest::TearDown();
  }

  void SetTextInputType(RenderWidgetHostViewBase* view,
                        ui::TextInputType type) {
    TextInputState state;
    state.type = type;
    view->TextInputStateChanged(state);
  }

  IPC::TestSink& tab_sink() { return process()->sink(); }
  IPC::TestSink& child_sink() { return child_process_host_->sink(); }
  TextInputManager* text_input_manager() {
    return delegate_.GetTextInputManager();
  }
  RenderWidgetHostViewMac* tab_view() { return rwhv_mac_; }
  RenderWidgetHostImpl* tab_widget() { return host_.get(); }
  RenderWidgetHostViewCocoa* tab_cocoa_view() { return rwhv_cocoa_.get(); }

  API_AVAILABLE(macos(10.12.2))
  NSCandidateListTouchBarItem* candidate_list_item() {
    return [tab_cocoa_view().touchBar
        itemForIdentifier:NSTouchBarItemIdentifierCandidateList];
  }

 protected:
  MockRenderProcessHost* child_process_host_;
  MockRenderWidgetHostImpl* child_widget_;
  TestRenderWidgetHostView* child_view_;

 private:
  std::unique_ptr<TestBrowserContext> child_browser_context_;

  DISALLOW_COPY_AND_ASSIGN(InputMethodMacTest);
};

// This test will verify that calling unmarkText on the cocoa view will lead to
// a finish composing text IPC for the corresponding active widget.
TEST_F(InputMethodMacTest, UnmarkText) {
  // Make the child view active and then call unmarkText on the view (Note that
  // |RenderWidgetHostViewCocoa::handlingKeyDown_| is false so calling
  // unmarkText would lead to an IPC. This assumption is made in other similar
  // tests as well). We should observe an IPC being sent to the |child_widget_|.
  SetTextInputType(child_view_, ui::TEXT_INPUT_TYPE_TEXT);
  EXPECT_EQ(child_widget_, text_input_manager()->GetActiveWidget());
  [tab_cocoa_view() unmarkText];
  base::RunLoop().RunUntilIdle();
  MockWidgetInputHandler::MessageVector events =
      child_widget_->GetAndResetDispatchedMessages();
  EXPECT_EQ("FinishComposingText", GetMessageNames(events));

  // Repeat the same steps for the tab's view .
  SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT);
  EXPECT_EQ(tab_widget(), text_input_manager()->GetActiveWidget());
  [tab_cocoa_view() unmarkText];
  base::RunLoop().RunUntilIdle();
  events = host_->GetAndResetDispatchedMessages();
  EXPECT_EQ("FinishComposingText", GetMessageNames(events));
}

// This test makes sure that calling setMarkedText on the cocoa view will lead
// to a set composition IPC for the corresponding active widget.
TEST_F(InputMethodMacTest, SetMarkedText) {
  // Some values for the call to setMarkedText.
  base::scoped_nsobject<NSString> text(
      [[NSString alloc] initWithString:@"sample text"]);
  NSRange selectedRange = NSMakeRange(0, 4);
  NSRange replacementRange = NSMakeRange(0, 1);

  // Make the child view active and then call setMarkedText with some values. We
  // should observe an IPC being sent to the |child_widget_|.
  SetTextInputType(child_view_, ui::TEXT_INPUT_TYPE_TEXT);
  EXPECT_EQ(child_widget_, text_input_manager()->GetActiveWidget());
  [tab_cocoa_view() setMarkedText:text
                    selectedRange:selectedRange
                 replacementRange:replacementRange];
  base::RunLoop().RunUntilIdle();
  MockWidgetInputHandler::MessageVector events =
      child_widget_->GetAndResetDispatchedMessages();
  EXPECT_EQ("SetComposition", GetMessageNames(events));

  // Repeat the same steps for the tab's view.
  SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT);
  EXPECT_EQ(tab_widget(), text_input_manager()->GetActiveWidget());
  [tab_cocoa_view() setMarkedText:text
                    selectedRange:selectedRange
                 replacementRange:replacementRange];
  base::RunLoop().RunUntilIdle();
  events = host_->GetAndResetDispatchedMessages();
  EXPECT_EQ("SetComposition", GetMessageNames(events));
}

// This test verifies that calling insertText on the cocoa view will lead to a
// commit text IPC sent to the active widget.
TEST_F(InputMethodMacTest, InsertText) {
  // Some values for the call to insertText.
  base::scoped_nsobject<NSString> text(
      [[NSString alloc] initWithString:@"sample text"]);
  NSRange replacementRange = NSMakeRange(0, 1);

  // Make the child view active and then call insertText with some values. We
  // should observe an IPC being sent to the |child_widget_|.
  SetTextInputType(child_view_, ui::TEXT_INPUT_TYPE_TEXT);
  EXPECT_EQ(child_widget_, text_input_manager()->GetActiveWidget());
  [tab_cocoa_view() insertText:text replacementRange:replacementRange];
  base::RunLoop().RunUntilIdle();
  MockWidgetInputHandler::MessageVector events =
      child_widget_->GetAndResetDispatchedMessages();
  EXPECT_EQ("CommitText", GetMessageNames(events));

  // Repeat the same steps for the tab's view.
  SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT);
  EXPECT_EQ(tab_widget(), text_input_manager()->GetActiveWidget());
  [tab_cocoa_view() insertText:text replacementRange:replacementRange];
  base::RunLoop().RunUntilIdle();
  events = host_->GetAndResetDispatchedMessages();
  EXPECT_EQ("CommitText", GetMessageNames(events));
}

// This test makes sure that calling finishComposingText on the cocoa view will
// lead to a finish composing text IPC for a the corresponding active widget.
TEST_F(InputMethodMacTest, FinishComposingText) {
  // Some values for the call to setMarkedText.
  base::scoped_nsobject<NSString> text(
      [[NSString alloc] initWithString:@"sample text"]);
  NSRange selectedRange = NSMakeRange(0, 4);
  NSRange replacementRange = NSMakeRange(0, 1);

  // Make child view active and then call finishComposingText. We should observe
  // an IPC being sent to the |child_widget_|.
  SetTextInputType(child_view_, ui::TEXT_INPUT_TYPE_TEXT);
  EXPECT_EQ(child_widget_, text_input_manager()->GetActiveWidget());
  // In order to finish composing text, we must first have some marked text. So,
  // we will first call setMarkedText on cocoa view. This would lead to a set
  // composition IPC in the sink, but it doesn't matter since we will be looking
  // for a finish composing text IPC for this test.
  [tab_cocoa_view() setMarkedText:text
                    selectedRange:selectedRange
                 replacementRange:replacementRange];
  [tab_cocoa_view() finishComposingText];
  base::RunLoop().RunUntilIdle();
  MockWidgetInputHandler::MessageVector events =
      child_widget_->GetAndResetDispatchedMessages();
  EXPECT_EQ("SetComposition FinishComposingText", GetMessageNames(events));

  // Repeat the same steps for the tab's view.
  SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT);
  EXPECT_EQ(tab_widget(), text_input_manager()->GetActiveWidget());
  [tab_cocoa_view() setMarkedText:text
                    selectedRange:selectedRange
                 replacementRange:replacementRange];
  [tab_cocoa_view() finishComposingText];
  base::RunLoop().RunUntilIdle();
  events = host_->GetAndResetDispatchedMessages();
  EXPECT_EQ("SetComposition FinishComposingText", GetMessageNames(events));
}

TEST_F(InputMethodMacTest, SecurePasswordInput) {
  ASSERT_FALSE(ui::ScopedPasswordInputEnabler::IsPasswordInputEnabled());
  ASSERT_EQ(text_input_manager(), tab_view()->GetTextInputManager());

  // RenderWidgetHostViewMacTest.BlurAndFocusOnSetActive checks the
  // Focus()/Blur() rules, just silence the warnings here.
  EXPECT_CALL(*host_, Focus()).Times(::testing::AnyNumber());
  EXPECT_CALL(*host_, Blur()).Times(::testing::AnyNumber());

  [window_ makeFirstResponder:tab_view()->cocoa_view()];

  // Shouldn't enable secure input if it's not a password textfield.
  tab_view()->SetActive(true);
  EXPECT_FALSE(ui::ScopedPasswordInputEnabler::IsPasswordInputEnabled());

  SetTextInputType(child_view_, ui::TEXT_INPUT_TYPE_PASSWORD);
  ASSERT_EQ(child_widget_, text_input_manager()->GetActiveWidget());
  ASSERT_EQ(text_input_manager(), tab_view()->GetTextInputManager());
  ASSERT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, tab_view()->GetTextInputType());

  // Single matched calls immediately update IsPasswordInputEnabled().
  tab_view()->SetActive(true);
  EXPECT_TRUE(ui::ScopedPasswordInputEnabler::IsPasswordInputEnabled());

  tab_view()->SetActive(false);
  EXPECT_FALSE(ui::ScopedPasswordInputEnabler::IsPasswordInputEnabled());
}

// This test creates a test view to mimic a child frame's view and verifies that
// calling ImeCancelComposition on either the child view or the tab's view will
// always lead to a call to cancelComposition on the cocoa view.
TEST_F(InputMethodMacTest, ImeCancelCompositionForAllViews) {
  // Some values for the call to setMarkedText.
  base::scoped_nsobject<NSString> text(
      [[NSString alloc] initWithString:@"sample text"]);
  NSRange selectedRange = NSMakeRange(0, 1);
  NSRange replacementRange = NSMakeRange(0, 1);

  // Make Cocoa view assume there is marked text.
  [tab_cocoa_view() setMarkedText:text
                    selectedRange:selectedRange
                 replacementRange:replacementRange];
  EXPECT_TRUE([tab_cocoa_view() hasMarkedText]);
  child_view_->ImeCancelComposition();
  EXPECT_FALSE([tab_cocoa_view() hasMarkedText]);

  // Repeat for the tab's view.
  [tab_cocoa_view() setMarkedText:text
                    selectedRange:selectedRange
                 replacementRange:replacementRange];
  EXPECT_TRUE([tab_cocoa_view() hasMarkedText]);
  tab_view()->ImeCancelComposition();
  EXPECT_FALSE([tab_cocoa_view() hasMarkedText]);
}

// This test verifies that calling FocusedNodeChanged() on
// RenderWidgetHostViewMac calls cancelComposition on the Cocoa view.
TEST_F(InputMethodMacTest, FocusedNodeChanged) {
  // Some values for the call to setMarkedText.
  base::scoped_nsobject<NSString> text(
      [[NSString alloc] initWithString:@"sample text"]);
  NSRange selectedRange = NSMakeRange(0, 1);
  NSRange replacementRange = NSMakeRange(0, 1);

  [tab_cocoa_view() setMarkedText:text
                    selectedRange:selectedRange
                 replacementRange:replacementRange];
  EXPECT_TRUE([tab_cocoa_view() hasMarkedText]);
  tab_view()->FocusedNodeChanged(true, gfx::Rect());
  EXPECT_FALSE([tab_cocoa_view() hasMarkedText]);
}

// This test verifies that when a RenderWidgetHostView changes its
// TextInputState to NONE we send the IPC to stop monitor composition info and,
// conversely, when its state is set to non-NONE, we start monitoring the
// composition info.
TEST_F(InputMethodMacTest, MonitorCompositionRangeForActiveWidget) {
  // First, we need to make the cocoa view the first responder so that the
  // method RWHVMac::HasFocus() returns true. Then we can make sure that as long
  // as there is some TextInputState of non-NONE, the corresponding widget will
  // be asked to start monitoring composition info.
  [window_ makeFirstResponder:tab_cocoa_view()];
  EXPECT_TRUE(tab_view()->HasFocus());

  TextInputState state;
  state.type = ui::TEXT_INPUT_TYPE_TEXT;

  // Make the tab's widget active.
  tab_view()->TextInputStateChanged(state);

  base::RunLoop().RunUntilIdle();
  MockWidgetInputHandler::MessageVector events =
      host_->GetAndResetDispatchedMessages();
  // The tab's widget must have received an IPC regarding composition updates.
  EXPECT_EQ("SetFocus RequestCompositionUpdates", GetMessageNames(events));

  // The message should ask for monitoring updates, but no immediate update.
  MockWidgetInputHandler::DispatchedRequestCompositionUpdatesMessage* message =
      events.at(1)->ToRequestCompositionUpdates();
  EXPECT_FALSE(message->immediate_request());
  EXPECT_TRUE(message->monitor_request());

  // Now make the child view active.
  child_view_->TextInputStateChanged(state);

  // The tab should receive another IPC for composition updates.
  base::RunLoop().RunUntilIdle();
  events = host_->GetAndResetDispatchedMessages();
  // The tab's widget must have received an IPC regarding composition updates.
  EXPECT_EQ("RequestCompositionUpdates", GetMessageNames(events));
  // This time, the tab should have been asked to stop monitoring (and no
  // immediate updates).
  message = events.at(0)->ToRequestCompositionUpdates();
  EXPECT_FALSE(message->immediate_request());
  EXPECT_FALSE(message->monitor_request());

  // The child too must have received an IPC for composition updates.
  events = child_widget_->GetAndResetDispatchedMessages();
  EXPECT_EQ("RequestCompositionUpdates", GetMessageNames(events));

  // Verify that the message is asking for monitoring to start; but no immediate
  // updates.
  message = events.at(0)->ToRequestCompositionUpdates();
  EXPECT_FALSE(message->immediate_request());
  EXPECT_TRUE(message->monitor_request());

  // Make the tab view active again.
  tab_view()->TextInputStateChanged(state);

  base::RunLoop().RunUntilIdle();
  events = child_widget_->GetAndResetDispatchedMessages();

  // Verify that the child received another IPC for composition updates.
  EXPECT_EQ("RequestCompositionUpdates", GetMessageNames(events));

  // Verify that this IPC is asking for no monitoring or immediate updates.
  message = events.at(0)->ToRequestCompositionUpdates();
  EXPECT_FALSE(message->immediate_request());
  EXPECT_FALSE(message->monitor_request());
}

TEST_F(InputMethodMacTest, TouchBarTextSuggestionsPresence) {
  base::test::ScopedFeatureList feature_list;
  if (@available(macOS 10.12.2, *)) {
    EXPECT_NSEQ(nil, candidate_list_item());
    SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_PASSWORD);
    EXPECT_NSEQ(nil, candidate_list_item());
    SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT);
    EXPECT_NSNE(nil, candidate_list_item());
  }
}

TEST_F(InputMethodMacTest, TouchBarTextSuggestionsReplacement) {
  base::test::ScopedFeatureList feature_list;
  if (@available(macOS 10.12.2, *)) {
    base::scoped_nsobject<FakeSpellChecker> spellChecker(
        [[FakeSpellChecker alloc] init]);
    tab_cocoa_view().spellCheckerForTesting =
        static_cast<NSSpellChecker*>(spellChecker.get());

    SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT);
    EXPECT_NSNE(nil, candidate_list_item());
    candidate_list_item().allowsCollapsing = NO;

    FakeTextCheckingResult* fakeResult =
        [FakeTextCheckingResult resultWithRange:NSMakeRange(0, 3)
                              replacementString:@"foo"];

    const base::string16 kOriginalString = base::UTF8ToUTF16("abcxxxghi");

    // Change the selection once; requests completions from the spell checker.
    tab_view()->SelectionChanged(kOriginalString, 3, gfx::Range(3, 3));

    NSInteger firstSequenceNumber = [spellChecker sequenceNumber];
    auto firstCompletionHandler = [spellChecker takeCompletionHandler];

    EXPECT_NE(nil, (id)firstCompletionHandler.get());
    EXPECT_EQ(0U, candidate_list_item().candidates.count);

    // Instead of replying right away, change the selection again!
    tab_view()->SelectionChanged(kOriginalString, 3, gfx::Range(5, 5));

    EXPECT_NE(firstSequenceNumber, [spellChecker sequenceNumber]);

    // Make sure that calling the stale completion handler is a no-op.
    firstCompletionHandler.get()(
        firstSequenceNumber,
        @[ static_cast<NSTextCheckingResult*>(fakeResult) ]);
    base::RunLoop().RunUntilIdle();
    EXPECT_EQ(0U, candidate_list_item().candidates.count);

    // But calling the current handler should work.
    [spellChecker takeCompletionHandler].get()(
        [spellChecker sequenceNumber],
        @[ static_cast<NSTextCheckingResult*>(fakeResult) ]);
    base::RunLoop().RunUntilIdle();
    EXPECT_EQ(1U, candidate_list_item().candidates.count);

    base::RunLoop().RunUntilIdle();
    MockWidgetInputHandler::MessageVector events =
        host_->GetAndResetDispatchedMessages();
    ASSERT_EQ("", GetMessageNames(events));

    // Now, select that result.
    [tab_cocoa_view() candidateListTouchBarItem:candidate_list_item()
                   endSelectingCandidateAtIndex:0];
    base::RunLoop().RunUntilIdle();
    events = host_->GetAndResetDispatchedMessages();
    ASSERT_EQ("CommitText", GetMessageNames(events));
  }
}

// https://crbug.com/893038: There exist code paths which set the selection
// range to gfx::Range::InvalidRange(). I'm not sure how to exercise them in
// practice, but this has caused crashes in the field.
TEST_F(InputMethodMacTest, TouchBarTextSuggestionsInvalidSelection) {
  base::test::ScopedFeatureList feature_list;
  if (@available(macOS 10.12.2, *)) {
    base::scoped_nsobject<FakeSpellChecker> spellChecker(
        [[FakeSpellChecker alloc] init]);
    tab_cocoa_view().spellCheckerForTesting =
        static_cast<NSSpellChecker*>(spellChecker.get());

    SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT);
    candidate_list_item().allowsCollapsing = NO;

    if (auto completionHandler = [spellChecker takeCompletionHandler]) {
      completionHandler.get()([spellChecker sequenceNumber], @[]);
      base::RunLoop().RunUntilIdle();
    }

    FakeTextCheckingResult* fakeResult =
        [FakeTextCheckingResult resultWithRange:NSMakeRange(0, 3)
                              replacementString:@"foo"];

    const base::string16 kOriginalString = base::UTF8ToUTF16("abcxxxghi");

    tab_view()->SelectionChanged(kOriginalString, 3,
                                 gfx::Range::InvalidRange());

    if (auto completionHandler = [spellChecker takeCompletionHandler]) {
      completionHandler.get()(
          [spellChecker sequenceNumber],
          @[ static_cast<NSTextCheckingResult*>(fakeResult) ]);
      base::RunLoop().RunUntilIdle();
    }

    EXPECT_NE(nil, candidate_list_item().candidates);
    EXPECT_EQ(0U, candidate_list_item().candidates.count);
  }
}

// This test verifies that in AutoResize mode a child-allocated
// viz::LocalSurfaceId will be properly routed and stored in the parent.
TEST_F(RenderWidgetHostViewMacTest, ChildAllocationAcceptedInParent) {
  viz::LocalSurfaceId local_surface_id1(
      rwhv_mac_->GetLocalSurfaceIdAllocation().local_surface_id());
  EXPECT_TRUE(local_surface_id1.is_valid());

  host_->SetAutoResize(true, gfx::Size(50, 50), gfx::Size(100, 100));

  viz::ChildLocalSurfaceIdAllocator child_allocator;
  child_allocator.UpdateFromParent(rwhv_mac_->GetLocalSurfaceIdAllocation());
  child_allocator.GenerateId();
  viz::LocalSurfaceId local_surface_id2 =
      child_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
  cc::RenderFrameMetadata metadata;
  metadata.viewport_size_in_pixels = gfx::Size(75, 75);
  metadata.local_surface_id_allocation =
      child_allocator.GetCurrentLocalSurfaceIdAllocation();
  host_->DidUpdateVisualProperties(metadata);

  viz::LocalSurfaceId local_surface_id3(
      rwhv_mac_->GetLocalSurfaceIdAllocation().local_surface_id());
  EXPECT_NE(local_surface_id1, local_surface_id3);
  EXPECT_EQ(local_surface_id2, local_surface_id3);
}

// This test verifies that when the child and parent both allocate their own
// viz::LocalSurfaceId the resulting conflict is resolved.
TEST_F(RenderWidgetHostViewMacTest, ConflictingAllocationsResolve) {
  viz::LocalSurfaceId local_surface_id1(
      rwhv_mac_->GetLocalSurfaceIdAllocation().local_surface_id());
  EXPECT_TRUE(local_surface_id1.is_valid());

  host_->SetAutoResize(true, gfx::Size(50, 50), gfx::Size(100, 100));
  viz::ChildLocalSurfaceIdAllocator child_allocator;
  child_allocator.UpdateFromParent(rwhv_mac_->GetLocalSurfaceIdAllocation());
  child_allocator.GenerateId();
  viz::LocalSurfaceId local_surface_id2 =
      child_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
  cc::RenderFrameMetadata metadata;
  metadata.viewport_size_in_pixels = gfx::Size(75, 75);
  metadata.local_surface_id_allocation =
      child_allocator.GetCurrentLocalSurfaceIdAllocation();
  host_->DidUpdateVisualProperties(metadata);

  // Cause a conflicting viz::LocalSurfaceId allocation
  BrowserCompositorMac* browser_compositor = rwhv_mac_->BrowserCompositor();
  EXPECT_TRUE(browser_compositor->ForceNewSurfaceForTesting());
  viz::LocalSurfaceId local_surface_id3(
      rwhv_mac_->GetLocalSurfaceIdAllocation().local_surface_id());
  EXPECT_NE(local_surface_id1, local_surface_id3);

  // RenderWidgetHostImpl has delayed auto-resize processing. Yield here to
  // let it complete.
  base::RunLoop run_loop;
  base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
                                                run_loop.QuitClosure());
  run_loop.Run();

  viz::LocalSurfaceId local_surface_id4(
      rwhv_mac_->GetLocalSurfaceIdAllocation().local_surface_id());
  EXPECT_NE(local_surface_id1, local_surface_id4);
  EXPECT_NE(local_surface_id2, local_surface_id4);
  viz::LocalSurfaceId merged_local_surface_id(
      local_surface_id2.parent_sequence_number() + 1,
      local_surface_id2.child_sequence_number(),
      local_surface_id2.embed_token());
  EXPECT_EQ(local_surface_id4, merged_local_surface_id);
}

TEST_F(RenderWidgetHostViewMacTest, TransformToRootNoParentLayer) {
  gfx::PointF point(10, 20);
  rwhv_mac_->TransformPointToRootSurface(&point);
  EXPECT_EQ(point, gfx::PointF(10, 20));
}

TEST_F(RenderWidgetHostViewMacTest, TransformToRootWithParentLayer) {
  std::unique_ptr<ui::RecyclableCompositorMac> compositor =
      ui::RecyclableCompositorMacFactory::Get()->CreateCompositor(
          ImageTransportFactory::GetInstance()->GetContextFactory(),
          ImageTransportFactory::GetInstance()->GetContextFactoryPrivate());
  std::unique_ptr<ui::Layer> root_surface_layer =
      std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR);
  std::unique_ptr<ui::Layer> parent_layer =
      std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR);

  compositor->compositor()->SetRootLayer(root_surface_layer.get());
  root_surface_layer->SetBounds(gfx::Rect(-5, -10, 1000, 2000));
  parent_layer->SetBounds(gfx::Rect(100, 300, 500, 400));
  root_surface_layer->Add(parent_layer.get());
  gfx::PointF point(10, 20);
  rwhv_mac_->SetParentUiLayer(parent_layer.get());
  rwhv_mac_->TransformPointToRootSurface(&point);
  EXPECT_EQ(point, gfx::PointF(105, 310));
}

TEST_F(RenderWidgetHostViewMacTest, AccessibilityParentTest) {
  NSView* view = rwhv_mac_->cocoa_view();

  // NSBox so it participates in the a11y hierarchy.
  base::scoped_nsobject<NSView> parent_view([[NSBox alloc] init]);
  base::scoped_nsobject<NSView> accessibility_parent([[NSView alloc] init]);
  base::scoped_nsobject<NSWindow> window([[NSWindow alloc]
      initWithContentRect:NSMakeRect(0, 0, 512, 512)
                styleMask:NSWindowStyleMaskResizable | NSWindowStyleMaskTitled
                  backing:NSBackingStoreBuffered
                    defer:NO]);
  [[window contentView] addSubview:accessibility_parent];

  [parent_view addSubview:view];
  EXPECT_NSEQ([view accessibilityParent], parent_view);

  rwhv_mac_->SetParentAccessibilityElement(accessibility_parent);
  EXPECT_NSEQ([view accessibilityParent],
              NSAccessibilityUnignoredAncestor(accessibility_parent));
  EXPECT_NSNE(nil, [view accessibilityParent]);

  rwhv_mac_->SetParentAccessibilityElement(nil);
  EXPECT_NSEQ([view accessibilityParent], parent_view);
}

// Tests that when entering mouse lock, the cursor will lock to window center.
TEST_F(RenderWidgetHostViewMacTest, PointerLockCenterPosition) {
  NSView* view = rwhv_mac_->cocoa_view();

  NSRect bound = NSMakeRect(123, 234, 456, 678);
  [view setFrame:bound];

  EXPECT_EQ(gfx::Rect([view bounds]), gfx::Rect(0, 0, 456, 678));

  rwhv_mac_->LockMouse();
  EXPECT_TRUE(rwhv_mac_->IsMouseLocked());

  gfx::Point mouse_pos =
      gfx::Point([window_ mouseLocationOutsideOfEventStream]);
  EXPECT_EQ(mouse_pos, gfx::Point(228, 339));
}

}  // namespace content
