• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_callback.h"
17 
18 #include "adapter.h"
19 #include "bundle_callback_utils.h"
20 #include "bundle_inner_interface.h"
21 #include "bundle_manager.h"
22 #include "iproxy_client.h"
23 #include "log.h"
24 #include "ohos_types.h"
25 #include "samgr_lite.h"
26 
27 namespace OHOS {
~BundleCallback()28 BundleCallback::~BundleCallback()
29 {
30     if (svcIdentity_ != nullptr) {
31         UnregisterIpcCallback(*svcIdentity_);
32         TransmitServiceId(*svcIdentity_, false);
33         AdapterFree(svcIdentity_);
34     }
35     callbackMap_.clear();
36 }
37 
Notify(IOwner owner,int code,IpcIo * reply)38 static int Notify(IOwner owner, int code, IpcIo *reply)
39 {
40     if ((reply == nullptr) || (owner == nullptr)) {
41         return EC_INVALID;
42     }
43     if (IpcIoPopUint8(reply) != CHANGE_CALLBACK_SERVICE_IDENTITY) {
44         return EC_INVALID;
45     }
46     uint8_t *result = reinterpret_cast<uint8_t *>(owner);
47     *result = IpcIoPopUint8(reply);
48     return EC_SUCCESS;
49 }
50 
InnerCallback(uint32_t installType,uint8_t resultCode,const char * bundleName)51 int32_t InnerCallback(uint32_t installType, uint8_t resultCode, const char *bundleName)
52 {
53     if (bundleName == nullptr) {
54         return ERR_APPEXECFWK_OBJECT_NULL;
55     }
56     BundleCallbackInfo callbackInfo = BundleCallback::GetInstance().GetCallbackInfoByName(bundleName);
57     BundleStateCallback callback = callbackInfo.bundleStateCallback;
58     if (callback == nullptr) {
59         HILOG_ERROR(HILOG_MODULE_APP, "InnerCallback is nullptr");
60         return ERR_APPEXECFWK_CALLBACK_NULL_CORRESPONDING_CALLBACK;
61     }
62 
63     if (resultCode != ERR_OK) {
64         callback(installType, resultCode, ObtainErrorMessage(resultCode).c_str(), bundleName, callbackInfo.data);
65         return ERR_OK;
66     }
67 
68     if (installType == INSTALL_CALLBACK) {
69         callback(installType, resultCode, INSTALL_SUCCESS, bundleName, callbackInfo.data);
70         return ERR_OK;
71     }
72 
73     if (installType == UNINSTALL_CALLBACK) {
74         callback(installType, resultCode, UNINSTALL_SUCCESS, bundleName, callbackInfo.data);
75         return ERR_OK;
76     }
77     HILOG_ERROR(HILOG_MODULE_APP, "param installType is invalid!");
78     return ERR_APPEXECFWK_CALLBACK_GET_ERROR_INSTALLTYPE;
79 }
80 
Callback(const IpcContext * context,void * ipcMsg,IpcIo * io,void * arg)81 static int32_t Callback(const IpcContext* context, void *ipcMsg, IpcIo *io, void *arg)
82 {
83     // at here, arg is always been nullptr
84     if (ipcMsg == nullptr) {
85         HILOG_ERROR(HILOG_MODULE_APP, "BundleCallback ipcMsg is nullptr");
86         return ERR_APPEXECFWK_OBJECT_NULL;
87     }
88 
89     if (io == nullptr) {
90         HILOG_ERROR(HILOG_MODULE_APP, "BundleCallback io is nullptr");
91         FreeBuffer(NULL, ipcMsg);
92         return ERR_APPEXECFWK_OBJECT_NULL;
93     }
94 
95     uint32_t installType = 0;
96     int32_t ret = GetCode(ipcMsg, &installType);
97     if (ret != LITEIPC_OK) {
98         FreeBuffer(NULL, ipcMsg);
99         HILOG_ERROR(HILOG_MODULE_APP, "BundleCallback Get install type failed");
100         return ERR_APPEXECFWK_CALLBACK_GET_INSTALLTYPE_FAILED;
101     }
102     if ((installType == INSTALL_CALLBACK) || (installType == UNINSTALL_CALLBACK)) {
103         uint8_t resultCode = static_cast<uint8_t>(IpcIoPopInt32(io));
104         size_t size = 0;
105         char *bundleName = reinterpret_cast<char *>(IpcIoPopString(io, &size));
106         ret = InnerCallback(installType, resultCode, bundleName);
107         FreeBuffer(NULL, ipcMsg);
108         return ret;
109     }
110     FreeBuffer(NULL, ipcMsg);
111     HILOG_ERROR(HILOG_MODULE_APP, "BundleSelfCallback get error install type");
112     return ERR_APPEXECFWK_CALLBACK_GET_ERROR_INSTALLTYPE;
113 }
114 
TransmitServiceId(const SvcIdentity & svc,bool flag)115 int32_t BundleCallback::TransmitServiceId(const SvcIdentity &svc, bool flag)
116 {
117     IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(BMS_SERVICE, BMS_FEATURE);
118     if (iUnknown == nullptr) {
119         return ERR_APPEXECFWK_CALLBACK_SERVICEID_TRANSMITTED_FAILED;
120     }
121     IClientProxy *bmsClient = nullptr;
122     int32_t result = iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, reinterpret_cast<void **>(&bmsClient));
123     if ((result != 0) || (bmsClient == nullptr)) {
124         return ERR_APPEXECFWK_CALLBACK_SERVICEID_TRANSMITTED_FAILED;
125     }
126     IpcIo ipcIo;
127     uint32_t data[IPC_IO_DATA_MAX];
128     IpcIoInit(&ipcIo, data, IPC_IO_DATA_MAX, 1);
129     IpcIoPushBool(&ipcIo, flag);
130     IpcIoPushSvc(&ipcIo, &svc);
131     if (!IpcIoAvailable(&ipcIo)) {
132         HILOG_ERROR(HILOG_MODULE_APP, "BundleCallback TransmitServiceId ipc failed");
133         return ERR_APPEXECFWK_IPCIO_UNAVAILABLED;
134     }
135     uint8_t errorCode = 0;
136     int32_t ret = bmsClient->Invoke(bmsClient, CHANGE_CALLBACK_SERVICE_IDENTITY, &ipcIo, &errorCode, Notify);
137     if (ret != OHOS_SUCCESS) {
138         HILOG_ERROR(HILOG_MODULE_APP, "TransmitServiceId calling Invoke function failed: %{public}d", ret);
139         return ERR_APPEXECFWK_INVOKE_ERROR;
140     }
141 
142     return errorCode;
143 }
144 
GenerateLocalServiceId()145 int32_t BundleCallback::GenerateLocalServiceId()
146 {
147     if (svcIdentity_ != nullptr) {
148         return ERR_OK;
149     }
150     svcIdentity_ = reinterpret_cast<SvcIdentity *>(AdapterMalloc(sizeof(SvcIdentity)));
151     if (svcIdentity_ == nullptr) {
152         return ERR_APPEXECFWK_CALLBACK_GENERATE_LOCAL_SERVICEID_FAILED;
153     }
154     int32_t ret = RegisterIpcCallback(Callback, 0, IPC_WAIT_FOREVER, svcIdentity_, NULL);
155     if ((ret != LITEIPC_OK)) {
156         AdapterFree(svcIdentity_);
157         return ERR_APPEXECFWK_CALLBACK_GENERATE_LOCAL_SERVICEID_FAILED;
158     }
159     ret = TransmitServiceId(*svcIdentity_, true);
160     if (ret != ERR_OK) {
161         UnregisterIpcCallback(*svcIdentity_);
162         AdapterFree(svcIdentity_);
163         return ERR_APPEXECFWK_CALLBACK_SERVICEID_TRANSMITTED_FAILED;
164     }
165     return ERR_OK;
166 }
167 
168 // register callback by bundle name
RegisterBundleStateCallback(const BundleStateCallback & callback,const char * bundleName,void * data)169 int32_t BundleCallback::RegisterBundleStateCallback(const BundleStateCallback &callback,
170     const char *bundleName, void *data)
171 {
172     int32_t ret = GenerateLocalServiceId();
173     if (ret != ERR_OK) {
174         return ERR_APPEXECFWK_CALLBACK_GENERATE_LOCAL_SERVICEID_FAILED;
175     }
176 
177     if ((bundleName == nullptr) || (strlen(bundleName) == 0)) {
178         // monitor all applications by the callback function bundleStateCallback_
179         bundleStateCallback_ = callback;
180         innerData_ = data;
181         callbackMap_.clear();
182         return ERR_OK;
183     }
184     // already monitor all applications
185     if (bundleStateCallback_ != nullptr) {
186         return ERR_OK;
187     }
188     std::string innerBundleName = bundleName;
189     auto it = callbackMap_.find(innerBundleName);
190     if (it != callbackMap_.end()) {
191         // already monitor the application
192         it->second.bundleStateCallback = callback;
193         it->second.data = data;
194         return ERR_OK;
195     }
196     BundleCallbackInfo bundleCallbackInfo;
197     bundleCallbackInfo.bundleStateCallback = callback;
198     bundleCallbackInfo.data = data;
199     callbackMap_.emplace(bundleName, bundleCallbackInfo);
200     return ERR_OK;
201 }
202 
203 // unregister callback of all application
UnregisterBundleStateCallback()204 int32_t BundleCallback::UnregisterBundleStateCallback()
205 {
206     if (svcIdentity_ == nullptr) {
207         return ERR_APPEXECFWK_CALLBACK_UNREGISTER_FAILED;
208     }
209 
210     bundleStateCallback_ = nullptr;
211     innerData_ = nullptr;
212     callbackMap_.clear();
213     (void) TransmitServiceId(*svcIdentity_, false);
214     (void) UnregisterIpcCallback(*svcIdentity_);
215     AdapterFree(svcIdentity_);
216     return ERR_OK;
217 }
218 
GetCallbackInfoByName(const char * bundleName)219 BundleCallbackInfo BundleCallback::GetCallbackInfoByName(const char *bundleName)
220 {
221     BundleCallbackInfo innerCallbackInfo = { nullptr, nullptr };
222     if ((bundleName == nullptr) || (strlen(bundleName) == 0)) {
223         return innerCallbackInfo;
224     }
225 
226     if (bundleStateCallback_ != nullptr) {
227         innerCallbackInfo.bundleStateCallback = bundleStateCallback_;
228         innerCallbackInfo.data = innerData_;
229         return innerCallbackInfo;
230     }
231     std::string innerBundleName = bundleName;
232     auto it = callbackMap_.find(innerBundleName);
233     if (it == callbackMap_.end()) {
234         return innerCallbackInfo;
235     }
236     return it->second;
237 }
238 } // namespace OHOS
239