diff --git a/sky/services/keyboard/BUILD.gn b/sky/services/keyboard/BUILD.gn new file mode 100644 index 000000000..c7320c15c --- /dev/null +++ b/sky/services/keyboard/BUILD.gn @@ -0,0 +1,21 @@ +# Copyright 2015 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. + +if (is_ios) { + source_set("keyboard") { + sources = [ + "ios/keyboard_service_impl.h", + "ios/keyboard_service_impl.mm", + ] + deps = [ + "//base:base", + "//mojo/common", + "//mojo/public/cpp/application", + "//mojo/services/keyboard/public/interfaces", + ] + } +} else { + group("keyboard") { + } +} diff --git a/sky/services/keyboard/ios/keyboard_service_impl.h b/sky/services/keyboard/ios/keyboard_service_impl.h new file mode 100644 index 000000000..0c4d300a6 --- /dev/null +++ b/sky/services/keyboard/ios/keyboard_service_impl.h @@ -0,0 +1,52 @@ +// Copyright 2015 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 SKY_SERVICES_KEYBOARD_IOS_KEYBOARD_SERVICE_IMPL_H_ +#define SKY_SERVICES_KEYBOARD_IOS_KEYBOARD_SERVICE_IMPL_H_ + +#include "base/macros.h" +#include "mojo/public/cpp/application/interface_factory.h" +#include "mojo/public/cpp/bindings/strong_binding.h" +#include "mojo/services/keyboard/public/interfaces/keyboard.mojom.h" + +#if __OBJC__ +@class KeyboardClient; +#else // __OBJC__ +class KeyboardClient; +#endif // __OBJC__ + +namespace sky { +namespace services { +namespace keyboard { + +class KeyboardServiceImpl : public ::keyboard::KeyboardService { + public: + explicit KeyboardServiceImpl( + mojo::InterfaceRequest<::keyboard::KeyboardService> request); + virtual ~KeyboardServiceImpl() override; + virtual void Show(::keyboard::KeyboardClientPtr client, + ::keyboard::KeyboardType type) override; + virtual void ShowByRequest() override; + virtual void Hide() override; + + private: + mojo::StrongBinding<::keyboard::KeyboardService> binding_; + KeyboardClient* client_; + + DISALLOW_COPY_AND_ASSIGN(KeyboardServiceImpl); +}; + +class KeyboardServiceFactory + : public mojo::InterfaceFactory<::keyboard::KeyboardService> { + public: + void Create( + mojo::ApplicationConnection* connection, + mojo::InterfaceRequest<::keyboard::KeyboardService> request) override; +}; + +} // namespace keyboard +} // namespace services +} // namespace sky + +#endif /* defined(SKY_SERVICES_KEYBOARD_IOS_KEYBOARD_SERVICE_IMPL_H__) * diff --git a/sky/services/keyboard/ios/keyboard_service_impl.mm b/sky/services/keyboard/ios/keyboard_service_impl.mm new file mode 100644 index 000000000..8af47414b --- /dev/null +++ b/sky/services/keyboard/ios/keyboard_service_impl.mm @@ -0,0 +1,117 @@ +// Copyright 2015 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 "sky/services/keyboard/ios/keyboard_service_impl.h" +#include + +static inline UIKeyboardType ToUIKeyboardType(::keyboard::KeyboardType type) { + switch (type) { + case ::keyboard::KEYBOARD_TYPE_TEXT: + return UIKeyboardTypeDefault; + case ::keyboard::KEYBOARD_TYPE_NUMBER: + return UIKeyboardTypeDecimalPad; + case ::keyboard::KEYBOARD_TYPE_PHONE: + return UIKeyboardTypePhonePad; + default: + break; + } + return UIKeyboardTypeDefault; +} + +@interface KeyboardClient : UIView + +- (void)show:(::keyboard::KeyboardClientPtr)client; +- (void)hide; + +@end + +@implementation KeyboardClient { + ::keyboard::KeyboardClientPtr _client; +} + +@synthesize keyboardType = _keyboardType; + +- (UITextAutocorrectionType)autocorrectionType { + return UITextAutocorrectionTypeNo; +} + +- (void)show:(::keyboard::KeyboardClientPtr)client { + _client = client.Pass(); + + NSAssert([UIApplication sharedApplication].keyWindow != nullptr, + @"The application must have a key window since the keyboard client " + @"must be part of the responder chain to function"); + [[UIApplication sharedApplication].keyWindow addSubview:self]; + [self becomeFirstResponder]; +} + +- (void)hide { + [self resignFirstResponder]; + [self removeFromSuperview]; + _client = nullptr; +} + +#pragma mark - UIResponder Overrides + +- (BOOL)canBecomeFirstResponder { + return YES; +} + +#pragma mark - UIKey Input Overrides + +- (BOOL)hasText { + return YES; +} + +- (void)insertText:(NSString*)text { + if (_client == nullptr) { + return; + } + + _client->CommitText(text.UTF8String, text.length); +} + +- (void)deleteBackward { + if (_client == nullptr) { + return; + } + + _client->DeleteSurroundingText(1, 0); +} + +@end + +namespace sky { +namespace services { +namespace keyboard { + +KeyboardServiceImpl::KeyboardServiceImpl( + mojo::InterfaceRequest<::keyboard::KeyboardService> request) + : binding_(this, request.Pass()), client_([[KeyboardClient alloc] init]) {} + +KeyboardServiceImpl::~KeyboardServiceImpl() { + [client_ release]; +} + +void KeyboardServiceImpl::Show(::keyboard::KeyboardClientPtr client, + ::keyboard::KeyboardType type) { + client_.keyboardType = ToUIKeyboardType(type); + [client_ show:client.Pass()]; +} + +void KeyboardServiceImpl::ShowByRequest() {} + +void KeyboardServiceImpl::Hide() { + [client_ hide]; +} + +void KeyboardServiceFactory::Create( + mojo::ApplicationConnection* connection, + mojo::InterfaceRequest<::keyboard::KeyboardService> request) { + new KeyboardServiceImpl(request.Pass()); +} + +} // namespace keyboard +} // namespace services +} // namespace sky diff --git a/sky/shell/BUILD.gn b/sky/shell/BUILD.gn index a019b4117..1d4cfaac4 100644 --- a/sky/shell/BUILD.gn +++ b/sky/shell/BUILD.gn @@ -199,6 +199,7 @@ if (is_android) { deps = common_deps + [ ":common", "//sky/services/ns_net", + "//sky/services/keyboard", ] } diff --git a/sky/shell/mac/platform_service_provider_mac.cc b/sky/shell/mac/platform_service_provider_mac.cc index c96d6ffc8..6419ba271 100644 --- a/sky/shell/mac/platform_service_provider_mac.cc +++ b/sky/shell/mac/platform_service_provider_mac.cc @@ -10,6 +10,7 @@ #include "mojo/public/interfaces/application/service_provider.mojom.h" #include "sky/engine/wtf/Assertions.h" #include "sky/services/ns_net/network_service_impl.h" +#include "sky/services/keyboard/ios/keyboard_service_impl.h" #include "sky/shell/service_provider.h" #if !TARGET_OS_IPHONE #include "sky/shell/testing/test_runner.h" @@ -21,18 +22,22 @@ namespace shell { class PlatformServiceProvider : public mojo::ServiceProvider { public: PlatformServiceProvider(mojo::InterfaceRequest request) - : binding_(this, request.Pass()) {} + : binding_(this, request.Pass()) {} void ConnectToService(const mojo::String& service_name, mojo::ScopedMessagePipeHandle client_handle) override { if (service_name == mojo::NetworkService::Name_) { - network_.Create(nullptr, - mojo::MakeRequest(client_handle.Pass())); + network_.Create(nullptr, mojo::MakeRequest( + client_handle.Pass())); + } + if (service_name == ::keyboard::KeyboardService::Name_) { + keyboard_.Create(nullptr, mojo::MakeRequest<::keyboard::KeyboardService>( + client_handle.Pass())); } #if !TARGET_OS_IPHONE if (service_name == TestHarness::Name_) { - TestRunner::Shared().Create(nullptr, - mojo::MakeRequest(client_handle.Pass())); + TestRunner::Shared().Create( + nullptr, mojo::MakeRequest(client_handle.Pass())); } #endif } @@ -40,6 +45,7 @@ class PlatformServiceProvider : public mojo::ServiceProvider { private: mojo::StrongBinding binding_; mojo::NetworkServiceFactory network_; + sky::services::keyboard::KeyboardServiceFactory keyboard_; }; static void CreatePlatformServiceProvider(