Commit c6a29b98 authored by Blake O'Hare's avatar Blake O'Hare Committed by Commit Bot

Add callback support to KeyboardController when setting container type

Currently, there is a field on KeyboardController for enqueuing a
container type change. Eventually we want to support invoking a JS
callback to notify the extension when a keyboard mode changes.

This is the first step in that direction. Instead of persisting a
single enum value for the enqueued container behavior, it tracks both
the type and a callback handle. This QueuedContainerBehavior object
will invoke the callback once it goes out of scope.

Change-Id: Iea4e96259314a34d31661342024a23617a9f4b74
Bug: 806189
Reviewed-on: https://chromium-review.googlesource.com/888119
Commit-Queue: Blake O'Hare <blakeo@chromium.org>
Reviewed-by: default avatarYuichiro Hanada <yhanada@chromium.org>
Cr-Commit-Position: refs/heads/master@{#533197}
parent 23fbbe66
...@@ -35,6 +35,8 @@ jumbo_component("keyboard") { ...@@ -35,6 +35,8 @@ jumbo_component("keyboard") {
"keyboard_util.h", "keyboard_util.h",
"notification_manager.cc", "notification_manager.cc",
"notification_manager.h", "notification_manager.h",
"queued_container_type.cc",
"queued_container_type.h",
] ]
defines = [ "KEYBOARD_IMPLEMENTATION" ] defines = [ "KEYBOARD_IMPLEMENTATION" ]
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include "ui/keyboard/keyboard_ui.h" #include "ui/keyboard/keyboard_ui.h"
#include "ui/keyboard/keyboard_util.h" #include "ui/keyboard/keyboard_util.h"
#include "ui/keyboard/notification_manager.h" #include "ui/keyboard/notification_manager.h"
#include "ui/keyboard/queued_container_type.h"
#include "ui/wm/core/window_animations.h" #include "ui/wm/core/window_animations.h"
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
...@@ -202,12 +203,11 @@ KeyboardController::KeyboardController(std::unique_ptr<KeyboardUI> ui, ...@@ -202,12 +203,11 @@ KeyboardController::KeyboardController(std::unique_ptr<KeyboardUI> ui,
show_on_content_update_(false), show_on_content_update_(false),
keyboard_locked_(false), keyboard_locked_(false),
state_(KeyboardControllerState::UNKNOWN), state_(KeyboardControllerState::UNKNOWN),
enqueued_container_type_(ContainerType::FULL_WIDTH),
weak_factory_report_lingering_state_(this), weak_factory_report_lingering_state_(this),
weak_factory_will_hide_(this) { weak_factory_will_hide_(this) {
ui_->GetInputMethod()->AddObserver(this); ui_->GetInputMethod()->AddObserver(this);
ui_->SetController(this); ui_->SetController(this);
SetContainerBehaviorInternal(enqueued_container_type_); SetContainerBehaviorInternal(ContainerType::FULL_WIDTH);
ChangeState(KeyboardControllerState::INITIAL); ChangeState(KeyboardControllerState::INITIAL);
} }
...@@ -385,11 +385,8 @@ void KeyboardController::HideKeyboard(HideReason reason) { ...@@ -385,11 +385,8 @@ void KeyboardController::HideKeyboard(HideReason reason) {
} }
void KeyboardController::HideAnimationFinished() { void KeyboardController::HideAnimationFinished() {
if (state_ != KeyboardControllerState::HIDDEN) if (state_ == KeyboardControllerState::HIDDEN && queued_container_type_) {
return; SetContainerBehaviorInternal(queued_container_type_->container_type());
if (enqueued_container_type_ != container_behavior_->GetType()) {
SetContainerBehaviorInternal(enqueued_container_type_);
ShowKeyboard(false /* lock */); ShowKeyboard(false /* lock */);
} }
} }
...@@ -624,6 +621,10 @@ void KeyboardController::PopulateKeyboardContent(int64_t display_id, ...@@ -624,6 +621,10 @@ void KeyboardController::PopulateKeyboardContent(int64_t display_id,
container_behavior_->DoShowingAnimation(container_.get(), &settings); container_behavior_->DoShowingAnimation(container_.get(), &settings);
// the queued container behavior will notify JS to change layout when it
// gets destroyed.
queued_container_type_ = nullptr;
ChangeState(KeyboardControllerState::SHOWN); ChangeState(KeyboardControllerState::SHOWN);
NotifyKeyboardBoundsChangingAndEnsureCaretInWorkArea(); NotifyKeyboardBoundsChangingAndEnsureCaretInWorkArea();
} }
...@@ -742,10 +743,20 @@ void KeyboardController::HandlePointerEvent(const ui::LocatedEvent& event) { ...@@ -742,10 +743,20 @@ void KeyboardController::HandlePointerEvent(const ui::LocatedEvent& event) {
} }
void KeyboardController::SetContainerType(const ContainerType type) { void KeyboardController::SetContainerType(const ContainerType type) {
if (container_behavior_->GetType() == type) SetContainerType(type, base::BindOnce([](bool ignored) { /* noop */ }));
}
void KeyboardController::SetContainerType(
const ContainerType type,
base::OnceCallback<void(bool)> callback) {
if (container_behavior_->GetType() == type) {
std::move(callback).Run(false);
return; return;
}
queued_container_type_ =
std::make_unique<QueuedContainerType>(this, type, std::move(callback));
enqueued_container_type_ = type;
if (state_ == KeyboardControllerState::SHOWN) { if (state_ == KeyboardControllerState::SHOWN) {
HideKeyboard(HIDE_REASON_AUTOMATIC); HideKeyboard(HIDE_REASON_AUTOMATIC);
} else { } else {
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "ui/keyboard/keyboard_layout_delegate.h" #include "ui/keyboard/keyboard_layout_delegate.h"
#include "ui/keyboard/keyboard_util.h" #include "ui/keyboard/keyboard_util.h"
#include "ui/keyboard/notification_manager.h" #include "ui/keyboard/notification_manager.h"
#include "ui/keyboard/queued_container_type.h"
namespace aura { namespace aura {
class Window; class Window;
...@@ -152,6 +153,10 @@ class KEYBOARD_EXPORT KeyboardController : public ui::InputMethodObserver, ...@@ -152,6 +153,10 @@ class KEYBOARD_EXPORT KeyboardController : public ui::InputMethodObserver,
KeyboardControllerState GetStateForTest() const { return state_; } KeyboardControllerState GetStateForTest() const { return state_; }
ContainerType GetActiveContainerType() const {
return container_behavior_->GetType();
}
const gfx::Rect AdjustSetBoundsRequest( const gfx::Rect AdjustSetBoundsRequest(
const gfx::Rect& display_bounds, const gfx::Rect& display_bounds,
const gfx::Rect& requested_bounds) const; const gfx::Rect& requested_bounds) const;
...@@ -171,6 +176,8 @@ class KEYBOARD_EXPORT KeyboardController : public ui::InputMethodObserver, ...@@ -171,6 +176,8 @@ class KEYBOARD_EXPORT KeyboardController : public ui::InputMethodObserver,
// will trigger a hide animation and a subsequent show animation. Otherwise // will trigger a hide animation and a subsequent show animation. Otherwise
// the ContainerBehavior change is synchronous. // the ContainerBehavior change is synchronous.
void SetContainerType(const ContainerType type); void SetContainerType(const ContainerType type);
void SetContainerType(const ContainerType type,
base::OnceCallback<void(bool)> callback);
// Sets floating keyboard drggable rect. // Sets floating keyboard drggable rect.
bool SetDraggableArea(const gfx::Rect& rect); bool SetDraggableArea(const gfx::Rect& rect);
...@@ -252,6 +259,8 @@ class KEYBOARD_EXPORT KeyboardController : public ui::InputMethodObserver, ...@@ -252,6 +259,8 @@ class KEYBOARD_EXPORT KeyboardController : public ui::InputMethodObserver,
// Current active visual behavior for the keyboard container. // Current active visual behavior for the keyboard container.
std::unique_ptr<ContainerBehavior> container_behavior_; std::unique_ptr<ContainerBehavior> container_behavior_;
std::unique_ptr<QueuedContainerType> queued_container_type_;
// If true, show the keyboard window when keyboard UI content updates. // If true, show the keyboard window when keyboard UI content updates.
bool show_on_content_update_; bool show_on_content_update_;
...@@ -268,8 +277,6 @@ class KEYBOARD_EXPORT KeyboardController : public ui::InputMethodObserver, ...@@ -268,8 +277,6 @@ class KEYBOARD_EXPORT KeyboardController : public ui::InputMethodObserver,
KeyboardControllerState state_; KeyboardControllerState state_;
ContainerType enqueued_container_type_;
NotificationManager notification_manager_; NotificationManager notification_manager_;
static KeyboardController* instance_; static KeyboardController* instance_;
......
...@@ -176,6 +176,32 @@ class TestKeyboardLayoutDelegate : public KeyboardLayoutDelegate { ...@@ -176,6 +176,32 @@ class TestKeyboardLayoutDelegate : public KeyboardLayoutDelegate {
DISALLOW_COPY_AND_ASSIGN(TestKeyboardLayoutDelegate); DISALLOW_COPY_AND_ASSIGN(TestKeyboardLayoutDelegate);
}; };
class SetModeCallbackInvocationCounter {
public:
SetModeCallbackInvocationCounter() : weak_factory_invoke_(this) {}
void Invoke(bool status) {
if (status)
invocation_count_success_++;
else
invocation_count_failure_++;
}
base::OnceCallback<void(bool)> GetInvocationCallback() {
return base::BindOnce(&SetModeCallbackInvocationCounter::Invoke,
weak_factory_invoke_.GetWeakPtr());
}
int invocation_count_for_status(bool status) {
return status ? invocation_count_success_ : invocation_count_failure_;
}
private:
int invocation_count_success_ = 0;
int invocation_count_failure_ = 0;
base::WeakPtrFactory<SetModeCallbackInvocationCounter> weak_factory_invoke_;
};
} // namespace } // namespace
class KeyboardControllerTest : public testing::Test, class KeyboardControllerTest : public testing::Test,
...@@ -655,13 +681,27 @@ TEST_F(KeyboardControllerAnimationTest, ContainerAnimation) { ...@@ -655,13 +681,27 @@ TEST_F(KeyboardControllerAnimationTest, ContainerAnimation) {
EXPECT_EQ(gfx::Rect(), notified_occluding_bounds()); EXPECT_EQ(gfx::Rect(), notified_occluding_bounds());
EXPECT_FALSE(notified_is_available()); EXPECT_FALSE(notified_is_available());
controller()->SetContainerType(ContainerType::FLOATING); SetModeCallbackInvocationCounter invocation_counter;
controller()->SetContainerType(ContainerType::FLOATING,
invocation_counter.GetInvocationCallback());
EXPECT_EQ(0, invocation_counter.invocation_count_for_status(true));
EXPECT_EQ(0, invocation_counter.invocation_count_for_status(false));
ShowKeyboard(); ShowKeyboard();
RunAnimationForLayer(layer); RunAnimationForLayer(layer);
EXPECT_EQ(1, invocation_counter.invocation_count_for_status(true));
EXPECT_EQ(0, invocation_counter.invocation_count_for_status(false));
// Visible bounds and occluding bounds are now different. // Visible bounds and occluding bounds are now different.
EXPECT_EQ(keyboard_container()->bounds(), notified_visible_bounds()); EXPECT_EQ(keyboard_container()->bounds(), notified_visible_bounds());
EXPECT_EQ(gfx::Rect(), notified_occluding_bounds()); EXPECT_EQ(gfx::Rect(), notified_occluding_bounds());
EXPECT_TRUE(notified_is_available()); EXPECT_TRUE(notified_is_available());
// callback should do nothing when container mode is set to the current active
// container type. An unnecessary call gets registered synchronously as a
// failure status to the callback.
controller()->SetContainerType(ContainerType::FLOATING,
invocation_counter.GetInvocationCallback());
EXPECT_EQ(1, invocation_counter.invocation_count_for_status(true));
EXPECT_EQ(1, invocation_counter.invocation_count_for_status(false));
} }
// Show keyboard during keyboard hide animation should abort the hide animation // Show keyboard during keyboard hide animation should abort the hide animation
......
// Copyright 2018 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 "base/bind.h"
#include "ui/keyboard/keyboard_controller.h"
namespace keyboard {
QueuedContainerType::QueuedContainerType(
KeyboardController* controller,
ContainerType container_type,
base::OnceCallback<void(bool success)> callback)
: controller_(controller),
container_type_(container_type),
callback_(std::move(callback)){};
QueuedContainerType::~QueuedContainerType() {
bool change_successful =
controller_->GetActiveContainerType() == container_type_;
std::move(callback_).Run(change_successful);
};
} // namespace keyboard
// Copyright 2018 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.
#ifndef UI_KEYBOARD_QUEUED_CONTAINER_TYPE_H_
#define UI_KEYBOARD_QUEUED_CONTAINER_TYPE_H_
#include "base/bind.h"
#include "ui/keyboard/container_type.h"
namespace keyboard {
class KeyboardController;
// Tracks a queued ContainerType change request. Couples a container type with a
// callback to invoke once the necessary animation and container changes are
// complete.
// The callback will be invoked once this object goes out of scope. Success
// is defined as the KeyboardController's current container behavior matching
// the same container type as the queued container type.
class QueuedContainerType {
public:
QueuedContainerType(KeyboardController* controller,
ContainerType container_type,
base::OnceCallback<void(bool success)> callback);
~QueuedContainerType();
ContainerType container_type() { return container_type_; }
private:
KeyboardController* controller_;
ContainerType container_type_;
base::OnceCallback<void(bool success)> callback_;
};
} // namespace keyboard
#endif // UI_KEYBOARD_QUEUED_CONTAINER_TYPE_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment