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
16 #include "bundle_inner_feature.h"
17
18 #include "ability_info_utils.h"
19 #include "appexecfwk_errors.h"
20 #include "bundle_info_utils.h"
21 #include "bundle_inner_interface.h"
22 #include "bundle_manager_service.h"
23 #include "bundle_message_id.h"
24 #include "convert_utils.h"
25 #include "liteipc_adapter.h"
26 #include "log.h"
27 #include "message.h"
28 #include "ohos_init.h"
29 #include "samgr_lite.h"
30 #include "securec.h"
31 #include "serializer.h"
32 #include "utils.h"
33 #include "want_utils.h"
34
35 namespace OHOS {
36 static BmsInnerImpl g_bmsInnerImpl = {
37 SERVER_IPROXY_IMPL_BEGIN,
38 .Invoke = BundleInnerFeature::Invoke,
39 IPROXY_END
40 };
41
42 BundleInvokeType BundleInnerFeature::BundleMsInvokeFuc[BMS_CMD_END - BMS_INNER_BEGIN] {
43 InstallInnerBundle,
44 UninstallInnerBundle,
45 #ifdef OHOS_DEBUG
46 SetExternalInstallMode,
47 SetInnerDebugMode,
48 SetInnerSignMode,
49 #endif
50 };
51
GetBmsInnerFeatureApi(Feature * feature)52 IUnknown *GetBmsInnerFeatureApi(Feature *feature)
53 {
54 g_bmsInnerImpl.bundleInnerFeature = reinterpret_cast<BundleInnerFeature *>(feature);
55 return GET_IUNKNOWN(g_bmsInnerImpl);
56 }
57
Init()58 static void Init()
59 {
60 SamgrLite *sm = SAMGR_GetInstance();
61 if (sm == nullptr) {
62 return;
63 }
64 sm->RegisterFeature(BMS_SERVICE, reinterpret_cast<Feature *>(BundleInnerFeature::GetInstance()));
65 sm->RegisterFeatureApi(BMS_SERVICE, BMS_INNER_FEATURE,
66 GetBmsInnerFeatureApi(reinterpret_cast<Feature *>(BundleInnerFeature::GetInstance())));
67 HILOG_DEBUG(HILOG_MODULE_APP, "BundleMS inner feature start success");
68 }
69 APP_FEATURE_INIT(Init);
70
BundleInnerFeature()71 BundleInnerFeature::BundleInnerFeature() : identity_()
72 {
73 this->Feature::GetName = BundleInnerFeature::GetFeatureName;
74 this->Feature::OnInitialize = BundleInnerFeature::OnFeatureInitialize;
75 this->Feature::OnStop = BundleInnerFeature::OnFeatureStop;
76 this->Feature::OnMessage = BundleInnerFeature::OnFeatureMessage;
77 }
78
~BundleInnerFeature()79 BundleInnerFeature::~BundleInnerFeature() {}
80
GetFeatureName(Feature * feature)81 const char *BundleInnerFeature::GetFeatureName(Feature *feature)
82 {
83 (void) feature;
84 return BMS_INNER_FEATURE;
85 }
86
OnFeatureInitialize(Feature * feature,Service * parent,Identity identity)87 void BundleInnerFeature::OnFeatureInitialize(Feature *feature, Service *parent, Identity identity)
88 {
89 if (feature == nullptr) {
90 return;
91 }
92 (reinterpret_cast<BundleInnerFeature *>(feature))->identity_ = identity;
93 }
94
OnFeatureStop(Feature * feature,Identity identity)95 void BundleInnerFeature::OnFeatureStop(Feature *feature, Identity identity)
96 {
97 (void) feature;
98 (void) identity;
99 }
100
OnFeatureMessage(Feature * feature,Request * request)101 BOOL BundleInnerFeature::OnFeatureMessage(Feature *feature, Request *request)
102 {
103 if (feature == nullptr || request == nullptr) {
104 return FALSE;
105 }
106 ManagerService::GetInstance().ServiceMsgProcess(request);
107 return TRUE;
108 }
109
InstallInnerBundle(const uint8_t funcId,IpcIo * req,IpcIo * reply)110 uint8_t BundleInnerFeature::InstallInnerBundle(const uint8_t funcId, IpcIo *req, IpcIo *reply)
111 {
112 if ((req == nullptr) || (reply == nullptr)) {
113 HILOG_ERROR(HILOG_MODULE_APP, "BundleMS InstallInnerBundle, request or reply is null");
114 return ERR_APPEXECFWK_OBJECT_NULL;
115 }
116 #ifdef __LINUX__
117 size_t length = 0;
118 char *reqPath = reinterpret_cast<char *>(IpcIoPopString(req, &length));
119 #else
120 BuffPtr *buff = IpcIoPopDataBuff(req);
121 if (buff == nullptr) {
122 HILOG_ERROR(HILOG_MODULE_APP, "BundleMS inner feature deserialize req data failed");
123 return ERR_APPEXECFWK_DESERIALIZATION_FAILED;
124 }
125 char *reqPath = reinterpret_cast<char *>(buff->buff);
126 if ((reqPath == nullptr) || (buff->buffSz == 0)) {
127 HILOG_ERROR(HILOG_MODULE_APP, "BundleMS inner feature deserialize install path failed");
128 return ERR_APPEXECFWK_DESERIALIZATION_FAILED;
129 }
130 #endif
131 SvcIdentity *svc = IpcIoPopSvc(req);
132 if (svc == nullptr) {
133 HILOG_ERROR(HILOG_MODULE_APP, "BundleMS inner feature deserialize serviceId failed");
134 return ERR_APPEXECFWK_DESERIALIZATION_FAILED;
135 }
136
137 SvcIdentityInfo *info = reinterpret_cast<SvcIdentityInfo *>(AdapterMalloc(sizeof(SvcIdentityInfo)));
138 if (info == nullptr) {
139 #ifdef __LINUX__
140 AdapterFree(svc);
141 svc = nullptr;
142 #endif
143 HILOG_ERROR(HILOG_MODULE_APP, "BundleMS inner feature malloc service info info failed");
144 return ERR_APPEXECFWK_SYSTEM_INTERNAL_ERROR;
145 }
146 uint8_t svcIdentityInfoRsp = GetSvcIdentityInfo(info, svc, reqPath, req);
147 #ifdef __LINUX__
148 BinderAcquire(svc->ipcContext, svc->handle);
149 AdapterFree(svc);
150 svc = nullptr;
151 #endif
152 if (svcIdentityInfoRsp != ERR_OK) {
153 return svcIdentityInfoRsp;
154 }
155 Request request = {
156 .msgId = BUNDLE_INSTALLED,
157 .len = static_cast<int16>(sizeof(SvcIdentityInfo)),
158 .data = reinterpret_cast<void *>(info),
159 .msgValue = 0
160 };
161 int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr);
162 if (propRet != OHOS_SUCCESS) {
163 AdapterFree(info->path);
164 AdapterFree(info->svc);
165 AdapterFree(info);
166 return ERR_APPEXECFWK_INSTALL_FAILED_SEND_REQUEST_ERROR;
167 }
168 return ERR_OK;
169 }
170
GetSvcIdentityInfo(SvcIdentityInfo * info,const SvcIdentity * svc,const char * reqPath,IpcIo * req)171 uint8_t BundleInnerFeature::GetSvcIdentityInfo(SvcIdentityInfo *info, const SvcIdentity *svc, const char *reqPath,
172 IpcIo *req)
173 {
174 if (info == nullptr) {
175 HILOG_ERROR(HILOG_MODULE_APP, "BundleMS inner feature malloc service info info failed");
176 return ERR_APPEXECFWK_SYSTEM_INTERNAL_ERROR;
177 }
178 info->path = Utils::Strdup(reqPath);
179 if (info->path == nullptr) {
180 AdapterFree(info);
181 HILOG_ERROR(HILOG_MODULE_APP, "BundleMS inner feature malloc path failed");
182 return ERR_APPEXECFWK_SYSTEM_INTERNAL_ERROR;
183 }
184 info->bundleName = nullptr;
185 info->svc = reinterpret_cast<SvcIdentity *>(AdapterMalloc(sizeof(SvcIdentity)));
186 if (info->svc == nullptr) {
187 AdapterFree(info->path);
188 AdapterFree(info);
189 HILOG_ERROR(HILOG_MODULE_APP, "BundleMS inner feature malloc serviceId failed");
190 return ERR_APPEXECFWK_SYSTEM_INTERNAL_ERROR;
191 }
192 *(info->svc) = *svc;
193 info->installLocation = IpcIoPopInt32(req);
194 info->keepData = false;
195
196 return ERR_OK;
197 }
198
UninstallInnerBundle(const uint8_t funcId,IpcIo * req,IpcIo * reply)199 uint8_t BundleInnerFeature::UninstallInnerBundle(const uint8_t funcId, IpcIo *req, IpcIo *reply)
200 {
201 if ((req == nullptr) || (reply == nullptr)) {
202 HILOG_ERROR(HILOG_MODULE_APP, "BundleMS UninstallInnerBundle, request or reply is null");
203 return ERR_APPEXECFWK_OBJECT_NULL;
204 }
205 size_t length = 0;
206 char *bundleName = reinterpret_cast<char *>(IpcIoPopString(req, &length));
207 if (bundleName == nullptr) {
208 HILOG_ERROR(HILOG_MODULE_APP, "BundleMS inner feature deserialize bundle name failed");
209 return ERR_APPEXECFWK_DESERIALIZATION_FAILED;
210 }
211 SvcIdentity *svc = IpcIoPopSvc(req);
212 if (svc == nullptr) {
213 HILOG_ERROR(HILOG_MODULE_APP, "BundleMS inner feature deserialize serviceId failed");
214 return ERR_APPEXECFWK_DESERIALIZATION_FAILED;
215 }
216 SvcIdentityInfo *info = reinterpret_cast<SvcIdentityInfo *>(AdapterMalloc(sizeof(SvcIdentityInfo)));
217 if (info == nullptr) {
218 #ifdef __LINUX__
219 AdapterFree(svc);
220 svc = nullptr;
221 #endif
222 HILOG_ERROR(HILOG_MODULE_APP, "BundleMS inner feature malloc service info failed");
223 return ERR_APPEXECFWK_SYSTEM_INTERNAL_ERROR;
224 }
225 info->path = nullptr;
226 info->bundleName = Utils::Strdup(bundleName);
227 info->svc = reinterpret_cast<SvcIdentity *>(AdapterMalloc(sizeof(SvcIdentity)));
228 if (info->svc == nullptr) {
229 AdapterFree(info->bundleName);
230 AdapterFree(info);
231 #ifdef __LINUX__
232 AdapterFree(svc);
233 svc = nullptr;
234 #endif
235 HILOG_ERROR(HILOG_MODULE_APP, "BundleMS inner feature malloc serviceId failed");
236 return ERR_APPEXECFWK_SYSTEM_INTERNAL_ERROR;
237 }
238 *(info->svc) = *svc;
239 #ifdef __LINUX__
240 BinderAcquire(svc->ipcContext, svc->handle);
241 AdapterFree(svc);
242 svc = nullptr;
243 #endif
244 info->installLocation = 0;
245 info->keepData = IpcIoPopBool(req);
246 Request request = {
247 .msgId = BUNDLE_UNINSTALLED,
248 .len = static_cast<int16>(sizeof(SvcIdentityInfo)),
249 .data = reinterpret_cast<void *>(info),
250 .msgValue = 0
251 };
252 int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr);
253 if (propRet != OHOS_SUCCESS) {
254 AdapterFree(info->bundleName);
255 AdapterFree(info->svc);
256 AdapterFree(info);
257 return ERR_APPEXECFWK_UNINSTALL_FAILED_SEND_REQUEST_ERROR;
258 }
259 return ERR_OK;
260 }
261
262 #ifdef OHOS_DEBUG
SetExternalInstallMode(const uint8_t funcId,IpcIo * req,IpcIo * reply)263 uint8_t BundleInnerFeature::SetExternalInstallMode(const uint8_t funcId, IpcIo *req, IpcIo *reply)
264 {
265 if ((req == nullptr) || (reply == nullptr)) {
266 return ERR_APPEXECFWK_OBJECT_NULL;
267 }
268 uint8_t errorCode = OHOS::ManagerService::GetInstance().SetExternalInstallMode(IpcIoPopBool(req));
269 if (errorCode == OHOS_SUCCESS) {
270 IpcIoPushUint8(reply, static_cast<uint8_t>(OHOS_SUCCESS));
271 }
272 return errorCode;
273 }
274
SetInnerDebugMode(const uint8_t funcId,IpcIo * req,IpcIo * reply)275 uint8_t BundleInnerFeature::SetInnerDebugMode(const uint8_t funcId, IpcIo *req, IpcIo *reply)
276 {
277 if ((req == nullptr) || (reply == nullptr)) {
278 return ERR_APPEXECFWK_OBJECT_NULL;
279 }
280 uint8_t errorCode = OHOS::ManagerService::GetInstance().SetDebugMode(IpcIoPopBool(req));
281 if (errorCode == OHOS_SUCCESS) {
282 IpcIoPushUint8(reply, static_cast<uint8_t>(OHOS_SUCCESS));
283 }
284 return errorCode;
285 }
286
SetInnerSignMode(const uint8_t funcId,IpcIo * req,IpcIo * reply)287 uint8_t BundleInnerFeature::SetInnerSignMode(const uint8_t funcId, IpcIo *req, IpcIo *reply)
288 {
289 if ((req == nullptr) || (reply == nullptr)) {
290 return ERR_APPEXECFWK_OBJECT_NULL;
291 }
292 uint8_t errorCode = OHOS::ManagerService::GetInstance().SetSignMode(IpcIoPopBool(req));
293 if (errorCode == OHOS_SUCCESS) {
294 IpcIoPushUint8(reply, static_cast<uint8_t>(OHOS_SUCCESS));
295 }
296 return errorCode;
297 }
298 #endif
299
Invoke(IServerProxy * iProxy,int funcId,void * origin,IpcIo * req,IpcIo * reply)300 int32 BundleInnerFeature::Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply)
301 {
302 if (req == nullptr) {
303 return ERR_APPEXECFWK_OBJECT_NULL;
304 }
305 IpcIoPushUint8(reply, static_cast<uint8_t>(funcId));
306 uint8_t ret = OHOS_SUCCESS;
307 #ifdef OHOS_DEBUG
308 if ((funcId >= BMS_INNER_BEGIN) && (funcId < BMS_CMD_END)) {
309 #else
310 if ((funcId >= BMS_INNER_BEGIN) && (funcId <= UNINSTALL)) {
311 #endif
312 ret = BundleMsInvokeFuc[funcId - BMS_INNER_BEGIN](funcId, req, reply);
313 } else {
314 ret = ERR_APPEXECFWK_COMMAND_ERROR;
315 }
316
317 if (ret != OHOS_SUCCESS) {
318 IpcIoPushUint8(reply, ret);
319 }
320 return ret;
321 }
322 } // namespace OHOS
323