1 /*
2 * Copyright (c) 2020 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 #include "appspawn_service.h"
16 #include <stdlib.h>
17
18 #ifdef OHOS_DEBUG
19 #include <errno.h>
20 #include <time.h>
21 #endif // OHOS_DEBUG
22
23 #include "appspawn_message.h"
24 #include "appspawn_process.h"
25 #include "iproxy_server.h"
26 #include "iunknown.h"
27 #include "ipc_skeleton.h"
28 #include "log.h"
29 #include "message.h"
30 #include "ohos_errno.h"
31 #include "ohos_init.h"
32 #include "samgr_lite.h"
33 #include "service.h"
34
35
36 static const int INVALID_PID = -1;
37
38 typedef struct AppSpawnFeatureApi {
39 INHERIT_SERVER_IPROXY;
40 } AppSpawnFeatureApi;
41
42 typedef struct AppSpawnService {
43 INHERIT_SERVICE;
44 INHERIT_IUNKNOWNENTRY(AppSpawnFeatureApi);
45 Identity identity;
46 } AppSpawnService;
47
GetName(Service * service)48 static const char* GetName(Service* service)
49 {
50 (void)service;
51 HILOG_INFO(HILOG_MODULE_HIVIEW, "[appspawn] get service name %{public}s.", APPSPAWN_SERVICE_NAME);
52 return APPSPAWN_SERVICE_NAME;
53 }
54
Initialize(Service * service,Identity identity)55 static BOOL Initialize(Service* service, Identity identity)
56 {
57 if (service == NULL) {
58 HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] initialize, service NULL!");
59 return FALSE;
60 }
61
62 AppSpawnService* spawnService = (AppSpawnService*)service;
63 spawnService->identity = identity;
64
65 HILOG_INFO(HILOG_MODULE_HIVIEW, "[appspawn] initialize, identity<%{public}d, %{public}d, %{public}p>", \
66 identity.serviceId, identity.featureId, identity.queueId);
67 return TRUE;
68 }
69
MessageHandle(Service * service,Request * msg)70 static BOOL MessageHandle(Service* service, Request* msg)
71 {
72 (void)service;
73 (void)msg;
74 HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] message handle not support yet!");
75 return FALSE;
76 }
77
GetTaskConfig(Service * service)78 static TaskConfig GetTaskConfig(Service* service)
79 {
80 (void)service;
81 TaskConfig config = {LEVEL_HIGH, PRI_BELOW_NORMAL, 0x800, 20, SHARED_TASK};
82 return config;
83 }
84
85 #ifdef OHOS_DEBUG
GetCurTime(struct timespec * tmCur)86 static void GetCurTime(struct timespec* tmCur)
87 {
88 if (tmCur == NULL) {
89 return;
90 }
91 if (clock_gettime(CLOCK_REALTIME, tmCur) != 0) {
92 HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] invoke, get time failed! err %{public}d", errno);
93 }
94 }
95 #endif // OHOS_DEBUG
96
GetMessageSt(MessageSt * msgSt,IpcIo * req)97 static int GetMessageSt(MessageSt* msgSt, IpcIo* req)
98 {
99 if (msgSt == NULL || req == NULL) {
100 return EC_FAILURE;
101 }
102 size_t len = 0;
103 char* str = ReadString(req, &len);
104 if (str == NULL || len == 0) {
105 HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] invoke, get data failed.");
106 return EC_FAILURE;
107 }
108
109 int ret = SplitMessage(str, len, msgSt); // after split message, str no need to free(linux version)
110 return ret;
111 }
112
Invoke(IServerProxy * iProxy,int funcId,void * origin,IpcIo * req,IpcIo * reply)113 static int Invoke(IServerProxy* iProxy, int funcId, void* origin, IpcIo* req, IpcIo* reply)
114 {
115 #ifdef OHOS_DEBUG
116 struct timespec tmStart = {0};
117 GetCurTime(&tmStart);
118 #endif // OHOS_DEBUG
119
120 (void)iProxy;
121 (void)origin;
122
123 if (reply == NULL || funcId != ID_CALL_CREATE_SERVICE || req == NULL) {
124 HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] invoke, funcId %{public}d invalid, reply %{public}d.", \
125 funcId, INVALID_PID);
126 WriteInt64(reply, INVALID_PID);
127 return EC_BADPTR;
128 }
129
130 MessageSt msgSt = {0};
131 if (GetMessageSt(&msgSt, req) != EC_SUCCESS) {
132 HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] invoke, parse failed! reply %{public}d.", INVALID_PID);
133 WriteInt64(reply, INVALID_PID);
134 return EC_FAILURE;
135 }
136
137 HILOG_INFO(HILOG_MODULE_HIVIEW, "[appspawn] invoke, msg<%{public}s,%{public}s,%{public}d,%{public}d>", \
138 msgSt.bundleName, msgSt.identityID, msgSt.uID, msgSt.gID);
139
140 pid_t newPid = CreateProcess(&msgSt);
141 FreeMessageSt(&msgSt);
142 WriteInt64(reply, newPid);
143
144 #ifdef OHOS_DEBUG
145 struct timespec tmEnd = {0};
146 GetCurTime(&tmEnd);
147
148 // 1s = 1000000000ns
149 long timeUsed = (tmEnd.tv_sec - tmStart.tv_sec) * 1000000000L + (tmEnd.tv_nsec - tmStart.tv_nsec);
150 HILOG_INFO(HILOG_MODULE_HIVIEW, "[appspawn] invoke, reply pid %{public}d, timeused %{public}ld ns.", \
151 newPid, timeUsed);
152 #else
153 HILOG_INFO(HILOG_MODULE_HIVIEW, "[appspawn] invoke, reply pid %{public}d.", newPid);
154 #endif // OHOS_DEBUG
155
156 return ((newPid > 0) ? EC_SUCCESS : EC_FAILURE);
157 }
158
159 static AppSpawnService g_appSpawnService = {
160 .GetName = GetName,
161 .Initialize = Initialize,
162 .MessageHandle = MessageHandle,
163 .GetTaskConfig = GetTaskConfig,
164 SERVER_IPROXY_IMPL_BEGIN,
165 .Invoke = Invoke,
166 IPROXY_END,
167 };
168
AppSpawnInit(void)169 void AppSpawnInit(void)
170 {
171 if (SAMGR_GetInstance()->RegisterService((Service *)&g_appSpawnService) != TRUE) {
172 HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] register service failed!");
173 return;
174 }
175
176 HILOG_INFO(HILOG_MODULE_HIVIEW, "[appspawn] register service succeed. %{public}p.", &g_appSpawnService);
177
178 if (SAMGR_GetInstance()->RegisterDefaultFeatureApi(APPSPAWN_SERVICE_NAME, \
179 GET_IUNKNOWN(g_appSpawnService)) != TRUE) {
180 (void)SAMGR_GetInstance()->UnregisterService(APPSPAWN_SERVICE_NAME);
181 HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] register featureapi failed!");
182 return;
183 }
184
185 HILOG_INFO(HILOG_MODULE_HIVIEW, "[appspawn] register featureapi succeed.");
186 }
187
188 SYSEX_SERVICE_INIT(AppSpawnInit);
189
190