1 /*
2 * Copyright (c) 2022 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 "aafwk_app_mgr_client_adapter_impl.h"
17
18 #include <chrono>
19 #include <thread>
20
21 #include "aafwk_browser_host_impl.h"
22 #include "aafwk_render_scheduler_impl.h"
23 #include "nweb_log.h"
24
25 namespace {
26 constexpr int GET_TERMINATION_STATUS_MAX_CNT = 5;
27 constexpr int START_RENDER_PROCESS_MAX_CNT = 10;
28 constexpr int SLEEP_FOR_MILLI_SECONDS_CNT = 10;
29 constexpr int RET_ALREADY_EXIST_RENDER = 8454244; // copy from ability_runtime
30 } // namespace
31
32 namespace OHOS::NWeb {
33 const std::string GPU_PROCESS_TYPE = "gpu-process";
AafwkAppMgrClientAdapterImpl()34 AafwkAppMgrClientAdapterImpl::AafwkAppMgrClientAdapterImpl()
35 : appMgrClient_(std::make_unique<AppExecFwk::AppMgrClient>())
36 {}
37
StartRenderProcess(const std::string & renderParam,int32_t ipcFd,int32_t sharedFd,int32_t crashFd,pid_t & renderPid)38 int AafwkAppMgrClientAdapterImpl::StartRenderProcess(
39 const std::string& renderParam, int32_t ipcFd, int32_t sharedFd, int32_t crashFd, pid_t& renderPid)
40 {
41 if (appMgrClient_ == nullptr) {
42 WVLOG_E("app mgr client is nullptr.");
43 return -1;
44 }
45
46 int retryCnt = 0;
47 int ret;
48 do {
49 ret = appMgrClient_->StartRenderProcess(renderParam, ipcFd, sharedFd, crashFd, renderPid, false);
50 if (ret == RET_ALREADY_EXIST_RENDER) {
51 WVLOG_E("app mgr client start render process failed, render process already exist.");
52 std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_FOR_MILLI_SECONDS_CNT));
53 continue;
54 }
55 if (ret != 0) {
56 WVLOG_E("app mgr client start render process failed, ret = %{public}d.", ret);
57 return -1;
58 }
59 } while (++retryCnt < START_RENDER_PROCESS_MAX_CNT && ret != 0);
60
61 if (ret != 0) {
62 WVLOG_E("over max retry times, app mgr client start render process failed, ret = %{public}d.", ret);
63 return -1;
64 }
65
66 return 0;
67 }
68
AttachRenderProcess(std::shared_ptr<AafwkRenderSchedulerHostAdapter> adapter)69 void AafwkAppMgrClientAdapterImpl::AttachRenderProcess(std::shared_ptr<AafwkRenderSchedulerHostAdapter> adapter)
70 {
71 if (appMgrClient_ == nullptr) {
72 WVLOG_E("app mgr client is nullptr.");
73 return;
74 }
75
76 if (adapter == nullptr) {
77 WVLOG_E("render scheduler is nullptr.");
78 return;
79 }
80
81 AafwkRenderSchedulerImpl *renderScheduler = new (std::nothrow) AafwkRenderSchedulerImpl(adapter);
82 if (renderScheduler == nullptr) {
83 WVLOG_E("new AafwkRenderSchedulerImpl failed.");
84 return;
85 }
86
87 appMgrClient_->AttachRenderProcess(renderScheduler);
88 }
89
GetRenderProcessTerminationStatus(pid_t renderPid,int & status)90 int AafwkAppMgrClientAdapterImpl::GetRenderProcessTerminationStatus(pid_t renderPid, int &status)
91 {
92 if (appMgrClient_ == nullptr) {
93 WVLOG_E("app mgr client is nullptr.");
94 return -1;
95 }
96
97 int retryCnt = 0;
98 do {
99 int ret = appMgrClient_->GetRenderProcessTerminationStatus(renderPid, status);
100 if (ret != 0) {
101 WVLOG_E("app mgr client get render process termination status failed, ret = %{public}d.", ret);
102 return -1;
103 }
104 } while (status < 0 && ++retryCnt < GET_TERMINATION_STATUS_MAX_CNT);
105
106 if (status < 0) {
107 WVLOG_E("render process termination status invalid, status = %{public}d.", status);
108 return -1;
109 }
110
111 return 0;
112 }
113
StartChildProcess(const std::string & renderParam,int32_t ipcFd,int32_t sharedFd,int32_t crashFd,pid_t & renderPid,const std::string & processType)114 int AafwkAppMgrClientAdapterImpl::StartChildProcess(
115 const std::string& renderParam, int32_t ipcFd, int32_t sharedFd,
116 int32_t crashFd, pid_t& renderPid, const std::string& processType)
117 {
118 if (appMgrClient_ == nullptr) {
119 WVLOG_E("app mgr client is nullptr.");
120 return -1;
121 }
122
123 bool isGPU = false;
124 if (processType == GPU_PROCESS_TYPE) {
125 isGPU = true;
126 }
127
128 int retryCnt = 0;
129 int ret;
130 do {
131 ret = appMgrClient_->StartRenderProcess(renderParam, ipcFd, sharedFd, crashFd, renderPid, isGPU);
132 if (ret == RET_ALREADY_EXIST_RENDER) {
133 WVLOG_E("app mgr client start %{public}s process failed, process already exist.", processType.c_str());
134 std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_FOR_MILLI_SECONDS_CNT));
135 continue;
136 }
137 if (ret != 0) {
138 WVLOG_E("app mgr client start render process failed, ret = %{public}d.", ret);
139 return -1;
140 }
141 } while (++retryCnt < START_RENDER_PROCESS_MAX_CNT && ret != 0);
142
143 if (ret != 0) {
144 WVLOG_E("over max retry times, app mgr client start render process failed, ret = %{public}d.", ret);
145 return -1;
146 }
147
148 return 0;
149 }
150
SaveBrowserConnect(std::shared_ptr<AafwkBrowserHostAdapter> adapter)151 void AafwkAppMgrClientAdapterImpl::SaveBrowserConnect(std::shared_ptr<AafwkBrowserHostAdapter> adapter)
152 {
153 if (appMgrClient_ == nullptr) {
154 WVLOG_E("app mgr client is nullptr.");
155 return;
156 }
157
158 if (adapter == nullptr) {
159 WVLOG_E("browser connect is nullptr.");
160 return;
161 }
162
163 AafwkBrowserHostImpl *browser = new (std::nothrow) AafwkBrowserHostImpl(adapter);
164 if (browser == nullptr) {
165 WVLOG_E("create new AafwkBrowserHostImpl failed!");
166 }
167 WVLOG_I("AafwkAppMgrClientAdapterImpl SaveBrowserConnect success!");
168 appMgrClient_->SaveBrowserChannel(browser);
169 }
170 } // namespace OHOS::NWeb
171