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 "ipc_skeleton.h"
26 #include "bundle_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     size_t length = 0;
117     char *reqPath = reinterpret_cast<char *>(ReadString(req, &length));
118     SvcIdentity svc;
119     if (!(ReadRemoteObject(req, &svc))) {
120         HILOG_ERROR(HILOG_MODULE_APP, "BundleMS inner feature deserialize serviceId failed");
121         return ERR_APPEXECFWK_DESERIALIZATION_FAILED;
122     }
123 
124     SvcIdentityInfo *info = reinterpret_cast<SvcIdentityInfo *>(AdapterMalloc(sizeof(SvcIdentityInfo)));
125     if (info == nullptr) {
126         HILOG_ERROR(HILOG_MODULE_APP, "BundleMS inner feature malloc service info info failed");
127         return ERR_APPEXECFWK_SYSTEM_INTERNAL_ERROR;
128     }
129     uint8_t svcIdentityInfoRsp = GetSvcIdentityInfo(info, &svc, reqPath, req);
130     if (svcIdentityInfoRsp != ERR_OK) {
131         AdapterFree(info->path);
132         AdapterFree(info->svc);
133         AdapterFree(info);
134         return svcIdentityInfoRsp;
135     }
136     Request request = {
137         .msgId = BUNDLE_INSTALLED,
138         .len = static_cast<int16>(sizeof(SvcIdentityInfo)),
139         .data = reinterpret_cast<void *>(info),
140         .msgValue = 0
141     };
142     int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr);
143     if (propRet != OHOS_SUCCESS) {
144         AdapterFree(info->path);
145         AdapterFree(info->svc);
146         AdapterFree(info);
147         return ERR_APPEXECFWK_INSTALL_FAILED_SEND_REQUEST_ERROR;
148     }
149     return ERR_OK;
150 }
151 
GetSvcIdentityInfo(SvcIdentityInfo * info,const SvcIdentity * svc,const char * reqPath,IpcIo * req)152 uint8_t BundleInnerFeature::GetSvcIdentityInfo(SvcIdentityInfo *info, const SvcIdentity *svc, const char *reqPath,
153     IpcIo *req)
154 {
155     if (info == nullptr) {
156         HILOG_ERROR(HILOG_MODULE_APP, "BundleMS inner feature malloc service info info failed");
157         return ERR_APPEXECFWK_SYSTEM_INTERNAL_ERROR;
158     }
159     info->path = Utils::Strdup(reqPath);
160     if (info->path == nullptr) {
161         AdapterFree(info);
162         HILOG_ERROR(HILOG_MODULE_APP, "BundleMS inner feature malloc path failed");
163         return ERR_APPEXECFWK_SYSTEM_INTERNAL_ERROR;
164     }
165     info->bundleName = nullptr;
166     info->svc = reinterpret_cast<SvcIdentity *>(AdapterMalloc(sizeof(SvcIdentity)));
167     if (info->svc == nullptr) {
168         AdapterFree(info->path);
169         AdapterFree(info);
170         HILOG_ERROR(HILOG_MODULE_APP, "BundleMS inner feature malloc serviceId failed");
171         return ERR_APPEXECFWK_SYSTEM_INTERNAL_ERROR;
172     }
173     *(info->svc) = *svc;
174     ReadInt32(req, &(info->installLocation));
175     info->keepData = false;
176 
177     return ERR_OK;
178 }
179 
UninstallInnerBundle(const uint8_t funcId,IpcIo * req,IpcIo * reply)180 uint8_t BundleInnerFeature::UninstallInnerBundle(const uint8_t funcId, IpcIo *req, IpcIo *reply)
181 {
182     if ((req == nullptr) || (reply == nullptr)) {
183         HILOG_ERROR(HILOG_MODULE_APP, "BundleMS UninstallInnerBundle, request or reply is null");
184         return ERR_APPEXECFWK_OBJECT_NULL;
185     }
186     size_t length = 0;
187     char *bundleName = reinterpret_cast<char *>(ReadString(req, &length));
188     if (bundleName == nullptr) {
189         HILOG_ERROR(HILOG_MODULE_APP, "BundleMS inner feature deserialize bundle name failed");
190         return ERR_APPEXECFWK_DESERIALIZATION_FAILED;
191     }
192     SvcIdentity svc;
193     if (!(ReadRemoteObject(req, &svc))) {
194         HILOG_ERROR(HILOG_MODULE_APP, "BundleMS inner feature deserialize serviceId failed");
195         return ERR_APPEXECFWK_DESERIALIZATION_FAILED;
196     }
197     SvcIdentityInfo *info = reinterpret_cast<SvcIdentityInfo *>(AdapterMalloc(sizeof(SvcIdentityInfo)));
198     if (info == nullptr) {
199         HILOG_ERROR(HILOG_MODULE_APP, "BundleMS inner feature malloc service info failed");
200         return ERR_APPEXECFWK_SYSTEM_INTERNAL_ERROR;
201     }
202     info->path = nullptr;
203     info->bundleName = Utils::Strdup(bundleName);
204     info->svc = reinterpret_cast<SvcIdentity *>(AdapterMalloc(sizeof(SvcIdentity)));
205     if (info->svc == nullptr) {
206         AdapterFree(info->bundleName);
207         AdapterFree(info);
208         HILOG_ERROR(HILOG_MODULE_APP, "BundleMS inner feature malloc serviceId failed");
209         return ERR_APPEXECFWK_SYSTEM_INTERNAL_ERROR;
210     }
211     *(info->svc) = svc;
212     info->installLocation = 0;
213     ReadBool(req, &(info->keepData));
214     Request request = {
215         .msgId = BUNDLE_UNINSTALLED,
216         .len = static_cast<int16>(sizeof(SvcIdentityInfo)),
217         .data = reinterpret_cast<void *>(info),
218         .msgValue = 0
219     };
220     int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr);
221     if (propRet != OHOS_SUCCESS) {
222         AdapterFree(info->bundleName);
223         AdapterFree(info->svc);
224         AdapterFree(info);
225         return ERR_APPEXECFWK_UNINSTALL_FAILED_SEND_REQUEST_ERROR;
226     }
227     return ERR_OK;
228 }
229 
230 #ifdef OHOS_DEBUG
SetExternalInstallMode(const uint8_t funcId,IpcIo * req,IpcIo * reply)231 uint8_t BundleInnerFeature::SetExternalInstallMode(const uint8_t funcId, IpcIo *req, IpcIo *reply)
232 {
233     if ((req == nullptr) || (reply == nullptr)) {
234         return ERR_APPEXECFWK_OBJECT_NULL;
235     }
236     bool mode;
237     ReadBool(req, &mode);
238     uint8_t errorCode = OHOS::ManagerService::GetInstance().SetExternalInstallMode(mode);
239     if (errorCode == OHOS_SUCCESS) {
240         WriteUint8(reply, static_cast<uint8_t>(OHOS_SUCCESS));
241     }
242     return errorCode;
243 }
244 
SetInnerDebugMode(const uint8_t funcId,IpcIo * req,IpcIo * reply)245 uint8_t BundleInnerFeature::SetInnerDebugMode(const uint8_t funcId, IpcIo *req, IpcIo *reply)
246 {
247     if ((req == nullptr) || (reply == nullptr)) {
248         return ERR_APPEXECFWK_OBJECT_NULL;
249     }
250     bool mode;
251     ReadBool(req, &mode);
252     uint8_t errorCode = OHOS::ManagerService::GetInstance().SetDebugMode(mode);
253     if (errorCode == OHOS_SUCCESS) {
254         WriteUint8(reply, static_cast<uint8_t>(OHOS_SUCCESS));
255     }
256     return errorCode;
257 }
258 
SetInnerSignMode(const uint8_t funcId,IpcIo * req,IpcIo * reply)259 uint8_t BundleInnerFeature::SetInnerSignMode(const uint8_t funcId, IpcIo *req, IpcIo *reply)
260 {
261     if ((req == nullptr) || (reply == nullptr)) {
262         return ERR_APPEXECFWK_OBJECT_NULL;
263     }
264     bool mode;
265     ReadBool(req, &mode);
266     uint8_t errorCode = OHOS::ManagerService::GetInstance().SetSignMode(mode);
267     if (errorCode == OHOS_SUCCESS) {
268         WriteUint8(reply, static_cast<uint8_t>(OHOS_SUCCESS));
269     }
270     return errorCode;
271 }
272 #endif
273 
Invoke(IServerProxy * iProxy,int funcId,void * origin,IpcIo * req,IpcIo * reply)274 int32 BundleInnerFeature::Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply)
275 {
276     if (req == nullptr) {
277         return ERR_APPEXECFWK_OBJECT_NULL;
278     }
279     WriteUint8(reply, static_cast<uint8_t>(funcId));
280     uint8_t ret = OHOS_SUCCESS;
281 #ifdef OHOS_DEBUG
282     if ((funcId >= BMS_INNER_BEGIN) && (funcId < BMS_CMD_END)) {
283 #else
284     if ((funcId >= BMS_INNER_BEGIN) && (funcId <= UNINSTALL)) {
285 #endif
286         ret = BundleMsInvokeFuc[funcId - BMS_INNER_BEGIN](funcId, req, reply);
287     } else {
288         ret = ERR_APPEXECFWK_COMMAND_ERROR;
289     }
290 
291     if (ret != OHOS_SUCCESS) {
292         WriteUint8(reply, ret);
293     }
294     return ret;
295 }
296 } // namespace OHOS
297