• 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_static_subscriber_extension_context.h"
16 
17 #include "ability_manager_client.h"
18 #include "ani_common_want.h"
19 #include "ani_common_start_options.h"
20 #include "ets_extension_context.h"
21 #include "event_log_wrapper.h"
22 #include "native_engine/native_engine.h"
23 #include "ani_event_errors_utils.h"
24 
25 namespace OHOS {
26 namespace EventManagerFwkAni {
27 namespace {
28 using namespace OHOS::EventFwk;
29 using namespace OHOS::AbilityRuntime;
30 
31 class StsStaticSubscriberExtensionContext final {
32 public:
GetInstance()33     static StsStaticSubscriberExtensionContext& GetInstance()
34     {
35         static StsStaticSubscriberExtensionContext instance;
36         return instance;
37     }
38 
39     void StartAbilityInner([[maybe_unused]] ani_env *env,
40         [[maybe_unused]] ani_object aniObj, ani_object wantObj);
41     static StaticSubscriberExtensionContext* GetAbilityContext(ani_env *env, ani_object obj);
42 
43 private:
44     explicit StsStaticSubscriberExtensionContext() = default;
45     ~StsStaticSubscriberExtensionContext() = default;
46 };
47 
48 constexpr const char* STATIC_SUBSCRIBER_EXTENSION_CONTEXT_CLASS_NAME =
49     "L@ohos/application/StaticSubscriberExtensionContext/StaticSubscriberExtensionContext;";
50 }
51 
StartAbility(ani_env * env,ani_object aniObj,ani_object wantObj)52 static void StartAbility([[maybe_unused]] ani_env *env,
53     [[maybe_unused]] ani_object aniObj, ani_object wantObj)
54 {
55     EVENT_LOGD("StartAbility");
56     StsStaticSubscriberExtensionContext::GetInstance().StartAbilityInner(env, aniObj, wantObj);
57 }
58 
StartAbilityInner(ani_env * env,ani_object aniObj,ani_object wantObj)59 void StsStaticSubscriberExtensionContext::StartAbilityInner([[maybe_unused]] ani_env *env,
60     [[maybe_unused]] ani_object aniObj, ani_object wantObj)
61 {
62     EVENT_LOGD("StartAbilityInner");
63     AAFwk::Want want;
64     ErrCode innerErrCode = ERR_OK;
65     if (!AppExecFwk::UnwrapWant(env, wantObj, want)) {
66         EVENT_LOGE("UnwrapWant filed");
67         OHOS::EventManagerFwkAni::ThrowError(env, ERROR_CODE_INVALID_PARAM);
68         return;
69     }
70     auto context = StsStaticSubscriberExtensionContext::GetAbilityContext(env, aniObj);
71     if (context == nullptr) {
72         EVENT_LOGE("GetAbilityContext is nullptr");
73         OHOS::EventManagerFwkAni::ThrowError(env, ERROR_CODE_INVALID_CONTEXT);
74         return;
75     }
76     innerErrCode = context->StartAbility(want);
77     if (innerErrCode != ERR_OK) {
78         EVENT_LOGE("StartAbility failed, code = %{public}d", innerErrCode);
79         OHOS::EventManagerFwkAni::ThrowErrorByNativeError(env, innerErrCode);
80     }
81 }
82 
GetAbilityContext(ani_env * env,ani_object obj)83 StaticSubscriberExtensionContext* StsStaticSubscriberExtensionContext::GetAbilityContext(ani_env *env, ani_object obj)
84 {
85     EVENT_LOGD("GetAbilityContext");
86     ani_class cls = nullptr;
87     ani_long nativeContextLong;
88     ani_field contextField = nullptr;
89     ani_status status = ANI_ERROR;
90     if (env == nullptr) {
91         EVENT_LOGD("null env");
92         return nullptr;
93     }
94     if ((status = env->FindClass(STATIC_SUBSCRIBER_EXTENSION_CONTEXT_CLASS_NAME, &cls)) != ANI_OK) {
95         EVENT_LOGD("GetAbilityContext find class status: %{public}d", status);
96         return nullptr;
97     }
98     if ((status = env->Class_FindField(cls, "nativeStaticSubscriberExtensionContext", &contextField)) != ANI_OK) {
99         EVENT_LOGD("GetAbilityContext find field status: %{public}d", status);
100         return nullptr;
101     }
102     if ((status = env->Object_GetField_Long(obj, contextField, &nativeContextLong)) != ANI_OK) {
103         EVENT_LOGD("GetAbilityContext get filed status: %{public}d", status);
104         return nullptr;
105     }
106     return (StaticSubscriberExtensionContext*)nativeContextLong;
107 }
108 
CreateStaticSubscriberExtensionContext(ani_env * env,std::shared_ptr<StaticSubscriberExtensionContext> context,const std::shared_ptr<OHOS::AppExecFwk::OHOSApplication> & application)109 ani_object CreateStaticSubscriberExtensionContext(ani_env *env,
110     std::shared_ptr<StaticSubscriberExtensionContext> context,
111     const std::shared_ptr<OHOS::AppExecFwk::OHOSApplication> &application)
112 {
113     if (env == nullptr) {
114         EVENT_LOGE("null env");
115         return nullptr;
116     }
117     std::shared_ptr<OHOS::AppExecFwk::AbilityInfo> abilityInfo = nullptr;
118     if (context) {
119         abilityInfo = context->GetAbilityInfo();
120     }
121     ani_class cls = nullptr;
122     ani_object contextObj = nullptr;
123     ani_field field = nullptr;
124     ani_method method = nullptr;
125     ani_status status = ANI_ERROR;
126     if ((status = env->FindClass(STATIC_SUBSCRIBER_EXTENSION_CONTEXT_CLASS_NAME, &cls)) != ANI_OK) {
127         EVENT_LOGE("find class status : %{public}d", status);
128         return nullptr;
129     }
130     std::array functions = {
131         ani_native_function { "nativeStartAbilitySync", "L@ohos/app/ability/Want/Want;:V",
132             reinterpret_cast<void*>(StartAbility) },
133     };
134     if ((status = env->Class_BindNativeMethods(cls, functions.data(), functions.size())) != ANI_OK) {
135         EVENT_LOGE("bind method status : %{public}d", status);
136         return nullptr;
137     }
138     if ((status = env->Class_FindMethod(cls, "<ctor>", ":V", &method)) != ANI_OK) {
139         EVENT_LOGE("find Method status: %{public}d", status);
140         return nullptr;
141     }
142     if ((status = env->Object_New(cls, method, &contextObj)) != ANI_OK) {
143         EVENT_LOGE("new Object status: %{public}d", status);
144         return nullptr;
145     }
146     if ((status = env->Class_FindField(cls, "nativeStaticSubscriberExtensionContext", &field)) != ANI_OK) {
147         EVENT_LOGE("find field status: %{public}d", status);
148         return nullptr;
149     }
150     ani_long nativeContextLong = (ani_long)context.get();
151     if ((status = env->Object_SetField_Long(contextObj, field, nativeContextLong)) != ANI_OK) {
152         EVENT_LOGE("set field status: %{public}d", status);
153         return nullptr;
154     }
155     if (application == nullptr) {
156         EVENT_LOGE("application null");
157         return nullptr;
158     }
159     OHOS::AbilityRuntime::CreateEtsExtensionContext(env, cls, contextObj, context, context->GetAbilityInfo());
160     return contextObj;
161 }
162 } // EventManagerFwkAni
163 } // OHOS