• 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 #include "ani_driver_extension.h"
16 
17 #include "ability_info.h"
18 #include "ani_common_want.h"
19 #include "ani_remote_object.h"
20 #include "ani_utils.h"
21 #include "DriverExtensionContext_ani.h"
22 #include "hitrace_meter.h"
23 #include "hilog_wrapper.h"
24 #include "ets_native_reference.h"
25 
26 constexpr const char* DRIVER_EXTENSION_CLS = "L@ohos/app/ability/DriverExtensionAbility/DriverExtensionAbility;";
27 namespace OHOS {
28 namespace AbilityRuntime {
29 using namespace OHOS::AppExecFwk;
AniDriverExtension(ETSRuntime & aniRuntime)30 AniDriverExtension::AniDriverExtension(ETSRuntime& aniRuntime) : stsRuntime_(aniRuntime) {}
31 AniDriverExtension::~AniDriverExtension() = default;
32 
Create(const std::unique_ptr<Runtime> & runtime)33 AniDriverExtension* AniDriverExtension::Create(const std::unique_ptr<Runtime>& runtime)
34 {
35     return new AniDriverExtension(static_cast<ETSRuntime&>(*runtime));
36 }
37 
Init(const std::shared_ptr<AbilityLocalRecord> & record,const std::shared_ptr<OHOSApplication> & application,std::shared_ptr<AbilityHandler> & handler,const sptr<IRemoteObject> & token)38 void AniDriverExtension::Init(const std::shared_ptr<AbilityLocalRecord> &record,
39     const std::shared_ptr<OHOSApplication> &application, std::shared_ptr<AbilityHandler> &handler,
40     const sptr<IRemoteObject> &token)
41 {
42     HILOG_DEBUG("%{public}s begin.", __func__);
43     DriverExtension::Init(record, application, handler, token);
44     if (Extension::abilityInfo_ == nullptr || Extension::abilityInfo_->srcEntrance.empty()) {
45         HILOG_ERROR("DriverExtensionAbility Init abilityInfo error");
46         return;
47     }
48     std::string srcPath(Extension::abilityInfo_->moduleName + "/");
49     srcPath.append(Extension::abilityInfo_->srcEntrance);
50     auto pos = srcPath.rfind(".");
51     if (pos != std::string::npos) {
52         srcPath.erase(pos);
53         srcPath.append(".abc");
54     }
55     std::string moduleName(Extension::abilityInfo_->moduleName);
56     moduleName.append("::").append(abilityInfo_->name);
57     stsObj_ = stsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->hapPath,
58                                      abilityInfo_->compileMode == AppExecFwk::CompileMode::ES_MODULE, false,
59                                      abilityInfo_->srcEntrance);
60     if (stsObj_ == nullptr) {
61         HILOG_ERROR("Failed to get etsObj");
62         return;
63     }
64     auto env = stsRuntime_.GetAniEnv();
65     BindContext(env, record->GetWant(), application);
66     HILOG_DEBUG("%{public}s end.", __func__);
67 }
68 
BindContext(ani_env * env,std::shared_ptr<AAFwk::Want> want,const std::shared_ptr<OHOSApplication> & application)69 void AniDriverExtension::BindContext(ani_env *env, std::shared_ptr<AAFwk::Want> want,
70     const std::shared_ptr<OHOSApplication> &application)
71 {
72     HILOG_DEBUG("StsServiceExtension BindContext Call");
73     if (env == nullptr || want == nullptr) {
74         HILOG_ERROR("Want info is null or env is null");
75         return;
76     }
77     auto context = GetContext();
78     if (context == nullptr) {
79         HILOG_ERROR("Failed to get context");
80         return;
81     }
82     ani_object contextObj = CreateAniDriverExtensionContext(env, context, application);
83     if (contextObj == nullptr) {
84         HILOG_ERROR("null contextObj");
85         return;
86     }
87     ani_field contextField;
88     ani_class cls = nullptr;
89     if ((env->FindClass(DRIVER_EXTENSION_CLS, &cls)) != ANI_OK) {
90         HILOG_ERROR("FindClass err: %{public}s", DRIVER_EXTENSION_CLS);
91         return;
92     }
93     auto status = env->Class_FindField(cls, "context", &contextField);
94     if (status != ANI_OK) {
95         HILOG_ERROR("Class_GetField context failed");
96         return;
97     }
98     ani_ref contextRef = nullptr;
99     if (env->GlobalReference_Create(contextObj, &contextRef) != ANI_OK) {
100         HILOG_ERROR("GlobalReference_Create contextObj failed");
101         return;
102     }
103     if (env->Object_SetField_Ref(stsObj_->aniObj, contextField, contextRef) != ANI_OK) {
104         HILOG_ERROR("Object_SetField_Ref contextObj failed");
105         return;
106     }
107     HILOG_DEBUG("BindContext end");
108 }
109 
OnStart(const AAFwk::Want & want)110 void AniDriverExtension::OnStart(const AAFwk::Want &want)
111 {
112     HILOG_DEBUG("%{public}s begin.", __func__);
113     Extension::OnStart(want);
114     auto env = stsRuntime_.GetAniEnv();
115     ani_object ani_want = OHOS::AppExecFwk::WrapWant(env, want);
116     if (ANI_OK != env->Object_CallMethodByName_Void(stsObj_->aniObj, "onInit", nullptr, ani_want)) {
117         HILOG_ERROR("Failed to call the method: onInit");
118         return;
119     }
120     HILOG_DEBUG("%{public}s end.", __func__);
121 }
122 
OnStop()123 void AniDriverExtension::OnStop()
124 {
125     HILOG_DEBUG("%{public}s begin.", __func__);
126     DriverExtension::OnStop();
127     auto env = stsRuntime_.GetAniEnv();
128     if (ANI_OK != env->Object_CallMethodByName_Void(stsObj_->aniObj, "onRelease", nullptr)) {
129         HILOG_ERROR("Failed to call the method: onRelease");
130         return;
131     }
132     HILOG_DEBUG("%{public}s end.", __func__);
133 }
134 
OnConnect(const AAFwk::Want & want)135 sptr<IRemoteObject> AniDriverExtension::OnConnect(const AAFwk::Want &want)
136 {
137     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
138     HILOG_DEBUG("%{public}s begin.", __func__);
139     Extension::OnConnect(want);
140     ani_ref result = nullptr;
141     auto env = stsRuntime_.GetAniEnv();
142     ani_object ani_want = OHOS::AppExecFwk::WrapWant(env, want);
143     if (ANI_OK != env->Object_CallMethodByName_Ref(stsObj_->aniObj, "onConnect", nullptr, &result, ani_want)) {
144         HILOG_ERROR("Failed to call the method: onConnect");
145         return nullptr;
146     }
147     if (result == nullptr) {
148         HILOG_ERROR("Failed to call onConnect : result == nullptr");
149         return nullptr;
150     }
151     HILOG_DEBUG("%{public}s end.", __func__);
152     auto obj = reinterpret_cast<ani_object>(result);
153     auto remoteObj = AniGetNativeRemoteObject(env, obj);
154     if (remoteObj == nullptr) {
155         HILOG_ERROR("remoteObj null");
156         return nullptr;
157     }
158     HILOG_DEBUG("end");
159     return remoteObj;
160 }
161 
OnConnect(const AAFwk::Want & want,AppExecFwk::AbilityTransactionCallbackInfo<sptr<IRemoteObject>> * callbackInfo,bool & isAsyncCallback)162 sptr<IRemoteObject> AniDriverExtension::OnConnect(const AAFwk::Want &want,
163     AppExecFwk::AbilityTransactionCallbackInfo<sptr<IRemoteObject>> *callbackInfo, bool &isAsyncCallback)
164 {
165     HILOG_DEBUG("%{public}s begin.", __func__);
166     if (callbackInfo == nullptr) {
167         HILOG_DEBUG("%{public}s is not AsyncCallback.", __func__);
168         isAsyncCallback = false;
169         return this->OnConnect(want);
170     }
171     Extension::OnConnect(want);
172     ani_boolean isAsync = false;
173     auto env = stsRuntime_.GetAniEnv();
174     if (ANI_OK != env->Object_SetFieldByName_Long(stsObj_->aniObj, "connectCbInfo",
175         reinterpret_cast<ani_long>(callbackInfo))) {
176         HILOG_ERROR("Failed to Set the connectCbInfo");
177         return nullptr;
178     }
179     ani_ref wantRef = OHOS::AppExecFwk::WrapWant(env, want);
180     ani_ref result = nullptr;
181     if (ANI_OK !=
182         env->Object_CallMethodByName_Ref(stsObj_->aniObj, "callOnConnect", nullptr, &result, wantRef)) {
183         HILOG_ERROR("2 Failed to call the method: callOnConnect");
184         return nullptr;
185     }
186     auto obj = reinterpret_cast<ani_object>(result);
187     auto remoteObj = AniGetNativeRemoteObject(env, obj);
188     if (remoteObj == nullptr) {
189         HILOG_ERROR("remoteObj null");
190         return nullptr;
191     }
192     if (ANI_OK != env->Object_GetFieldByName_Boolean(stsObj_->aniObj, "isOnConnectAsync", &isAsync)) {
193         HILOG_ERROR("Failed to Get the isOnConnectAsync");
194         return nullptr;
195     }
196     if (isAsync) {
197         isAsyncCallback = true;
198         callbackInfo->Call(remoteObj);
199         AppExecFwk::AbilityTransactionCallbackInfo<sptr<IRemoteObject>>::Destroy(callbackInfo);
200         return nullptr;
201     }
202     HILOG_DEBUG("%{public}s end.", __func__);
203     return remoteObj;
204 }
205 
OnDisconnect(const AAFwk::Want & want)206 void AniDriverExtension::OnDisconnect(const AAFwk::Want &want)
207 {
208     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
209     HILOG_DEBUG("%{public}s begin.", __func__);
210     Extension::OnDisconnect(want);
211     auto env = stsRuntime_.GetAniEnv();
212     ani_object ani_want = OHOS::AppExecFwk::WrapWant(env, want);
213     if (ANI_OK != env->Object_CallMethodByName_Void(stsObj_->aniObj, "callOnDisConnect", nullptr, ani_want)) {
214         HILOG_ERROR("Failed to call the method: onDisconnect");
215         return;
216     }
217     HILOG_DEBUG("%{public}s end.", __func__);
218 }
219 
OnDisconnect(const AAFwk::Want & want,AppExecFwk::AbilityTransactionCallbackInfo<> * callbackInfo,bool & isAsyncCallback)220 void AniDriverExtension::OnDisconnect(const AAFwk::Want &want,
221     AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo, bool &isAsyncCallback)
222 {
223     HILOG_DEBUG("%{public}s begin.", __func__);
224     if (callbackInfo == nullptr) {
225         this->OnDisconnect(want);
226         return;
227     }
228     auto env = stsRuntime_.GetAniEnv();
229     Extension::OnDisconnect(want);
230     if (ANI_OK != env->Object_SetFieldByName_Long(stsObj_->aniObj, "disConnectCbInfo",
231         reinterpret_cast<ani_long>(callbackInfo))) {
232         HILOG_ERROR("Failed to Set the disConnectCbInfo");
233         return;
234     }
235     ani_object ani_want = OHOS::AppExecFwk::WrapWant(env, want);
236     if (ANI_OK != env->Object_CallMethodByName_Void(stsObj_->aniObj, "callOnDisConnect", nullptr, ani_want)) {
237         HILOG_ERROR("Failed to call the method: callOnDisConnect");
238         return;
239     }
240     ani_boolean isAsync = false;
241     if (ANI_OK != env->Object_GetFieldByName_Boolean(stsObj_->aniObj, "isOnDisconnectAsync", &isAsync)) {
242         HILOG_ERROR("Failed to Get the isOnDisconnectAsync");
243         return;
244     }
245     if (isAsync) {
246         isAsyncCallback = true;
247         callbackInfo->Call();
248         AppExecFwk::AbilityTransactionCallbackInfo<>::Destroy(callbackInfo);
249         return;
250     }
251     HILOG_DEBUG("%{public}s end.", __func__);
252 }
253 
ToAniStringList(ani_env * env,const std::vector<std::string> & params,const uint32_t length)254 ani_array_ref AniDriverExtension::ToAniStringList(ani_env *env,
255     const std::vector<std::string> &params, const uint32_t length)
256 {
257     HILOG_DEBUG("%{public}s begin.", __func__);
258     if (env == nullptr) {
259         return nullptr;
260     }
261     ani_array_ref result = nullptr;
262     ani_class stringCls = nullptr;
263     if (ANI_OK != env->FindClass("Lstd/core/String;", &stringCls)) {
264         HILOG_ERROR("FindClass Lstd/core/String Failed");
265         return result;
266     }
267     if (env->Array_New_Ref(stringCls, length, nullptr, &result) != ANI_OK) {
268         return result;
269     }
270     for (auto i = 0; i < length;  ++i) {
271         if (ANI_OK != env->Array_Set_Ref(result, i, AniStringUtils::ToAni(env, params[i]))) {
272             return result;
273         }
274     }
275     HILOG_DEBUG("%{public}s end.", __func__);
276     return result;
277 }
278 
Dump(const std::vector<std::string> & params,std::vector<std::string> & info)279 void AniDriverExtension::Dump(const std::vector<std::string> &params, std::vector<std::string> &info)
280 {
281     HILOG_DEBUG("%{public}s begin.", __func__);
282     Extension::Dump(params, info);
283     auto env = stsRuntime_.GetAniEnv();
284     ani_array_ref params_ = ToAniStringList(env, params, params.size());
285     ani_ref result = nullptr;
286     if (ANI_OK != env->Object_CallMethodByName_Ref(stsObj_->aniObj, "onDump", nullptr, &result, params_)) {
287         HILOG_ERROR("Failed to call the method: Dump");
288         return;
289     }
290     ani_double length;
291     if (ANI_OK != env->Object_GetPropertyByName_Double(static_cast<ani_object>(result), "length", &length)) {
292         HILOG_ERROR("Object_GetPropertyByName_Double length Failed");
293         return;
294     }
295     for (int i = 0; i < int(length); i++) {
296         ani_ref stringEntryRef;
297         if (ANI_OK != env->Object_CallMethodByName_Ref(static_cast<ani_object>(result), "$_get",
298             "I:Lstd/core/Object;", &stringEntryRef, (ani_int)i)) {
299             HILOG_ERROR("Object_CallMethodByName_Ref get Failed");
300             return;
301         }
302         info.push_back(AniStringUtils::ToStd(env, static_cast<ani_string>(stringEntryRef)));
303     }
304     HILOG_DEBUG("%{public}s end.", __func__);
305 }
306 } // AbilityRuntime
307 } // OHOS