提交 1f0c506d 编写于 作者: C Chinmay Garde

Basic Sky shell for iOS targets

R=abarth@chromium.org

Review URL: https://codereview.chromium.org/1171573002.
上级 232879f7
*.pbxproj
*.xcworkspace
*.xcodeproj
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>application-identifier</key>
<string>F5T262WGN6.com.google.sky</string>
<key>com.apple.developer.team-identifier</key>
<string>F5T262WGN6</string>
<key>get-task-allow</key>
<true/>
<key>keychain-access-groups</key>
<array>
<string>F5T262WGN6.com.google.sky</string>
</array>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<!--
This executable name must match the name of the app provided to the
ios_app GN template
-->
<key>CFBundleExecutable</key>
<string>Sky</string>
<key>CFBundleIdentifier</key>
<string>com.google.sky</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Sky</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<!--
mojo:// URL handlers
-->
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>CFBundleURLName</key>
<string>com.google.mojo</string>
<key>CFBundleURLSchemes</key>
<array>
<string>mojo</string>
</array>
</dict>
</array>
<!--
Sky Load URL
-->
<key>com.google.sky.load_url</key>
<string>https://domokit.github.io/sky_home</string>
<!--
FIXME(csg): Xcode, as part of its build process, adds the following
items to the Info.plist. It is not immediately clear if there is a
command line utility that generates these. For now, just add the same
manually
-->
<key>DTPlatformName</key>
<string>iphonesimulator</string>
<key>DTSDKName</key>
<string>iphonesimulator8.3</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>MinimumOSVersion</key>
<string>8.3</string>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>
<integer>2</integer>
</array>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>iPhoneSimulator</string>
</array>
</dict>
</plist>
// 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.
#import <UIKit/UIKit.h>
#include <asl.h>
#import "sky_app_delegate.h"
#include "base/at_exit.h"
#include "base/logging.h"
#include "base/i18n/icu_util.h"
#include "base/command_line.h"
#include "base/mac/scoped_nsautorelease_pool.h"
#include "ui/gl/gl_surface.h"
static void InitializeLogging() {
logging::LoggingSettings settings;
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
logging::InitLogging(settings);
logging::SetLogItems(false, // Process ID
false, // Thread ID
false, // Timestamp
false); // Tick count
}
static void RedirectIOConnectionsToSyslog() {
asl_log_descriptor(NULL, NULL, ASL_LEVEL_INFO, STDOUT_FILENO,
ASL_LOG_DESCRIPTOR_WRITE);
asl_log_descriptor(NULL, NULL, ASL_LEVEL_NOTICE, STDERR_FILENO,
ASL_LOG_DESCRIPTOR_WRITE);
}
#ifndef NDEBUG
static void SkyDebuggerHookMain(void) {
// By default, LLDB breaks way too early. This is before libraries have been
// loaded and __attribute__((constructor)) methods have been called. In most
// situations, this is unnecessary. Also, breakpoint resolution is not
// immediate. So we provide this hook to break on.
}
#endif
int main(int argc, char* argv[]) {
#ifndef NDEBUG
SkyDebuggerHookMain();
#endif
base::mac::ScopedNSAutoreleasePool pool;
base::AtExitManager exit_manager;
RedirectIOConnectionsToSyslog();
auto result = false;
result = base::CommandLine::Init(0, nullptr);
DLOG_ASSERT(result);
InitializeLogging();
result = base::i18n::InitializeICU();
DLOG_ASSERT(result);
result = gfx::GLSurface::InitializeOneOff();
DLOG_ASSERT(result);
return UIApplicationMain(argc, argv, nil,
NSStringFromClass([SkyAppDelegate class]));
}
// 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/engine/config.h"
#include "sky/engine/wtf/Assertions.h"
#include "sky/shell/service_provider.h"
#include "base/single_thread_task_runner.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/lazy_instance.h"
#include "base/location.h"
#include "mojo/public/cpp/application/service_provider_impl.h"
#include "sky/services/ns_net/network_service_impl.h"
namespace sky {
namespace shell {
// FIXME(csg): Put this in an application owned context
base::LazyInstance<scoped_ptr<mojo::ServiceProviderImpl>> g_service_provider =
LAZY_INSTANCE_INITIALIZER;
base::LazyInstance<scoped_ptr<mojo::NetworkServiceFactory>>
g_network_service_factory = LAZY_INSTANCE_INITIALIZER;
static void CreatePlatformServiceProvider(
mojo::InterfaceRequest<mojo::ServiceProvider> request) {
g_service_provider.Get().reset(new mojo::ServiceProviderImpl(request.Pass()));
g_network_service_factory.Get().reset(new mojo::NetworkServiceFactory());
g_service_provider.Get()->AddService(g_network_service_factory.Get().get());
}
mojo::ServiceProviderPtr CreateServiceProvider(
ServiceProviderContext* context) {
DCHECK(context);
mojo::MessagePipe pipe;
auto request = mojo::MakeRequest<mojo::ServiceProvider>(pipe.handle1.Pass());
context->platform_task_runner->PostTask(
FROM_HERE,
base::Bind(CreatePlatformServiceProvider, base::Passed(request.Pass())));
return mojo::MakeProxy(
mojo::InterfacePtrInfo<mojo::ServiceProvider>(pipe.handle0.Pass(), 0u));
}
} // namespace shell
} // namespace sky
// 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_SHELL_PLATFORM_VIEW_IOS_H_
#define SKY_SHELL_PLATFORM_VIEW_IOS_H_
#include "sky/shell/platform_view.h"
namespace sky {
namespace shell {
class PlatformViewIOS : public PlatformView {
public:
void SurfaceCreated(gfx::AcceleratedWidget widget);
void SurfaceDestroyed(void);
private:
DISALLOW_COPY_AND_ASSIGN(PlatformViewIOS);
};
} // namespace shell
} // namespace sky
#endif // SKY_SHELL_PLATFORM_VIEW_IOS_H_
// 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 "platform_view_ios.h"
namespace sky {
namespace shell {
void PlatformViewIOS::SurfaceCreated(gfx::AcceleratedWidget widget) {
DCHECK(window_ == 0);
window_ = widget;
SurfaceWasCreated();
}
void PlatformViewIOS::SurfaceDestroyed() {
DCHECK(window_);
window_ = 0;
SurfaceWasDestroyed();
}
} // namespace shell
} // namespace sky
// 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.
#import <UIKit/UIKit.h>
@interface SkyAppDelegate : UIResponder<UIApplicationDelegate>
@property(strong, nonatomic) UIWindow* window;
@end
// 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.
#import "sky_app_delegate.h"
#import "sky_view_controller.h"
#include "sky/shell/shell.h"
#include "sky/shell/service_provider.h"
#include "sky/shell/ui_delegate.h"
#include "base/lazy_instance.h"
#include "base/message_loop/message_loop.h"
@implementation SkyAppDelegate {
base::LazyInstance<scoped_ptr<base::MessageLoop>> _main_message_loop;
}
- (BOOL)application:(UIApplication*)application
didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
[self setupSkyShell];
[self setupViewport];
return YES;
}
- (void)setupSkyShell {
[self adoptPlatformRunLoop];
auto service_provider_context =
make_scoped_ptr(new sky::shell::ServiceProviderContext(
_main_message_loop.Get()->task_runner()));
sky::shell::Shell::Init(service_provider_context.Pass());
}
- (void)adoptPlatformRunLoop {
_main_message_loop.Get().reset(new base::MessageLoopForUI);
// One cannot start the message loop on the platform main thread. Instead,
// we attach to the CFRunLoop
base::MessageLoopForUI::current()->Attach();
}
- (void)setupViewport {
CGRect frame = [UIScreen mainScreen].bounds;
UIWindow* window = [[UIWindow alloc] initWithFrame:frame];
SkyViewController* viewController = [[SkyViewController alloc] init];
window.rootViewController = viewController;
[viewController release];
self.window = window;
[window release];
[self.window makeKeyAndVisible];
}
@end
// 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.
#import <UIKit/UIKit.h>
@interface SkySurface : UIView
@end
// 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.
#import "sky_surface.h"
#import <QuartzCore/QuartzCore.h>
#import <OpenGLES/EAGL.h>
#import <OpenGLES/EAGLDrawable.h>
#include "sky/shell/ui_delegate.h"
#include "sky/shell/shell.h"
#include "sky/shell/ios/platform_view_ios.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "sky/services/viewport/input_event.mojom.h"
#include "base/time/time.h"
static inline sky::EventType EventTypeFromUITouchPhase(UITouchPhase phase) {
switch (phase) {
case UITouchPhaseBegan:
return sky::EVENT_TYPE_POINTER_DOWN;
case UITouchPhaseMoved:
case UITouchPhaseStationary:
// There is no EVENT_TYPE_POINTER_STATIONARY. So we just pass a move type
// with the same coordinates
return sky::EVENT_TYPE_POINTER_MOVE;
case UITouchPhaseEnded:
return sky::EVENT_TYPE_POINTER_UP;
case UITouchPhaseCancelled:
return sky::EVENT_TYPE_POINTER_CANCEL;
}
return sky::EVENT_TYPE_UNKNOWN;
}
@implementation SkySurface {
BOOL _platformViewInitialized;
sky::ViewportObserverPtr _viewport_observer;
}
- (gfx::AcceleratedWidget)acceleratedWidget {
return (gfx::AcceleratedWidget)self.layer;
}
- (void)layoutSubviews {
[super layoutSubviews];
[self configureLayerDefaults];
[self setupPlatformViewIfNecessary];
CGSize size = self.bounds.size;
CGFloat scale = [UIScreen mainScreen].scale;
_viewport_observer->OnViewportMetricsChanged(size.width * scale,
size.height * scale, scale);
}
- (void)configureLayerDefaults {
CAEAGLLayer* layer = reinterpret_cast<CAEAGLLayer*>(self.layer);
layer.allowsGroupOpacity = YES;
layer.opaque = YES;
CGFloat screenScale = [UIScreen mainScreen].scale;
layer.contentsScale = screenScale;
// Note: shouldRasterize is still NO. This is just a defensive measure
layer.rasterizationScale = screenScale;
}
- (void)setupPlatformViewIfNecessary {
if (_platformViewInitialized) {
return;
}
_platformViewInitialized = YES;
[self notifySurfaceCreation];
[self connectToViewportObserverAndLoad];
}
- (sky::shell::PlatformViewIOS*)platformView {
auto view = static_cast<sky::shell::PlatformViewIOS*>(
sky::shell::Shell::Shared().view());
DCHECK(view);
return view;
}
- (void)notifySurfaceCreation {
self.platformView->SurfaceCreated(self.acceleratedWidget);
}
- (NSString*)skyInitialLoadURL {
return [NSBundle mainBundle].infoDictionary[@"com.google.sky.load_url"];
}
- (void)connectToViewportObserverAndLoad {
auto view = sky::shell::Shell::Shared().view();
auto interface_request = mojo::GetProxy(&_viewport_observer);
view->ConnectToViewportObserver(interface_request.Pass());
mojo::String string(self.skyInitialLoadURL.UTF8String);
_viewport_observer->LoadURL(string);
}
- (void)notifySurfaceDestruction {
self.platformView->SurfaceDestroyed();
}
#pragma mark - UIResponder overrides for raw touches
- (void)dispatchTouches:(NSSet*)touches phase:(UITouchPhase)phase {
auto eventType = EventTypeFromUITouchPhase(phase);
const CGFloat scale = [UIScreen mainScreen].scale;
for (UITouch* touch in touches) {
auto input = sky::InputEvent::New();
input->type = eventType;
auto timedelta = base::TimeDelta::FromSecondsD(touch.timestamp);
input->time_stamp = timedelta.InMilliseconds();
input->pointer_data = sky::PointerData::New();
input->pointer_data->kind = sky::POINTER_KIND_TOUCH;
CGPoint windowCoordinates = [touch locationInView:nil];
input->pointer_data->x = windowCoordinates.x * scale;
input->pointer_data->y = windowCoordinates.y * scale;
_viewport_observer->OnInputEvent(input.Pass());
}
}
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
[self dispatchTouches:touches phase:UITouchPhaseBegan];
}
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
[self dispatchTouches:touches phase:UITouchPhaseMoved];
}
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
[self dispatchTouches:touches phase:UITouchPhaseEnded];
}
- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event {
[self dispatchTouches:touches phase:UITouchPhaseCancelled];
}
#pragma mark - Misc.
+ (Class)layerClass {
return [CAEAGLLayer class];
}
- (void)dealloc {
[self notifySurfaceDestruction];
[super dealloc];
}
@end
// 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.
#import <UIKit/UIKit.h>
@interface SkyViewController : UIViewController
@end
// 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.
#import "sky_view_controller.h"
#import "sky_surface.h"
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
@implementation SkyViewController
- (void)loadView {
SkySurface* surface = [[SkySurface alloc] init];
surface.autoresizingMask =
UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.view = surface;
[surface release];
}
@end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册