
This abstraction layer for PPAPI is no longer useful. Just use //base
APIs directly.
Bug: 1302059
Change-Id: I3342f5654ab2aaeea1778ebfca6196f1dd939c52
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3498884
Reviewed-by: Nigi <nigi@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/main@{#977239}
984 lines
36 KiB
C++
984 lines
36 KiB
C++
// Copyright 2021 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 "pdf/pdf_view_web_plugin.h"
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include "base/location.h"
|
|
#include "base/memory/raw_ptr.h"
|
|
#include "base/memory/weak_ptr.h"
|
|
#include "base/run_loop.h"
|
|
#include "base/strings/string_piece.h"
|
|
#include "base/test/bind.h"
|
|
#include "base/test/values_test_util.h"
|
|
#include "base/time/time.h"
|
|
#include "cc/paint/paint_canvas.h"
|
|
#include "cc/test/pixel_comparator.h"
|
|
#include "cc/test/pixel_test_utils.h"
|
|
#include "pdf/ppapi_migration/bitmap.h"
|
|
#include "pdf/test/test_helpers.h"
|
|
#include "pdf/test/test_pdfium_engine.h"
|
|
#include "testing/gmock/include/gmock/gmock-matchers.h"
|
|
#include "testing/gmock/include/gmock/gmock.h"
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
#include "third_party/blink/public/common/input/web_coalesced_input_event.h"
|
|
#include "third_party/blink/public/common/input/web_input_event.h"
|
|
#include "third_party/blink/public/common/input/web_keyboard_event.h"
|
|
#include "third_party/blink/public/common/input/web_mouse_event.h"
|
|
#include "third_party/blink/public/common/input/web_pointer_properties.h"
|
|
#include "third_party/blink/public/platform/web_string.h"
|
|
#include "third_party/blink/public/platform/web_text_input_type.h"
|
|
#include "third_party/blink/public/platform/web_vector.h"
|
|
#include "third_party/blink/public/web/web_associated_url_loader.h"
|
|
#include "third_party/blink/public/web/web_plugin_container.h"
|
|
#include "third_party/blink/public/web/web_plugin_params.h"
|
|
#include "third_party/skia/include/core/SkBitmap.h"
|
|
#include "third_party/skia/include/core/SkColor.h"
|
|
#include "ui/base/cursor/cursor.h"
|
|
#include "ui/events/blink/blink_event_util.h"
|
|
#include "ui/events/keycodes/dom/dom_code.h"
|
|
#include "ui/events/keycodes/dom/dom_key.h"
|
|
#include "ui/gfx/canvas.h"
|
|
#include "ui/gfx/geometry/point.h"
|
|
#include "ui/gfx/geometry/point_f.h"
|
|
#include "ui/gfx/geometry/rect.h"
|
|
#include "ui/gfx/geometry/size.h"
|
|
#include "ui/gfx/geometry/skia_conversions.h"
|
|
#include "ui/gfx/geometry/vector2d_f.h"
|
|
#include "ui/latency/latency_info.h"
|
|
|
|
namespace chrome_pdf {
|
|
|
|
namespace {
|
|
|
|
using ::testing::InSequence;
|
|
using ::testing::Invoke;
|
|
using ::testing::MockFunction;
|
|
using ::testing::NiceMock;
|
|
using ::testing::Pointwise;
|
|
using ::testing::Return;
|
|
|
|
// `kCanvasSize` needs to be big enough to hold plugin's snapshots during
|
|
// testing.
|
|
constexpr gfx::Size kCanvasSize(100, 100);
|
|
|
|
// A common device scale for high DPI displays.
|
|
constexpr float kDeviceScale = 2.0f;
|
|
|
|
// Note: Make sure `kDefaultColor` is different from `kPaintColor` and the
|
|
// plugin's background color. This will help identify bitmap changes after
|
|
// painting.
|
|
constexpr SkColor kDefaultColor = SK_ColorGREEN;
|
|
|
|
constexpr SkColor kPaintColor = SK_ColorRED;
|
|
|
|
struct PaintParams {
|
|
// The plugin container's device scale.
|
|
float device_scale;
|
|
|
|
// The window area in CSS pixels.
|
|
gfx::Rect window_rect;
|
|
|
|
// The target painting area on the canvas in CSS pixels.
|
|
gfx::Rect paint_rect;
|
|
|
|
// The expected clipped area to be filled with paint color. The clipped area
|
|
// should be the intersection of `paint_rect` and `window_rect`.
|
|
gfx::Rect expected_clipped_rect;
|
|
};
|
|
|
|
MATCHER(SearchStringResultEq, "") {
|
|
PDFEngine::Client::SearchStringResult l = std::get<0>(arg);
|
|
PDFEngine::Client::SearchStringResult r = std::get<1>(arg);
|
|
return l.start_index == r.start_index && l.length == r.length;
|
|
}
|
|
|
|
MATCHER_P(IsExpectedImeKeyEvent, expected_text, "") {
|
|
if (arg.GetType() != blink::WebInputEvent::Type::kChar)
|
|
return false;
|
|
|
|
const auto& event = static_cast<const blink::WebKeyboardEvent&>(arg);
|
|
return event.GetModifiers() == blink::WebInputEvent::kNoModifiers &&
|
|
event.windows_key_code == expected_text[0] &&
|
|
event.native_key_code == expected_text[0] &&
|
|
event.dom_code == static_cast<int>(ui::DomCode::NONE) &&
|
|
event.dom_key == ui::DomKey::NONE && !event.is_system_key &&
|
|
!event.is_browser_shortcut && event.text == expected_text &&
|
|
event.unmodified_text == expected_text;
|
|
}
|
|
|
|
// Generates the expected `SkBitmap` with `paint_color` filled in the expected
|
|
// clipped area and `kDefaultColor` as the background color.
|
|
SkBitmap GenerateExpectedBitmapForPaint(const gfx::Rect& expected_clipped_rect,
|
|
SkColor paint_color) {
|
|
SkBitmap expected_bitmap =
|
|
CreateN32PremulSkBitmap(gfx::SizeToSkISize(kCanvasSize));
|
|
expected_bitmap.eraseColor(kDefaultColor);
|
|
expected_bitmap.erase(paint_color, gfx::RectToSkIRect(expected_clipped_rect));
|
|
return expected_bitmap;
|
|
}
|
|
|
|
blink::WebMouseEvent CreateDefaultMouseDownEvent() {
|
|
blink::WebMouseEvent web_event(
|
|
blink::WebInputEvent::Type::kMouseDown,
|
|
/*position=*/gfx::PointF(),
|
|
/*global_position=*/gfx::PointF(),
|
|
blink::WebPointerProperties::Button::kLeft,
|
|
/*click_count_param=*/1, blink::WebInputEvent::Modifiers::kLeftButtonDown,
|
|
blink::WebInputEvent::GetStaticTimeStampForTests());
|
|
web_event.SetFrameScale(1);
|
|
return web_event;
|
|
}
|
|
|
|
class FakeContainerWrapper : public PdfViewWebPlugin::ContainerWrapper {
|
|
public:
|
|
explicit FakeContainerWrapper(PdfViewWebPlugin* web_plugin)
|
|
: web_plugin_(web_plugin) {
|
|
ON_CALL(*this, UpdateTextInputState)
|
|
.WillByDefault(Invoke(
|
|
this, &FakeContainerWrapper::UpdateTextInputStateFromPlugin));
|
|
|
|
UpdateTextInputStateFromPlugin();
|
|
}
|
|
|
|
FakeContainerWrapper(const FakeContainerWrapper&) = delete;
|
|
FakeContainerWrapper& operator=(const FakeContainerWrapper&) = delete;
|
|
~FakeContainerWrapper() override = default;
|
|
|
|
// PdfViewWebPlugin::ContainerWrapper:
|
|
void Invalidate() override {}
|
|
|
|
MOCK_METHOD(void,
|
|
RequestTouchEventType,
|
|
(blink::WebPluginContainer::TouchEventRequestType),
|
|
(override));
|
|
|
|
MOCK_METHOD(void, ReportFindInPageMatchCount, (int, int, bool), (override));
|
|
|
|
MOCK_METHOD(void, ReportFindInPageSelection, (int, int), (override));
|
|
|
|
MOCK_METHOD(void,
|
|
ReportFindInPageTickmarks,
|
|
(const std::vector<gfx::Rect>&),
|
|
(override));
|
|
|
|
float DeviceScaleFactor() override { return device_scale_; }
|
|
|
|
MOCK_METHOD(gfx::PointF, GetScrollPosition, (), (override));
|
|
|
|
MOCK_METHOD(void,
|
|
SetReferrerForRequest,
|
|
(blink::WebURLRequest&, const blink::WebURL&),
|
|
(override));
|
|
|
|
MOCK_METHOD(void, Alert, (const blink::WebString&), (override));
|
|
|
|
MOCK_METHOD(bool, Confirm, (const blink::WebString&), (override));
|
|
|
|
MOCK_METHOD(blink::WebString,
|
|
Prompt,
|
|
(const blink::WebString&, const blink::WebString&),
|
|
(override));
|
|
|
|
MOCK_METHOD(void,
|
|
TextSelectionChanged,
|
|
(const blink::WebString&, uint32_t, const gfx::Range&),
|
|
(override));
|
|
|
|
MOCK_METHOD(std::unique_ptr<blink::WebAssociatedURLLoader>,
|
|
CreateAssociatedURLLoader,
|
|
(const blink::WebAssociatedURLLoaderOptions&),
|
|
(override));
|
|
|
|
MOCK_METHOD(void, UpdateTextInputState, (), (override));
|
|
|
|
MOCK_METHOD(void, UpdateSelectionBounds, (), (override));
|
|
|
|
std::string GetEmbedderOriginString() override {
|
|
return "chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/";
|
|
}
|
|
|
|
blink::WebLocalFrame* GetFrame() override { return nullptr; }
|
|
|
|
blink::WebLocalFrameClient* GetWebLocalFrameClient() override {
|
|
return nullptr;
|
|
}
|
|
|
|
// TODO(https://crbug.com/1207575): Container() should not be used for testing
|
|
// since it doesn't have a valid blink::WebPluginContainer. Make this method
|
|
// fail once ContainerWrapper instead of blink::WebPluginContainer is used for
|
|
// initializing `PostMessageSender`.
|
|
blink::WebPluginContainer* Container() override { return nullptr; }
|
|
|
|
blink::WebTextInputType widget_text_input_type() const {
|
|
return widget_text_input_type_;
|
|
}
|
|
|
|
void set_device_scale(float device_scale) { device_scale_ = device_scale; }
|
|
|
|
private:
|
|
void UpdateTextInputStateFromPlugin() {
|
|
widget_text_input_type_ = web_plugin_->GetPluginTextInputType();
|
|
}
|
|
|
|
float device_scale_ = 1.0f;
|
|
|
|
// Represents the frame widget's text input type.
|
|
blink::WebTextInputType widget_text_input_type_;
|
|
|
|
raw_ptr<PdfViewWebPlugin> web_plugin_;
|
|
};
|
|
|
|
class FakePdfViewWebPluginClient : public PdfViewWebPlugin::Client {
|
|
public:
|
|
FakePdfViewWebPluginClient() = default;
|
|
FakePdfViewWebPluginClient(const FakePdfViewWebPluginClient&) = delete;
|
|
FakePdfViewWebPluginClient& operator=(const FakePdfViewWebPluginClient&) =
|
|
delete;
|
|
~FakePdfViewWebPluginClient() override = default;
|
|
|
|
// PdfViewWebPlugin::Client:
|
|
MOCK_METHOD(std::unique_ptr<base::Value>,
|
|
FromV8Value,
|
|
(v8::Local<v8::Value>, v8::Local<v8::Context>),
|
|
(override));
|
|
MOCK_METHOD(v8::Local<v8::Value>,
|
|
ToV8Value,
|
|
(const base::Value&, v8::Local<v8::Context>),
|
|
(override));
|
|
MOCK_METHOD(base::WeakPtr<Client>, GetWeakPtr, (), (override));
|
|
MOCK_METHOD(bool, IsUseZoomForDSFEnabled, (), (const, override));
|
|
|
|
private:
|
|
base::WeakPtrFactory<FakePdfViewWebPluginClient> weak_factory_{this};
|
|
};
|
|
|
|
} // namespace
|
|
|
|
class PdfViewWebPluginWithoutInitializeTest : public testing::Test {
|
|
public:
|
|
PdfViewWebPluginWithoutInitializeTest(
|
|
const PdfViewWebPluginWithoutInitializeTest&) = delete;
|
|
PdfViewWebPluginWithoutInitializeTest& operator=(
|
|
const PdfViewWebPluginWithoutInitializeTest&) = delete;
|
|
|
|
protected:
|
|
// Custom deleter for `plugin_`. PdfViewWebPlugin must be destroyed by
|
|
// PdfViewWebPlugin::Destroy() instead of its destructor.
|
|
struct PluginDeleter {
|
|
void operator()(PdfViewWebPlugin* ptr) { ptr->Destroy(); }
|
|
};
|
|
|
|
PdfViewWebPluginWithoutInitializeTest() = default;
|
|
~PdfViewWebPluginWithoutInitializeTest() override = default;
|
|
|
|
void SetUp() override {
|
|
// Set a dummy URL for initializing the plugin.
|
|
blink::WebPluginParams params;
|
|
params.attribute_names.push_back(blink::WebString("src"));
|
|
params.attribute_values.push_back(blink::WebString("dummy.pdf"));
|
|
|
|
auto client = std::make_unique<NiceMock<FakePdfViewWebPluginClient>>();
|
|
client_ptr_ = client.get();
|
|
|
|
mojo::AssociatedRemote<pdf::mojom::PdfService> unbound_remote;
|
|
plugin_ =
|
|
std::unique_ptr<PdfViewWebPlugin, PluginDeleter>(new PdfViewWebPlugin(
|
|
std::move(client), std::move(unbound_remote), params));
|
|
}
|
|
|
|
void TearDown() override { plugin_.reset(); }
|
|
|
|
raw_ptr<FakePdfViewWebPluginClient> client_ptr_;
|
|
std::unique_ptr<PdfViewWebPlugin, PluginDeleter> plugin_;
|
|
};
|
|
|
|
class PdfViewWebPluginTest : public PdfViewWebPluginWithoutInitializeTest {
|
|
protected:
|
|
void SetUp() override {
|
|
PdfViewWebPluginWithoutInitializeTest::SetUp();
|
|
|
|
auto wrapper =
|
|
std::make_unique<NiceMock<FakeContainerWrapper>>(plugin_.get());
|
|
wrapper_ptr_ = wrapper.get();
|
|
auto engine = CreateEngine();
|
|
engine_ptr_ = engine.get();
|
|
EXPECT_TRUE(
|
|
plugin_->InitializeForTesting(std::move(wrapper), std::move(engine)));
|
|
}
|
|
|
|
void TearDown() override {
|
|
wrapper_ptr_ = nullptr;
|
|
|
|
PdfViewWebPluginWithoutInitializeTest::TearDown();
|
|
}
|
|
|
|
// Allow derived test classes to create their own custom TestPDFiumEngine.
|
|
virtual std::unique_ptr<TestPDFiumEngine> CreateEngine() {
|
|
return std::make_unique<NiceMock<TestPDFiumEngine>>(plugin_.get());
|
|
}
|
|
|
|
void SetDocumentDimensions(const gfx::Size& dimensions) {
|
|
EXPECT_CALL(*engine_ptr_, ApplyDocumentLayout)
|
|
.WillRepeatedly(Return(dimensions));
|
|
plugin_->OnMessage(base::test::ParseJson(R"({
|
|
"type": "viewport",
|
|
"userInitiated": false,
|
|
"zoom": 1,
|
|
"layoutOptions": {
|
|
"direction": 2,
|
|
"defaultPageOrientation": 0,
|
|
"twoUpViewEnabled": false,
|
|
},
|
|
"xOffset": 0,
|
|
"yOffset": 0,
|
|
"pinchPhase": 0,
|
|
})"));
|
|
}
|
|
|
|
void UpdatePluginGeometry(float device_scale, const gfx::Rect& window_rect) {
|
|
UpdatePluginGeometryWithoutWaiting(device_scale, window_rect);
|
|
|
|
// Waits for main thread callback scheduled by `PaintManager`.
|
|
base::RunLoop run_loop;
|
|
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
|
|
run_loop.QuitClosure());
|
|
run_loop.Run();
|
|
}
|
|
|
|
void UpdatePluginGeometryWithoutWaiting(float device_scale,
|
|
const gfx::Rect& window_rect) {
|
|
// The plugin container's device scale must be set before calling
|
|
// UpdateGeometry().
|
|
ASSERT_TRUE(wrapper_ptr_);
|
|
wrapper_ptr_->set_device_scale(device_scale);
|
|
plugin_->UpdateGeometry(window_rect, window_rect, window_rect,
|
|
/*is_visible=*/true);
|
|
}
|
|
|
|
void TestUpdateGeometrySetsPluginRect(float device_scale,
|
|
const gfx::Rect& window_rect,
|
|
float expected_device_scale,
|
|
const gfx::Rect& expected_plugin_rect) {
|
|
UpdatePluginGeometryWithoutWaiting(device_scale, window_rect);
|
|
EXPECT_EQ(expected_device_scale, plugin_->GetDeviceScaleForTesting())
|
|
<< "Device scale comparison failure at device scale of "
|
|
<< device_scale;
|
|
EXPECT_EQ(expected_plugin_rect, plugin_->GetPluginRectForTesting())
|
|
<< "Plugin rect comparison failure at device scale of " << device_scale
|
|
<< ", window rect of " << window_rect.ToString();
|
|
}
|
|
|
|
void TestPaintEmptySnapshots(float device_scale,
|
|
const gfx::Rect& window_rect,
|
|
const gfx::Rect& paint_rect,
|
|
const gfx::Rect& expected_clipped_rect) {
|
|
UpdatePluginGeometryWithoutWaiting(device_scale, window_rect);
|
|
canvas_.DrawColor(kDefaultColor);
|
|
|
|
plugin_->Paint(canvas_.sk_canvas(), paint_rect);
|
|
|
|
// Expect the clipped area on canvas to be filled with plugin's background
|
|
// color.
|
|
SkBitmap expected_bitmap = GenerateExpectedBitmapForPaint(
|
|
expected_clipped_rect, plugin_->GetBackgroundColor());
|
|
EXPECT_TRUE(
|
|
cc::MatchesBitmap(canvas_.GetBitmap(), expected_bitmap,
|
|
cc::ExactPixelComparator(/*discard_alpha=*/false)))
|
|
<< "Failure at device scale of " << device_scale << ", window rect of "
|
|
<< window_rect.ToString();
|
|
}
|
|
|
|
void TestPaintSnapshots(float device_scale,
|
|
const gfx::Rect& window_rect,
|
|
const gfx::Rect& paint_rect,
|
|
const gfx::Rect& expected_clipped_rect) {
|
|
UpdatePluginGeometry(device_scale, window_rect);
|
|
canvas_.DrawColor(kDefaultColor);
|
|
|
|
// Fill the graphics device with `kPaintColor` and update the plugin's
|
|
// snapshot.
|
|
const gfx::Rect& plugin_rect = plugin_->GetPluginRectForTesting();
|
|
std::unique_ptr<Graphics> graphics =
|
|
plugin_->CreatePaintGraphics(plugin_rect.size());
|
|
graphics->PaintImage(
|
|
CreateSkiaImageForTesting(plugin_rect.size(), kPaintColor),
|
|
gfx::Rect(plugin_rect.width(), plugin_rect.height()));
|
|
graphics->Flush(base::DoNothing());
|
|
|
|
plugin_->Paint(canvas_.sk_canvas(), paint_rect);
|
|
|
|
// Expect the clipped area on canvas to be filled with `kPaintColor`.
|
|
SkBitmap expected_bitmap =
|
|
GenerateExpectedBitmapForPaint(expected_clipped_rect, kPaintColor);
|
|
EXPECT_TRUE(
|
|
cc::MatchesBitmap(canvas_.GetBitmap(), expected_bitmap,
|
|
cc::ExactPixelComparator(/*discard_alpha=*/false)))
|
|
<< "Failure at device scale of " << device_scale << ", window rect of "
|
|
<< window_rect.ToString();
|
|
}
|
|
|
|
raw_ptr<TestPDFiumEngine> engine_ptr_;
|
|
raw_ptr<FakeContainerWrapper> wrapper_ptr_;
|
|
|
|
// Provides the cc::PaintCanvas for painting.
|
|
gfx::Canvas canvas_{kCanvasSize, /*image_scale=*/1.0f, /*is_opaque=*/true};
|
|
};
|
|
|
|
TEST_F(PdfViewWebPluginWithoutInitializeTest, Initialize) {
|
|
auto wrapper =
|
|
std::make_unique<NiceMock<FakeContainerWrapper>>(plugin_.get());
|
|
auto engine = std::make_unique<NiceMock<TestPDFiumEngine>>(plugin_.get());
|
|
EXPECT_CALL(*wrapper,
|
|
RequestTouchEventType(
|
|
blink::WebPluginContainer::kTouchEventRequestTypeRaw));
|
|
|
|
EXPECT_TRUE(
|
|
plugin_->InitializeForTesting(std::move(wrapper), std::move(engine)));
|
|
}
|
|
|
|
TEST_F(PdfViewWebPluginTest, UpdateGeometrySetsPluginRectUseZoomForDSFEnabled) {
|
|
EXPECT_CALL(*client_ptr_, IsUseZoomForDSFEnabled)
|
|
.WillRepeatedly(Return(true));
|
|
EXPECT_CALL(*engine_ptr_, ZoomUpdated(2.0f));
|
|
TestUpdateGeometrySetsPluginRect(
|
|
/*device_scale=*/2.0f, /*window_rect=*/gfx::Rect(4, 4, 12, 12),
|
|
/*expected_device_scale=*/2.0f,
|
|
/*expected_plugin_rect=*/gfx::Rect(4, 4, 12, 12));
|
|
}
|
|
|
|
TEST_F(PdfViewWebPluginTest,
|
|
UpdateGeometrySetsPluginRectUseZoomForDSFDisabled) {
|
|
EXPECT_CALL(*client_ptr_, IsUseZoomForDSFEnabled)
|
|
.WillRepeatedly(Return(false));
|
|
EXPECT_CALL(*engine_ptr_, ZoomUpdated(2.0f));
|
|
TestUpdateGeometrySetsPluginRect(
|
|
/*device_scale=*/2.0f, /*window_rect=*/gfx::Rect(4, 4, 12, 12),
|
|
/*expected_device_scale=*/2.0f,
|
|
/*expected_plugin_rect=*/gfx::Rect(8, 8, 24, 24));
|
|
}
|
|
|
|
TEST_F(PdfViewWebPluginTest,
|
|
UpdateGeometrySetsPluginRectOnVariousDeviceScales) {
|
|
struct UpdateGeometryParams {
|
|
// The plugin container's device scale.
|
|
float device_scale;
|
|
|
|
// The window rect in CSS pixels.
|
|
gfx::Rect window_rect;
|
|
|
|
// The expected plugin device scale.
|
|
float expected_device_scale;
|
|
|
|
// The expected plugin rect in device pixels.
|
|
gfx::Rect expected_plugin_rect;
|
|
};
|
|
|
|
// Keep the using zoom for DSF setting consistent within the test.
|
|
EXPECT_CALL(*client_ptr_, IsUseZoomForDSFEnabled)
|
|
.WillRepeatedly(Return(true));
|
|
|
|
static constexpr UpdateGeometryParams kUpdateGeometryParams[] = {
|
|
{1.0f, gfx::Rect(3, 4, 5, 6), 1.0f, gfx::Rect(3, 4, 5, 6)},
|
|
{2.0f, gfx::Rect(3, 4, 5, 6), 2.0f, gfx::Rect(3, 4, 5, 6)},
|
|
};
|
|
|
|
for (const auto& params : kUpdateGeometryParams) {
|
|
TestUpdateGeometrySetsPluginRect(params.device_scale, params.window_rect,
|
|
params.expected_device_scale,
|
|
params.expected_plugin_rect);
|
|
}
|
|
}
|
|
|
|
TEST_F(PdfViewWebPluginTest, UpdateGeometryScrollsUseZoomForDSFEnabled) {
|
|
EXPECT_CALL(*client_ptr_, IsUseZoomForDSFEnabled)
|
|
.WillRepeatedly(Return(true));
|
|
SetDocumentDimensions({100, 200});
|
|
|
|
EXPECT_CALL(*wrapper_ptr_, GetScrollPosition)
|
|
.WillRepeatedly(Return(gfx::PointF(4.0f, 6.0f)));
|
|
EXPECT_CALL(*engine_ptr_, ScrolledToXPosition(4));
|
|
EXPECT_CALL(*engine_ptr_, ScrolledToYPosition(6));
|
|
UpdatePluginGeometryWithoutWaiting(2.0f, gfx::Rect(3, 4, 5, 6));
|
|
}
|
|
|
|
TEST_F(PdfViewWebPluginTest, UpdateGeometryScrollsUseZoomForDSFDisabled) {
|
|
EXPECT_CALL(*client_ptr_, IsUseZoomForDSFEnabled)
|
|
.WillRepeatedly(Return(false));
|
|
SetDocumentDimensions({100, 200});
|
|
|
|
EXPECT_CALL(*wrapper_ptr_, GetScrollPosition)
|
|
.WillRepeatedly(Return(gfx::PointF(2.0f, 3.0f)));
|
|
EXPECT_CALL(*engine_ptr_, ScrolledToXPosition(4));
|
|
EXPECT_CALL(*engine_ptr_, ScrolledToYPosition(6));
|
|
UpdatePluginGeometryWithoutWaiting(2.0f, gfx::Rect(3, 4, 5, 6));
|
|
}
|
|
|
|
class PdfViewWebPluginTestUseZoomForDSF
|
|
: public PdfViewWebPluginTest,
|
|
public testing::WithParamInterface<bool> {
|
|
public:
|
|
void SetUp() override {
|
|
PdfViewWebPluginTest::SetUp();
|
|
ON_CALL(*client_ptr_, IsUseZoomForDSFEnabled)
|
|
.WillByDefault(Return(GetParam()));
|
|
}
|
|
};
|
|
|
|
TEST_P(PdfViewWebPluginTestUseZoomForDSF,
|
|
UpdateGeometrySetsPluginRectWithEmptyWindow) {
|
|
EXPECT_CALL(*engine_ptr_, ZoomUpdated).Times(0);
|
|
TestUpdateGeometrySetsPluginRect(
|
|
/*device_scale=*/2.0f, /*window_rect=*/gfx::Rect(2, 2, 0, 0),
|
|
/*expected_device_scale=*/1.0f, /*expected_plugin_rect=*/gfx::Rect());
|
|
}
|
|
|
|
TEST_P(PdfViewWebPluginTestUseZoomForDSF, SetCaretPositionIgnoresOrigin) {
|
|
SetDocumentDimensions({16, 9});
|
|
UpdatePluginGeometryWithoutWaiting(1.0f, {10, 20, 20, 5});
|
|
|
|
EXPECT_CALL(*engine_ptr_, SetCaretPosition(gfx::Point(2, 3)));
|
|
plugin_->SetCaretPosition({4.0f, 3.0f});
|
|
}
|
|
|
|
TEST_P(PdfViewWebPluginTestUseZoomForDSF, PaintEmptySnapshots) {
|
|
TestPaintEmptySnapshots(/*device_scale=*/4.0f,
|
|
/*window_rect=*/gfx::Rect(10, 10, 20, 20),
|
|
/*paint_rect=*/gfx::Rect(5, 5, 15, 15),
|
|
/*expected_clipped_rect=*/gfx::Rect(10, 10, 10, 10));
|
|
}
|
|
|
|
TEST_P(PdfViewWebPluginTestUseZoomForDSF, PaintSnapshots) {
|
|
TestPaintSnapshots(/*device_scale=*/4.0f,
|
|
/*window_rect=*/gfx::Rect(10, 10, 20, 20),
|
|
/*paint_rect=*/gfx::Rect(5, 5, 15, 15),
|
|
/*expected_clipped_rect=*/gfx::Rect(10, 10, 10, 10));
|
|
}
|
|
|
|
TEST_P(PdfViewWebPluginTestUseZoomForDSF,
|
|
PaintSnapshotsWithVariousDeviceScales) {
|
|
static constexpr PaintParams kPaintWithVariousScalesParams[] = {
|
|
{0.4f, gfx::Rect(8, 8, 30, 30), gfx::Rect(10, 10, 30, 30),
|
|
gfx::Rect(10, 10, 28, 28)},
|
|
{1.0f, gfx::Rect(8, 8, 30, 30), gfx::Rect(10, 10, 30, 30),
|
|
gfx::Rect(10, 10, 28, 28)},
|
|
{4.0f, gfx::Rect(8, 8, 30, 30), gfx::Rect(10, 10, 30, 30),
|
|
gfx::Rect(10, 10, 28, 28)},
|
|
};
|
|
|
|
for (const auto& params : kPaintWithVariousScalesParams) {
|
|
TestPaintSnapshots(params.device_scale, params.window_rect,
|
|
params.paint_rect, params.expected_clipped_rect);
|
|
}
|
|
}
|
|
|
|
TEST_P(PdfViewWebPluginTestUseZoomForDSF,
|
|
PaintSnapshotsWithVariousRectPositions) {
|
|
static constexpr PaintParams kPaintWithVariousPositionsParams[] = {
|
|
// The window origin falls outside the `paint_rect` area.
|
|
{4.0f, gfx::Rect(10, 10, 20, 20), gfx::Rect(5, 5, 15, 15),
|
|
gfx::Rect(10, 10, 10, 10)},
|
|
// The window origin falls within the `paint_rect` area.
|
|
{4.0f, gfx::Rect(4, 4, 20, 20), gfx::Rect(8, 8, 15, 15),
|
|
gfx::Rect(8, 8, 15, 15)},
|
|
};
|
|
|
|
for (const auto& params : kPaintWithVariousPositionsParams) {
|
|
TestPaintSnapshots(params.device_scale, params.window_rect,
|
|
params.paint_rect, params.expected_clipped_rect);
|
|
}
|
|
}
|
|
|
|
TEST_P(PdfViewWebPluginTestUseZoomForDSF, UpdateLayerTransformWithIdentity) {
|
|
plugin_->UpdateLayerTransform(1.0f, gfx::Vector2dF());
|
|
TestPaintSnapshots(/*device_scale=*/4.0f,
|
|
/*window_rect=*/gfx::Rect(10, 10, 20, 20),
|
|
/*paint_rect=*/gfx::Rect(10, 10, 20, 20),
|
|
/*expected_clipped_rect=*/gfx::Rect(10, 10, 20, 20));
|
|
}
|
|
|
|
TEST_P(PdfViewWebPluginTestUseZoomForDSF, UpdateLayerTransformWithScale) {
|
|
plugin_->UpdateLayerTransform(0.5f, gfx::Vector2dF());
|
|
TestPaintSnapshots(/*device_scale=*/4.0f,
|
|
/*window_rect=*/gfx::Rect(10, 10, 20, 20),
|
|
/*paint_rect=*/gfx::Rect(10, 10, 20, 20),
|
|
/*expected_clipped_rect=*/gfx::Rect(10, 10, 10, 10));
|
|
}
|
|
|
|
TEST_F(PdfViewWebPluginTest,
|
|
UpdateLayerTransformWithTranslateUseZoomForDSFDisabled) {
|
|
EXPECT_CALL(*client_ptr_, IsUseZoomForDSFEnabled)
|
|
.WillRepeatedly(Return(false));
|
|
|
|
plugin_->UpdateLayerTransform(1.0f, gfx::Vector2dF(-5, 5));
|
|
TestPaintSnapshots(/*device_scale=*/4.0f,
|
|
/*window_rect=*/gfx::Rect(10, 10, 20, 20),
|
|
/*paint_rect=*/gfx::Rect(10, 10, 20, 20),
|
|
/*expected_clipped_rect=*/gfx::Rect(10, 15, 15, 15));
|
|
}
|
|
|
|
TEST_F(PdfViewWebPluginTest,
|
|
UpdateLayerTransformWithTranslateUseZoomForDSFEnabled) {
|
|
EXPECT_CALL(*client_ptr_, IsUseZoomForDSFEnabled)
|
|
.WillRepeatedly(Return(true));
|
|
|
|
plugin_->UpdateLayerTransform(1.0f, gfx::Vector2dF(-1.25, 1.25));
|
|
TestPaintSnapshots(/*device_scale=*/4.0f,
|
|
/*window_rect=*/gfx::Rect(10, 10, 20, 20),
|
|
/*paint_rect=*/gfx::Rect(10, 10, 20, 20),
|
|
/*expected_clipped_rect=*/gfx::Rect(10, 15, 15, 15));
|
|
}
|
|
|
|
TEST_F(PdfViewWebPluginTest,
|
|
UpdateLayerTransformWithScaleAndTranslateUseZoomForDSFDisabled) {
|
|
EXPECT_CALL(*client_ptr_, IsUseZoomForDSFEnabled)
|
|
.WillRepeatedly(Return(false));
|
|
|
|
plugin_->UpdateLayerTransform(0.5f, gfx::Vector2dF(-5, 5));
|
|
TestPaintSnapshots(/*device_scale=*/4.0f,
|
|
/*window_rect=*/gfx::Rect(10, 10, 20, 20),
|
|
/*paint_rect=*/gfx::Rect(10, 10, 20, 20),
|
|
/*expected_clipped_rect=*/gfx::Rect(10, 15, 5, 10));
|
|
}
|
|
|
|
TEST_F(PdfViewWebPluginTest,
|
|
UpdateLayerTransformWithScaleAndTranslateUseZoomForDSFEnabled) {
|
|
EXPECT_CALL(*client_ptr_, IsUseZoomForDSFEnabled)
|
|
.WillRepeatedly(Return(true));
|
|
|
|
plugin_->UpdateLayerTransform(0.5f, gfx::Vector2dF(-1.25, 1.25));
|
|
TestPaintSnapshots(/*device_scale=*/4.0f,
|
|
/*window_rect=*/gfx::Rect(10, 10, 20, 20),
|
|
/*paint_rect=*/gfx::Rect(10, 10, 20, 20),
|
|
/*expected_clipped_rect=*/gfx::Rect(10, 15, 5, 10));
|
|
}
|
|
|
|
INSTANTIATE_TEST_SUITE_P(All,
|
|
PdfViewWebPluginTestUseZoomForDSF,
|
|
testing::Bool());
|
|
|
|
class PdfViewWebPluginMouseEventsTest : public PdfViewWebPluginTest {
|
|
public:
|
|
class TestPDFiumEngineForMouseEvents : public TestPDFiumEngine {
|
|
public:
|
|
explicit TestPDFiumEngineForMouseEvents(PDFEngine::Client* client)
|
|
: TestPDFiumEngine(client) {}
|
|
|
|
// TestPDFiumEngine:
|
|
bool HandleInputEvent(const blink::WebInputEvent& event) override {
|
|
// Since blink::WebInputEvent is an abstract class, we cannot use equal
|
|
// matcher to verify its value. Here we test with blink::WebMouseEvent
|
|
// specifically.
|
|
if (!blink::WebInputEvent::IsMouseEventType(event.GetType()))
|
|
return false;
|
|
|
|
scaled_mouse_event_ = std::make_unique<blink::WebMouseEvent>();
|
|
*scaled_mouse_event_ = static_cast<const blink::WebMouseEvent&>(event);
|
|
return true;
|
|
}
|
|
|
|
const blink::WebMouseEvent* GetScaledMouseEvent() const {
|
|
return scaled_mouse_event_.get();
|
|
}
|
|
|
|
private:
|
|
std::unique_ptr<blink::WebMouseEvent> scaled_mouse_event_;
|
|
};
|
|
|
|
std::unique_ptr<TestPDFiumEngine> CreateEngine() override {
|
|
return std::make_unique<NiceMock<TestPDFiumEngineForMouseEvents>>(
|
|
plugin_.get());
|
|
}
|
|
|
|
TestPDFiumEngineForMouseEvents* engine() {
|
|
return static_cast<TestPDFiumEngineForMouseEvents*>(engine_ptr_);
|
|
}
|
|
};
|
|
|
|
TEST_F(PdfViewWebPluginMouseEventsTest,
|
|
HandleInputEventWithUseZoomForDSFEnabled) {
|
|
// Test when using zoom for DSF is enabled.
|
|
EXPECT_CALL(*client_ptr_, IsUseZoomForDSFEnabled)
|
|
.WillRepeatedly(Return(true));
|
|
wrapper_ptr_->set_device_scale(kDeviceScale);
|
|
UpdatePluginGeometry(kDeviceScale, gfx::Rect(20, 20));
|
|
|
|
ui::Cursor dummy_cursor;
|
|
plugin_->HandleInputEvent(
|
|
blink::WebCoalescedInputEvent(CreateDefaultMouseDownEvent(),
|
|
ui::LatencyInfo()),
|
|
&dummy_cursor);
|
|
|
|
const blink::WebMouseEvent* event = engine()->GetScaledMouseEvent();
|
|
ASSERT_TRUE(event);
|
|
EXPECT_EQ(gfx::PointF(-10.0f, 0.0f), event->PositionInWidget());
|
|
}
|
|
|
|
TEST_F(PdfViewWebPluginMouseEventsTest,
|
|
HandleInputEventWithUseZoomForDSFDisabled) {
|
|
// Test when using zoom for DSF is disabled.
|
|
EXPECT_CALL(*client_ptr_, IsUseZoomForDSFEnabled)
|
|
.WillRepeatedly(Return(false));
|
|
wrapper_ptr_->set_device_scale(kDeviceScale);
|
|
UpdatePluginGeometry(kDeviceScale, gfx::Rect(20, 20));
|
|
|
|
ui::Cursor dummy_cursor;
|
|
plugin_->HandleInputEvent(
|
|
blink::WebCoalescedInputEvent(CreateDefaultMouseDownEvent(),
|
|
ui::LatencyInfo()),
|
|
&dummy_cursor);
|
|
|
|
const blink::WebMouseEvent* event = engine()->GetScaledMouseEvent();
|
|
ASSERT_TRUE(event);
|
|
EXPECT_EQ(gfx::PointF(-20.0f, 0.0f), event->PositionInWidget());
|
|
}
|
|
|
|
class PdfViewWebPluginImeTest : public PdfViewWebPluginTest {
|
|
public:
|
|
void TestImeSetCompositionForPlugin(const blink::WebString& text) {
|
|
EXPECT_CALL(*engine_ptr_, HandleInputEvent).Times(0);
|
|
plugin_->ImeSetCompositionForPlugin(text, std::vector<ui::ImeTextSpan>(),
|
|
gfx::Range(),
|
|
/*selection_start=*/0,
|
|
/*selection_end=*/0);
|
|
}
|
|
|
|
void TestImeFinishComposingTextForPlugin(
|
|
const blink::WebString& expected_text) {
|
|
InSequence sequence;
|
|
std::u16string expected_text16 = expected_text.Utf16();
|
|
if (expected_text16.size()) {
|
|
for (const auto& c : expected_text16) {
|
|
base::StringPiece16 expected_key(&c, 1);
|
|
EXPECT_CALL(*engine_ptr_,
|
|
HandleInputEvent(IsExpectedImeKeyEvent(expected_key)))
|
|
.WillOnce(Return(true));
|
|
}
|
|
} else {
|
|
EXPECT_CALL(*engine_ptr_, HandleInputEvent).Times(0);
|
|
}
|
|
plugin_->ImeFinishComposingTextForPlugin(false);
|
|
}
|
|
|
|
void TestImeCommitTextForPlugin(const blink::WebString& text) {
|
|
InSequence sequence;
|
|
std::u16string expected_text16 = text.Utf16();
|
|
if (expected_text16.size()) {
|
|
for (const auto& c : expected_text16) {
|
|
base::StringPiece16 event(&c, 1);
|
|
EXPECT_CALL(*engine_ptr_,
|
|
HandleInputEvent(IsExpectedImeKeyEvent(event)))
|
|
.WillOnce(Return(true));
|
|
}
|
|
} else {
|
|
EXPECT_CALL(*engine_ptr_, HandleInputEvent).Times(0);
|
|
}
|
|
plugin_->ImeCommitTextForPlugin(text, std::vector<ui::ImeTextSpan>(),
|
|
gfx::Range(),
|
|
/*relative_cursor_pos=*/0);
|
|
}
|
|
};
|
|
|
|
TEST_F(PdfViewWebPluginImeTest, ImeSetCompositionAndFinishAscii) {
|
|
const blink::WebString text = blink::WebString::FromASCII("input");
|
|
TestImeSetCompositionForPlugin(text);
|
|
TestImeFinishComposingTextForPlugin(text);
|
|
}
|
|
|
|
TEST_F(PdfViewWebPluginImeTest, ImeSetCompositionAndFinishUnicode) {
|
|
const blink::WebString text = blink::WebString::FromUTF16(u"你好");
|
|
TestImeSetCompositionForPlugin(text);
|
|
TestImeFinishComposingTextForPlugin(text);
|
|
// Calling ImeFinishComposingTextForPlugin() again is a no-op.
|
|
TestImeFinishComposingTextForPlugin("");
|
|
}
|
|
|
|
TEST_F(PdfViewWebPluginImeTest, ImeSetCompositionAndFinishEmpty) {
|
|
const blink::WebString text;
|
|
TestImeSetCompositionForPlugin(text);
|
|
TestImeFinishComposingTextForPlugin(text);
|
|
}
|
|
|
|
TEST_F(PdfViewWebPluginImeTest, ImeCommitTextForPluginAscii) {
|
|
const blink::WebString text = blink::WebString::FromASCII("a b");
|
|
TestImeCommitTextForPlugin(text);
|
|
}
|
|
|
|
TEST_F(PdfViewWebPluginImeTest, ImeCommitTextForPluginUnicode) {
|
|
const blink::WebString text = blink::WebString::FromUTF16(u"さようなら");
|
|
TestImeCommitTextForPlugin(text);
|
|
}
|
|
|
|
TEST_F(PdfViewWebPluginImeTest, ImeCommitTextForPluginEmpty) {
|
|
const blink::WebString text;
|
|
TestImeCommitTextForPlugin(text);
|
|
}
|
|
|
|
TEST_F(PdfViewWebPluginTest, ChangeTextSelection) {
|
|
ASSERT_FALSE(plugin_->HasSelection());
|
|
ASSERT_TRUE(plugin_->SelectionAsText().IsEmpty());
|
|
ASSERT_TRUE(plugin_->SelectionAsMarkup().IsEmpty());
|
|
|
|
static constexpr char kSelectedText[] = "1234";
|
|
EXPECT_CALL(*wrapper_ptr_,
|
|
TextSelectionChanged(blink::WebString::FromUTF8(kSelectedText), 0,
|
|
gfx::Range(0, 4)));
|
|
|
|
plugin_->SetSelectedText(kSelectedText);
|
|
EXPECT_TRUE(plugin_->HasSelection());
|
|
EXPECT_EQ(kSelectedText, plugin_->SelectionAsText().Utf8());
|
|
EXPECT_EQ(kSelectedText, plugin_->SelectionAsMarkup().Utf8());
|
|
|
|
static constexpr char kEmptyText[] = "";
|
|
EXPECT_CALL(*wrapper_ptr_,
|
|
TextSelectionChanged(blink::WebString::FromUTF8(kEmptyText), 0,
|
|
gfx::Range(0, 0)));
|
|
plugin_->SetSelectedText(kEmptyText);
|
|
EXPECT_FALSE(plugin_->HasSelection());
|
|
EXPECT_TRUE(plugin_->SelectionAsText().IsEmpty());
|
|
EXPECT_TRUE(plugin_->SelectionAsMarkup().IsEmpty());
|
|
}
|
|
|
|
TEST_F(PdfViewWebPluginTest, FormTextFieldFocusChangeUpdatesTextInputType) {
|
|
ASSERT_EQ(blink::WebTextInputType::kWebTextInputTypeNone,
|
|
wrapper_ptr_->widget_text_input_type());
|
|
|
|
MockFunction<void()> checkpoint;
|
|
{
|
|
InSequence sequence;
|
|
EXPECT_CALL(*wrapper_ptr_, UpdateTextInputState);
|
|
EXPECT_CALL(checkpoint, Call);
|
|
EXPECT_CALL(*wrapper_ptr_, UpdateTextInputState);
|
|
EXPECT_CALL(checkpoint, Call);
|
|
EXPECT_CALL(*wrapper_ptr_, UpdateTextInputState);
|
|
EXPECT_CALL(checkpoint, Call);
|
|
EXPECT_CALL(*wrapper_ptr_, UpdateTextInputState);
|
|
}
|
|
|
|
plugin_->FormFieldFocusChange(PDFEngine::FocusFieldType::kText);
|
|
EXPECT_EQ(blink::WebTextInputType::kWebTextInputTypeText,
|
|
wrapper_ptr_->widget_text_input_type());
|
|
|
|
checkpoint.Call();
|
|
|
|
plugin_->FormFieldFocusChange(PDFEngine::FocusFieldType::kNoFocus);
|
|
EXPECT_EQ(blink::WebTextInputType::kWebTextInputTypeNone,
|
|
wrapper_ptr_->widget_text_input_type());
|
|
|
|
checkpoint.Call();
|
|
|
|
plugin_->FormFieldFocusChange(PDFEngine::FocusFieldType::kText);
|
|
EXPECT_EQ(blink::WebTextInputType::kWebTextInputTypeText,
|
|
wrapper_ptr_->widget_text_input_type());
|
|
|
|
checkpoint.Call();
|
|
|
|
plugin_->FormFieldFocusChange(PDFEngine::FocusFieldType::kNonText);
|
|
EXPECT_EQ(blink::WebTextInputType::kWebTextInputTypeNone,
|
|
wrapper_ptr_->widget_text_input_type());
|
|
}
|
|
|
|
TEST_F(PdfViewWebPluginTest, SearchString) {
|
|
static constexpr char16_t kPattern[] = u"fox";
|
|
static constexpr char16_t kTarget[] =
|
|
u"The quick brown fox jumped over the lazy Fox";
|
|
|
|
{
|
|
static constexpr PDFEngine::Client::SearchStringResult kExpectation[] = {
|
|
{16, 3}};
|
|
EXPECT_THAT(
|
|
plugin_->SearchString(kTarget, kPattern, /*case_sensitive=*/true),
|
|
Pointwise(SearchStringResultEq(), kExpectation));
|
|
}
|
|
{
|
|
static constexpr PDFEngine::Client::SearchStringResult kExpectation[] = {
|
|
{16, 3}, {41, 3}};
|
|
EXPECT_THAT(
|
|
plugin_->SearchString(kTarget, kPattern, /*case_sensitive=*/false),
|
|
Pointwise(SearchStringResultEq(), kExpectation));
|
|
}
|
|
}
|
|
|
|
TEST_F(PdfViewWebPluginTest, UpdateFocus) {
|
|
MockFunction<void(int checkpoint_num)> checkpoint;
|
|
|
|
{
|
|
InSequence sequence;
|
|
|
|
// Focus false -> true: Triggers updates.
|
|
EXPECT_CALL(*wrapper_ptr_, UpdateTextInputState);
|
|
EXPECT_CALL(*wrapper_ptr_, UpdateSelectionBounds);
|
|
EXPECT_CALL(checkpoint, Call(1));
|
|
|
|
// Focus true -> true: No updates.
|
|
EXPECT_CALL(checkpoint, Call(2));
|
|
|
|
// Focus true -> false: Triggers updates. `UpdateTextInputState` is called
|
|
// twice because it also gets called due to
|
|
// `PDFiumEngine::UpdateFocus(false)`.
|
|
EXPECT_CALL(*wrapper_ptr_, UpdateTextInputState).Times(2);
|
|
EXPECT_CALL(*wrapper_ptr_, UpdateSelectionBounds);
|
|
EXPECT_CALL(checkpoint, Call(3));
|
|
|
|
// Focus false -> false: No updates.
|
|
EXPECT_CALL(checkpoint, Call(4));
|
|
|
|
// Focus false -> true: Triggers updates.
|
|
EXPECT_CALL(*wrapper_ptr_, UpdateTextInputState);
|
|
EXPECT_CALL(*wrapper_ptr_, UpdateSelectionBounds);
|
|
}
|
|
|
|
// The focus type does not matter in this test.
|
|
plugin_->UpdateFocus(/*focused=*/true, blink::mojom::FocusType::kNone);
|
|
checkpoint.Call(1);
|
|
plugin_->UpdateFocus(/*focused=*/true, blink::mojom::FocusType::kNone);
|
|
checkpoint.Call(2);
|
|
plugin_->UpdateFocus(/*focused=*/false, blink::mojom::FocusType::kNone);
|
|
checkpoint.Call(3);
|
|
plugin_->UpdateFocus(/*focused=*/false, blink::mojom::FocusType::kNone);
|
|
checkpoint.Call(4);
|
|
plugin_->UpdateFocus(/*focused=*/true, blink::mojom::FocusType::kNone);
|
|
}
|
|
|
|
TEST_F(PdfViewWebPluginTest, ShouldDispatchImeEventsToPlugin) {
|
|
ASSERT_TRUE(plugin_->ShouldDispatchImeEventsToPlugin());
|
|
}
|
|
|
|
TEST_F(PdfViewWebPluginTest, CaretChangeUseZoomForDSFEnabled) {
|
|
EXPECT_CALL(*client_ptr_, IsUseZoomForDSFEnabled)
|
|
.WillRepeatedly(Return(true));
|
|
EXPECT_CALL(*engine_ptr_, ZoomUpdated(2.0f));
|
|
UpdatePluginGeometry(
|
|
/*device_scale=*/2.0f, /*window_rect=*/gfx::Rect(12, 24, 36, 48));
|
|
plugin_->CaretChanged(gfx::Rect(10, 20, 30, 40));
|
|
EXPECT_EQ(gfx::Rect(28, 20, 30, 40), plugin_->GetPluginCaretBounds());
|
|
}
|
|
|
|
TEST_F(PdfViewWebPluginTest, CaretChangeUseZoomForDSFDisabled) {
|
|
EXPECT_CALL(*client_ptr_, IsUseZoomForDSFEnabled)
|
|
.WillRepeatedly(Return(false));
|
|
EXPECT_CALL(*engine_ptr_, ZoomUpdated(2.0f));
|
|
UpdatePluginGeometry(
|
|
/*device_scale=*/2.0f, /*window_rect=*/gfx::Rect(12, 24, 36, 48));
|
|
plugin_->CaretChanged(gfx::Rect(10, 20, 30, 40));
|
|
EXPECT_EQ(gfx::Rect(23, 10, 15, 20), plugin_->GetPluginCaretBounds());
|
|
}
|
|
|
|
TEST_F(PdfViewWebPluginTest, NotifyNumberOfFindResultsChanged) {
|
|
plugin_->StartFind("x", /*case_sensitive=*/false, /*identifier=*/123);
|
|
|
|
const std::vector<gfx::Rect> tickmarks = {gfx::Rect(1, 2), gfx::Rect(3, 4)};
|
|
plugin_->UpdateTickMarks(tickmarks);
|
|
|
|
EXPECT_CALL(*wrapper_ptr_, ReportFindInPageTickmarks(tickmarks));
|
|
EXPECT_CALL(*wrapper_ptr_, ReportFindInPageMatchCount(123, 5, true));
|
|
plugin_->NotifyNumberOfFindResultsChanged(/*total=*/5, /*final_result=*/true);
|
|
}
|
|
|
|
} // namespace chrome_pdf
|