• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "native_child_ipc_process.h"
17 #include <dlfcn.h>
18 #include <thread>
19 #include <chrono>
20 #include "hilog_tag_wrapper.h"
21 #include "child_process_manager_error_utils.h"
22 
23 namespace OHOS {
24 namespace AbilityRuntime {
25 
Create()26 std::shared_ptr<ChildProcess> NativeChildIpcProcess::Create()
27 {
28     return std::make_shared<NativeChildIpcProcess>();
29 }
30 
~NativeChildIpcProcess()31 NativeChildIpcProcess::~NativeChildIpcProcess()
32 {
33     UnloadNativeLib();
34 }
35 
Init(const std::shared_ptr<ChildProcessStartInfo> & info)36 bool NativeChildIpcProcess::Init(const std::shared_ptr<ChildProcessStartInfo> &info)
37 {
38     TAG_LOGD(AAFwkTag::PROCESSMGR, "init");
39     if (info == nullptr || info->ipcObj == nullptr) {
40         TAG_LOGE(AAFwkTag::PROCESSMGR, "null info or ipc callback");
41         return false;
42     }
43 
44     if (!ChildProcess::Init(info)) {
45         TAG_LOGE(AAFwkTag::PROCESSMGR, "init failed");
46         return false;
47     }
48 
49     auto iNotify = iface_cast<OHOS::AppExecFwk::INativeChildNotify>(info->ipcObj);
50     if (iNotify == nullptr) {
51         TAG_LOGE(AAFwkTag::PROCESSMGR, "null iNotify");
52         return false;
53     }
54 
55     if (!LoadNativeLib(info)) {
56         auto errcode = ChildProcessManagerErrorUtil::CvtChildProcessManagerErrCode(
57             ChildProcessManagerErrorCode::ERR_LIB_LOADING_FAILED);
58         iNotify->OnError(static_cast<int32_t>(errcode));
59         return false;
60     }
61 
62     mainProcessCb_ = iNotify;
63     return true;
64 }
65 
OnStart()66 void NativeChildIpcProcess::OnStart()
67 {
68     if (funcNativeLibOnConnect_ == nullptr || funcNativeLibMainProc_ == nullptr || mainProcessCb_ == nullptr) {
69         TAG_LOGE(AAFwkTag::PROCESSMGR, "No init");
70         return;
71     }
72 
73     ChildProcess::OnStart();
74     OHIPCRemoteStub *ipcStub = funcNativeLibOnConnect_();
75     if (ipcStub == nullptr || ipcStub->remote == nullptr) {
76         TAG_LOGE(AAFwkTag::PROCESSMGR, "null ipcStub");
77         auto errcode = ChildProcessManagerErrorUtil::CvtChildProcessManagerErrCode(
78             ChildProcessManagerErrorCode::ERR_CONNECTION_FAILED);
79         mainProcessCb_->OnError(static_cast<int32_t>(errcode));
80         return;
81     }
82 
83     std::thread cbThread([this, childIpcStub = std::move(ipcStub->remote)] () -> void {
84         // Wait MainProc run first
85         std::this_thread::sleep_for(std::chrono::milliseconds(1));
86         TAG_LOGI(AAFwkTag::PROCESSMGR, "Notify native child process started");
87         mainProcessCb_->OnNativeChildStarted(childIpcStub);
88     });
89 
90     TAG_LOGI(AAFwkTag::PROCESSMGR, "Enter MainProc");
91     funcNativeLibMainProc_();
92     TAG_LOGI(AAFwkTag::PROCESSMGR, "MainProc returned");
93 
94     if (cbThread.joinable()) {
95         cbThread.join();
96     }
97 }
98 
LoadNativeLib(const std::shared_ptr<ChildProcessStartInfo> & info)99 bool NativeChildIpcProcess::LoadNativeLib(const std::shared_ptr<ChildProcessStartInfo> &info)
100 {
101     if (nativeLibHandle_ != nullptr) {
102         TAG_LOGE(AAFwkTag::PROCESSMGR, "null nativeLibHandle");
103         return false;
104     }
105 
106     if (info->moduleName.empty()) {
107         TAG_LOGE(AAFwkTag::PROCESSMGR, "empty module name");
108         return false;
109     }
110 
111     Dl_namespace dlnsApp;
112     std::string appDlNameSpace = "moduleNs_" + info->moduleName;
113     int ret = dlns_get(appDlNameSpace.c_str(), &dlnsApp);
114     if (ret != 0) {
115         TAG_LOGE(AAFwkTag::PROCESSMGR, "Get dlns(%{private}s) err:%{public}d",
116             appDlNameSpace.c_str(), ret);
117         return false;
118     }
119 
120     void *libHandle = dlopen_ns(&dlnsApp, info->srcEntry.c_str(), RTLD_LAZY);
121     if (libHandle == nullptr) {
122         TAG_LOGE(AAFwkTag::PROCESSMGR, "Load lib file %{private}s err %{public}s",
123             info->srcEntry.c_str(), dlerror());
124         return false;
125     }
126 
127     do {
128         NativeChildProcess_OnConnect funcOnConnect =
129             reinterpret_cast<NativeChildProcess_OnConnect>(dlsym(libHandle, "NativeChildProcess_OnConnect"));
130         if (funcOnConnect == nullptr) {
131             TAG_LOGE(AAFwkTag::PROCESSMGR, "null funcOnConnect, err %{public}s", dlerror());
132             break;
133         }
134 
135         NativeChildProcess_MainProc funcMainProc =
136             reinterpret_cast<NativeChildProcess_MainProc>(dlsym(libHandle, "NativeChildProcess_MainProc"));
137         if (funcMainProc == nullptr) {
138             TAG_LOGE(AAFwkTag::PROCESSMGR, "null funcMainProc, err %{public}s", dlerror());
139             break;
140         }
141 
142         funcNativeLibOnConnect_ = funcOnConnect;
143         funcNativeLibMainProc_ = funcMainProc;
144         nativeLibHandle_ = libHandle;
145         return true;
146     } while (false);
147 
148     dlclose(libHandle);
149     return false;
150 }
151 
UnloadNativeLib()152 void NativeChildIpcProcess::UnloadNativeLib()
153 {
154     if (nativeLibHandle_ != nullptr) {
155         dlclose(nativeLibHandle_);
156         nativeLibHandle_ = nullptr;
157         funcNativeLibOnConnect_ = nullptr;
158         funcNativeLibMainProc_ = nullptr;
159     }
160 }
161 
162 } // namespace AbilityRuntime
163 } // namespace OHOS
164