• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "ets_free_install_observer.h"
17 
18 #include "ability_business_error.h"
19 #include "ani_common_ability_result.h"
20 #include "ani_common_util.h"
21 #include "ani_common_want.h"
22 #include "hilog_tag_wrapper.h"
23 #include "hitrace_meter.h"
24 
25 namespace OHOS {
26 namespace AbilityRuntime {
EtsFreeInstallObserver(ani_vm * etsVm)27 EtsFreeInstallObserver::EtsFreeInstallObserver(ani_vm *etsVm) : etsVm_(etsVm) {}
28 
~EtsFreeInstallObserver()29 EtsFreeInstallObserver::~EtsFreeInstallObserver()
30 {
31     ani_env *env = nullptr;
32     ani_status status = ANI_ERROR;
33     ani_option interopEnabled { "--interop=disable", nullptr };
34     ani_options aniArgs { 1, &interopEnabled };
35     if (etsVm_ == nullptr) {
36         TAG_LOGE(AAFwkTag::FREE_INSTALL, "null etsVm_");
37         return;
38     }
39     if ((etsVm_->AttachCurrentThread(&aniArgs, ANI_VERSION_1, &env)) != ANI_OK) {
40         TAG_LOGE(AAFwkTag::FREE_INSTALL, "status: %{public}d", status);
41         return;
42     }
43     if (env == nullptr) {
44         TAG_LOGE(AAFwkTag::FREE_INSTALL, "null env");
45         return;
46     }
47     for (auto it = etsObserverObjectList_.begin(); it != etsObserverObjectList_.end();) {
48         env->GlobalReference_Delete(it->callback);
49         it++;
50     }
51     if ((status = etsVm_->DetachCurrentThread()) != ANI_OK) {
52         TAG_LOGE(AAFwkTag::FREE_INSTALL, "status: %{public}d", status);
53     }
54 }
55 
OnInstallFinished(const std::string & bundleName,const std::string & abilityName,const std::string & startTime,int32_t resultCode)56 void EtsFreeInstallObserver::OnInstallFinished(
57     const std::string &bundleName, const std::string &abilityName, const std::string &startTime, int32_t resultCode)
58 {
59     TAG_LOGD(AAFwkTag::FREE_INSTALL, "OnInstallFinished");
60     HandleOnInstallFinished(bundleName, abilityName, startTime, resultCode);
61 }
62 
OnInstallFinished(const std::string & bundleName,const std::string & abilityName,const std::string & startTime,ani_object abilityResult)63 void EtsFreeInstallObserver::OnInstallFinished(const std::string &bundleName, const std::string &abilityName,
64     const std::string &startTime, ani_object abilityResult)
65 {
66     TAG_LOGD(AAFwkTag::FREE_INSTALL, "OnInstallFinished");
67     std::vector<ani_object> callbacks;
68     {
69         std::unique_lock<std::mutex> lock(etsObserverObjectListLock_);
70         for (auto it = etsObserverObjectList_.begin(); it != etsObserverObjectList_.end();) {
71             if ((it->bundleName != bundleName) || (it->abilityName != abilityName) || (it->startTime != startTime)
72                 || (it->callback == nullptr) || (!it->isAbilityResult)) {
73                 it++;
74                 continue;
75             }
76             callbacks.emplace_back(it->callback);
77             it = etsObserverObjectList_.erase(it);
78             TAG_LOGD(AAFwkTag::FREE_INSTALL, "etsObserverObjectList_ size:%{public}zu", etsObserverObjectList_.size());
79         }
80     }
81 
82     for (auto& callback : callbacks) {
83         CallCallback(callback, abilityResult);
84         FinishAsyncTrace(HITRACE_TAG_ABILITY_MANAGER, "StartFreeInstall", atoi(startTime.c_str()));
85     }
86 }
87 
OnInstallFinishedByUrl(const std::string & startTime,const std::string & url,int32_t resultCode)88 void EtsFreeInstallObserver::OnInstallFinishedByUrl(
89     const std::string &startTime, const std::string &url, int32_t resultCode)
90 {
91     TAG_LOGD(AAFwkTag::FREE_INSTALL, "OnInstallFinishedByUrl");
92     HandleOnInstallFinishedByUrl(startTime, url, resultCode);
93 }
94 
HandleOnInstallFinished(const std::string & bundleName,const std::string & abilityName,const std::string & startTime,int32_t resultCode)95 void EtsFreeInstallObserver::HandleOnInstallFinished(
96     const std::string &bundleName, const std::string &abilityName, const std::string &startTime, int32_t resultCode)
97 {
98     std::vector<ani_object> callbacks;
99     {
100         std::unique_lock<std::mutex> lock(etsObserverObjectListLock_);
101         for (auto it = etsObserverObjectList_.begin(); it != etsObserverObjectList_.end();) {
102             if ((it->bundleName != bundleName) || (it->abilityName != abilityName) || (it->startTime != startTime) ||
103                 (it->callback == nullptr) || (it->isAbilityResult && resultCode == ERR_OK)) {
104                 it++;
105                 continue;
106             }
107             callbacks.emplace_back(it->callback);
108             it = etsObserverObjectList_.erase(it);
109         }
110     }
111 
112     for (auto& callback : callbacks) {
113         CallCallback(callback, resultCode);
114         FinishAsyncTrace(HITRACE_TAG_ABILITY_MANAGER, "StartFreeInstall", atoi(startTime.c_str()));
115     }
116 }
117 
HandleOnInstallFinishedByUrl(const std::string & startTime,const std::string & url,int32_t resultCode)118 void EtsFreeInstallObserver::HandleOnInstallFinishedByUrl(
119     const std::string &startTime, const std::string &url, int32_t resultCode)
120 {
121     std::vector<ani_object> callbacks;
122     {
123         std::unique_lock<std::mutex> lock(etsObserverObjectListLock_);
124         for (auto it = etsObserverObjectList_.begin(); it != etsObserverObjectList_.end();) {
125             if ((it->startTime != startTime) || (it->url != url) || (it->callback == nullptr)) {
126                 it++;
127                 continue;
128             }
129             callbacks.emplace_back(it->callback);
130             it = etsObserverObjectList_.erase(it);
131         }
132     }
133 
134     for (auto& callback : callbacks) {
135         CallCallback(callback, resultCode);
136         FinishAsyncTrace(HITRACE_TAG_ABILITY_MANAGER, "StartFreeInstall", atoi(startTime.c_str()));
137     }
138 }
139 
CallCallback(ani_object callback,int32_t resultCode)140 void EtsFreeInstallObserver::CallCallback(ani_object callback, int32_t resultCode)
141 {
142     TAG_LOGD(AAFwkTag::FREE_INSTALL, "CallCallback");
143     if (callback == nullptr) {
144         TAG_LOGE(AAFwkTag::FREE_INSTALL, "null callback");
145         return;
146     }
147     if (etsVm_ == nullptr) {
148         TAG_LOGE(AAFwkTag::FREE_INSTALL, "null etsVm");
149         return;
150     }
151     ani_env *env = nullptr;
152     ani_status status = ANI_ERROR;
153     ani_option interopEnabled { "--interop=disable", nullptr };
154     ani_options aniArgs { 1, &interopEnabled };
155     if ((status = etsVm_->AttachCurrentThread(&aniArgs, ANI_VERSION_1, &env)) != ANI_OK || env == nullptr) {
156         TAG_LOGE(AAFwkTag::FREE_INSTALL, "Failed to getEnv, status: %{public}d", status);
157     } else if ((status = etsVm_->GetEnv(ANI_VERSION_1, &env)) != ANI_OK || env == nullptr) {
158         TAG_LOGE(AAFwkTag::FREE_INSTALL, "Failed to getEnv, status: %{public}d", status);
159         return;
160     }
161     ani_object aniObject = EtsErrorUtil::CreateError(env, AbilityErrorCode::ERROR_OK);
162     if (resultCode != ERR_OK) {
163         aniObject = EtsErrorUtil::CreateErrorByNativeErr(env, resultCode);
164     }
165     AppExecFwk::AsyncCallback(env, callback, aniObject, nullptr);
166     env->GlobalReference_Delete(callback);
167     if ((status = etsVm_->DetachCurrentThread()) != ANI_OK) {
168         TAG_LOGE(AAFwkTag::FREE_INSTALL, "status: %{public}d", status);
169     }
170 }
171 
CallCallback(ani_object callback,ani_object abilityResult)172 void EtsFreeInstallObserver::CallCallback(ani_object callback, ani_object abilityResult)
173 {
174     TAG_LOGD(AAFwkTag::FREE_INSTALL, "CallCallback");
175     if (abilityResult == nullptr) {
176         TAG_LOGE(AAFwkTag::FREE_INSTALL, "null abilityResult");
177         return;
178     }
179     if (callback == nullptr) {
180         TAG_LOGE(AAFwkTag::FREE_INSTALL, "null callback");
181         return;
182     }
183     if (etsVm_ == nullptr) {
184         TAG_LOGE(AAFwkTag::FREE_INSTALL, "null etsVm");
185         return;
186     }
187     ani_env *env = nullptr;
188     ani_status status = ANI_ERROR;
189     if ((status = etsVm_->GetEnv(ANI_VERSION_1, &env)) != ANI_OK || env == nullptr) {
190         TAG_LOGE(AAFwkTag::FREE_INSTALL, "Failed to getEnv, status: %{public}d", status);
191     }
192     ani_object aniObject = EtsErrorUtil::CreateError(env, AbilityErrorCode::ERROR_OK);
193     AppExecFwk::AsyncCallback(env, callback, aniObject, abilityResult);
194     env->GlobalReference_Delete(callback);
195 }
196 
AddEtsObserverObject(ani_env * env,const std::string & bundleName,const std::string & abilityName,const std::string & startTime,ani_object callback,bool isAbilityResult)197 void EtsFreeInstallObserver::AddEtsObserverObject(ani_env *env, const std::string &bundleName,
198     const std::string &abilityName, const std::string &startTime, ani_object callback, bool isAbilityResult)
199 {
200     TAG_LOGD(AAFwkTag::FREE_INSTALL, "AddEtsObserverObject");
201     {
202         std::unique_lock<std::mutex> lock(etsObserverObjectListLock_);
203         for (auto it = etsObserverObjectList_.begin(); it != etsObserverObjectList_.end(); ++it) {
204             if (it->bundleName == bundleName && it->abilityName == abilityName && it->startTime == startTime) {
205                 TAG_LOGW(AAFwkTag::FREE_INSTALL, "The EtsFreeInstallObserverObject has been added");
206                 return;
207             }
208         }
209     }
210     StartAsyncTrace(HITRACE_TAG_ABILITY_MANAGER, "StartFreeInstall", atoi(startTime.c_str()));
211     EtsFreeInstallObserverObject object;
212     object.bundleName = bundleName;
213     object.abilityName = abilityName;
214     object.startTime = startTime;
215     object.isAbilityResult = isAbilityResult;
216     AddEtsObserverCommon(env, object, callback);
217 }
218 
AddEtsObserverObject(ani_env * env,const std::string & startTime,const std::string & url,ani_object callback,bool isAbilityResult)219 void EtsFreeInstallObserver::AddEtsObserverObject(
220     ani_env *env, const std::string &startTime, const std::string &url, ani_object callback, bool isAbilityResult)
221 {
222     TAG_LOGD(AAFwkTag::FREE_INSTALL, "AddEtsObserverObject");
223     {
224         std::unique_lock<std::mutex> lock(etsObserverObjectListLock_);
225         for (auto it = etsObserverObjectList_.begin(); it != etsObserverObjectList_.end(); ++it) {
226             if (it->startTime == startTime && it->url == url) {
227                 TAG_LOGW(AAFwkTag::FREE_INSTALL, "add etsObject");
228                 return;
229             }
230         }
231     }
232     StartAsyncTrace(HITRACE_TAG_ABILITY_MANAGER, "StartFreeInstall", atoi(startTime.c_str()));
233     EtsFreeInstallObserverObject object;
234     object.url = url;
235     object.startTime = startTime;
236     object.isAbilityResult = isAbilityResult;
237     AddEtsObserverCommon(env, object, callback);
238 }
239 
AddEtsObserverCommon(ani_env * env,EtsFreeInstallObserverObject & object,ani_object callback)240 void EtsFreeInstallObserver::AddEtsObserverCommon(
241     ani_env *env, EtsFreeInstallObserverObject &object, ani_object callback)
242 {
243     TAG_LOGD(AAFwkTag::FREE_INSTALL, "AddEtsObserverCommon");
244     std::unique_lock<std::mutex> lock(etsObserverObjectListLock_);
245     ani_ref global = nullptr;
246     ani_status status = ANI_ERROR;
247     if ((status = env->GlobalReference_Create(callback, &global)) != ANI_OK) {
248         TAG_LOGE(AAFwkTag::UI_EXT, "status: %{public}d", status);
249         return;
250     }
251     object.callback = reinterpret_cast<ani_object>(global);
252     etsObserverObjectList_.emplace_back(object);
253 }
254 } // namespace AbilityRuntime
255 } // namespace OHOS