From 0d446703bf3104653c060db292d498df9f7e490a Mon Sep 17 00:00:00 2001 From: Chinmay Garde Date: Wed, 27 Jan 2016 15:01:53 -0800 Subject: [PATCH] iOS: Implementation of ::activity::Activity from activity.mojom --- build/config/ios/rules.gni | 5 +- sky/build/sdk_xcode_harness/Runner/Info.plist | 2 + sky/build/sky_precompilation_sdk.gni | 5 +- sky/services/activity/BUILD.gn | 4 + sky/services/activity/ios/activity_impl.h | 54 ++++++++++++ sky/services/activity/ios/activity_impl.mm | 83 +++++++++++++++++++ sky/services/activity/ios/path_service_impl.h | 10 +-- .../activity/ios/path_service_impl.mm | 4 +- .../activity/ios/user_feedback_impl.h | 38 +++++++++ .../activity/ios/user_feedback_impl.mm | 38 +++++++++ sky/shell/platform/ios/sky_surface.mm | 10 +++ .../platform/mac/platform_service_provider.cc | 18 ++-- .../platform/mac/platform_service_provider.h | 2 + 13 files changed, 254 insertions(+), 19 deletions(-) create mode 100644 sky/services/activity/ios/activity_impl.h create mode 100644 sky/services/activity/ios/activity_impl.mm create mode 100644 sky/services/activity/ios/user_feedback_impl.h create mode 100644 sky/services/activity/ios/user_feedback_impl.mm diff --git a/build/config/ios/rules.gni b/build/config/ios/rules.gni index 101df2ced20..429c153e35b 100644 --- a/build/config/ios/rules.gni +++ b/build/config/ios/rules.gni @@ -146,10 +146,11 @@ template("ios_app") { executable(bin_gen_target_name) { libs = [ - "UIKit.framework", + "AudioToolbox.framework", "AVFoundation.framework", + "OpenGLES.framework", "QuartzCore.framework", - "OpenGLES.framework" + "UIKit.framework", ] deps = invoker.deps output_name = app_name diff --git a/sky/build/sdk_xcode_harness/Runner/Info.plist b/sky/build/sdk_xcode_harness/Runner/Info.plist index 8dd89947e22..3c5a0699acf 100644 --- a/sky/build/sdk_xcode_harness/Runner/Info.plist +++ b/sky/build/sdk_xcode_harness/Runner/Info.plist @@ -22,6 +22,8 @@ 1 LSRequiresIPhoneOS + UIViewControllerBasedStatusBarAppearance + UILaunchStoryboardName LaunchScreen UIRequiredDeviceCapabilities diff --git a/sky/build/sky_precompilation_sdk.gni b/sky/build/sky_precompilation_sdk.gni index 1e6a913be3e..d2ee596f42f 100644 --- a/sky/build/sky_precompilation_sdk.gni +++ b/sky/build/sky_precompilation_sdk.gni @@ -75,10 +75,11 @@ template("sky_precompilation_sdk") { executable_gen_target_name = target_name + "_runner" executable(executable_gen_target_name) { libs = [ - "UIKit.framework", + "AudioToolbox.framework", "AVFoundation.framework", - "QuartzCore.framework", "OpenGLES.framework", + "QuartzCore.framework", + "UIKit.framework", ] deps = [ "//sky/shell:ios_scaffolding" ] } diff --git a/sky/services/activity/BUILD.gn b/sky/services/activity/BUILD.gn index cc29c499a38..a5cde3b2910 100644 --- a/sky/services/activity/BUILD.gn +++ b/sky/services/activity/BUILD.gn @@ -43,8 +43,12 @@ if (is_android) { if (is_ios) { source_set("activity_lib") { sources = [ + "ios/activity_impl.h", + "ios/activity_impl.mm", "ios/path_service_impl.h", "ios/path_service_impl.mm", + "ios/user_feedback_impl.h", + "ios/user_feedback_impl.mm", ] deps = [ "//base:base", diff --git a/sky/services/activity/ios/activity_impl.h b/sky/services/activity/ios/activity_impl.h new file mode 100644 index 00000000000..c8a4b47844c --- /dev/null +++ b/sky/services/activity/ios/activity_impl.h @@ -0,0 +1,54 @@ +// Copyright 2016 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_ACTIVITY_IOS_ACTIVITY_IMPL_H_ +#define SKY_SERVICES_ACTIVITY_IOS_ACTIVITY_IMPL_H_ + +#include "base/macros.h" +#include "mojo/public/cpp/application/interface_factory.h" +#include "mojo/public/cpp/bindings/strong_binding.h" +#include "sky/services/activity/activity.mojom.h" + +namespace sky { +namespace services { +namespace activity { + +class ActivityImpl : public ::activity::Activity { + public: + explicit ActivityImpl(mojo::InterfaceRequest<::activity::Activity> request); + ~ActivityImpl() override; + + void GetUserFeedback( + mojo::InterfaceRequest<::activity::UserFeedback> user_feedback) override; + + void StartActivity(::activity::IntentPtr intent) override; + + void FinishCurrentActivity() override; + + void SetTaskDescription(::activity::TaskDescriptionPtr description) override; + + void SetSystemUIVisibility( + ::activity::SystemUiVisibility visibility) override; + + void SetRequestedOrientation( + ::activity::ScreenOrientation orientation) override; + + private: + mojo::StrongBinding<::activity::Activity> binding_; + + DISALLOW_COPY_AND_ASSIGN(ActivityImpl); +}; + +class ActivityFactory + : public mojo::InterfaceFactory<::activity::Activity> { + public: + void Create(mojo::ApplicationConnection* connection, + mojo::InterfaceRequest<::activity::Activity> request) override; +}; + +} // namespace activity +} // namespace services +} // namespace sky + +#endif // SKY_SERVICES_ACTIVITY_IOS_ACTIVITY_IMPL_H_ diff --git a/sky/services/activity/ios/activity_impl.mm b/sky/services/activity/ios/activity_impl.mm new file mode 100644 index 00000000000..0e493ad029d --- /dev/null +++ b/sky/services/activity/ios/activity_impl.mm @@ -0,0 +1,83 @@ +// Copyright 2016 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/logging.h" +#include "base/mac/scoped_nsautorelease_pool.h" +#include "sky/services/activity/ios/activity_impl.h" +#include "sky/services/activity/ios/user_feedback_impl.h" + +#include + +namespace sky { +namespace services { +namespace activity { + +ActivityImpl::ActivityImpl(mojo::InterfaceRequest<::activity::Activity> request) + : binding_(this, request.Pass()) {} + +ActivityImpl::~ActivityImpl() {} + +void ActivityImpl::GetUserFeedback( + mojo::InterfaceRequest<::activity::UserFeedback> request) { + new UserFeedbackImpl(request.Pass()); +} + +void ActivityImpl::StartActivity(::activity::IntentPtr intent) { + CHECK(false) << "Cannot start activities on iOS"; +} + +void ActivityImpl::FinishCurrentActivity() { + CHECK(false) << "Cannot finish activities on iOS"; +} + +void ActivityImpl::SetTaskDescription( + ::activity::TaskDescriptionPtr description) { + // No counterpart on iOS but is a benign operation. So no asserts. +} + +void ActivityImpl::SetSystemUIVisibility( + ::activity::SystemUiVisibility visibility) { + using Visibility = ::activity::SystemUiVisibility; + + bool visible = true; + switch (visibility) { + case Visibility::STANDARD: + visible = true; + break; + case Visibility::IMMERSIVE: + // There is no difference between fullscreen and immersive on iOS + case Visibility::FULLSCREEN: + visible = false; + break; + } + + base::mac::ScopedNSAutoreleasePool pool; + + // We opt out of view controller based status bar visibility since we want + // to be able to modify this on the fly. The key used is + // UIViewControllerBasedStatusBarAppearance + [UIApplication sharedApplication].statusBarHidden = !visible; +} + +void ActivityImpl::SetRequestedOrientation( + ::activity::ScreenOrientation orientation) { + base::mac::ScopedNSAutoreleasePool pool; + + // TODO: This needs to be wired up to communicate with the root view + // controller in the embedder. The current implementation is a stopgap + // measure + [[UIDevice currentDevice] + setValue:[NSNumber numberWithInteger:UIInterfaceOrientationPortrait] + forKey:@"orientation"]; +} + +void ActivityFactory::Create( + mojo::ApplicationConnection* connection, + mojo::InterfaceRequest<::activity::Activity> request) { + new ActivityImpl(request.Pass()); +} + +} // namespace activity +} // namespace services +} // namespace sky diff --git a/sky/services/activity/ios/path_service_impl.h b/sky/services/activity/ios/path_service_impl.h index 428b84093ec..3ae30458790 100644 --- a/sky/services/activity/ios/path_service_impl.h +++ b/sky/services/activity/ios/path_service_impl.h @@ -14,10 +14,10 @@ namespace sky { namespace services { namespace path { -class PathServiceImpl : public activity::PathService { +class PathServiceImpl : public ::activity::PathService { public: explicit PathServiceImpl( - mojo::InterfaceRequest request); + mojo::InterfaceRequest<::activity::PathService> request); ~PathServiceImpl() override; void GetAppDataDir(const GetAppDataDirCallback& callback) override; @@ -25,16 +25,16 @@ class PathServiceImpl : public activity::PathService { void GetCacheDir(const GetCacheDirCallback& callback) override; private: - mojo::StrongBinding binding_; + mojo::StrongBinding<::activity::PathService> binding_; DISALLOW_COPY_AND_ASSIGN(PathServiceImpl); }; class PathServiceFactory - : public mojo::InterfaceFactory { + : public mojo::InterfaceFactory<::activity::PathService> { public: void Create(mojo::ApplicationConnection* connection, - mojo::InterfaceRequest request) override; + mojo::InterfaceRequest<::activity::PathService> request) override; }; } // namespace path diff --git a/sky/services/activity/ios/path_service_impl.mm b/sky/services/activity/ios/path_service_impl.mm index 2398e3c7d1c..a2f495e6fde 100644 --- a/sky/services/activity/ios/path_service_impl.mm +++ b/sky/services/activity/ios/path_service_impl.mm @@ -12,7 +12,7 @@ namespace services { namespace path { PathServiceImpl::PathServiceImpl( - mojo::InterfaceRequest request) + mojo::InterfaceRequest<::activity::PathService> request) : binding_(this, request.Pass()) {} PathServiceImpl::~PathServiceImpl() {} @@ -49,7 +49,7 @@ void PathServiceImpl::GetCacheDir(const GetCacheDirCallback& callback) { void PathServiceFactory::Create( mojo::ApplicationConnection* connection, - mojo::InterfaceRequest request) { + mojo::InterfaceRequest<::activity::PathService> request) { new PathServiceImpl(request.Pass()); } diff --git a/sky/services/activity/ios/user_feedback_impl.h b/sky/services/activity/ios/user_feedback_impl.h new file mode 100644 index 00000000000..1ed88ccbcc2 --- /dev/null +++ b/sky/services/activity/ios/user_feedback_impl.h @@ -0,0 +1,38 @@ +// Copyright 2016 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_ACTIVITY_IOS_USER_FEEDBACK_IMPL_H_ +#define SKY_SERVICES_ACTIVITY_IOS_USER_FEEDBACK_IMPL_H_ + +#include "base/macros.h" +#include "mojo/public/cpp/application/interface_factory.h" +#include "mojo/public/cpp/bindings/strong_binding.h" +#include "sky/services/activity/activity.mojom.h" + +namespace sky { +namespace services { +namespace activity { + +class UserFeedbackImpl : public ::activity::UserFeedback { + public: + explicit UserFeedbackImpl( + mojo::InterfaceRequest<::activity::UserFeedback> request); + + ~UserFeedbackImpl() override; + + void PerformHapticFeedback(::activity::HapticFeedbackType type) override; + + void PerformAuralFeedback(::activity::AuralFeedbackType type) override; + + private: + mojo::StrongBinding<::activity::UserFeedback> binding_; + + DISALLOW_COPY_AND_ASSIGN(UserFeedbackImpl); +}; + +} // namespace activity +} // namespace services +} // namespace sky + +#endif // SKY_SERVICES_ACTIVITY_IOS_USER_FEEDBACK_IMPL_H_ diff --git a/sky/services/activity/ios/user_feedback_impl.mm b/sky/services/activity/ios/user_feedback_impl.mm new file mode 100644 index 00000000000..3bc13c57ed4 --- /dev/null +++ b/sky/services/activity/ios/user_feedback_impl.mm @@ -0,0 +1,38 @@ +// Copyright 2016 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/logging.h" +#include "base/mac/scoped_nsautorelease_pool.h" +#include "sky/services/activity/ios/user_feedback_impl.h" + +#include +#include + +namespace sky { +namespace services { +namespace activity { + +UserFeedbackImpl::UserFeedbackImpl( + mojo::InterfaceRequest<::activity::UserFeedback> request) + : binding_(this, request.Pass()) {} + +UserFeedbackImpl::~UserFeedbackImpl() {} + +void UserFeedbackImpl::PerformHapticFeedback( + ::activity::HapticFeedbackType type) { + // All feedback types are specific to Android and are treated as equal on iOS + AudioServicesPlayAlertSound(kSystemSoundID_Vibrate); +} + +void UserFeedbackImpl::PerformAuralFeedback( + ::activity::AuralFeedbackType type) { + base::mac::ScopedNSAutoreleasePool pool; + // All feedback types are specific to Android and are treated as equal on iOS + // The surface must (and does) adopt the UIInputViewAudioFeedback protocol + [[UIDevice currentDevice] playInputClick]; +} + +} // namespace activity +} // namespace services +} // namespace sky diff --git a/sky/shell/platform/ios/sky_surface.mm b/sky/shell/platform/ios/sky_surface.mm index df891cc1a3d..ac884c74e81 100644 --- a/sky/shell/platform/ios/sky_surface.mm +++ b/sky/shell/platform/ios/sky_surface.mm @@ -86,6 +86,10 @@ class TouchMapper { std::map touch_map_; }; +@interface SkySurface () + +@end + @implementation SkySurface { BOOL _platformViewInitialized; CGPoint _lastScrollTranslation; @@ -289,6 +293,12 @@ static std::string TracesBasePath() { [self dispatchTouches:touches phase:UITouchPhaseCancelled]; } +#pragma mark - Input Clicks + +- (BOOL)enableInputClicksWhenVisible { + return YES; +} + #pragma mark - Misc. + (Class)layerClass { diff --git a/sky/shell/platform/mac/platform_service_provider.cc b/sky/shell/platform/mac/platform_service_provider.cc index 1b8f9745132..4b2a8cf264c 100644 --- a/sky/shell/platform/mac/platform_service_provider.cc +++ b/sky/shell/platform/mac/platform_service_provider.cc @@ -9,18 +9,16 @@ namespace shell { PlatformServiceProvider::PlatformServiceProvider( mojo::InterfaceRequest request) - : binding_(this, request.Pass()) { -} + : binding_(this, request.Pass()) {} -PlatformServiceProvider::~PlatformServiceProvider() { -} +PlatformServiceProvider::~PlatformServiceProvider() {} void PlatformServiceProvider::ConnectToService( const mojo::String& service_name, mojo::ScopedMessagePipeHandle client_handle) { if (service_name == mojo::NetworkService::Name_) { - network_.Create(nullptr, mojo::MakeRequest( - client_handle.Pass())); + network_.Create( + nullptr, mojo::MakeRequest(client_handle.Pass())); } #if TARGET_OS_IPHONE if (service_name == ::keyboard::KeyboardService::Name_) { @@ -28,8 +26,8 @@ void PlatformServiceProvider::ConnectToService( client_handle.Pass())); } if (service_name == ::media::MediaPlayer::Name_) { - media_player_.Create(nullptr, mojo::MakeRequest<::media::MediaPlayer>( - client_handle.Pass())); + media_player_.Create( + nullptr, mojo::MakeRequest<::media::MediaPlayer>(client_handle.Pass())); } if (service_name == ::media::MediaService::Name_) { media_service_.Create(nullptr, mojo::MakeRequest<::media::MediaService>( @@ -43,6 +41,10 @@ void PlatformServiceProvider::ConnectToService( path_.Create(nullptr, mojo::MakeRequest<::activity::PathService>( client_handle.Pass())); } + if (service_name == ::activity::Activity::Name_) { + activity_.Create( + nullptr, mojo::MakeRequest<::activity::Activity>(client_handle.Pass())); + } #endif } diff --git a/sky/shell/platform/mac/platform_service_provider.h b/sky/shell/platform/mac/platform_service_provider.h index 2cce9bc3673..8d017edfe90 100644 --- a/sky/shell/platform/mac/platform_service_provider.h +++ b/sky/shell/platform/mac/platform_service_provider.h @@ -10,6 +10,7 @@ #include "sky/services/ns_net/network_service_impl.h" #if TARGET_OS_IPHONE +#include "sky/services/activity/ios/activity_impl.h" #include "sky/services/activity/ios/path_service_impl.h" #include "sky/services/keyboard/ios/keyboard_service_impl.h" #include "sky/services/media/ios/media_player_impl.h" @@ -36,6 +37,7 @@ class PlatformServiceProvider : public mojo::ServiceProvider { mojo::StrongBinding binding_; mojo::NetworkServiceFactory network_; #if TARGET_OS_IPHONE + sky::services::activity::ActivityFactory activity_; sky::services::keyboard::KeyboardServiceFactory keyboard_; sky::services::media::MediaPlayerFactory media_player_; sky::services::media::MediaServiceFactory media_service_;