Skip to content

Introduce spawn API at embedder #117

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions shell/platform/embedder/embedder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,24 @@ FlutterEngineResult FlutterEngineRun(size_t version,
return FlutterEngineRunInitialized(*engine_out);
}

FlutterEngineResult FlutterEngineSpawn(size_t version,
const FlutterRendererConfig* config,
const FlutterProjectArgs* args,
void* user_data,
FLUTTER_API_SYMBOL(FlutterEngine) *
engine_out,
FLUTTER_API_SYMBOL(FlutterEngine)
engine_main) {
auto result =
FlutterEngineInitialize(version, config, args, user_data, engine_out);

if (result != kSuccess) {
return result;
}

return FlutterEngineSpawnInitialized(*engine_out, engine_main);
}

FlutterEngineResult FlutterEngineInitialize(size_t version,
const FlutterRendererConfig* config,
const FlutterProjectArgs* args,
Expand Down Expand Up @@ -1309,6 +1327,44 @@ FlutterEngineResult FlutterEngineRunInitialized(
return kSuccess;
}

FlutterEngineResult FlutterEngineSpawnInitialized(
FLUTTER_API_SYMBOL(FlutterEngine) engine,
FLUTTER_API_SYMBOL(FlutterEngine) engine_main) {
if (!engine || !engine_main) {
return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
}

auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);
auto embedder_engine_main =
reinterpret_cast<flutter::EmbedderEngine*>(engine_main);

// The engine must not already be running. Initialize may only be called
// once on an engine instance.
if (embedder_engine->IsValid()) {
return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
}

// The main engine must be running.
if (!embedder_engine_main->IsValid()) {
return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
}

// Spawn the shell.
if (!embedder_engine->SpawnShell(embedder_engine_main)) {
return LOG_EMBEDDER_ERROR(kInvalidArguments,
"Could not launch the engine using supplied "
"initialization arguments.");
}

// Step 2: Tell the platform view to initialize itself.
if (!embedder_engine->NotifyCreated()) {
return LOG_EMBEDDER_ERROR(kInternalInconsistency,
"Could not create platform view components.");
}

return kSuccess;
}

