blob: 19bcb38b8cf4f17a03b6c397feefdb83ef9d7ce4 [file]
// Copyright 2017 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 "ui/aura/mus/input_method_mus.h"
#include "services/ui/public/interfaces/ime/ime.mojom.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/window.h"
#include "ui/base/ime/input_method_delegate.h"
namespace aura {
namespace {
// Empty implementation of InputMethodDelegate.
class TestInputMethodDelegate : public ui::internal::InputMethodDelegate {
public:
TestInputMethodDelegate() {}
~TestInputMethodDelegate() override {}
// ui::internal::InputMethodDelegate:
ui::EventDispatchDetails DispatchKeyEventPostIME(ui::KeyEvent* key) override {
return ui::EventDispatchDetails();
}
private:
DISALLOW_COPY_AND_ASSIGN(TestInputMethodDelegate);
};
using ProcessKeyEventCallback = base::Callback<void(bool)>;
using ProcessKeyEventCallbacks = std::vector<ProcessKeyEventCallback>;
using EventResultCallback = base::Callback<void(ui::mojom::EventResult)>;
// InputMethod implementation that queues up the callbacks supplied to
// ProcessKeyEvent().
class TestInputMethod : public ui::mojom::InputMethod {
public:
TestInputMethod() {}
~TestInputMethod() override {}
ProcessKeyEventCallbacks* process_key_event_callbacks() {
return &process_key_event_callbacks_;
}
// ui::ime::InputMethod:
void OnTextInputTypeChanged(ui::TextInputType text_input_type) override {}
void OnCaretBoundsChanged(const gfx::Rect& caret_bounds) override {}
void ProcessKeyEvent(std::unique_ptr<ui::Event> key_event,
const ProcessKeyEventCallback& callback) override {
process_key_event_callbacks_.push_back(callback);
}
void CancelComposition() override {}
private:
ProcessKeyEventCallbacks process_key_event_callbacks_;
DISALLOW_COPY_AND_ASSIGN(TestInputMethod);
};
} // namespace
using InputMethodMusTest = test::AuraTestBaseMus;
class InputMethodMusTestApi {
public:
static void SetInputMethod(InputMethodMus* input_method_mus,
ui::mojom::InputMethod* input_method) {
input_method_mus->input_method_ = input_method;
}
static void CallSendKeyEventToInputMethod(
InputMethodMus* input_method_mus,
const ui::KeyEvent& event,
std::unique_ptr<EventResultCallback> ack_callback) {
input_method_mus->SendKeyEventToInputMethod(event, std::move(ack_callback));
}
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(InputMethodMusTestApi);
};
namespace {
// Used in closure supplied to processing the event.
void RunFunctionWithEventResult(bool* was_run, ui::mojom::EventResult result) {
*was_run = true;
}
} // namespace
TEST_F(InputMethodMusTest, PendingCallbackRunFromDestruction) {
aura::Window window(nullptr);
window.Init(ui::LAYER_NOT_DRAWN);
bool was_event_result_callback_run = false;
// Create an InputMethodMus and foward an event to it.
{
TestInputMethodDelegate input_method_delegate;
InputMethodMus input_method_mus(&input_method_delegate, &window);
TestInputMethod test_input_method;
InputMethodMusTestApi::SetInputMethod(&input_method_mus,
&test_input_method);
std::unique_ptr<EventResultCallback> callback =
base::MakeUnique<EventResultCallback>(base::Bind(
&RunFunctionWithEventResult, &was_event_result_callback_run));
InputMethodMusTestApi::CallSendKeyEventToInputMethod(
&input_method_mus, ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, 0),
std::move(callback));
// Add a null callback as well, to make sure null is deal with.
InputMethodMusTestApi::CallSendKeyEventToInputMethod(
&input_method_mus, ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, 0),
nullptr);
// The event should have been queued.
EXPECT_EQ(2u, test_input_method.process_key_event_callbacks()->size());
// Callback should not have been run yet.
EXPECT_FALSE(was_event_result_callback_run);
}
// When the destructor is run the callback should be run.
EXPECT_TRUE(was_event_result_callback_run);
}
} // namespace aura