Skip to content

Commit

Permalink
[ios] Adds an API for running Dart code without a PlatformViewIOS (fl…
Browse files Browse the repository at this point in the history
  • Loading branch information
zanderso authored Nov 1, 2017
1 parent d6dd5b1 commit 6c73503
Show file tree
Hide file tree
Showing 10 changed files with 215 additions and 8 deletions.
2 changes: 2 additions & 0 deletions shell/common/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ source_set("common") {
"animator.h",
"engine.cc",
"engine.h",
"null_platform_view.cc",
"null_platform_view.h",
"null_rasterizer.cc",
"null_rasterizer.h",
"picture_serializer.cc",
Expand Down
34 changes: 34 additions & 0 deletions shell/common/null_platform_view.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2017 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 "flutter/shell/common/null_platform_view.h"

#include "flutter/shell/common/null_rasterizer.h"
#include "flutter/shell/common/shell.h"

namespace shell {

NullPlatformView::NullPlatformView()
: PlatformView(std::make_unique<NullRasterizer>()), weak_factory_(this) {}

void NullPlatformView::Attach() {
CreateEngine();
}

NullPlatformView::~NullPlatformView() = default;

fxl::WeakPtr<NullPlatformView> NullPlatformView::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}

bool NullPlatformView::ResourceContextMakeCurrent() {
return false;
}

// Hot-reload of the null platform view is not supported.
void NullPlatformView::RunFromSource(const std::string& assets_directory,
const std::string& main,
const std::string& packages) {}

} // namespace shell
38 changes: 38 additions & 0 deletions shell/common/null_platform_view.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright 2017 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 COMMON_NULL_PLATFORM_VIEW_H_
#define COMMON_NULL_PLATFORM_VIEW_H_

#include "flutter/shell/common/platform_view.h"
#include "lib/fxl/macros.h"
#include "lib/fxl/memory/weak_ptr.h"

namespace shell {

class NullPlatformView : public PlatformView {
public:
NullPlatformView();

~NullPlatformView();

fxl::WeakPtr<NullPlatformView> GetWeakPtr();

virtual void Attach() override;

bool ResourceContextMakeCurrent() override;

void RunFromSource(const std::string& assets_directory,
const std::string& main,
const std::string& packages) override;

private:
fxl::WeakPtrFactory<NullPlatformView> weak_factory_;

FXL_DISALLOW_COPY_AND_ASSIGN(NullPlatformView);
};

} // namespace shell

#endif // COMMON_NULL_PLATFORM_VIEW_H_
2 changes: 2 additions & 0 deletions shell/platform/darwin/ios/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ _flutter_framework_headers = [
"framework/Headers/FlutterChannels.h",
"framework/Headers/FlutterCodecs.h",
"framework/Headers/FlutterDartProject.h",
"framework/Headers/FlutterHeadlessDartRunner.h",
"framework/Headers/FlutterMacros.h",
"framework/Headers/FlutterNavigationController.h",
"framework/Headers/FlutterPlugin.h",
Expand All @@ -37,6 +38,7 @@ shared_library("create_flutter_framework_dylib") {
"framework/Source/FlutterCodecs.mm",
"framework/Source/FlutterDartProject.mm",
"framework/Source/FlutterDartProject_Internal.h",
"framework/Source/FlutterHeadlessDartRunner.mm",
"framework/Source/FlutterDartSource.h",
"framework/Source/FlutterDartSource.mm",
"framework/Source/FlutterNavigationController.mm",
Expand Down
1 change: 1 addition & 0 deletions shell/platform/darwin/ios/framework/Headers/Flutter.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "FlutterChannels.h"
#include "FlutterCodecs.h"
#include "FlutterDartProject.h"
#include "FlutterHeadlessDartRunner.h"
#include "FlutterMacros.h"
#include "FlutterNavigationController.h"
#include "FlutterPlugin.h"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2017 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 FLUTTER_FLUTTERHEADLESSDARTRUNNER_H_
#define FLUTTER_FLUTTERHEADLESSDARTRUNNER_H_

#import <Foundation/Foundation.h>

#include "FlutterDartProject.h"
#include "FlutterMacros.h"

/**
The FlutterHeadlessDartRunner runs Flutter Dart code with a null rasterizer,
and no native drawing surface. It is appropriate for use in running Dart
code e.g. in the background from a plugin.
*/
FLUTTER_EXPORT
@interface FlutterHeadlessDartRunner : NSObject

/**
Runs a Dart function on an Isolate that is not the main application's Isolate.
The first call will create a new Isolate. Subsequent calls will reuse that
Isolate. The Isolate is destroyed when the FlutterHeadlessDartRunner is
destroyed.
- Parameter entrypoint: The name of a top-level function from the same Dart
library that contains the app's main() function.
*/
- (void)runWithEntrypoint:(NSString*)entrypoint;

@end

#endif // FLUTTER_FLUTTERHEADLESSDARTRUNNER_H_
64 changes: 56 additions & 8 deletions shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ - (NSString*)pathForFLXFromBundle:(NSBundle*)bundle {
}

- (void)launchInEngine:(shell::Engine*)engine
withEntrypoint:(NSString*)entrypoint
embedderVMType:(VMType)embedderVMType
result:(LaunchResult)result {
if (_vmTypeRequirement == VMTypeInvalid) {
Expand All @@ -193,10 +194,48 @@ - (void)launchInEngine:(shell::Engine*)engine

switch (_vmTypeRequirement) {
case VMTypeInterpreter:
[self runFromSourceInEngine:engine result:result];
[self runFromSourceInEngine:engine withEntrypoint:entrypoint result:result];
return;
case VMTypePrecompilation:
[self runFromPrecompiledSourceInEngine:engine result:result];
[self runFromPrecompiledSourceInEngine:engine withEntrypoint:entrypoint result:result];
return;
case VMTypeInvalid:
break;
}

return result(NO, @"Internal error");
}

- (void)launchInEngine:(shell::Engine*)engine
embedderVMType:(VMType)embedderVMType
result:(LaunchResult)result {
if (_vmTypeRequirement == VMTypeInvalid) {
result(NO, @"The Dart project is invalid and cannot be loaded by any VM.");
return;
}

if (embedderVMType == VMTypeInvalid) {
result(NO, @"The embedder is invalid.");
return;
}

if (_vmTypeRequirement != embedderVMType) {
NSString* message =
[NSString stringWithFormat:
@"Could not load the project because of differing project type. "
@"The project can run in '%@' but the embedder is configured as "
@"'%@'",
NSStringFromVMType(_vmTypeRequirement), NSStringFromVMType(embedderVMType)];
result(NO, message);
return;
}

switch (_vmTypeRequirement) {
case VMTypeInterpreter:
[self runFromSourceInEngine:engine withEntrypoint:@"main" result:result];
return;
case VMTypePrecompilation:
[self runFromPrecompiledSourceInEngine:engine withEntrypoint:@"main" result:result];
return;
case VMTypeInvalid:
break;
Expand All @@ -207,7 +246,9 @@ - (void)launchInEngine:(shell::Engine*)engine

#pragma mark - Running from precompiled application bundles

- (void)runFromPrecompiledSourceInEngine:(shell::Engine*)engine result:(LaunchResult)result {
- (void)runFromPrecompiledSourceInEngine:(shell::Engine*)engine
withEntrypoint:(NSString*)entrypoint
result:(LaunchResult)result {
if (![_precompiledDartBundle load]) {
NSString* message = [NSString
stringWithFormat:@"Could not load the framework ('%@') containing precompiled code.",
Expand All @@ -227,17 +268,21 @@ - (void)runFromPrecompiledSourceInEngine:(shell::Engine*)engine result:(LaunchRe
}

std::string bundle_path = path.UTF8String;
blink::Threads::UI()->PostTask([ engine = engine->GetWeakPtr(), bundle_path ] {
blink::Threads::UI()->PostTask([
engine = engine->GetWeakPtr(), bundle_path, entrypoint = std::string([entrypoint UTF8String])
] {
if (engine)
engine->RunBundle(bundle_path);
engine->RunBundle(bundle_path, entrypoint);
});

result(YES, @"Success");
}

#pragma mark - Running from source

- (void)runFromSourceInEngine:(shell::Engine*)engine result:(LaunchResult)result {
- (void)runFromSourceInEngine:(shell::Engine*)engine
withEntrypoint:(NSString*)entrypoint
result:(LaunchResult)result {
if (_dartSource == nil) {
result(NO, @"Dart source not specified.");
return;
Expand All @@ -251,9 +296,12 @@ - (void)runFromSourceInEngine:(shell::Engine*)engine result:(LaunchResult)result
std::string bundle_path = _dartSource.flxArchive.absoluteURL.path.UTF8String;

if (_dartSource.archiveContainsScriptSnapshot) {
blink::Threads::UI()->PostTask([ engine = engine->GetWeakPtr(), bundle_path ] {
blink::Threads::UI()->PostTask([
engine = engine->GetWeakPtr(), bundle_path,
entrypoint = std::string([entrypoint UTF8String])
] {
if (engine)
engine->RunBundle(bundle_path);
engine->RunBundle(bundle_path, entrypoint);
});
} else {
std::string main = _dartSource.dartMain.absoluteURL.path.UTF8String;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ typedef void (^LaunchResult)(BOOL success, NSString* message);
embedderVMType:(VMType)type
result:(LaunchResult)result;

- (void)launchInEngine:(shell::Engine*)engine
withEntrypoint:(NSString*)entrypoint
embedderVMType:(VMType)type
result:(LaunchResult)result;

@end

#endif // SHELL_PLATFORM_IOS_FRAMEWORK_SOURCE_FLUTTERDARTPROJECT_INTERNAL_H_
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2017 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 "flutter/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h"

#include <memory>

#include "flutter/fml/platform/darwin/scoped_nsobject.h"
#include "flutter/shell/common/null_platform_view.h"
#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h"

@interface FlutterHeadlessDartRunner ()
@end

@implementation FlutterHeadlessDartRunner {
fml::scoped_nsprotocol<FlutterDartProject*> _dartProject;
std::shared_ptr<shell::NullPlatformView> _platformView;
}

- (instancetype)init {
_dartProject.reset([[FlutterDartProject alloc] initFromDefaultSourceForConfiguration]);
_platformView = std::make_shared<shell::NullPlatformView>();
_platformView->Attach();
return self;
}

- (void)runWithEntrypoint:(NSString*)entrypoint {
const enum VMType type = Dart_IsPrecompiledRuntime() ? VMTypePrecompilation : VMTypeInterpreter;
[_dartProject launchInEngine:&_platformView->engine()
withEntrypoint:entrypoint
embedderVMType:type
result:^(BOOL success, NSString* message) {
if (!success)
NSLog(@"%@", message);
}];
}

@end
4 changes: 4 additions & 0 deletions travis/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,8 @@ FILE: ../../../flutter/lib/ui/painting/vertices.cc
FILE: ../../../flutter/lib/ui/painting/vertices.h
FILE: ../../../flutter/lib/ui/text/font_collection.cc
FILE: ../../../flutter/lib/ui/text/font_collection.h
FILE: ../../../flutter/shell/common/null_platform_view.cc
FILE: ../../../flutter/shell/common/null_platform_view.h
FILE: ../../../flutter/shell/gpu/gpu_surface_software.cc
FILE: ../../../flutter/shell/gpu/gpu_surface_software.h
FILE: ../../../flutter/shell/platform/android/android_surface_software.cc
Expand Down Expand Up @@ -1165,10 +1167,12 @@ FILE: ../../../flutter/shell/platform/android/platform_view_android_jni.h
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterBinaryMessenger.h
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterChannels.h
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterCodecs.h
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterNavigationController.h
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlugin.h
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterChannels.mm
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterCodecs.mm
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterHeadlessDartRunner.mm
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterNavigationController.mm
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterStandardCodec.mm
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterStandardCodec_Internal.h
Expand Down

0 comments on commit 6c73503

Please sign in to comment.