Commit bfb8f93b authored by Steven Bennetts's avatar Steven Bennetts Committed by Commit Bot

Add Enable methods to keyboard_controller.mojom (Take 2)

The CL:
* Introduces keyboard.mojom.KeyboardEnableState, an enum used to track
  the various states that control whether the virtual keyboard should
  be enabled. Some states enable the keyboard, others disable it.
* Moves ownership of the states and the state machine to determine when
  the keyboard should be enabled to KeyboardController.
* Adds mojo interfaces to set and clear states, get the current enabled
  state, and explicitly reload the keyboard.

Note: All mojo API calls to change an enable state will also enable or
disable the keyboard accordingly. This is consistent with existing
logic where these calls are made so should not change any behavior.

Note: Not all calls to keyboard_util.cc helpers have been replaced,
including a few in src/chrome, only places where no additional
re-factoring is required were changed.

Bug: 843332
Change-Id: Ic1741188e2e1ccafda4ad95a71063462ac7f52ff

From original CL:
TBR=tsepez@chromium.org,shend@chromium.org

Change-Id: Ic1741188e2e1ccafda4ad95a71063462ac7f52ff
Reviewed-on: https://chromium-review.googlesource.com/c/1291350Reviewed-by: default avatarSteven Bennetts <stevenjb@chromium.org>
Reviewed-by: default avatarTom Sepez <tsepez@chromium.org>
Reviewed-by: default avatarJames Cook <jamescook@chromium.org>
Commit-Queue: Steven Bennetts <stevenjb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#601253}
parent bd0e4f14
...@@ -13,10 +13,10 @@ ...@@ -13,10 +13,10 @@
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
#include "ui/keyboard/keyboard_controller.h" #include "ui/keyboard/keyboard_controller.h"
#include "ui/keyboard/keyboard_ui.h" #include "ui/keyboard/keyboard_ui.h"
#include "ui/keyboard/keyboard_util.h"
using keyboard::mojom::KeyboardConfig; using keyboard::mojom::KeyboardConfig;
using keyboard::mojom::KeyboardConfigPtr; using keyboard::mojom::KeyboardConfigPtr;
using keyboard::mojom::KeyboardEnableFlag;
namespace ash { namespace ash {
...@@ -41,7 +41,7 @@ void AshKeyboardController::BindRequest( ...@@ -41,7 +41,7 @@ void AshKeyboardController::BindRequest(
} }
void AshKeyboardController::EnableKeyboard() { void AshKeyboardController::EnableKeyboard() {
if (!keyboard::IsKeyboardEnabled()) if (!keyboard_controller_->IsKeyboardEnableRequested())
return; return;
if (keyboard_controller_->IsEnabled()) { if (keyboard_controller_->IsEnabled()) {
...@@ -103,11 +103,34 @@ void AshKeyboardController::SetKeyboardConfig( ...@@ -103,11 +103,34 @@ void AshKeyboardController::SetKeyboardConfig(
keyboard_controller_->UpdateKeyboardConfig(*keyboard_config); keyboard_controller_->UpdateKeyboardConfig(*keyboard_config);
} }
void AshKeyboardController::IsKeyboardEnabled(
IsKeyboardEnabledCallback callback) {
std::move(callback).Run(keyboard_controller_->IsEnabled());
}
void AshKeyboardController::SetEnableFlag(KeyboardEnableFlag flag) {
bool was_enabled = keyboard_controller_->IsEnabled();
keyboard_controller_->SetEnableFlag(flag);
UpdateEnableFlag(was_enabled);
}
void AshKeyboardController::ClearEnableFlag(KeyboardEnableFlag flag) {
bool was_enabled = keyboard_controller_->IsEnabled();
keyboard_controller_->ClearEnableFlag(flag);
UpdateEnableFlag(was_enabled);
}
void AshKeyboardController::ReloadKeyboard() {
// Test IsKeyboardEnableRequested in case of an unlikely edge case where this
// is called while after the enable state changed to disabled (in which case
// we do not want to override the requested state).
if (keyboard_controller_->IsKeyboardEnableRequested())
EnableKeyboard();
}
void AshKeyboardController::OnSessionStateChanged( void AshKeyboardController::OnSessionStateChanged(
session_manager::SessionState state) { session_manager::SessionState state) {
// NOTE: keyboard::IsKeyboardEnabled() is false in mash, but may not be in if (!keyboard_controller_->IsKeyboardEnableRequested())
// unit tests. crbug.com/646565.
if (!keyboard::IsKeyboardEnabled())
return; return;
switch (state) { switch (state) {
...@@ -136,6 +159,15 @@ void AshKeyboardController::ActivateKeyboard() { ...@@ -136,6 +159,15 @@ void AshKeyboardController::ActivateKeyboard() {
keyboard_controller_.get()); keyboard_controller_.get());
} }
void AshKeyboardController::UpdateEnableFlag(bool was_enabled) {
bool is_enabled = keyboard_controller_->IsKeyboardEnableRequested();
if (is_enabled && !was_enabled) {
EnableKeyboard();
} else if (!is_enabled && was_enabled) {
DisableKeyboard();
}
}
void AshKeyboardController::OnKeyboardConfigChanged() { void AshKeyboardController::OnKeyboardConfigChanged() {
KeyboardConfigPtr config = KeyboardConfigPtr config =
KeyboardConfig::New(keyboard_controller_->keyboard_config()); KeyboardConfig::New(keyboard_controller_->keyboard_config());
......
...@@ -57,11 +57,15 @@ class ASH_EXPORT AshKeyboardController ...@@ -57,11 +57,15 @@ class ASH_EXPORT AshKeyboardController
void DestroyVirtualKeyboard(); void DestroyVirtualKeyboard();
// mojom::KeyboardController: // mojom::KeyboardController:
void AddObserver(
mojom::KeyboardControllerObserverAssociatedPtrInfo observer) override;
void GetKeyboardConfig(GetKeyboardConfigCallback callback) override; void GetKeyboardConfig(GetKeyboardConfigCallback callback) override;
void SetKeyboardConfig( void SetKeyboardConfig(
keyboard::mojom::KeyboardConfigPtr keyboard_config) override; keyboard::mojom::KeyboardConfigPtr keyboard_config) override;
void IsKeyboardEnabled(IsKeyboardEnabledCallback callback) override;
void SetEnableFlag(keyboard::mojom::KeyboardEnableFlag flag) override;
void ClearEnableFlag(keyboard::mojom::KeyboardEnableFlag flag) override;
void ReloadKeyboard() override;
void AddObserver(
mojom::KeyboardControllerObserverAssociatedPtrInfo observer) override;
// SessionObserver: // SessionObserver:
void OnSessionStateChanged(session_manager::SessionState state) override; void OnSessionStateChanged(session_manager::SessionState state) override;
...@@ -78,6 +82,10 @@ class ASH_EXPORT AshKeyboardController ...@@ -78,6 +82,10 @@ class ASH_EXPORT AshKeyboardController
// Ensures that the keyboard controller is activated for the primary window. // Ensures that the keyboard controller is activated for the primary window.
void ActivateKeyboard(); void ActivateKeyboard();
// Called whenever the enable flags may have changed the enabled state from
// |was_enabled|. If changed, enables or disables the keyboard.
void UpdateEnableFlag(bool was_enabled);
// keyboard::KeyboardControllerObserver // keyboard::KeyboardControllerObserver
void OnKeyboardConfigChanged() override; void OnKeyboardConfigChanged() override;
void OnKeyboardVisibilityStateChanged(bool is_visible) override; void OnKeyboardVisibilityStateChanged(bool is_visible) override;
......
...@@ -6,17 +6,18 @@ ...@@ -6,17 +6,18 @@
#include <memory> #include <memory>
#include "ash/public/interfaces/keyboard_controller.mojom.h" #include "ash/public/interfaces/keyboard_controller.mojom.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/test/scoped_task_environment.h" #include "base/test/scoped_task_environment.h"
#include "mojo/public/cpp/bindings/associated_binding.h" #include "mojo/public/cpp/bindings/associated_binding.h"
#include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/connector.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "ui/keyboard/keyboard_controller.h" #include "ui/keyboard/keyboard_controller.h"
#include "ui/keyboard/keyboard_ui.h"
#include "ui/keyboard/test/keyboard_test_util.h"
using keyboard::mojom::KeyboardConfig; using keyboard::mojom::KeyboardConfig;
using keyboard::mojom::KeyboardConfigPtr; using keyboard::mojom::KeyboardConfigPtr;
using keyboard::mojom::KeyboardEnableFlag;
namespace ash { namespace ash {
...@@ -32,22 +33,23 @@ class TestObserver : public mojom::KeyboardControllerObserver { ...@@ -32,22 +33,23 @@ class TestObserver : public mojom::KeyboardControllerObserver {
~TestObserver() override = default; ~TestObserver() override = default;
// mojom::KeyboardControllerObserver: // mojom::KeyboardControllerObserver:
void OnKeyboardEnabledChanged(bool enabled) override {} void OnKeyboardEnabledChanged(bool enabled) override {
if (!enabled)
++destroyed_count_;
}
void OnKeyboardVisibilityChanged(bool visible) override {} void OnKeyboardVisibilityChanged(bool visible) override {}
void OnKeyboardVisibleBoundsChanged(const gfx::Rect& bounds) override {} void OnKeyboardVisibleBoundsChanged(const gfx::Rect& bounds) override {}
void OnKeyboardConfigChanged(KeyboardConfigPtr config) override { void OnKeyboardConfigChanged(KeyboardConfigPtr config) override {
config_ = *config; config_ = *config;
} }
const KeyboardConfig& config() const { return config_; } KeyboardConfig config_;
void set_config(const KeyboardConfig& config) { config_ = config; } int destroyed_count_ = 0;
private: private:
mojo::AssociatedBinding<ash::mojom::KeyboardControllerObserver> mojo::AssociatedBinding<ash::mojom::KeyboardControllerObserver>
keyboard_controller_observer_binding_{this}; keyboard_controller_observer_binding_{this};
KeyboardConfig config_;
DISALLOW_COPY_AND_ASSIGN(TestObserver); DISALLOW_COPY_AND_ASSIGN(TestObserver);
}; };
...@@ -59,6 +61,15 @@ class TestClient { ...@@ -59,6 +61,15 @@ class TestClient {
test_observer_ = std::make_unique<TestObserver>(keyboard_controller_.get()); test_observer_ = std::make_unique<TestObserver>(keyboard_controller_.get());
} }
~TestClient() = default;
bool GetIsEnabled() {
keyboard_controller_->IsKeyboardEnabled(base::BindOnce(
&TestClient::OnIsKeyboardEnabled, base::Unretained(this)));
keyboard_controller_.FlushForTesting();
return is_enabled_;
}
void GetKeyboardConfig() { void GetKeyboardConfig() {
keyboard_controller_->GetKeyboardConfig(base::BindOnce( keyboard_controller_->GetKeyboardConfig(base::BindOnce(
&TestClient::OnGetKeyboardConfig, base::Unretained(this))); &TestClient::OnGetKeyboardConfig, base::Unretained(this)));
...@@ -70,11 +81,30 @@ class TestClient { ...@@ -70,11 +81,30 @@ class TestClient {
keyboard_controller_.FlushForTesting(); keyboard_controller_.FlushForTesting();
} }
int got_keyboard_config_count() const { return got_keyboard_config_count_; } void SetEnableFlag(KeyboardEnableFlag flag) {
const KeyboardConfig& keyboard_config() const { return keyboard_config_; } keyboard_controller_->SetEnableFlag(flag);
keyboard_controller_.FlushForTesting();
}
void ClearEnableFlag(KeyboardEnableFlag flag) {
keyboard_controller_->ClearEnableFlag(flag);
keyboard_controller_.FlushForTesting();
}
void ReloadKeyboard() {
keyboard_controller_->ReloadKeyboard();
keyboard_controller_.FlushForTesting();
}
TestObserver* test_observer() const { return test_observer_.get(); } TestObserver* test_observer() const { return test_observer_.get(); }
bool is_enabled_ = false;
int got_keyboard_config_count_ = 0;
KeyboardConfig keyboard_config_;
private: private:
void OnIsKeyboardEnabled(bool enabled) { is_enabled_ = enabled; }
void OnGetKeyboardConfig(KeyboardConfigPtr config) { void OnGetKeyboardConfig(KeyboardConfigPtr config) {
++got_keyboard_config_count_; ++got_keyboard_config_count_;
keyboard_config_ = *config; keyboard_config_ = *config;
...@@ -82,27 +112,15 @@ class TestClient { ...@@ -82,27 +112,15 @@ class TestClient {
mojom::KeyboardControllerPtr keyboard_controller_; mojom::KeyboardControllerPtr keyboard_controller_;
std::unique_ptr<TestObserver> test_observer_; std::unique_ptr<TestObserver> test_observer_;
int got_keyboard_config_count_ = 0;
KeyboardConfig keyboard_config_;
}; };
class AshKeyboardControllerTest : public testing::Test { class AshKeyboardControllerTest : public AshTestBase {
public: public:
AshKeyboardControllerTest() AshKeyboardControllerTest() = default;
: scoped_task_environment_(
base::test::ScopedTaskEnvironment::MainThreadType::DEFAULT,
base::test::ScopedTaskEnvironment::ExecutionMode::QUEUED) {}
~AshKeyboardControllerTest() override = default; ~AshKeyboardControllerTest() override = default;
void SetUp() override { void SetUp() override {
ash_keyboard_controller_ = std::make_unique<AshKeyboardController>( AshTestBase::SetUp();
nullptr /* session_controller */);
// Call SetupUI() so that observer methods get called.
auto test_ui =
std::make_unique<keyboard::TestKeyboardUI>(nullptr /* input_method */);
ash_keyboard_controller_->keyboard_controller()->EnableKeyboard(
std::move(test_ui), nullptr /* delegate */);
// Create a local service manager connector to handle requests to // Create a local service manager connector to handle requests to
// mojom::KeyboardController. // mojom::KeyboardController.
...@@ -118,29 +136,28 @@ class AshKeyboardControllerTest : public testing::Test { ...@@ -118,29 +136,28 @@ class AshKeyboardControllerTest : public testing::Test {
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
test_client_ = std::make_unique<TestClient>(connector_.get()); test_client_ = std::make_unique<TestClient>(connector_.get());
// Set the initial observer config to the client (default) config.
test_client_->test_observer()->config_ = test_client()->keyboard_config_;
} }
void TearDown() override { void TearDown() override {
test_client_.reset(); test_client_.reset();
keyboard_controller()->DisableKeyboard(); AshTestBase::TearDown();
ash_keyboard_controller_.reset();
} }
void AddKeyboardControllerBinding(mojo::ScopedMessagePipeHandle handle) { void AddKeyboardControllerBinding(mojo::ScopedMessagePipeHandle handle) {
ash_keyboard_controller_->BindRequest( Shell::Get()->ash_keyboard_controller()->BindRequest(
mojom::KeyboardControllerRequest(std::move(handle))); mojom::KeyboardControllerRequest(std::move(handle)));
} }
keyboard::KeyboardController* keyboard_controller() { keyboard::KeyboardController* keyboard_controller() {
return ash_keyboard_controller_->keyboard_controller(); return Shell::Get()->ash_keyboard_controller()->keyboard_controller();
} }
TestClient* test_client() { return test_client_.get(); } TestClient* test_client() { return test_client_.get(); }
private: private:
base::test::ScopedTaskEnvironment scoped_task_environment_;
std::unique_ptr<service_manager::Connector> connector_; std::unique_ptr<service_manager::Connector> connector_;
std::unique_ptr<AshKeyboardController> ash_keyboard_controller_;
std::unique_ptr<TestClient> test_client_; std::unique_ptr<TestClient> test_client_;
DISALLOW_COPY_AND_ASSIGN(AshKeyboardControllerTest); DISALLOW_COPY_AND_ASSIGN(AshKeyboardControllerTest);
...@@ -150,27 +167,67 @@ class AshKeyboardControllerTest : public testing::Test { ...@@ -150,27 +167,67 @@ class AshKeyboardControllerTest : public testing::Test {
TEST_F(AshKeyboardControllerTest, GetKeyboardConfig) { TEST_F(AshKeyboardControllerTest, GetKeyboardConfig) {
test_client()->GetKeyboardConfig(); test_client()->GetKeyboardConfig();
EXPECT_EQ(1, test_client()->got_keyboard_config_count()); EXPECT_EQ(1, test_client()->got_keyboard_config_count_);
} }
TEST_F(AshKeyboardControllerTest, SetKeyboardConfig) { TEST_F(AshKeyboardControllerTest, SetKeyboardConfig) {
// Enable the keyboard so that config changes trigger observer events.
test_client()->SetEnableFlag(KeyboardEnableFlag::kExtensionEnabled);
test_client()->GetKeyboardConfig(); test_client()->GetKeyboardConfig();
EXPECT_EQ(1, test_client()->got_keyboard_config_count()); EXPECT_EQ(1, test_client()->got_keyboard_config_count_);
KeyboardConfigPtr config = KeyboardConfigPtr config =
KeyboardConfig::New(test_client()->keyboard_config()); KeyboardConfig::New(test_client()->keyboard_config_);
// Set the observer config to the client (default) config. // Set the observer config to the client (default) config.
test_client()->test_observer()->set_config(*config); test_client()->test_observer()->config_ = *config;
// Test that the config changes. // Change the keyboard config.
bool old_auto_complete = config->auto_complete; bool old_auto_complete = config->auto_complete;
config->auto_complete = !config->auto_complete; config->auto_complete = !config->auto_complete;
test_client()->SetKeyboardConfig(std::move(config)); test_client()->SetKeyboardConfig(std::move(config));
// Test that the config changes.
test_client()->GetKeyboardConfig(); test_client()->GetKeyboardConfig();
EXPECT_NE(old_auto_complete, test_client()->keyboard_config().auto_complete); EXPECT_NE(old_auto_complete, test_client()->keyboard_config_.auto_complete);
// Test that the test observer received the change. // Test that the test observer received the change.
EXPECT_NE(old_auto_complete, EXPECT_NE(old_auto_complete,
test_client()->test_observer()->config().auto_complete); test_client()->test_observer()->config_.auto_complete);
}
TEST_F(AshKeyboardControllerTest, Enabled) {
EXPECT_FALSE(test_client()->GetIsEnabled());
// Enable the keyboard.
test_client()->SetEnableFlag(KeyboardEnableFlag::kExtensionEnabled);
EXPECT_TRUE(test_client()->GetIsEnabled());
// Set the enable override to disable the keyboard.
test_client()->SetEnableFlag(KeyboardEnableFlag::kPolicyDisabled);
EXPECT_FALSE(test_client()->GetIsEnabled());
// Clear the enable override; should enable the keyboard.
test_client()->ClearEnableFlag(KeyboardEnableFlag::kPolicyDisabled);
EXPECT_TRUE(test_client()->GetIsEnabled());
}
TEST_F(AshKeyboardControllerTest, ReloadKeyboard) {
EXPECT_EQ(0, test_client()->test_observer()->destroyed_count_);
// Enable the keyboard.
test_client()->SetEnableFlag(KeyboardEnableFlag::kExtensionEnabled);
EXPECT_EQ(0, test_client()->test_observer()->destroyed_count_);
// Enable the keyboard again; this should not reload the keyboard.
test_client()->SetEnableFlag(KeyboardEnableFlag::kExtensionEnabled);
EXPECT_EQ(0, test_client()->test_observer()->destroyed_count_);
// Reload the keyboard. This should destroy the previous keyboard window.
test_client()->ReloadKeyboard();
EXPECT_EQ(1, test_client()->test_observer()->destroyed_count_);
// Disable the keyboard. The keyboard window should be destroyed.
test_client()->ClearEnableFlag(KeyboardEnableFlag::kExtensionEnabled);
EXPECT_EQ(2, test_client()->test_observer()->destroyed_count_);
} }
} // namespace ash } // namespace ash
...@@ -6,11 +6,13 @@ module ash.mojom; ...@@ -6,11 +6,13 @@ module ash.mojom;
import "ui/gfx/geometry/mojo/geometry.mojom"; import "ui/gfx/geometry/mojo/geometry.mojom";
import "ui/keyboard/public/keyboard_config.mojom"; import "ui/keyboard/public/keyboard_config.mojom";
import "ui/keyboard/public/keyboard_enable_flag.mojom";
interface KeyboardControllerObserver { interface KeyboardControllerObserver {
// Called when the keyboard is enabled or disabled. If the keyboard is enabled // Called when the keyboard is enabled or disabled. If ReloadKeyboard() is
// while already enabled, this will be called twice, once when the keyboard is // called or other code enables the keyboard while already enabled, this will
// disabled and again when it is re-enabled. // be called twice, once when the keyboard is disabled and again when it is
// re-enabled.
OnKeyboardEnabledChanged(bool is_enabled); OnKeyboardEnabledChanged(bool is_enabled);
// Called when the virtual keyboard configuration changes. // Called when the virtual keyboard configuration changes.
...@@ -31,6 +33,20 @@ interface KeyboardController { ...@@ -31,6 +33,20 @@ interface KeyboardController {
// Sets the current keyboard configuration. // Sets the current keyboard configuration.
SetKeyboardConfig(keyboard.mojom.KeyboardConfig config); SetKeyboardConfig(keyboard.mojom.KeyboardConfig config);
// Returns whether the virtual keyboard has been enabled.
IsKeyboardEnabled() => (bool enabled);
// Sets the provided keyboard enable flag. If the computed enabled state
// changes, enables or disables the keyboard to match the new state.
SetEnableFlag(keyboard.mojom.KeyboardEnableFlag flag);
// Clears the privided keyboard enable flag. If the computed enabled state
// changes, enables or disables the keyboard to match the new state.
ClearEnableFlag(keyboard.mojom.KeyboardEnableFlag flag);
// Reloads the virtual keyboard if it is enabled.
ReloadKeyboard();
// Adds a KeyboardControllerObserver. // Adds a KeyboardControllerObserver.
AddObserver(associated KeyboardControllerObserver observer); AddObserver(associated KeyboardControllerObserver observer);
}; };
specific_include_rules = { specific_include_rules = {
# TODO(mash): Fix this. https://crbug.com/890677 # TODO(mash): Remove. http://crbug.com/890677
"arc_input_method_manager_service\.cc": [ "arc_input_method_manager_service_unittest\.cc": [
"+ash/keyboard/ash_keyboard_controller.h",
"+ash/shell.h", "+ash/shell.h",
], ],
} }
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <algorithm> #include <algorithm>
#include <utility> #include <utility>
#include "ash/shell.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/singleton.h" #include "base/memory/singleton.h"
#include "base/stl_util.h" #include "base/stl_util.h"
...@@ -16,6 +15,7 @@ ...@@ -16,6 +15,7 @@
#include "chrome/browser/chromeos/arc/arc_util.h" #include "chrome/browser/chromeos/arc/arc_util.h"
#include "chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_bridge_impl.h" #include "chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_bridge_impl.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/ash/chrome_keyboard_controller_client.h"
#include "chrome/browser/ui/ash/tablet_mode_client.h" #include "chrome/browser/ui/ash/tablet_mode_client.h"
#include "chrome/browser/ui/ash/tablet_mode_client_observer.h" #include "chrome/browser/ui/ash/tablet_mode_client_observer.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#include "ui/base/ime/chromeos/input_method_util.h" #include "ui/base/ime/chromeos/input_method_util.h"
#include "ui/base/ime/ime_bridge.h" #include "ui/base/ime/ime_bridge.h"
#include "ui/base/ime/input_method_observer.h" #include "ui/base/ime/input_method_observer.h"
#include "ui/keyboard/keyboard_util.h"
namespace arc { namespace arc {
...@@ -70,6 +69,16 @@ void SwitchImeToCallback(const std::string& ime_id, ...@@ -70,6 +69,16 @@ void SwitchImeToCallback(const std::string& ime_id,
NOTREACHED() << "There is no enabled non-ARC IME."; NOTREACHED() << "There is no enabled non-ARC IME.";
} }
void SetKeyboardDisabled(bool disabled) {
if (disabled) {
ChromeKeyboardControllerClient::Get()->SetEnableFlag(
keyboard::mojom::KeyboardEnableFlag::kAndroidDisabled);
} else {
ChromeKeyboardControllerClient::Get()->ClearEnableFlag(
keyboard::mojom::KeyboardEnableFlag::kAndroidDisabled);
}
}
// Singleton factory for ArcInputMethodManagerService // Singleton factory for ArcInputMethodManagerService
class ArcInputMethodManagerServiceFactory class ArcInputMethodManagerServiceFactory
: public internal::ArcBrowserContextKeyedServiceFactoryBase< : public internal::ArcBrowserContextKeyedServiceFactoryBase<
...@@ -408,24 +417,13 @@ void ArcInputMethodManagerService::InputMethodChanged( ...@@ -408,24 +417,13 @@ void ArcInputMethodManagerService::InputMethodChanged(
return; return;
SwitchImeTo(state->GetCurrentInputMethod().id()); SwitchImeTo(state->GetCurrentInputMethod().id());
// ash::Shell is not created in the unit tests.
if (!ash::Shell::HasInstance())
return;
const bool was_enabled = keyboard::IsKeyboardEnabled();
if (chromeos::extension_ime_util::IsArcIME( if (chromeos::extension_ime_util::IsArcIME(
state->GetCurrentInputMethod().id())) { state->GetCurrentInputMethod().id())) {
// Disable fallback virtual keyboard while Android IME is activated. // Disable fallback virtual keyboard while Android IME is activated.
keyboard::SetKeyboardShowOverride( SetKeyboardDisabled(true);
keyboard::KEYBOARD_SHOW_OVERRIDE_DISABLED);
if (was_enabled)
ash::Shell::Get()->DisableKeyboard();
} else { } else {
// Stop overriding virtual keyboard availability. // Stop overriding virtual keyboard availability.
keyboard::SetKeyboardShowOverride(keyboard::KEYBOARD_SHOW_OVERRIDE_NONE); SetKeyboardDisabled(false);
// If the device is still in tablet mode, virtual keyboard may be enabled.
const bool is_enabled = keyboard::IsKeyboardEnabled();
if (!was_enabled && is_enabled)
ash::Shell::Get()->EnableKeyboard();
} }
} }
......
...@@ -9,13 +9,18 @@ ...@@ -9,13 +9,18 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "ash/keyboard/ash_keyboard_controller.h"
#include "ash/public/interfaces/constants.mojom.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h" #include "ash/test/ash_test_base.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/scoped_refptr.h" #include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h" #include "base/test/scoped_feature_list.h"
#include "chrome/browser/ui/ash/chrome_keyboard_controller_client.h"
#include "chrome/browser/ui/ash/tablet_mode_client.h" #include "chrome/browser/ui/ash/tablet_mode_client.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile.h"
...@@ -24,6 +29,8 @@ ...@@ -24,6 +29,8 @@
#include "components/arc/test/test_browser_context.h" #include "components/arc/test/test_browser_context.h"
#include "components/crx_file/id_util.h" #include "components/crx_file/id_util.h"
#include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_service_manager_context.h"
#include "services/service_manager/public/cpp/connector.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/ime/chromeos/extension_ime_util.h" #include "ui/base/ime/chromeos/extension_ime_util.h"
#include "ui/base/ime/chromeos/mock_input_method_manager.h" #include "ui/base/ime/chromeos/mock_input_method_manager.h"
...@@ -31,8 +38,6 @@ ...@@ -31,8 +38,6 @@
#include "ui/base/ime/ime_bridge.h" #include "ui/base/ime/ime_bridge.h"
#include "ui/base/ime/mock_ime_input_context_handler.h" #include "ui/base/ime/mock_ime_input_context_handler.h"
#include "ui/base/ime/mock_input_method.h" #include "ui/base/ime/mock_input_method.h"
#include "ui/keyboard/keyboard_controller.h"
#include "ui/keyboard/keyboard_util.h"
namespace arc { namespace arc {
namespace { namespace {
...@@ -249,8 +254,25 @@ class ArcInputMethodManagerServiceTest : public ash::AshTestBase { ...@@ -249,8 +254,25 @@ class ArcInputMethodManagerServiceTest : public ash::AshTestBase {
input_method_manager_ = new TestInputMethodManager(); input_method_manager_ = new TestInputMethodManager();
chromeos::input_method::InputMethodManager::Initialize( chromeos::input_method::InputMethodManager::Initialize(
input_method_manager_); input_method_manager_);
tablet_mode_client_ = std::make_unique<TabletModeClient>();
profile_ = std::make_unique<TestingProfile>(); profile_ = std::make_unique<TestingProfile>();
tablet_mode_client_ = std::make_unique<TabletModeClient>();
// Create a local service manager connector to handle requests to
// ash::mojom::CrosDisplayConfigController.
service_manager::mojom::ConnectorRequest request;
connector_ = service_manager::Connector::Create(&request);
service_manager::Connector::TestApi test_api(connector_.get());
test_api.OverrideBinderForTesting(
service_manager::Identity(ash::mojom::kServiceName),
ash::mojom::KeyboardController::Name_,
base::BindRepeating(
&ArcInputMethodManagerServiceTest::AddKeyboardControllerBinding,
base::Unretained(this)));
// Provide the local connector to ChromeKeyboardControllerClient.
chrome_keyboard_controller_client_ =
std::make_unique<ChromeKeyboardControllerClient>(connector_.get());
chrome_keyboard_controller_client_->set_profile_for_test(profile_.get());
service_ = ArcInputMethodManagerService::GetForBrowserContextForTesting( service_ = ArcInputMethodManagerService::GetForBrowserContextForTesting(
profile_.get()); profile_.get());
test_bridge_ = new TestInputMethodManagerBridge(); test_bridge_ = new TestInputMethodManagerBridge();
...@@ -258,10 +280,17 @@ class ArcInputMethodManagerServiceTest : public ash::AshTestBase { ...@@ -258,10 +280,17 @@ class ArcInputMethodManagerServiceTest : public ash::AshTestBase {
base::WrapUnique(test_bridge_)); base::WrapUnique(test_bridge_));
} }
void AddKeyboardControllerBinding(mojo::ScopedMessagePipeHandle handle) {
ash::Shell::Get()->ash_keyboard_controller()->BindRequest(
ash::mojom::KeyboardControllerRequest(std::move(handle)));
}
void TearDown() override { void TearDown() override {
test_bridge_ = nullptr; test_bridge_ = nullptr;
service_->Shutdown(); service_->Shutdown();
profile_.reset(nullptr); profile_.reset(nullptr);
chrome_keyboard_controller_client_.reset();
connector_.reset();
tablet_mode_client_.reset(nullptr); tablet_mode_client_.reset(nullptr);
chromeos::input_method::InputMethodManager::Shutdown(); chromeos::input_method::InputMethodManager::Shutdown();
ui::IMEBridge::Shutdown(); ui::IMEBridge::Shutdown();
...@@ -269,12 +298,15 @@ class ArcInputMethodManagerServiceTest : public ash::AshTestBase { ...@@ -269,12 +298,15 @@ class ArcInputMethodManagerServiceTest : public ash::AshTestBase {
} }
private: private:
content::TestServiceManagerContext service_manager_context_;
std::unique_ptr<service_manager::Connector> connector_;
std::unique_ptr<ArcServiceManager> arc_service_manager_; std::unique_ptr<ArcServiceManager> arc_service_manager_;
std::unique_ptr<TestingProfile> profile_; std::unique_ptr<TestingProfile> profile_;
std::unique_ptr<TabletModeClient> tablet_mode_client_; std::unique_ptr<TabletModeClient> tablet_mode_client_;
std::unique_ptr<ChromeKeyboardControllerClient>
chrome_keyboard_controller_client_;
TestInputMethodManager* input_method_manager_ = nullptr; TestInputMethodManager* input_method_manager_ = nullptr;
TestInputMethodManagerBridge* test_bridge_ = nullptr; // Owned by |service_| TestInputMethodManagerBridge* test_bridge_ = nullptr; // Owned by |service_|
ArcInputMethodManagerService* service_ = nullptr; ArcInputMethodManagerService* service_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(ArcInputMethodManagerServiceTest); DISALLOW_COPY_AND_ASSIGN(ArcInputMethodManagerServiceTest);
...@@ -856,19 +888,25 @@ TEST_F(ArcInputMethodManagerServiceTest, DisableFallbackVirtualKeyboard) { ...@@ -856,19 +888,25 @@ TEST_F(ArcInputMethodManagerServiceTest, DisableFallbackVirtualKeyboard) {
service()->InputMethodChanged(imm(), profile(), false /* show_message */); service()->InputMethodChanged(imm(), profile(), false /* show_message */);
// Enable Chrome OS virtual keyboard // Enable Chrome OS virtual keyboard
keyboard::SetTouchKeyboardEnabled(true); auto* client = ChromeKeyboardControllerClient::Get();
keyboard::SetKeyboardShowOverride(keyboard::KEYBOARD_SHOW_OVERRIDE_NONE); client->ClearEnableFlag(
ASSERT_TRUE(keyboard::IsKeyboardEnabled()); keyboard::mojom::KeyboardEnableFlag::kAndroidDisabled);
client->SetEnableFlag(keyboard::mojom::KeyboardEnableFlag::kTouchEnabled);
client->FlushForTesting();
base::RunLoop().RunUntilIdle(); // Allow observers to fire and process.
ASSERT_TRUE(client->is_keyboard_enabled());
// It's disabled when the ARC IME is activated. // It's disabled when the ARC IME is activated.
imm()->state()->SetActiveInputMethod(arc_ime_id); imm()->state()->SetActiveInputMethod(arc_ime_id);
service()->InputMethodChanged(imm(), profile(), false); service()->InputMethodChanged(imm(), profile(), false);
EXPECT_FALSE(keyboard::IsKeyboardEnabled()); client->FlushForTesting();
EXPECT_FALSE(client->is_keyboard_enabled());
// It's re-enabled when the ARC IME is deactivated. // It's re-enabled when the ARC IME is deactivated.
imm()->state()->SetActiveInputMethod(component_extension_ime_id); imm()->state()->SetActiveInputMethod(component_extension_ime_id);
service()->InputMethodChanged(imm(), profile(), false); service()->InputMethodChanged(imm(), profile(), false);
EXPECT_TRUE(keyboard::IsKeyboardEnabled()); client->FlushForTesting();
EXPECT_TRUE(client->is_keyboard_enabled());
} }
TEST_F(ArcInputMethodManagerServiceTest, ShowVirtualKeyboard) { TEST_F(ArcInputMethodManagerServiceTest, ShowVirtualKeyboard) {
......
...@@ -758,7 +758,8 @@ void ChromeBrowserMainPartsChromeos::PreProfileInit() { ...@@ -758,7 +758,8 @@ void ChromeBrowserMainPartsChromeos::PreProfileInit() {
// loading the default profile). // loading the default profile).
keyboard::InitializeKeyboardResources(); keyboard::InitializeKeyboardResources();
chrome_keyboard_controller_client_ = chrome_keyboard_controller_client_ =
std::make_unique<ChromeKeyboardControllerClient>(); std::make_unique<ChromeKeyboardControllerClient>(
content::ServiceManagerConnection::GetForProcess()->GetConnector());
if (lock_screen_apps::StateController::IsEnabled()) { if (lock_screen_apps::StateController::IsEnabled()) {
lock_screen_apps_state_controller_ = lock_screen_apps_state_controller_ =
......
...@@ -8,10 +8,6 @@ include_rules = [ ...@@ -8,10 +8,6 @@ include_rules = [
] ]
specific_include_rules = { specific_include_rules = {
# TODO(mash): Fix. https://crbug.com/648733
"app_launch_controller\.cc": [
"+ash/shell.h",
],
"login_browsertest\.cc": [ "login_browsertest\.cc": [
"+ash/system/status_area_widget.h", "+ash/system/status_area_widget.h",
"+ash/system/unified/unified_system_tray.h", "+ash/system/unified/unified_system_tray.h",
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
#include "chrome/browser/chromeos/login/app_launch_controller.h" #include "chrome/browser/chromeos/login/app_launch_controller.h"
#include "ash/public/cpp/ash_features.h" #include "ash/public/cpp/ash_features.h"
#include "ash/shell.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
...@@ -31,6 +30,7 @@ ...@@ -31,6 +30,7 @@
#include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/ash/chrome_keyboard_controller_client.h"
#include "chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.h"
#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
#include "chromeos/settings/cros_settings_names.h" #include "chromeos/settings/cros_settings_names.h"
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
#include "extensions/common/features/feature_session_type.h" #include "extensions/common/features/feature_session_type.h"
#include "net/base/network_change_notifier.h" #include "net/base/network_change_notifier.h"
#include "ui/base/ui_base_features.h" #include "ui/base/ui_base_features.h"
#include "ui/keyboard/keyboard_util.h"
namespace chromeos { namespace chromeos {
...@@ -321,13 +320,7 @@ void AppLaunchController::OnProfileLoaded(Profile* profile) { ...@@ -321,13 +320,7 @@ void AppLaunchController::OnProfileLoaded(Profile* profile) {
profile_->InitChromeOSPreferences(); profile_->InitChromeOSPreferences();
// Reset virtual keyboard to use IME engines in app profile early. // Reset virtual keyboard to use IME engines in app profile early.
if (!features::IsUsingWindowService()) { ChromeKeyboardControllerClient::Get()->ReloadKeyboard();
if (keyboard::IsKeyboardEnabled())
ash::Shell::Get()->EnableKeyboard();
} else {
// TODO(xiyuan): Update with mash VK work http://crbug.com/648733
NOTIMPLEMENTED();
}
kiosk_profile_loader_.reset(); kiosk_profile_loader_.reset();
startup_app_launcher_.reset( startup_app_launcher_.reset(
......
...@@ -55,20 +55,6 @@ std::string GenerateFeatureFlag(const std::string& feature, bool enabled) { ...@@ -55,20 +55,6 @@ std::string GenerateFeatureFlag(const std::string& feature, bool enabled) {
return feature + (enabled ? "-enabled" : "-disabled"); return feature + (enabled ? "-enabled" : "-disabled");
} }
keyboard::KeyboardState getKeyboardStateEnum(
keyboard_api::KeyboardState state) {
switch (state) {
case keyboard_api::KEYBOARD_STATE_ENABLED:
return keyboard::KEYBOARD_STATE_ENABLED;
case keyboard_api::KEYBOARD_STATE_DISABLED:
return keyboard::KEYBOARD_STATE_DISABLED;
case keyboard_api::KEYBOARD_STATE_AUTO:
case keyboard_api::KEYBOARD_STATE_NONE:
return keyboard::KEYBOARD_STATE_AUTO;
}
return keyboard::KEYBOARD_STATE_AUTO;
}
} // namespace } // namespace
namespace extensions { namespace extensions {
...@@ -132,8 +118,7 @@ void ChromeVirtualKeyboardDelegate::SetHotrodKeyboard(bool enable) { ...@@ -132,8 +118,7 @@ void ChromeVirtualKeyboardDelegate::SetHotrodKeyboard(bool enable) {
// This reloads virtual keyboard even if it exists. This ensures virtual // This reloads virtual keyboard even if it exists. This ensures virtual
// keyboard gets the correct state of the hotrod keyboard through // keyboard gets the correct state of the hotrod keyboard through
// chrome.virtualKeyboardPrivate.getKeyboardConfig. // chrome.virtualKeyboardPrivate.getKeyboardConfig.
if (keyboard::IsKeyboardEnabled()) ChromeKeyboardControllerClient::Get()->ReloadKeyboard();
ash::Shell::Get()->EnableKeyboard();
} }
bool ChromeVirtualKeyboardDelegate::LockKeyboard(bool state) { bool ChromeVirtualKeyboardDelegate::LockKeyboard(bool state) {
...@@ -235,17 +220,23 @@ bool ChromeVirtualKeyboardDelegate::SetDraggableArea( ...@@ -235,17 +220,23 @@ bool ChromeVirtualKeyboardDelegate::SetDraggableArea(
} }
bool ChromeVirtualKeyboardDelegate::SetRequestedKeyboardState(int state_enum) { bool ChromeVirtualKeyboardDelegate::SetRequestedKeyboardState(int state_enum) {
keyboard::KeyboardState keyboard_state = getKeyboardStateEnum( using keyboard::mojom::KeyboardEnableFlag;
static_cast<keyboard_api::KeyboardState>(state_enum)); auto* client = ChromeKeyboardControllerClient::Get();
bool was_enabled = keyboard::IsKeyboardEnabled(); keyboard_api::KeyboardState state =
keyboard::SetRequestedKeyboardState(keyboard_state); static_cast<keyboard_api::KeyboardState>(state_enum);
bool is_enabled = keyboard::IsKeyboardEnabled(); switch (state) {
if (was_enabled == is_enabled) case keyboard_api::KEYBOARD_STATE_ENABLED:
return true; client->SetEnableFlag(KeyboardEnableFlag::kExtensionEnabled);
if (is_enabled) break;
ash::Shell::Get()->EnableKeyboard(); case keyboard_api::KEYBOARD_STATE_DISABLED:
else client->SetEnableFlag(KeyboardEnableFlag::kExtensionDisabled);
ash::Shell::Get()->DisableKeyboard(); break;
case keyboard_api::KEYBOARD_STATE_AUTO:
case keyboard_api::KEYBOARD_STATE_NONE:
client->ClearEnableFlag(KeyboardEnableFlag::kExtensionDisabled);
client->ClearEnableFlag(KeyboardEnableFlag::kExtensionEnabled);
break;
}
return true; return true;
} }
...@@ -385,8 +376,7 @@ ChromeVirtualKeyboardDelegate::RestrictFeatures( ...@@ -385,8 +376,7 @@ ChromeVirtualKeyboardDelegate::RestrictFeatures(
// keyboard gets the correct state through // keyboard gets the correct state through
// chrome.virtualKeyboardPrivate.getKeyboardConfig. // chrome.virtualKeyboardPrivate.getKeyboardConfig.
// TODO(oka): Extension should reload on it's own by receiving event // TODO(oka): Extension should reload on it's own by receiving event
if (keyboard::IsKeyboardEnabled()) ChromeKeyboardControllerClient::Get()->ReloadKeyboard();
ash::Shell::Get()->EnableKeyboard();
} }
return update; return update;
} }
......
...@@ -8,9 +8,8 @@ ...@@ -8,9 +8,8 @@
#include "ash/public/interfaces/constants.mojom.h" #include "ash/public/interfaces/constants.mojom.h"
#include "base/values.h" #include "base/values.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_manager.h"
#include "content/public/browser/browser_context.h"
#include "content/public/common/service_manager_connection.h"
#include "extensions/browser/api/virtual_keyboard_private/virtual_keyboard_delegate.h" #include "extensions/browser/api/virtual_keyboard_private/virtual_keyboard_delegate.h"
#include "extensions/browser/api/virtual_keyboard_private/virtual_keyboard_private_api.h" #include "extensions/browser/api/virtual_keyboard_private/virtual_keyboard_private_api.h"
#include "extensions/browser/event_router.h" #include "extensions/browser/event_router.h"
...@@ -27,13 +26,6 @@ namespace { ...@@ -27,13 +26,6 @@ namespace {
static ChromeKeyboardControllerClient* g_chrome_keyboard_controller_client = static ChromeKeyboardControllerClient* g_chrome_keyboard_controller_client =
nullptr; nullptr;
Profile* GetProfile() {
// Always use the active profile for generating keyboard events so that any
// virtual keyboard extensions associated with the active user are notified.
// (Note: UI and associated extensions only exist for the active user).
return ProfileManager::GetActiveUserProfile();
}
} // namespace } // namespace
// static // static
...@@ -43,13 +35,17 @@ ChromeKeyboardControllerClient* ChromeKeyboardControllerClient::Get() { ...@@ -43,13 +35,17 @@ ChromeKeyboardControllerClient* ChromeKeyboardControllerClient::Get() {
return g_chrome_keyboard_controller_client; return g_chrome_keyboard_controller_client;
} }
ChromeKeyboardControllerClient::ChromeKeyboardControllerClient() { // static
bool ChromeKeyboardControllerClient::HasInstance() {
return !!g_chrome_keyboard_controller_client;
}
ChromeKeyboardControllerClient::ChromeKeyboardControllerClient(
service_manager::Connector* connector) {
CHECK(!g_chrome_keyboard_controller_client); CHECK(!g_chrome_keyboard_controller_client);
g_chrome_keyboard_controller_client = this; g_chrome_keyboard_controller_client = this;
content::ServiceManagerConnection::GetForProcess() connector->BindInterface(ash::mojom::kServiceName, &keyboard_controller_ptr_);
->GetConnector()
->BindInterface(ash::mojom::kServiceName, &keyboard_controller_ptr_);
// Request the configuration. This will be queued until the service is ready. // Request the configuration. This will be queued until the service is ready.
keyboard_controller_ptr_->GetKeyboardConfig(base::BindOnce( keyboard_controller_ptr_->GetKeyboardConfig(base::BindOnce(
...@@ -87,6 +83,24 @@ void ChromeKeyboardControllerClient::SetKeyboardConfig( ...@@ -87,6 +83,24 @@ void ChromeKeyboardControllerClient::SetKeyboardConfig(
keyboard_controller_ptr_->SetKeyboardConfig(cached_keyboard_config_.Clone()); keyboard_controller_ptr_->SetKeyboardConfig(cached_keyboard_config_.Clone());
} }
void ChromeKeyboardControllerClient::SetEnableFlag(
const keyboard::mojom::KeyboardEnableFlag& flag) {
keyboard_controller_ptr_->SetEnableFlag(flag);
}
void ChromeKeyboardControllerClient::ClearEnableFlag(
const keyboard::mojom::KeyboardEnableFlag& flag) {
keyboard_controller_ptr_->ClearEnableFlag(flag);
}
void ChromeKeyboardControllerClient::ReloadKeyboard() {
keyboard_controller_ptr_->ReloadKeyboard();
}
void ChromeKeyboardControllerClient::FlushForTesting() {
keyboard_controller_ptr_.FlushForTesting();
}
void ChromeKeyboardControllerClient::OnGetInitialKeyboardConfig( void ChromeKeyboardControllerClient::OnGetInitialKeyboardConfig(
keyboard::mojom::KeyboardConfigPtr config) { keyboard::mojom::KeyboardConfigPtr config) {
// Only set the cached value if not already set by SetKeyboardConfig (the // Only set the cached value if not already set by SetKeyboardConfig (the
...@@ -98,19 +112,26 @@ void ChromeKeyboardControllerClient::OnGetInitialKeyboardConfig( ...@@ -98,19 +112,26 @@ void ChromeKeyboardControllerClient::OnGetInitialKeyboardConfig(
ash::mojom::KeyboardControllerObserverAssociatedPtrInfo ptr_info; ash::mojom::KeyboardControllerObserverAssociatedPtrInfo ptr_info;
keyboard_controller_observer_binding_.Bind(mojo::MakeRequest(&ptr_info)); keyboard_controller_observer_binding_.Bind(mojo::MakeRequest(&ptr_info));
keyboard_controller_ptr_->AddObserver(std::move(ptr_info)); keyboard_controller_ptr_->AddObserver(std::move(ptr_info));
// Request the initial enabled state.
keyboard_controller_ptr_->IsKeyboardEnabled(
base::BindOnce(&ChromeKeyboardControllerClient::OnKeyboardEnabledChanged,
weak_ptr_factory_.GetWeakPtr()));
} }
void ChromeKeyboardControllerClient::OnKeyboardEnabledChanged(bool enabled) { void ChromeKeyboardControllerClient::OnKeyboardEnabledChanged(bool enabled) {
if (enabled) bool was_enabled = is_keyboard_enabled_;
is_keyboard_enabled_ = enabled;
if (enabled || !was_enabled)
return; return;
// When the keyboard becomes disabled, send the onKeyboardClosed event. // When the keyboard becomes disabled, send the onKeyboardClosed event.
Profile* profile = GetProfile(); Profile* profile = GetProfile();
extensions::EventRouter* router = extensions::EventRouter::Get(profile); extensions::EventRouter* router = extensions::EventRouter::Get(profile);
// |router| may be null in tests.
if (!router->HasEventListener( if (!router || !router->HasEventListener(
virtual_keyboard_private::OnKeyboardClosed::kEventName)) { virtual_keyboard_private::OnKeyboardClosed::kEventName)) {
return; return;
} }
...@@ -139,9 +160,9 @@ void ChromeKeyboardControllerClient::OnKeyboardVisibleBoundsChanged( ...@@ -139,9 +160,9 @@ void ChromeKeyboardControllerClient::OnKeyboardVisibleBoundsChanged(
const gfx::Rect& bounds) { const gfx::Rect& bounds) {
Profile* profile = GetProfile(); Profile* profile = GetProfile();
extensions::EventRouter* router = extensions::EventRouter::Get(profile); extensions::EventRouter* router = extensions::EventRouter::Get(profile);
// |router| may be null in tests.
if (!router->HasEventListener( if (!router || !router->HasEventListener(
virtual_keyboard_private::OnBoundsChanged::kEventName)) { virtual_keyboard_private::OnBoundsChanged::kEventName)) {
return; return;
} }
...@@ -159,3 +180,13 @@ void ChromeKeyboardControllerClient::OnKeyboardVisibleBoundsChanged( ...@@ -159,3 +180,13 @@ void ChromeKeyboardControllerClient::OnKeyboardVisibleBoundsChanged(
std::move(event_args), profile); std::move(event_args), profile);
router->BroadcastEvent(std::move(event)); router->BroadcastEvent(std::move(event));
} }
Profile* ChromeKeyboardControllerClient::GetProfile() {
if (profile_for_test_)
return profile_for_test_;
// Always use the active profile for generating keyboard events so that any
// virtual keyboard extensions associated with the active user are notified.
// (Note: UI and associated extensions only exist for the active user).
return ProfileManager::GetActiveUserProfile();
}
...@@ -12,6 +12,12 @@ ...@@ -12,6 +12,12 @@
#include "base/observer_list_types.h" #include "base/observer_list_types.h"
#include "mojo/public/cpp/bindings/associated_binding.h" #include "mojo/public/cpp/bindings/associated_binding.h"
class Profile;
namespace service_manager {
class Connector;
}
// This class implements mojom::KeyboardControllerObserver and makes calls // This class implements mojom::KeyboardControllerObserver and makes calls
// into the mojom::KeyboardController service. // into the mojom::KeyboardController service.
class ChromeKeyboardControllerClient class ChromeKeyboardControllerClient
...@@ -29,12 +35,16 @@ class ChromeKeyboardControllerClient ...@@ -29,12 +35,16 @@ class ChromeKeyboardControllerClient
}; };
// This class uses a static getter and only supports a single instance. // This class uses a static getter and only supports a single instance.
ChromeKeyboardControllerClient(); explicit ChromeKeyboardControllerClient(
service_manager::Connector* connector);
~ChromeKeyboardControllerClient() override; ~ChromeKeyboardControllerClient() override;
// Static getter. The single instance must be instantiated first. // Static getter. The single instance must be instantiated first.
static ChromeKeyboardControllerClient* Get(); static ChromeKeyboardControllerClient* Get();
// Used in tests to determine whether this has been instantiated.
static bool HasInstance();
void AddObserver(Observer* observer); void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer); void RemoveObserver(Observer* observer);
...@@ -44,6 +54,19 @@ class ChromeKeyboardControllerClient ...@@ -44,6 +54,19 @@ class ChromeKeyboardControllerClient
// Sets the new keyboard configuration and updates the cached config. // Sets the new keyboard configuration and updates the cached config.
void SetKeyboardConfig(const keyboard::mojom::KeyboardConfig& config); void SetKeyboardConfig(const keyboard::mojom::KeyboardConfig& config);
// Sets/clears the privided keyboard enable state.
void SetEnableFlag(const keyboard::mojom::KeyboardEnableFlag& state);
void ClearEnableFlag(const keyboard::mojom::KeyboardEnableFlag& state);
// Reloads the virtual keyboard if enabled.
void ReloadKeyboard();
void FlushForTesting();
bool is_keyboard_enabled() { return is_keyboard_enabled_; }
void set_profile_for_test(Profile* profile) { profile_for_test_ = profile; }
private: private:
void OnGetInitialKeyboardConfig(keyboard::mojom::KeyboardConfigPtr config); void OnGetInitialKeyboardConfig(keyboard::mojom::KeyboardConfigPtr config);
...@@ -54,6 +77,9 @@ class ChromeKeyboardControllerClient ...@@ -54,6 +77,9 @@ class ChromeKeyboardControllerClient
void OnKeyboardVisibilityChanged(bool visible) override; void OnKeyboardVisibilityChanged(bool visible) override;
void OnKeyboardVisibleBoundsChanged(const gfx::Rect& bounds) override; void OnKeyboardVisibleBoundsChanged(const gfx::Rect& bounds) override;
// Returns either the test profile or the active user profile.
Profile* GetProfile();
ash::mojom::KeyboardControllerPtr keyboard_controller_ptr_; ash::mojom::KeyboardControllerPtr keyboard_controller_ptr_;
mojo::AssociatedBinding<ash::mojom::KeyboardControllerObserver> mojo::AssociatedBinding<ash::mojom::KeyboardControllerObserver>
keyboard_controller_observer_binding_{this}; keyboard_controller_observer_binding_{this};
...@@ -61,8 +87,13 @@ class ChromeKeyboardControllerClient ...@@ -61,8 +87,13 @@ class ChromeKeyboardControllerClient
// Cached copy of the latest config provided by mojom::KeyboardController. // Cached copy of the latest config provided by mojom::KeyboardController.
keyboard::mojom::KeyboardConfigPtr cached_keyboard_config_; keyboard::mojom::KeyboardConfigPtr cached_keyboard_config_;
// Tracks the enabled state of the keyboard.
bool is_keyboard_enabled_ = false;
base::ObserverList<Observer> observers_; base::ObserverList<Observer> observers_;
Profile* profile_for_test_ = nullptr;
base::WeakPtrFactory<ChromeKeyboardControllerClient> weak_ptr_factory_{this}; base::WeakPtrFactory<ChromeKeyboardControllerClient> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(ChromeKeyboardControllerClient); DISALLOW_COPY_AND_ASSIGN(ChromeKeyboardControllerClient);
......
...@@ -38,7 +38,6 @@ ...@@ -38,7 +38,6 @@
#include "ui/keyboard/keyboard_controller.h" #include "ui/keyboard/keyboard_controller.h"
#include "ui/keyboard/keyboard_resource_util.h" #include "ui/keyboard/keyboard_resource_util.h"
#include "ui/keyboard/keyboard_switches.h" #include "ui/keyboard/keyboard_switches.h"
#include "ui/keyboard/keyboard_util.h"
#include "ui/wm/core/shadow_types.h" #include "ui/wm/core/shadow_types.h"
namespace { namespace {
......
...@@ -7,10 +7,6 @@ specific_include_rules = { ...@@ -7,10 +7,6 @@ specific_include_rules = {
"arc_app_window_launcher_controller\.cc": [ "arc_app_window_launcher_controller\.cc": [
"+ash/shell.h", "+ash/shell.h",
], ],
# TODO(mash): Fix. https://crbug.com/826391
"chrome_launcher_controller\.cc": [
"+ash/shell.h",
],
# https://crbug.com/887156 # https://crbug.com/887156
"crostini_app_window_shelf_controller\.cc": [ "crostini_app_window_shelf_controller\.cc": [
"+ash/shell.h", "+ash/shell.h",
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#include "ash/public/cpp/shelf_prefs.h" #include "ash/public/cpp/shelf_prefs.h"
#include "ash/public/cpp/window_animation_types.h" #include "ash/public/cpp/window_animation_types.h"
#include "ash/public/interfaces/constants.mojom.h" #include "ash/public/interfaces/constants.mojom.h"
#include "ash/shell.h"
#include "base/strings/pattern.h" #include "base/strings/pattern.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
...@@ -35,6 +34,7 @@ ...@@ -35,6 +34,7 @@
#include "chrome/browser/ui/app_list/crostini/crostini_app_icon_loader.h" #include "chrome/browser/ui/app_list/crostini/crostini_app_icon_loader.h"
#include "chrome/browser/ui/app_list/internal_app/internal_app_icon_loader.h" #include "chrome/browser/ui/app_list/internal_app/internal_app_icon_loader.h"
#include "chrome/browser/ui/app_list/md_icon_normalizer.h" #include "chrome/browser/ui/app_list/md_icon_normalizer.h"
#include "chrome/browser/ui/ash/chrome_keyboard_controller_client.h"
#include "chrome/browser/ui/ash/chrome_launcher_prefs.h" #include "chrome/browser/ui/ash/chrome_launcher_prefs.h"
#include "chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.h" #include "chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.h"
#include "chrome/browser/ui/ash/launcher/app_window_launcher_controller.h" #include "chrome/browser/ui/ash/launcher/app_window_launcher_controller.h"
...@@ -82,7 +82,6 @@ ...@@ -82,7 +82,6 @@
#include "ui/base/resource/resource_bundle.h" #include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_features.h" #include "ui/base/ui_base_features.h"
#include "ui/display/types/display_constants.h" #include "ui/display/types/display_constants.h"
#include "ui/keyboard/keyboard_util.h"
#include "ui/resources/grit/ui_resources.h" #include "ui/resources/grit/ui_resources.h"
using extension_misc::kChromeAppId; using extension_misc::kChromeAppId;
...@@ -289,10 +288,7 @@ ChromeLauncherController::~ChromeLauncherController() { ...@@ -289,10 +288,7 @@ ChromeLauncherController::~ChromeLauncherController() {
void ChromeLauncherController::Init() { void ChromeLauncherController::Init() {
CreateBrowserShortcutLauncherItem(); CreateBrowserShortcutLauncherItem();
UpdateAppLaunchersFromPref(); UpdateAppLaunchersFromPref();
SetVirtualKeyboardBehaviorFromPrefs();
// TODO(sky): update unit test so that this test isn't necessary.
if (ash::Shell::HasInstance())
SetVirtualKeyboardBehaviorFromPrefs();
} }
ash::ShelfID ChromeLauncherController::CreateAppLauncherItem( ash::ShelfID ChromeLauncherController::CreateAppLauncherItem(
...@@ -996,24 +992,20 @@ void ChromeLauncherController::UpdatePolicyPinnedAppsFromPrefs() { ...@@ -996,24 +992,20 @@ void ChromeLauncherController::UpdatePolicyPinnedAppsFromPrefs() {
} }
void ChromeLauncherController::SetVirtualKeyboardBehaviorFromPrefs() { void ChromeLauncherController::SetVirtualKeyboardBehaviorFromPrefs() {
using keyboard::mojom::KeyboardEnableFlag;
if (!ChromeKeyboardControllerClient::HasInstance()) // May be null in tests
return;
auto* client = ChromeKeyboardControllerClient::Get();
const PrefService* service = profile()->GetPrefs(); const PrefService* service = profile()->GetPrefs();
const bool was_enabled = keyboard::IsKeyboardEnabled(); if (service->HasPrefPath(prefs::kTouchVirtualKeyboardEnabled)) {
if (!service->HasPrefPath(prefs::kTouchVirtualKeyboardEnabled)) { // Since these flags are mutually exclusive, setting one clears the other.
keyboard::SetKeyboardShowOverride(keyboard::KEYBOARD_SHOW_OVERRIDE_NONE); client->SetEnableFlag(
service->GetBoolean(prefs::kTouchVirtualKeyboardEnabled)
? KeyboardEnableFlag::kPolicyEnabled
: KeyboardEnableFlag::kPolicyDisabled);
} else { } else {
const bool enable = client->ClearEnableFlag(KeyboardEnableFlag::kPolicyDisabled);
service->GetBoolean(prefs::kTouchVirtualKeyboardEnabled); client->ClearEnableFlag(KeyboardEnableFlag::kPolicyEnabled);
keyboard::SetKeyboardShowOverride(
enable ? keyboard::KEYBOARD_SHOW_OVERRIDE_ENABLED
: keyboard::KEYBOARD_SHOW_OVERRIDE_DISABLED);
}
// TODO(crbug.com/557406): Fix this interaction pattern in Mash.
if (!features::IsMultiProcessMash()) {
const bool is_enabled = keyboard::IsKeyboardEnabled();
if (was_enabled && !is_enabled)
ash::Shell::Get()->DisableKeyboard();
else if (is_enabled && !was_enabled)
ash::Shell::Get()->EnableKeyboard();
} }
} }
......
# These tests fail. https://crbug.com/646565 # These tests fail. https://crbug.com/646565
-AppListPresenterDelegateTest.TapAppListWithVirtualKeyboardDismissesVirtualKeyboard/0 -AppListPresenterDelegateTest.TapAppListWithVirtualKeyboardDismissesVirtualKeyboard/0
-AppListPresenterDelegateTest.TapAppListWithVirtualKeyboardDismissesVirtualKeyboard/1 -AppListPresenterDelegateTest.TapAppListWithVirtualKeyboardDismissesVirtualKeyboard/1
-AshKeyboardControllerTest.*
-LockActionHandlerLayoutManagerTest.KeyboardBounds -LockActionHandlerLayoutManagerTest.KeyboardBounds
-PipPositionerTest.* -PipPositionerTest.*
-PipWindowResizerTest.* -PipWindowResizerTest.*
......
...@@ -139,6 +139,7 @@ build_closure("inputview") { ...@@ -139,6 +139,7 @@ build_closure("inputview") {
mojom("mojom") { mojom("mojom") {
sources = [ sources = [
"public/keyboard_config.mojom", "public/keyboard_config.mojom",
"public/keyboard_enable_flag.mojom",
] ]
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "ui/aura/client/aura_constants.h" #include "ui/aura/client/aura_constants.h"
...@@ -402,6 +403,68 @@ bool KeyboardController::UpdateKeyboardConfig( ...@@ -402,6 +403,68 @@ bool KeyboardController::UpdateKeyboardConfig(
return true; return true;
} }
void KeyboardController::SetEnableFlag(mojom::KeyboardEnableFlag flag) {
if (!base::ContainsKey(keyboard_enable_flags_, flag))
keyboard_enable_flags_.insert(flag);
// If there is a flag that is mutually exclusive with |flag|, clear it.
using mojom::KeyboardEnableFlag;
switch (flag) {
case KeyboardEnableFlag::kPolicyEnabled:
keyboard_enable_flags_.erase(KeyboardEnableFlag::kPolicyDisabled);
break;
case KeyboardEnableFlag::kPolicyDisabled:
keyboard_enable_flags_.erase(KeyboardEnableFlag::kPolicyEnabled);
break;
case KeyboardEnableFlag::kExtensionEnabled:
keyboard_enable_flags_.erase(KeyboardEnableFlag::kExtensionDisabled);
break;
case KeyboardEnableFlag::kExtensionDisabled:
keyboard_enable_flags_.erase(KeyboardEnableFlag::kExtensionEnabled);
break;
default:
break;
}
}
void KeyboardController::ClearEnableFlag(mojom::KeyboardEnableFlag flag) {
keyboard_enable_flags_.erase(flag);
}
bool KeyboardController::IsEnableFlagSet(mojom::KeyboardEnableFlag flag) const {
return base::ContainsKey(keyboard_enable_flags_, flag);
}
bool KeyboardController::IsKeyboardEnableRequested() const {
using mojom::KeyboardEnableFlag;
// Accessibility setting prioritized over policy/arc overrides.
if (IsEnableFlagSet(KeyboardEnableFlag::kAccessibilityEnabled))
return true;
// Keyboard can be enabled temporarily by the shelf.
if (IsEnableFlagSet(KeyboardEnableFlag::kShelfEnabled))
return true;
if (IsEnableFlagSet(KeyboardEnableFlag::kAndroidDisabled) ||
IsEnableFlagSet(KeyboardEnableFlag::kPolicyDisabled)) {
return false;
}
if (IsEnableFlagSet(KeyboardEnableFlag::kPolicyEnabled))
return true;
// Command line overrides extension and touch enabled flags.
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableVirtualKeyboard)) {
return true;
}
if (IsEnableFlagSet(KeyboardEnableFlag::kExtensionDisabled))
return false;
return IsEnableFlagSet(KeyboardEnableFlag::kExtensionEnabled) ||
IsEnableFlagSet(KeyboardEnableFlag::kTouchEnabled);
}
bool KeyboardController::IsKeyboardOverscrollEnabled() const { bool KeyboardController::IsKeyboardOverscrollEnabled() const {
if (!keyboard::IsKeyboardEnabled()) if (!keyboard::IsKeyboardEnabled())
return false; return false;
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#define UI_KEYBOARD_KEYBOARD_CONTROLLER_H_ #define UI_KEYBOARD_KEYBOARD_CONTROLLER_H_
#include <memory> #include <memory>
#include <set>
#include <vector>
#include "base/macros.h" #include "base/macros.h"
#include "base/observer_list.h" #include "base/observer_list.h"
...@@ -27,6 +29,7 @@ ...@@ -27,6 +29,7 @@
#include "ui/keyboard/keyboard_ukm_recorder.h" #include "ui/keyboard/keyboard_ukm_recorder.h"
#include "ui/keyboard/notification_manager.h" #include "ui/keyboard/notification_manager.h"
#include "ui/keyboard/public/keyboard_config.mojom.h" #include "ui/keyboard/public/keyboard_config.mojom.h"
#include "ui/keyboard/public/keyboard_enable_flag.mojom.h"
#include "ui/keyboard/queued_container_type.h" #include "ui/keyboard/queued_container_type.h"
#include "ui/keyboard/queued_display_change.h" #include "ui/keyboard/queued_display_change.h"
...@@ -140,10 +143,21 @@ class KEYBOARD_EXPORT KeyboardController ...@@ -140,10 +143,21 @@ class KEYBOARD_EXPORT KeyboardController
bool InsertText(const base::string16& text); bool InsertText(const base::string16& text);
// Updates |keyboard_config_| with |config|. Returns |false| if there is no // Updates |keyboard_config_| with |config|. Returns |false| if there is no
// change, otherwise returns true and notifies observers if this is enabled(). // change, otherwise returns true and notifies observers if this is enabled.
bool UpdateKeyboardConfig(const mojom::KeyboardConfig& config); bool UpdateKeyboardConfig(const mojom::KeyboardConfig& config);
const mojom::KeyboardConfig& keyboard_config() { return keyboard_config_; } const mojom::KeyboardConfig& keyboard_config() { return keyboard_config_; }
// Sets and clears |keyboard_enable_flags_| entries.
void SetEnableFlag(mojom::KeyboardEnableFlag flag);
void ClearEnableFlag(mojom::KeyboardEnableFlag flag);
bool IsEnableFlagSet(mojom::KeyboardEnableFlag flag) const;
// Returns true if the keyboard should be enabled, i.e. the current result
// of Set/ClearEnableFlag should cause the keyboard to be enabled.
// TODO(stevenjb/shend): Consider removing this and have all calls to
// Set/ClearEnableFlag always enable or disable the keyboard directly.
bool IsKeyboardEnableRequested() const;
// Returns true if keyboard overscroll is enabled. // Returns true if keyboard overscroll is enabled.
bool IsKeyboardOverscrollEnabled() const; bool IsKeyboardOverscrollEnabled() const;
...@@ -403,6 +417,10 @@ class KEYBOARD_EXPORT KeyboardController ...@@ -403,6 +417,10 @@ class KEYBOARD_EXPORT KeyboardController
// Keyboard configuration associated with the controller. // Keyboard configuration associated with the controller.
mojom::KeyboardConfig keyboard_config_; mojom::KeyboardConfig keyboard_config_;
// Set of active enabled request flags. Used to determine whether the keyboard
// should be enabled.
std::set<mojom::KeyboardEnableFlag> keyboard_enable_flags_;
NotificationManager notification_manager_; NotificationManager notification_manager_;
base::Time time_of_last_blur_ = base::Time::UnixEpoch(); base::Time time_of_last_blur_ = base::Time::UnixEpoch();
......
...@@ -18,17 +18,17 @@ ...@@ -18,17 +18,17 @@
#include "ui/events/keycodes/dom/dom_key.h" #include "ui/events/keycodes/dom/dom_key.h"
#include "ui/events/keycodes/dom/keycode_converter.h" #include "ui/events/keycodes/dom/keycode_converter.h"
#include "ui/events/keycodes/keyboard_code_conversion.h" #include "ui/events/keycodes/keyboard_code_conversion.h"
#include "ui/keyboard/keyboard_controller.h"
#include "ui/keyboard/keyboard_switches.h" #include "ui/keyboard/keyboard_switches.h"
namespace keyboard { namespace keyboard {
namespace { namespace {
const char kKeyDown[] ="keydown"; const char kKeyDown[] = "keydown";
const char kKeyUp[] = "keyup"; const char kKeyUp[] = "keyup";
void SendProcessKeyEvent(ui::EventType type, void SendProcessKeyEvent(ui::EventType type, aura::WindowTreeHost* host) {
aura::WindowTreeHost* host) {
ui::KeyEvent event(type, ui::VKEY_PROCESSKEY, ui::DomCode::NONE, ui::KeyEvent event(type, ui::VKEY_PROCESSKEY, ui::DomCode::NONE,
ui::EF_IS_SYNTHESIZED, ui::DomKey::PROCESS, ui::EF_IS_SYNTHESIZED, ui::DomKey::PROCESS,
ui::EventTimeForNow()); ui::EventTimeForNow());
...@@ -37,44 +37,51 @@ void SendProcessKeyEvent(ui::EventType type, ...@@ -37,44 +37,51 @@ void SendProcessKeyEvent(ui::EventType type,
CHECK(!details.dispatcher_destroyed); CHECK(!details.dispatcher_destroyed);
} }
bool g_accessibility_keyboard_enabled = false; // Until src/chrome is fully transitioned to use ChromeKeyboardControllerClient
// we need to test whether KeyboardController exists; it is null in OopMash.
// TODO(stevenjb): Remove remaining calls from src/chrome.
// https://crbug.com/84332.
bool g_keyboard_enabled_from_shelf = false; bool GetFlag(mojom::KeyboardEnableFlag flag) {
auto* controller = KeyboardController::Get();
bool g_touch_keyboard_enabled = false; return controller ? controller->IsEnableFlagSet(flag) : false;
}
KeyboardState g_requested_keyboard_state = KEYBOARD_STATE_AUTO;
KeyboardShowOverride g_keyboard_show_override = KEYBOARD_SHOW_OVERRIDE_NONE; void SetOrClearEnableFlag(mojom::KeyboardEnableFlag flag, bool enabled) {
auto* controller = KeyboardController::Get();
if (!controller)
return;
if (enabled)
controller->SetEnableFlag(flag);
else
controller->ClearEnableFlag(flag);
}
} // namespace } // namespace
void SetAccessibilityKeyboardEnabled(bool enabled) { void SetAccessibilityKeyboardEnabled(bool enabled) {
g_accessibility_keyboard_enabled = enabled; SetOrClearEnableFlag(mojom::KeyboardEnableFlag::kAccessibilityEnabled,
enabled);
} }
bool GetAccessibilityKeyboardEnabled() { bool GetAccessibilityKeyboardEnabled() {
return g_accessibility_keyboard_enabled; return GetFlag(mojom::KeyboardEnableFlag::kAccessibilityEnabled);
} }
void SetKeyboardEnabledFromShelf(bool enabled) { void SetKeyboardEnabledFromShelf(bool enabled) {
g_keyboard_enabled_from_shelf = enabled; SetOrClearEnableFlag(mojom::KeyboardEnableFlag::kShelfEnabled, enabled);
} }
bool GetKeyboardEnabledFromShelf() { bool GetKeyboardEnabledFromShelf() {
return g_keyboard_enabled_from_shelf; return GetFlag(mojom::KeyboardEnableFlag::kShelfEnabled);
} }
void SetTouchKeyboardEnabled(bool enabled) { void SetTouchKeyboardEnabled(bool enabled) {
g_touch_keyboard_enabled = enabled; SetOrClearEnableFlag(mojom::KeyboardEnableFlag::kTouchEnabled, enabled);
} }
bool GetTouchKeyboardEnabled() { bool GetTouchKeyboardEnabled() {
return g_touch_keyboard_enabled; return GetFlag(mojom::KeyboardEnableFlag::kTouchEnabled);
}
void SetRequestedKeyboardState(KeyboardState state) {
g_requested_keyboard_state = state;
} }
std::string GetKeyboardLayout() { std::string GetKeyboardLayout() {
...@@ -84,32 +91,7 @@ std::string GetKeyboardLayout() { ...@@ -84,32 +91,7 @@ std::string GetKeyboardLayout() {
} }
bool IsKeyboardEnabled() { bool IsKeyboardEnabled() {
// Accessibility setting prioritized over policy setting. return KeyboardController::Get()->IsKeyboardEnableRequested();
if (g_accessibility_keyboard_enabled)
return true;
// Keyboard can be enabled temporarily by the shelf.
if (g_keyboard_enabled_from_shelf)
return true;
// Policy strictly disables showing a virtual keyboard.
if (g_keyboard_show_override == KEYBOARD_SHOW_OVERRIDE_DISABLED)
return false;
// Policy strictly enables the keyboard.
if (g_keyboard_show_override == KEYBOARD_SHOW_OVERRIDE_ENABLED)
return true;
// Run-time flag to enable keyboard has been included.
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableVirtualKeyboard))
return true;
// Requested state from the application layer.
if (g_requested_keyboard_state == KEYBOARD_STATE_DISABLED)
return false;
// Check if any of the other flags are enabled.
return g_touch_keyboard_enabled ||
g_requested_keyboard_state == KEYBOARD_STATE_ENABLED;
}
void SetKeyboardShowOverride(KeyboardShowOverride show_override) {
g_keyboard_show_override = show_override;
} }
bool SendKeyEvent(const std::string type, bool SendKeyEvent(const std::string type,
...@@ -154,8 +136,8 @@ bool SendKeyEvent(const std::string type, ...@@ -154,8 +136,8 @@ bool SendKeyEvent(const std::string type,
// Log the rough lengths of characters typed between backspaces. This // Log the rough lengths of characters typed between backspaces. This
// metric will be used to determine the error rate for the keyboard. // metric will be used to determine the error rate for the keyboard.
UMA_HISTOGRAM_CUSTOM_COUNTS( UMA_HISTOGRAM_CUSTOM_COUNTS(
"VirtualKeyboard.KeystrokesBetweenBackspaces", "VirtualKeyboard.KeystrokesBetweenBackspaces", keys_seen, 1, 1000,
keys_seen, 1, 1000, 50); 50);
keys_seen = 0; keys_seen = 0;
} else { } else {
++keys_seen; ++keys_seen;
...@@ -166,11 +148,7 @@ bool SendKeyEvent(const std::string type, ...@@ -166,11 +148,7 @@ bool SendKeyEvent(const std::string type,
if (dom_code == ui::DomCode::NONE) if (dom_code == ui::DomCode::NONE)
dom_code = ui::UsLayoutKeyboardCodeToDomCode(code); dom_code = ui::UsLayoutKeyboardCodeToDomCode(code);
CHECK(dom_code != ui::DomCode::NONE); CHECK(dom_code != ui::DomCode::NONE);
ui::KeyEvent event( ui::KeyEvent event(event_type, code, dom_code, modifiers);
event_type,
code,
dom_code,
modifiers);
// Marks the simulated key event is from the Virtual Keyboard. // Marks the simulated key event is from the Virtual Keyboard.
ui::Event::Properties properties; ui::Event::Properties properties;
......
...@@ -20,13 +20,6 @@ class WindowTreeHost; ...@@ -20,13 +20,6 @@ class WindowTreeHost;
namespace keyboard { namespace keyboard {
// An enumeration of keyboard policy settings.
enum KeyboardShowOverride {
KEYBOARD_SHOW_OVERRIDE_DISABLED = 0,
KEYBOARD_SHOW_OVERRIDE_ENABLED,
KEYBOARD_SHOW_OVERRIDE_NONE,
};
// An enumeration of keyboard states. // An enumeration of keyboard states.
enum KeyboardState { enum KeyboardState {
// Default state. System decides whether to show the keyboard or not. // Default state. System decides whether to show the keyboard or not.
...@@ -43,12 +36,6 @@ KEYBOARD_EXPORT void SetAccessibilityKeyboardEnabled(bool enabled); ...@@ -43,12 +36,6 @@ KEYBOARD_EXPORT void SetAccessibilityKeyboardEnabled(bool enabled);
// Gets the state of the a11y onscreen keyboard. // Gets the state of the a11y onscreen keyboard.
KEYBOARD_EXPORT bool GetAccessibilityKeyboardEnabled(); KEYBOARD_EXPORT bool GetAccessibilityKeyboardEnabled();
// Sets the state of the hotrod onscreen keyboard.
KEYBOARD_EXPORT void SetHotrodKeyboardEnabled(bool enabled);
// Gets the state of the hotrod onscreen keyboard.
KEYBOARD_EXPORT bool GetHotrodKeyboardEnabled();
// Sets whether the keyboard is enabled from the shelf. // Sets whether the keyboard is enabled from the shelf.
KEYBOARD_EXPORT void SetKeyboardEnabledFromShelf(bool enabled); KEYBOARD_EXPORT void SetKeyboardEnabledFromShelf(bool enabled);
...@@ -61,29 +48,12 @@ KEYBOARD_EXPORT void SetTouchKeyboardEnabled(bool enabled); ...@@ -61,29 +48,12 @@ KEYBOARD_EXPORT void SetTouchKeyboardEnabled(bool enabled);
// Gets the state of the touch onscreen keyboard. // Gets the state of the touch onscreen keyboard.
KEYBOARD_EXPORT bool GetTouchKeyboardEnabled(); KEYBOARD_EXPORT bool GetTouchKeyboardEnabled();
// Sets the requested state of the keyboard.
KEYBOARD_EXPORT void SetRequestedKeyboardState(KeyboardState state);
// Gets the requested state of the keyboard.
KEYBOARD_EXPORT int GetRequestedKeyboardState();
// Gets the default keyboard layout. // Gets the default keyboard layout.
KEYBOARD_EXPORT std::string GetKeyboardLayout(); KEYBOARD_EXPORT std::string GetKeyboardLayout();
// Returns true if the virtual keyboard is enabled. // Returns true if the virtual keyboard is enabled.
KEYBOARD_EXPORT bool IsKeyboardEnabled(); KEYBOARD_EXPORT bool IsKeyboardEnabled();
// Sets policy override on whether to show the keyboard.
KEYBOARD_EXPORT void SetKeyboardShowOverride(
KeyboardShowOverride show_override);
// Sets whehther the keyboards is in restricted state - state where advanced
// virtual keyboard features are disabled.
KEYBOARD_EXPORT void SetKeyboardRestricted(bool restricted);
// Returns whether the keyboard is in restricted state.
KEYBOARD_EXPORT bool GetKeyboardRestricted();
// Sends a fabricated key event, where |type| is the event type, |key_value| // Sends a fabricated key event, where |type| is the event type, |key_value|
// is the unicode value of the character, |key_code| is the legacy key code // is the unicode value of the character, |key_code| is the legacy key code
// value, |key_name| is the name of the key as defined in the DOM3 key event // value, |key_name| is the name of the key as defined in the DOM3 key event
......
...@@ -22,34 +22,45 @@ class KeyboardUtilTest : public testing::Test { ...@@ -22,34 +22,45 @@ class KeyboardUtilTest : public testing::Test {
// Sets all flags controlling whether the keyboard should be shown to // Sets all flags controlling whether the keyboard should be shown to
// their disabled state. // their disabled state.
void DisableAllFlags() { void DisableAllFlags() {
ResetAllFlags();
keyboard::SetAccessibilityKeyboardEnabled(false); keyboard::SetAccessibilityKeyboardEnabled(false);
keyboard::SetTouchKeyboardEnabled(false); keyboard::SetTouchKeyboardEnabled(false);
keyboard::SetKeyboardShowOverride( SetEnableFlag(mojom::KeyboardEnableFlag::kPolicyDisabled);
keyboard::KEYBOARD_SHOW_OVERRIDE_DISABLED); SetEnableFlag(mojom::KeyboardEnableFlag::kExtensionDisabled);
keyboard::SetRequestedKeyboardState(keyboard::KEYBOARD_STATE_DISABLED);
} }
// Sets all flags controlling whether the keyboard should be shown to // Sets all flags controlling whether the keyboard should be shown to
// their enabled state. // their enabled flag.
void EnableAllFlags() { void EnableAllFlags() {
ResetAllFlags();
keyboard::SetAccessibilityKeyboardEnabled(true); keyboard::SetAccessibilityKeyboardEnabled(true);
keyboard::SetTouchKeyboardEnabled(true); keyboard::SetTouchKeyboardEnabled(true);
keyboard::SetKeyboardShowOverride(keyboard::KEYBOARD_SHOW_OVERRIDE_ENABLED); SetEnableFlag(mojom::KeyboardEnableFlag::kPolicyEnabled);
keyboard::SetRequestedKeyboardState(keyboard::KEYBOARD_STATE_ENABLED); SetEnableFlag(mojom::KeyboardEnableFlag::kExtensionEnabled);
} }
// Sets all flags controlling whether the keyboard should be shown to // Sets all flags controlling whether the keyboard should be shown to
// their neutral state. // their neutral flag.
void ResetAllFlags() { void ResetAllFlags() {
keyboard::SetAccessibilityKeyboardEnabled(false); keyboard::SetAccessibilityKeyboardEnabled(false);
keyboard::SetTouchKeyboardEnabled(false); keyboard::SetTouchKeyboardEnabled(false);
keyboard::SetKeyboardShowOverride(keyboard::KEYBOARD_SHOW_OVERRIDE_NONE); ClearEnableFlag(mojom::KeyboardEnableFlag::kPolicyDisabled);
keyboard::SetRequestedKeyboardState(keyboard::KEYBOARD_STATE_AUTO); ClearEnableFlag(mojom::KeyboardEnableFlag::kExtensionDisabled);
ClearEnableFlag(mojom::KeyboardEnableFlag::kPolicyEnabled);
ClearEnableFlag(mojom::KeyboardEnableFlag::kExtensionEnabled);
} }
void SetUp() override { ResetAllFlags(); } void SetUp() override { ResetAllFlags(); }
protected: protected:
void SetEnableFlag(mojom::KeyboardEnableFlag flag) {
keyboard_controller_.SetEnableFlag(flag);
}
void ClearEnableFlag(mojom::KeyboardEnableFlag flag) {
keyboard_controller_.ClearEnableFlag(flag);
}
// Used indirectly by keyboard utils. // Used indirectly by keyboard utils.
KeyboardController keyboard_controller_; KeyboardController keyboard_controller_;
...@@ -74,7 +85,7 @@ TEST_F(KeyboardUtilTest, AlwaysShowIfPolicyEnabled) { ...@@ -74,7 +85,7 @@ TEST_F(KeyboardUtilTest, AlwaysShowIfPolicyEnabled) {
EXPECT_FALSE(keyboard::IsKeyboardEnabled()); EXPECT_FALSE(keyboard::IsKeyboardEnabled());
// If policy is enabled, should ignore other flag values. // If policy is enabled, should ignore other flag values.
DisableAllFlags(); DisableAllFlags();
keyboard::SetKeyboardShowOverride(keyboard::KEYBOARD_SHOW_OVERRIDE_ENABLED); SetEnableFlag(mojom::KeyboardEnableFlag::kPolicyEnabled);
EXPECT_TRUE(keyboard::IsKeyboardEnabled()); EXPECT_TRUE(keyboard::IsKeyboardEnabled());
} }
...@@ -86,32 +97,32 @@ TEST_F(KeyboardUtilTest, HidesIfPolicyDisabled) { ...@@ -86,32 +97,32 @@ TEST_F(KeyboardUtilTest, HidesIfPolicyDisabled) {
keyboard::SetAccessibilityKeyboardEnabled(false); keyboard::SetAccessibilityKeyboardEnabled(false);
EXPECT_TRUE(keyboard::IsKeyboardEnabled()); EXPECT_TRUE(keyboard::IsKeyboardEnabled());
// Disable policy. Keyboard should be disabled. // Disable policy. Keyboard should be disabled.
keyboard::SetKeyboardShowOverride(keyboard::KEYBOARD_SHOW_OVERRIDE_DISABLED); SetEnableFlag(mojom::KeyboardEnableFlag::kPolicyDisabled);
EXPECT_FALSE(keyboard::IsKeyboardEnabled()); EXPECT_FALSE(keyboard::IsKeyboardEnabled());
} }
// Tests that the keyboard shows when requested state provided higher priority // Tests that the keyboard shows when requested flag provided higher priority
// flags have not been set. // flags have not been set.
TEST_F(KeyboardUtilTest, ShowKeyboardWhenRequested) { TEST_F(KeyboardUtilTest, ShowKeyboardWhenRequested) {
DisableAllFlags(); DisableAllFlags();
// Remove device policy, which has higher precedence than us. // Remove device policy, which has higher precedence than us.
keyboard::SetKeyboardShowOverride(keyboard::KEYBOARD_SHOW_OVERRIDE_NONE); ClearEnableFlag(mojom::KeyboardEnableFlag::kPolicyDisabled);
EXPECT_FALSE(keyboard::IsKeyboardEnabled()); EXPECT_FALSE(keyboard::IsKeyboardEnabled());
// Requested should have higher precedence than all the remaining flags. // Requested should have higher precedence than all the remaining flags.
keyboard::SetRequestedKeyboardState(keyboard::KEYBOARD_STATE_ENABLED); SetEnableFlag(mojom::KeyboardEnableFlag::kExtensionEnabled);
EXPECT_TRUE(keyboard::IsKeyboardEnabled()); EXPECT_TRUE(keyboard::IsKeyboardEnabled());
} }
// Tests that the touch keyboard is hidden when requested state is disabled and // Tests that the touch keyboard is hidden when requested flag is disabled and
// higher priority flags have not been set. // higher priority flags have not been set.
TEST_F(KeyboardUtilTest, HideKeyboardWhenRequested) { TEST_F(KeyboardUtilTest, HideKeyboardWhenRequested) {
EnableAllFlags(); EnableAllFlags();
// Remove higher precedence flags. // Remove higher precedence flags.
keyboard::SetKeyboardShowOverride(keyboard::KEYBOARD_SHOW_OVERRIDE_NONE); ClearEnableFlag(mojom::KeyboardEnableFlag::kPolicyEnabled);
keyboard::SetAccessibilityKeyboardEnabled(false); keyboard::SetAccessibilityKeyboardEnabled(false);
EXPECT_TRUE(keyboard::IsKeyboardEnabled()); EXPECT_TRUE(keyboard::IsKeyboardEnabled());
// Set requested state to disable. Keyboard should disable. // Set requested flag to disable. Keyboard should disable.
keyboard::SetRequestedKeyboardState(keyboard::KEYBOARD_STATE_DISABLED); SetEnableFlag(mojom::KeyboardEnableFlag::kExtensionDisabled);
EXPECT_FALSE(keyboard::IsKeyboardEnabled()); EXPECT_FALSE(keyboard::IsKeyboardEnabled());
} }
...@@ -126,7 +137,7 @@ TEST_F(KeyboardUtilTest, HideKeyboardWhenTouchEnabled) { ...@@ -126,7 +137,7 @@ TEST_F(KeyboardUtilTest, HideKeyboardWhenTouchEnabled) {
TEST_F(KeyboardUtilTest, UpdateKeyboardConfig) { TEST_F(KeyboardUtilTest, UpdateKeyboardConfig) {
ResetAllFlags(); ResetAllFlags();
auto config = keyboard_controller_.keyboard_config(); mojom::KeyboardConfig config = keyboard_controller_.keyboard_config();
EXPECT_TRUE(config.spell_check); EXPECT_TRUE(config.spell_check);
EXPECT_FALSE(keyboard_controller_.UpdateKeyboardConfig(config)); EXPECT_FALSE(keyboard_controller_.UpdateKeyboardConfig(config));
...@@ -147,16 +158,16 @@ TEST_F(KeyboardUtilTest, IsOverscrollEnabled) { ...@@ -147,16 +158,16 @@ TEST_F(KeyboardUtilTest, IsOverscrollEnabled) {
keyboard::SetTouchKeyboardEnabled(true); keyboard::SetTouchKeyboardEnabled(true);
EXPECT_TRUE(keyboard_controller_.IsKeyboardOverscrollEnabled()); EXPECT_TRUE(keyboard_controller_.IsKeyboardOverscrollEnabled());
// Set overscroll enabled state. // Set overscroll enabled flag.
auto config = keyboard::KeyboardController::Get()->keyboard_config(); mojom::KeyboardConfig config = keyboard_controller_.keyboard_config();
config.overscroll_behavior = config.overscroll_behavior =
keyboard::mojom::KeyboardOverscrollBehavior::kDisabled; keyboard::mojom::KeyboardOverscrollBehavior::kDisabled;
keyboard::KeyboardController::Get()->UpdateKeyboardConfig(config); keyboard_controller_.UpdateKeyboardConfig(config);
EXPECT_FALSE(keyboard_controller_.IsKeyboardOverscrollEnabled()); EXPECT_FALSE(keyboard_controller_.IsKeyboardOverscrollEnabled());
config.overscroll_behavior = config.overscroll_behavior =
keyboard::mojom::KeyboardOverscrollBehavior::kDefault; keyboard::mojom::KeyboardOverscrollBehavior::kDefault;
keyboard::KeyboardController::Get()->UpdateKeyboardConfig(config); keyboard_controller_.UpdateKeyboardConfig(config);
EXPECT_TRUE(keyboard_controller_.IsKeyboardOverscrollEnabled()); EXPECT_TRUE(keyboard_controller_.IsKeyboardOverscrollEnabled());
// Set keyboard_locked() to true. // Set keyboard_locked() to true.
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
module keyboard.mojom; module keyboard.mojom;
// Determines how the keyboard overscroll enabled state is set, // Determines how the keyboard overscroll enabled state is set.
enum KeyboardOverscrollBehavior { enum KeyboardOverscrollBehavior {
// Use the default behavior. // Use the default behavior.
kDefault, kDefault,
......
// 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.
module keyboard.mojom;
// Flags that affect whether or not the virtual keyboard should be enabled.
// Enabled/Disabled flag pairs are mutually exclusive, but flags from multiple
// sources may be set. Precedence is determined by the implementation in
// KeyboardController::IsKeyboardEnableRequested.
enum KeyboardEnableFlag {
// Enabled by policy.
kPolicyEnabled,
// Disabled by policy.
kPolicyDisabled,
// Disabled by the Android keyboard.
kAndroidDisabled,
// Enabled by a first-party extension.
kExtensionEnabled,
// Disabled by a first-party extension.
kExtensionDisabled,
// Enabled by an a11y controller.
kAccessibilityEnabled,
// Enabled by the shelf/launcher controller.
kShelfEnabled,
// Enabled by the touch controller.
kTouchEnabled,
};
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