FLUTTER_EXPORT
FlutterEngineResult FlutterEngineDeinitialize(FLUTTER_API_SYMBOL(FlutterEngine)
engine) {
Expand Down Expand Up @@ -2220,6 +2276,7 @@ FlutterEngineResult FlutterEngineGetProcAddresses(
SET_PROC(CreateAOTData, FlutterEngineCreateAOTData);
SET_PROC(CollectAOTData, FlutterEngineCollectAOTData);
SET_PROC(Run, FlutterEngineRun);
SET_PROC(Spawn, FlutterEngineSpawn);
SET_PROC(Shutdown, FlutterEngineShutdown);
SET_PROC(Initialize, FlutterEngineInitialize);
SET_PROC(Deinitialize, FlutterEngineDeinitialize);
Expand Down
29 changes: 29 additions & 0 deletions shell/platform/embedder/embedder.h
Original file line number Diff line number Diff line change
Expand Up @@ -1598,6 +1598,19 @@ FlutterEngineResult FlutterEngineRun(size_t version,
FLUTTER_API_SYMBOL(FlutterEngine) *
engine_out);

//------------------------------------------------------------------------------
// TODO : Update required
///
FLUTTER_EXPORT
FlutterEngineResult FlutterEngineSpawn(size_t version,
const FlutterRendererConfig* config,
const FlutterProjectArgs* args,
void* user_data,
FLUTTER_API_SYMBOL(FlutterEngine) *
engine_out,
FLUTTER_API_SYMBOL(FlutterEngine)
engine_main);

//------------------------------------------------------------------------------
/// @brief Shuts down a Flutter engine instance. The engine handle is no
/// longer valid for any calls in the embedder API after this point.
Expand Down Expand Up @@ -1673,6 +1686,14 @@ FLUTTER_EXPORT
FlutterEngineResult FlutterEngineRunInitialized(
FLUTTER_API_SYMBOL(FlutterEngine) engine);

//------------------------------------------------------------------------------
// TODO : Update required
///
FLUTTER_EXPORT
FlutterEngineResult FlutterEngineSpawnInitialized(
FLUTTER_API_SYMBOL(FlutterEngine) engine,
FLUTTER_API_SYMBOL(FlutterEngine) engine_main);

FLUTTER_EXPORT
FlutterEngineResult FlutterEngineSendWindowMetricsEvent(
FLUTTER_API_SYMBOL(FlutterEngine) engine,
Expand Down Expand Up @@ -2204,6 +2225,13 @@ typedef FlutterEngineResult (*FlutterEngineRunFnPtr)(
const FlutterProjectArgs* args,
void* user_data,
FLUTTER_API_SYMBOL(FlutterEngine) * engine_out);
typedef FlutterEngineResult (*FlutterEngineSpawnFnPtr)(
size_t version,
const FlutterRendererConfig* config,
const FlutterProjectArgs* args,
void* user_data,
FLUTTER_API_SYMBOL(FlutterEngine) * engine_out,
FLUTTER_API_SYMBOL(FlutterEngine) engine_main);
typedef FlutterEngineResult (*FlutterEngineShutdownFnPtr)(
FLUTTER_API_SYMBOL(FlutterEngine) engine);
typedef FlutterEngineResult (*FlutterEngineInitializeFnPtr)(
Expand Down Expand Up @@ -2315,6 +2343,7 @@ typedef struct {
FlutterEngineCreateAOTDataFnPtr CreateAOTData;
FlutterEngineCollectAOTDataFnPtr CollectAOTData;
FlutterEngineRunFnPtr Run;
FlutterEngineSpawnFnPtr Spawn;
FlutterEngineShutdownFnPtr Shutdown;
FlutterEngineInitializeFnPtr Initialize;
FlutterEngineDeinitializeFnPtr Deinitialize;
Expand Down
33 changes: 33 additions & 0 deletions shell/platform/embedder/embedder_engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,39 @@ bool EmbedderEngine::LaunchShell() {
return IsValid();
}

bool EmbedderEngine::SpawnShell(EmbedderEngine* main) {
if (!shell_args_) {
FML_DLOG(ERROR) << "Invalid shell arguments.";
return false;
}

if (shell_) {
FML_DLOG(ERROR) << "Shell already initialized";
}

if (!run_configuration_.IsValid()) {
FML_DLOG(ERROR) << "Invalid Configration";
}

shell_ = main->SpawnShell(std::move(run_configuration_),
shell_args_->on_create_platform_view,
shell_args_->on_create_rasterizer);

// // Reset the args no matter what. They will never be used to initialize a
// // shell again.
shell_args_.reset();

return IsValid();
}

std::unique_ptr<Shell> EmbedderEngine::SpawnShell(
RunConfiguration run_configuration,
const Shell::CreateCallback<PlatformView>& on_create_platform_view,
const Shell::CreateCallback<Rasterizer>& on_create_rasterizer) {
return shell_->Spawn(std::move(run_configuration), on_create_platform_view,
on_create_rasterizer);
}

bool EmbedderEngine::CollectShell() {
shell_.reset();
return IsValid();
Expand Down
7 changes: 7 additions & 0 deletions shell/platform/embedder/embedder_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ class EmbedderEngine {

bool LaunchShell();

bool SpawnShell(EmbedderEngine* main);

std::unique_ptr<Shell> SpawnShell(
RunConfiguration run_configuration,
const Shell::CreateCallback<PlatformView>& on_create_platform_view,
const Shell::CreateCallback<Rasterizer>& on_create_rasterizer);

bool CollectShell();

const TaskRunners& GetTaskRunners() const;
Expand Down
34 changes: 34 additions & 0 deletions shell/platform/embedder/tests/embedder_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1434,5 +1434,39 @@ TEST_F(EmbedderTest, KeyDataResponseIsCorrectlyInvoked) {
EXPECT_TRUE(user_data3.returned);
}

//------------------------------------------------------------------------------
///
TEST_F(EmbedderTest, CabRunFlutterEngineSpawnInitialized) {
EmbedderConfigBuilder builder(
GetEmbedderContext(EmbedderTestContextType::kSoftwareContext));
builder.SetSoftwareRendererConfig();
auto engine = builder.InitializeEngine();
auto main_engine = builder.InitializeEngine();

ASSERT_TRUE(engine.is_valid());
ASSERT_TRUE(main_engine.is_valid());

// Spawn with invalid parameter
ASSERT_EQ(FlutterEngineSpawnInitialized(nullptr, nullptr), kInvalidArguments);
ASSERT_EQ(FlutterEngineSpawnInitialized(engine.get(), nullptr),
kInvalidArguments);
ASSERT_EQ(FlutterEngineSpawnInitialized(nullptr, main_engine.get()),
kInvalidArguments);

// Test with the main engine not running
ASSERT_EQ(FlutterEngineSpawnInitialized(engine.get(), main_engine.get()),
kInvalidArguments);

// Execute main engine
ASSERT_EQ(FlutterEngineRunInitialized(main_engine.get()), kSuccess);

// Test spawn API
ASSERT_EQ(FlutterEngineSpawnInitialized(engine.get(), main_engine.get()),
kSuccess);

engine.reset();
main_engine.reset();
}

} // namespace testing
} // namespace flutter
9 changes: 9 additions & 0 deletions shell/platform/tizen/flutter_tizen.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ FlutterDesktopEngineRef FlutterDesktopRunEngine(
return HandleForEngine(engine.release());
}

FlutterDesktopEngineRef FlutterDesktopSpawnEngine(
FlutterDesktopEngineRef engine_ref,
const FlutterDesktopEngineProperties& engine_properties,
bool headed) {
auto engine = EngineFromHandle(engine_ref);
auto spawned_engine = engine->SpawnEngine(headed, engine_properties);
return HandleForEngine(spawned_engine);
}

void FlutterDesktopShutdownEngine(FlutterDesktopEngineRef engine_ref) {
auto engine = EngineFromHandle(engine_ref);
engine->StopEngine();
Expand Down
Loading