diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/cpp/types/libflutter/index.d.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/cpp/types/libflutter/index.d.ets index ee0d9abe81e4c36a15a84a7b85c6ff5fab9fe471..e87ee85e6a666d83b54f94dcce1b624bfc39f3be 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/cpp/types/libflutter/index.d.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/cpp/types/libflutter/index.d.ets @@ -47,6 +47,14 @@ export const nativeInit: ( export const nativeAttach: (napi: FlutterNapi) => number; +export const nativeSpawn: ( + nativeSpawningShellId: number, + entrypointFunctionName: string, + pathToEntrypointFunction: string, + initialRoute: string, + entrypointArgs: Array +) => number; + export const nativeRunBundleAndSnapshotFromLibrary: ( nativeShellHolderId: number, bundlePath: string, diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/cpp/types/libflutter/index_actual.d.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/cpp/types/libflutter/index_actual.d.ets index f74af44a9d9f5796d76516723d45ec0a8791a76b..afab18030d24d6263139b464623c36cbd8ace369 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/cpp/types/libflutter/index_actual.d.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/cpp/types/libflutter/index_actual.d.ets @@ -74,7 +74,7 @@ export const nativeSpawn: ( pathToEntrypointFunction: string, initialRoute: string, entrypointArgs: Array -) => FlutterNapi; +) => number; /** * Detaches flutterNapi和engine之间的关联 diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterNapi.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterNapi.ets index 4ec3580943e01308e76b67db671ae4e404455929..eef82c9ea7847bb73ec46e4110f3e5b7c65c6293 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterNapi.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterNapi.ets @@ -219,7 +219,10 @@ export default class FlutterNapi { } spawn(entrypointFunctionName: string, pathToEntrypointFunction: string, initialRoute: string, entrypointArgs: Array): FlutterNapi { - return new FlutterNapi(); + let shellHolderId = flutter.nativeSpawn(this.nativeShellHolderId, entrypointFunctionName, pathToEntrypointFunction, initialRoute, entrypointArgs) + let flutterNapi = new FlutterNapi() + flutterNapi.nativeShellHolderId = shellHolderId + return flutterNapi; } addEngineLifecycleListener(engineLifecycleListener: EngineLifecycleListener): void { diff --git a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp index b4bbe98c3c9d5836706372aa7b3c91e222a1b38c..3da5999832a2295bb2342a6f3b9831a20847faa3 100644 --- a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp +++ b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp @@ -571,10 +571,63 @@ napi_value PlatformViewOHOSNapi::nativeGetPixelMap(napi_env env, /** * 从当前的flutterNapi复制一个新的实例 */ -napi_value PlatformViewOHOSNapi::nativeSpawn(napi_env env, - napi_callback_info info) { - // TODO: - return nullptr; +napi_value PlatformViewOHOSNapi::nativeSpawn(napi_env env, napi_callback_info info) { + napi_status ret; + size_t argc = 6; + napi_value args[6] = {nullptr}; + ret = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + if (ret != napi_ok) { + LOGE("nativeSpawn napi_get_cb_info error"); + return nullptr; + } + + int64_t shell_holder; + ret = napi_get_value_int64(env, args[0], &shell_holder); + if (ret != napi_ok) { + LOGE("nativeSpawn napi_get_value_int64 error"); + return nullptr; + } + LOGD("nativeSpawn::shell_holder : %{public}ld", shell_holder); + + std::string entrypoint; + if (fml::napi::SUCCESS != fml::napi::GetString(env, args[1], entrypoint)) { + LOGE(" napi_get_value_string_utf8 error"); + return nullptr; + } + LOGD("entrypoint: %{public}s", entrypoint.c_str()); + + std::string libraryUrl; + if (fml::napi::SUCCESS != fml::napi::GetString(env, args[2], libraryUrl)) { + LOGE(" napi_get_value_string_utf8 error"); + return nullptr; + } + LOGD(" libraryUrl: %{public}s", libraryUrl.c_str()); + + std::string initial_route; + if (fml::napi::SUCCESS != fml::napi::GetString(env, args[3], initial_route)) { + LOGE(" napi_get_value_string_utf8 error"); + return nullptr; + } + LOGD(" initialRoute: %{public}s", initial_route.c_str()); + + std::vector entrypoint_args; + if (fml::napi::SUCCESS != fml::napi::GetArrayString(env, args[4], entrypoint_args)) { + LOGE("nativeRunBundleAndSnapshotFromLibrary GetArrayString error"); + return nullptr; + } + + std::shared_ptr napi_facade = std::make_shared(env); + auto spawned_shell_holder = OHOS_SHELL_HOLDER->Spawn( + napi_facade, entrypoint, libraryUrl, initial_route, entrypoint_args); + + if (spawned_shell_holder == nullptr || !spawned_shell_holder->IsValid()) { + FML_LOG(ERROR) << "Could not spawn Shell"; + return nullptr; + } + + napi_value shell_holder_id; + napi_create_int64(env, reinterpret_cast(spawned_shell_holder.release()), &shell_holder_id); + return shell_holder_id; } static void LoadLoadingUnitFailure(intptr_t loading_unit_id, diff --git a/shell/platform/ohos/ohos_shell_holder.cpp b/shell/platform/ohos/ohos_shell_holder.cpp index 7024a36a260b338ab63b679f377f40b34bdc6328..26aa35c67a658f7b71eb8990de8bf48f5d5efd87 100644 --- a/shell/platform/ohos/ohos_shell_holder.cpp +++ b/shell/platform/ohos/ohos_shell_holder.cpp @@ -188,6 +188,27 @@ OHOSShellHolder::OHOSShellHolder( is_valid_ = shell_ != nullptr; } +OHOSShellHolder::OHOSShellHolder( + const Settings& settings, + const std::shared_ptr& napi_facade, + const std::shared_ptr& thread_host, + std::unique_ptr shell, + std::unique_ptr apk_asset_provider, + const fml::WeakPtr& platform_view) + : settings_(settings), + platform_view_(platform_view), + thread_host_(thread_host), + shell_(std::move(shell)), + assetProvider_(std::move(apk_asset_provider)), + napi_facade_(napi_facade) { + FML_DCHECK(napi_facade); + FML_DCHECK(shell_); + FML_DCHECK(shell_->IsSetup()); + FML_DCHECK(platform_view_); + FML_DCHECK(thread_host_); + is_valid_ = shell_ != nullptr; +} + bool OHOSShellHolder::IsValid() const { return is_valid_; } @@ -196,6 +217,56 @@ const flutter::Settings& OHOSShellHolder::GetSettings() const { return settings_; } +std::unique_ptr OHOSShellHolder::Spawn( + std::shared_ptr napi_facade, + const std::string& entrypoint, + const std::string& libraryUrl, + const std::string& initial_route, + const std::vector& entrypoint_args) const { + FML_DCHECK(shell_ && shell_->IsSetup()) + << "A new Shell can only be spawned " + "if the current Shell is properly constructed"; + + fml::WeakPtr weak_platform_view; + PlatformViewOHOS* ohos_platform_view = platform_view_.get(); + FML_DCHECK(ohos_platform_view); + std::shared_ptr ohos_context = + ohos_platform_view->GetOHOSContext(); + FML_DCHECK(ohos_context); + + Shell::CreateCallback on_create_platform_view = + [&napi_facade, ohos_context, &weak_platform_view](Shell& shell) { + std::unique_ptr platform_view_ohos; + platform_view_ohos = std::make_unique( + shell, // delegate + shell.GetTaskRunners(), // task runners + napi_facade, // JNI interop + ohos_context // Ohos context + ); + weak_platform_view = platform_view_ohos->GetWeakPtr(); + return platform_view_ohos; + }; + + Shell::CreateCallback on_create_rasterizer = [](Shell& shell) { + return std::make_unique(shell); + }; + + auto config = BuildRunConfiguration(entrypoint, libraryUrl, entrypoint_args); + if (!config) { + // If the RunConfiguration was null, the kernel blob wasn't readable. + // Fail the whole thing. + return nullptr; + } + + std::unique_ptr shell = + shell_->Spawn(std::move(config.value()), initial_route, + on_create_platform_view, on_create_rasterizer); + + return std::unique_ptr(new OHOSShellHolder( + GetSettings(), napi_facade, thread_host_, std::move(shell), + assetProvider_->Clone(), weak_platform_view)); +} + fml::WeakPtr OHOSShellHolder::GetPlatformView() { FML_DCHECK(platform_view_); return platform_view_; diff --git a/shell/platform/ohos/ohos_shell_holder.h b/shell/platform/ohos/ohos_shell_holder.h index 760cc6f15e911f91deadede1f2eb672a4e7f0e00..6e94255f2544bca19caa184ae73f8066e8ce8433 100644 --- a/shell/platform/ohos/ohos_shell_holder.h +++ b/shell/platform/ohos/ohos_shell_holder.h @@ -55,6 +55,13 @@ class OHOSShellHolder { const std::string& libraryUrl, const std::vector& entrypoint_args); + std::unique_ptr Spawn( + std::shared_ptr napi_facade, + const std::string& entrypoint, + const std::string& libraryUrl, + const std::string& initial_route, + const std::vector& entrypoint_args) const; + const std::shared_ptr& GetPlatformMessageHandler() const { LOGI("GetPlatformMessageHandler LOGI"); @@ -78,6 +85,13 @@ class OHOSShellHolder { std::shared_ptr napi_facade_; + OHOSShellHolder(const flutter::Settings& settings, + const std::shared_ptr& napi_facade, + const std::shared_ptr& thread_host, + std::unique_ptr shell, + std::unique_ptr apk_asset_provider, + const fml::WeakPtr& platform_view); + static void ThreadDestructCallback(void* value); FML_DISALLOW_COPY_AND_ASSIGN(OHOSShellHolder); diff --git a/shell/platform/ohos/platform_view_ohos.h b/shell/platform/ohos/platform_view_ohos.h index 1debe9617e8bd956acd053b5995ca99ebc607ad6..a1b863ed345f0ee206825a79323a4c2fa67cfa61 100644 --- a/shell/platform/ohos/platform_view_ohos.h +++ b/shell/platform/ohos/platform_view_ohos.h @@ -100,7 +100,7 @@ class PlatformViewOHOS final : public PlatformView { std::unique_ptr updated_asset_resolver, AssetResolver::AssetResolverType type) override; - const std::shared_ptr& GetAndroidContext() { + const std::shared_ptr& GetOHOSContext() { return ohos_context_; }