mirror of
https://gitee.com/openharmony/startup_appspawn
synced 2024-12-04 05:14:38 +00:00
b16447d24f
Signed-off-by: ohxianzhi <duxianzhi@huawei.com>
174 lines
5.7 KiB
C++
174 lines
5.7 KiB
C++
/*
|
|
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include <algorithm>
|
|
#include <cerrno>
|
|
#include <ctime>
|
|
#include <dlfcn.h>
|
|
#include <map>
|
|
#include <mutex>
|
|
#include <string>
|
|
|
|
#ifdef __MUSL__
|
|
#include <cerrno>
|
|
#include <dlfcn_ext.h>
|
|
#include <sys/mman.h>
|
|
#endif
|
|
|
|
#include "appspawn_hook.h"
|
|
#include "appspawn_manager.h"
|
|
|
|
#ifdef WITH_SECCOMP
|
|
#include "seccomp_policy.h"
|
|
#endif
|
|
|
|
#ifndef APPSPAWN_TEST
|
|
#define APPSPAWN_STATIC static
|
|
#else
|
|
#define APPSPAWN_STATIC
|
|
#endif
|
|
|
|
namespace {
|
|
#if defined(webview_arm64)
|
|
const std::string ARK_WEB_CORE_HAP_LIB_PATH =
|
|
"/data/storage/el1/bundle/arkwebcore/libs/arm64";
|
|
#elif defined(webview_x86_64)
|
|
const std::string ARK_WEB_CORE_HAP_LIB_PATH =
|
|
"/data/storage/el1/bundle/arkwebcore/libs/x86_64";
|
|
#else
|
|
const std::string ARK_WEB_CORE_HAP_LIB_PATH =
|
|
"/data/storage/el1/bundle/arkwebcore/libs/arm";
|
|
#endif
|
|
const std::string ARK_WEB_ENGINE_LIB_NAME = "libarkweb_engine.so";
|
|
const std::string ARK_WEB_RENDER_LIB_NAME = "libarkweb_render.so";
|
|
const std::string WEB_ENGINE_LIB_NAME = "libweb_engine.so";
|
|
const std::string WEB_RENDER_LIB_NAME = "libnweb_render.so";
|
|
} // namespace
|
|
|
|
APPSPAWN_STATIC bool SetSeccompPolicyForRenderer(void *nwebRenderHandle)
|
|
{
|
|
#ifdef WITH_SECCOMP
|
|
if (IsEnableSeccomp()) {
|
|
using SeccompFuncType = bool (*)(void);
|
|
SeccompFuncType funcSetRendererSeccompPolicy =
|
|
reinterpret_cast<SeccompFuncType>(dlsym(nwebRenderHandle, "SetRendererSeccompPolicy"));
|
|
if (funcSetRendererSeccompPolicy != nullptr && funcSetRendererSeccompPolicy()) {
|
|
return true;
|
|
}
|
|
APPSPAWN_LOGE("SetRendererSeccompPolicy dlsym errno: %{public}d", errno);
|
|
return false;
|
|
}
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
APPSPAWN_STATIC std::string GetArkWebEngineLibName()
|
|
{
|
|
std::string arkWebEngineLibPath = ARK_WEB_CORE_HAP_LIB_PATH + "/"
|
|
+ ARK_WEB_ENGINE_LIB_NAME;
|
|
bool isArkWebEngineLibPathExist = access(arkWebEngineLibPath.c_str(), F_OK) == 0;
|
|
return isArkWebEngineLibPathExist ?
|
|
ARK_WEB_ENGINE_LIB_NAME : WEB_ENGINE_LIB_NAME;
|
|
}
|
|
|
|
APPSPAWN_STATIC std::string GetArkWebRenderLibName()
|
|
{
|
|
std::string arkWebRenderLibPath = ARK_WEB_CORE_HAP_LIB_PATH + "/"
|
|
+ ARK_WEB_RENDER_LIB_NAME;
|
|
bool isArkWebRenderLibPathExist = access(arkWebRenderLibPath.c_str(), F_OK) == 0;
|
|
return isArkWebRenderLibPathExist ?
|
|
ARK_WEB_RENDER_LIB_NAME : WEB_RENDER_LIB_NAME;
|
|
}
|
|
|
|
APPSPAWN_STATIC int RunChildProcessor(AppSpawnContent *content, AppSpawnClient *client)
|
|
{
|
|
uint32_t len = 0;
|
|
char *renderCmd = reinterpret_cast<char *>(GetAppPropertyExt(
|
|
reinterpret_cast<AppSpawningCtx *>(client), MSG_EXT_NAME_RENDER_CMD, &len));
|
|
if (renderCmd == nullptr) {
|
|
return -1;
|
|
}
|
|
std::string renderStr(renderCmd);
|
|
void *webEngineHandle = nullptr;
|
|
void *nwebRenderHandle = nullptr;
|
|
|
|
const std::string& libPath = ARK_WEB_CORE_HAP_LIB_PATH;
|
|
const std::string engineLibName = GetArkWebEngineLibName();
|
|
const std::string renderLibName = GetArkWebRenderLibName();
|
|
|
|
#ifdef __MUSL__
|
|
Dl_namespace dlns;
|
|
dlns_init(&dlns, "nweb_ns");
|
|
dlns_create(&dlns, libPath.c_str());
|
|
Dl_namespace ndkns;
|
|
dlns_get("ndk", &ndkns);
|
|
dlns_inherit(&dlns, &ndkns, "allow_all_shared_libs");
|
|
// preload libweb_engine
|
|
webEngineHandle = dlopen_ns(&dlns, engineLibName.c_str(), RTLD_NOW | RTLD_GLOBAL);
|
|
// load libnweb_render
|
|
nwebRenderHandle =
|
|
dlopen_ns(&dlns, renderLibName.c_str(), RTLD_NOW | RTLD_GLOBAL);
|
|
#else
|
|
// preload libweb_engine
|
|
const std::string engineLibPath = libPath + "/" + engineLibName;
|
|
webEngineHandle = dlopen(engineLibPath.c_str(), RTLD_NOW | RTLD_GLOBAL);
|
|
|
|
// load libnweb_render
|
|
const std::string renderLibPath = libPath + "/" + renderLibName;
|
|
nwebRenderHandle = dlopen(renderLibPath.c_str(), RTLD_NOW | RTLD_GLOBAL);
|
|
#endif
|
|
if (webEngineHandle == nullptr) {
|
|
APPSPAWN_LOGE("Fail to dlopen libweb_engine.so, errno: %{public}d", errno);
|
|
}
|
|
if (nwebRenderHandle == nullptr) {
|
|
APPSPAWN_LOGE("Fail to dlopen libnweb_render.so, errno: %{public}d", errno);
|
|
return -1;
|
|
}
|
|
|
|
std::string processType = reinterpret_cast<char *>(GetAppPropertyExt(
|
|
reinterpret_cast<AppSpawningCtx *>(client), MSG_EXT_NAME_PROCESS_TYPE, &len));
|
|
if (processType == "render" && !SetSeccompPolicyForRenderer(nwebRenderHandle)) {
|
|
return -1;
|
|
}
|
|
using FuncType = void (*)(const char *cmd);
|
|
|
|
FuncType funcNWebRenderMain = reinterpret_cast<FuncType>(dlsym(nwebRenderHandle, "NWebRenderMain"));
|
|
if (funcNWebRenderMain == nullptr) {
|
|
APPSPAWN_LOGE("webviewspawn dlsym errno: %{public}d", errno);
|
|
return -1;
|
|
}
|
|
AppSpawnEnvClear(content, client);
|
|
APPSPAWN_LOGI("RunChildProcessorNweb %{public}s", renderStr.c_str());
|
|
funcNWebRenderMain(renderStr.c_str());
|
|
return 0;
|
|
}
|
|
|
|
static int PreLoadNwebSpawn(AppSpawnMgr *content)
|
|
{
|
|
APPSPAWN_LOGI("PreLoadNwebSpawn %{public}d", IsNWebSpawnMode(content));
|
|
if (!IsNWebSpawnMode(content)) {
|
|
return 0;
|
|
}
|
|
// register
|
|
RegChildLooper(&content->content, RunChildProcessor);
|
|
return 0;
|
|
}
|
|
|
|
MODULE_CONSTRUCTOR(void)
|
|
{
|
|
APPSPAWN_LOGI("Load nweb module ...");
|
|
AddPreloadHook(HOOK_PRIO_HIGHEST, PreLoadNwebSpawn);
|
|
}
|