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 "ani_static_subscriber_extension.h"
17
18 #include "ability_handler.h"
19 #include "ani_common_want.h"
20 #include "ani_common_event_utils.h"
21 #include "ani_static_subscriber_extension_context.h"
22 #include "application_context.h"
23 #include "context.h"
24 #include "connection_manager.h"
25 #include "event_log_wrapper.h"
26 #include "extension_base.h"
27 #include "native_engine/native_engine.h"
28 #include "ets_runtime.h"
29 #include "static_subscriber_stub_impl.h"
30
31 namespace OHOS {
32 namespace EventManagerFwkAni {
33 using namespace OHOS::AppExecFwk;
34 using namespace OHOS::AbilityRuntime;
35 using namespace OHOS::EventFwk;
36 using namespace OHOS::EventManagerFwkAni;
37
Create(const std::unique_ptr<Runtime> & runtime)38 StsStaticSubscriberExtension* StsStaticSubscriberExtension::Create(const std::unique_ptr<Runtime>& runtime)
39 {
40 return new StsStaticSubscriberExtension(static_cast<ETSRuntime&>(*runtime));
41 }
StsStaticSubscriberExtension(ETSRuntime & stsRuntime)42 StsStaticSubscriberExtension::StsStaticSubscriberExtension(ETSRuntime &stsRuntime) : stsRuntime_(stsRuntime) {}
~StsStaticSubscriberExtension()43 StsStaticSubscriberExtension::~StsStaticSubscriberExtension()
44 {
45 EVENT_LOGD("~StsStaticSubscriberExtension called");
46 }
47
Init(const std::shared_ptr<AbilityLocalRecord> & record,const std::shared_ptr<OHOSApplication> & application,std::shared_ptr<AbilityHandler> & handler,const sptr<IRemoteObject> & token)48 void StsStaticSubscriberExtension::Init(const std::shared_ptr<AbilityLocalRecord> &record,
49 const std::shared_ptr<OHOSApplication> &application, std::shared_ptr<AbilityHandler> &handler,
50 const sptr<IRemoteObject> &token)
51 {
52 if (record == nullptr) {
53 EVENT_LOGE("record null");
54 return;
55 }
56 StaticSubscriberExtension::Init(record, application, handler, token);
57 if (Extension::abilityInfo_ == nullptr || Extension::abilityInfo_->srcEntrance.empty()) {
58 EVENT_LOGE("StaticSubscriberExtension Init abilityInfo error");
59 return;
60 }
61 std::string srcPath(Extension::abilityInfo_->moduleName + "/");
62 srcPath.append(Extension::abilityInfo_->srcEntrance);
63 auto pos = srcPath.rfind(".");
64 if (pos != std::string::npos) {
65 srcPath.erase(pos);
66 srcPath.append(".abc");
67 }
68 std::string moduleName(Extension::abilityInfo_->moduleName);
69 moduleName.append("::").append(abilityInfo_->name);
70 stsObj_ = stsRuntime_.LoadModule(
71 moduleName, srcPath, abilityInfo_->hapPath, abilityInfo_->compileMode == AppExecFwk::CompileMode::ES_MODULE,
72 false, abilityInfo_->srcEntrance);
73 if (stsObj_ == nullptr) {
74 EVENT_LOGE("stsObj_ null");
75 return;
76 }
77
78 auto env = stsRuntime_.GetAniEnv();
79 if (env == nullptr) {
80 EVENT_LOGE("null env");
81 return;
82 }
83 BindContext(env, application);
84 return;
85 }
86
BindContext(ani_env * env,const std::shared_ptr<OHOSApplication> & application)87 void StsStaticSubscriberExtension::BindContext(ani_env* env, const std::shared_ptr<OHOSApplication> &application)
88 {
89 EVENT_LOGD("StsStaticSubscriberExtension BindContext Call");
90 auto context = GetContext();
91 if (context == nullptr) {
92 EVENT_LOGE("Failed to get context");
93 return;
94 }
95
96 ani_object contextObj = CreateSTSContext(env, context, application);
97 if (contextObj == nullptr) {
98 EVENT_LOGE("null contextObj");
99 return;
100 }
101
102 ani_field contextField;
103 auto status = env->Class_FindField(stsObj_->aniCls, "context", &contextField);
104 if (status != ANI_OK) {
105 EVENT_LOGE("Class_GetField context failed");
106 ResetEnv(env);
107 return;
108 }
109 ani_ref contextRef = nullptr;
110 if (env->GlobalReference_Create(contextObj, &contextRef) != ANI_OK) {
111 EVENT_LOGE("GlobalReference_Create contextObj failed");
112 return;
113 }
114 if (env->Object_SetField_Ref(stsObj_->aniObj, contextField, contextRef) != ANI_OK) {
115 EVENT_LOGE("Object_SetField_Ref contextObj failed");
116 ResetEnv(env);
117 }
118 }
119
CreateSTSContext(ani_env * env,std::shared_ptr<StaticSubscriberExtensionContext> context,const std::shared_ptr<OHOSApplication> & application)120 ani_object StsStaticSubscriberExtension::CreateSTSContext(ani_env* env,
121 std::shared_ptr<StaticSubscriberExtensionContext> context,
122 const std::shared_ptr<OHOSApplication> &application)
123 {
124 ani_object STSContext = CreateStaticSubscriberExtensionContext(env, context, application);
125 return STSContext;
126 }
127
GetWeakPtr()128 std::weak_ptr<StsStaticSubscriberExtension> StsStaticSubscriberExtension::GetWeakPtr()
129 {
130 return std::static_pointer_cast<StsStaticSubscriberExtension>(shared_from_this());
131 }
132
OnReceiveEvent(std::shared_ptr<CommonEventData> data)133 void StsStaticSubscriberExtension::OnReceiveEvent(std::shared_ptr<CommonEventData> data)
134 {
135 const CommonEventData& commonEventData = *data;
136 EVENT_LOGD("OnReceiveEvent execute action = %{public}s", commonEventData.GetWant().GetAction().c_str());
137
138 if (handler_ == nullptr) {
139 EVENT_LOGE("handler is invalid");
140 return;
141 }
142 std::weak_ptr<StsStaticSubscriberExtension> wThis = GetWeakPtr();
143 auto task = [wThis, commonEventData, this]() {
144 std::shared_ptr<StsStaticSubscriberExtension> sThis = wThis.lock();
145 if (sThis == nullptr) {
146 return;
147 }
148 ani_env* env = sThis->stsRuntime_.GetAniEnv();
149 if (!env) {
150 EVENT_LOGE("task env not found env");
151 return;
152 }
153
154 ani_object ani_data {};
155 AniCommonEventUtils::ConvertCommonEventDataToEts(env, ani_data, commonEventData);
156 const char* signature = "LcommonEvent/commonEventData/CommonEventData;:V";
157 CallObjectMethod(false, "onReceiveEvent", signature, ani_data);
158 };
159 handler_->PostTask(task, "CommonEvent" + data->GetWant().GetAction());
160 }
161
ResetEnv(ani_env * env)162 void StsStaticSubscriberExtension::ResetEnv(ani_env* env)
163 {
164 env->DescribeError();
165 env->ResetError();
166 }
167
OnStart(const AAFwk::Want & want)168 void StsStaticSubscriberExtension::OnStart(const AAFwk::Want& want)
169 {
170 EVENT_LOGD("%{public}s called.", __func__);
171 Extension::OnStart(want);
172 }
173
OnStop()174 void StsStaticSubscriberExtension::OnStop()
175 {
176 EVENT_LOGD("%{public}s called.", __func__);
177 Extension::OnStop();
178 }
179
OnDisconnect(const AAFwk::Want & want)180 void StsStaticSubscriberExtension::OnDisconnect(const AAFwk::Want& want)
181 {
182 EVENT_LOGD("%{public}s called.", __func__);
183 Extension::OnDisconnect(want);
184 }
185
OnConnect(const AAFwk::Want & want)186 sptr<IRemoteObject> StsStaticSubscriberExtension::OnConnect(const AAFwk::Want& want)
187 {
188 EVENT_LOGD("%{public}s called.", __func__);
189 Extension::OnConnect(want);
190 sptr<StaticSubscriberStubImpl> remoteObject = new (std::nothrow) StaticSubscriberStubImpl(
191 std::static_pointer_cast<StsStaticSubscriberExtension>(shared_from_this()));
192 if (remoteObject == nullptr) {
193 EVENT_LOGE("failed to create StaticSubscriberStubImpl");
194 return nullptr;
195 }
196 return remoteObject->AsObject();
197 }
198
CallObjectMethod(bool withResult,const char * name,const char * signature,...)199 void StsStaticSubscriberExtension::CallObjectMethod(bool withResult, const char *name, const char *signature, ...)
200 {
201 ani_status status = ANI_ERROR;
202 ani_method method = nullptr;
203 auto env = stsRuntime_.GetAniEnv();
204 if (!env) {
205 EVENT_LOGE("env not found StsStaticSubscriberExtensions");
206 return;
207 }
208 if (stsObj_ == nullptr) {
209 EVENT_LOGE("stsObj_ nullptr");
210 return;
211 }
212 if ((status = env->Class_FindMethod(stsObj_->aniCls, name, signature, &method)) != ANI_OK) {
213 EVENT_LOGE("Class_FindMethod nullptr:%{public}d", status);
214 return;
215 }
216 if (method == nullptr) {
217 return;
218 }
219
220 ani_ref res = nullptr;
221 va_list args;
222 if (withResult) {
223 va_start(args, signature);
224 if ((status = env->Object_CallMethod_Ref_V(stsObj_->aniObj, method, &res, args)) != ANI_OK) {
225 EVENT_LOGE("status : %{public}d", status);
226 }
227 va_end(args);
228 return;
229 }
230 va_start(args, signature);
231 if ((status = env->Object_CallMethod_Void_V(stsObj_->aniObj, method, args)) != ANI_OK) {
232 EVENT_LOGE("status : %{public}d", status);
233 }
234 va_end(args);
235 return;
236 }
237 } // EventManagerFwkAni
238 } // OHOS