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> ¶ms, 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> ¶ms, 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