• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "cj_application_context_ffi.h"
17 
18 #include "ability_delegator_registry.h"
19 #include "ability_manager_errors.h"
20 #include "application_context.h"
21 #include "cj_ability_runtime_error.h"
22 #include "cj_application_context.h"
23 #include "cj_lambda.h"
24 #include "cj_utils_ffi.h"
25 #include "hilog_tag_wrapper.h"
26 #include "running_process_info.h"
27 #include "js_application_context_utils.h"
28 
29 namespace OHOS {
30 namespace ApplicationContextCJ {
31 using namespace OHOS::FFI;
32 using namespace OHOS::AbilityRuntime;
33 
34 extern "C" {
FFIGetArea(int64_t id)35 int64_t FFIGetArea(int64_t id)
36 {
37     auto context = FFI::FFIData::GetData<CJApplicationContext>(id);
38     if (context == nullptr) {
39         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
40         return INVALID_CODE;
41     }
42     return context->GetArea();
43 }
44 
FFICJApplicationInfo(int64_t id)45 CApplicationInfo *FFICJApplicationInfo(int64_t id)
46 {
47     auto context = FFI::FFIData::GetData<CJApplicationContext>(id);
48     if (context == nullptr) {
49         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
50         return nullptr;
51     }
52     auto appInfo = context->GetApplicationInfo();
53     CApplicationInfo *buffer = static_cast<CApplicationInfo *>(malloc(sizeof(CApplicationInfo)));
54     if (buffer == nullptr) {
55         TAG_LOGE(AAFwkTag::CONTEXT, "malloc appinfo fail");
56         return nullptr;
57     }
58     buffer->name = CreateCStringFromString(appInfo->name);
59     buffer->bundleName = CreateCStringFromString(appInfo->bundleName);
60     return buffer;
61 }
62 
FfiCJApplicationContextOnOnEnvironment(int64_t id,void (* cfgCallback)(CConfiguration),void (* memCallback)(int32_t),int32_t * errCode)63 int32_t FfiCJApplicationContextOnOnEnvironment(int64_t id, void (*cfgCallback)(CConfiguration),
64                                                void (*memCallback)(int32_t), int32_t *errCode)
65 {
66     auto context = FFI::FFIData::GetData<CJApplicationContext>(id);
67     if (context == nullptr) {
68         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
69         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
70         return -1;
71     }
72     return context->OnOnEnvironment(cfgCallback, memCallback, false, errCode);
73 }
74 
FfiCJApplicationContextOnOnAbilityLifecycle(int64_t id,CArrI64 cFuncIds,int32_t * errCode)75 int32_t FfiCJApplicationContextOnOnAbilityLifecycle(int64_t id, CArrI64 cFuncIds, int32_t *errCode)
76 {
77     auto context = FFI::FFIData::GetData<CJApplicationContext>(id);
78     if (context == nullptr) {
79         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
80         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
81         return -1;
82     }
83     return context->OnOnAbilityLifecycle(cFuncIds, false, errCode);
84 }
85 
FfiCJApplicationContextOnOnApplicationStateChange(int64_t id,void (* foregroundCallback)(void),void (* backgroundCallback)(void),int32_t * errCode)86 int32_t FfiCJApplicationContextOnOnApplicationStateChange(int64_t id, void (*foregroundCallback)(void),
87                                                           void (*backgroundCallback)(void), int32_t *errCode)
88 {
89     auto context = FFI::FFIData::GetData<CJApplicationContext>(id);
90     if (context == nullptr) {
91         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
92         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
93         return -1;
94     }
95     return context->OnOnApplicationStateChange(foregroundCallback, backgroundCallback, errCode);
96 }
97 
FfiCJApplicationContextOnOff(int64_t id,const char * type,int32_t callbackId,int32_t * errCode)98 void FfiCJApplicationContextOnOff(int64_t id, const char *type, int32_t callbackId, int32_t *errCode)
99 {
100     auto context = FFI::FFIData::GetData<CJApplicationContext>(id);
101     if (context == nullptr) {
102         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
103         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
104         return;
105     }
106     auto typeString = std::string(type);
107     if (typeString == "environment") {
108         return context->OnOffEnvironment(callbackId, errCode);
109     }
110     if (typeString == "abilityLifecycle") {
111         return context->OnOffAbilityLifecycle(callbackId, errCode);
112     }
113     if (typeString == "applicationStateChange") {
114         return context->OnOffApplicationStateChange(callbackId, errCode);
115     }
116     TAG_LOGE(AAFwkTag::CONTEXT, "off function type not match");
117     *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
118     return;
119 }
120 
FfiCJApplicationContextSetFont(int64_t id,const char * font,int32_t * errCode)121 void FfiCJApplicationContextSetFont(int64_t id, const char *font, int32_t *errCode)
122 {
123     auto context = FFI::FFIData::GetData<CJApplicationContext>(id);
124     if (context == nullptr) {
125         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
126         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
127         return;
128     }
129     auto fontString = std::string(font);
130     context->OnSetFont(fontString);
131 }
132 
FfiCJApplicationContextSetLanguage(int64_t id,const char * language,int32_t * errCode)133 void FfiCJApplicationContextSetLanguage(int64_t id, const char *language, int32_t *errCode)
134 {
135     auto context = FFI::FFIData::GetData<CJApplicationContext>(id);
136     if (context == nullptr) {
137         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
138         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
139         return;
140     }
141     auto languageString = std::string(language);
142     context->OnSetLanguage(languageString);
143 }
144 
FfiCJApplicationContextSetColorMode(int64_t id,int32_t colorMode,int32_t * errCode)145 void FfiCJApplicationContextSetColorMode(int64_t id, int32_t colorMode, int32_t *errCode)
146 {
147     auto context = FFI::FFIData::GetData<CJApplicationContext>(id);
148     if (context == nullptr) {
149         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
150         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
151         return;
152     }
153     context->OnSetColorMode(colorMode);
154 }
155 
ConvertToJsAppProcessState(const AppExecFwk::AppProcessState & appProcessState,const bool & isFocused)156 CjAppProcessState ConvertToJsAppProcessState(const AppExecFwk::AppProcessState &appProcessState, const bool &isFocused)
157 {
158     CjAppProcessState processState;
159     switch (appProcessState) {
160         case AppExecFwk::AppProcessState::APP_STATE_CREATE:
161         case AppExecFwk::AppProcessState::APP_STATE_READY:
162             processState = STATE_CREATE;
163             break;
164         case AppExecFwk::AppProcessState::APP_STATE_FOREGROUND:
165             processState = isFocused ? STATE_ACTIVE : STATE_FOREGROUND;
166             break;
167         case AppExecFwk::AppProcessState::APP_STATE_BACKGROUND:
168             processState = STATE_BACKGROUND;
169             break;
170         case AppExecFwk::AppProcessState::APP_STATE_TERMINATED:
171         case AppExecFwk::AppProcessState::APP_STATE_END:
172             processState = STATE_DESTROY;
173             break;
174         default:
175             TAG_LOGE(AAFwkTag::CONTEXT, "Process state is invalid.");
176             processState = STATE_DESTROY;
177             break;
178     }
179     return processState;
180 }
181 
FfiCJApplicationContextGetRunningProcessInformation(int64_t id,int32_t * errCode)182 CArrProcessInformation FfiCJApplicationContextGetRunningProcessInformation(int64_t id, int32_t *errCode)
183 {
184     CArrProcessInformation cArrProcessInformation = {.head = nullptr, .size = 0};
185     auto context = FFI::FFIData::GetData<CJApplicationContext>(id);
186     if (context == nullptr) {
187         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
188         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
189         return cArrProcessInformation;
190     }
191     auto processInfo = context->OnGetRunningProcessInformation(errCode);
192     if (*errCode != ERR_OK) {
193         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INTERNAL_ERROR;
194         return cArrProcessInformation;
195     }
196 
197     CProcessInformation *head = static_cast<CProcessInformation *>(malloc(sizeof(CProcessInformation)));
198     if (head == nullptr) {
199         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INTERNAL_ERROR;
200         return cArrProcessInformation;
201     }
202     head->processName = CreateCStringFromString(processInfo->processName_);
203     head->pid = processInfo->pid_;
204     head->uid = processInfo->uid_;
205     head->bundleNames.head = VectorToCArrString(processInfo->bundleNames);
206     head->bundleNames.size = (processInfo->bundleNames).size();
207     head->state = ConvertToJsAppProcessState(processInfo->state_, processInfo->isFocused);
208     head->bundleType = processInfo->bundleType;
209     head->appCloneIndex = processInfo->appCloneIndex;
210     cArrProcessInformation.size = 1;
211     cArrProcessInformation.head = head;
212     return cArrProcessInformation;
213 }
214 
FfiCJApplicationContextKillAllProcesses(int64_t id,bool clearPageStack,int32_t * errCode)215 void FfiCJApplicationContextKillAllProcesses(int64_t id, bool clearPageStack, int32_t *errCode)
216 {
217     auto context = FFI::FFIData::GetData<CJApplicationContext>(id);
218     if (context == nullptr) {
219         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
220         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
221         return;
222     }
223     context->OnKillProcessBySelf(clearPageStack, errCode);
224 }
225 
FfiCJApplicationContextGetCurrentAppCloneIndex(int64_t id,int32_t * errCode)226 int32_t FfiCJApplicationContextGetCurrentAppCloneIndex(int64_t id, int32_t *errCode)
227 {
228     auto context = FFI::FFIData::GetData<CJApplicationContext>(id);
229     if (context == nullptr) {
230         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
231         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
232         return -1;
233     }
234     return context->OnGetCurrentAppCloneIndex(errCode);
235 }
236 
FfiCJApplicationContextRestartApp(int64_t id,WantHandle want,int32_t * errCode)237 void FfiCJApplicationContextRestartApp(int64_t id, WantHandle want, int32_t *errCode)
238 {
239     auto context = FFI::FFIData::GetData<CJApplicationContext>(id);
240     if (context == nullptr) {
241         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
242         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
243         return;
244     }
245     auto actualWant = reinterpret_cast<AAFwk::Want *>(want);
246     if (actualWant == nullptr) {
247         TAG_LOGE(AAFwkTag::CONTEXT, "null want");
248         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
249         return;
250     }
251     return context->OnRestartApp(*actualWant, errCode);
252 }
253 
FfiCJApplicationContextClearUpApplicationData(int64_t id,int32_t * errCode)254 void FfiCJApplicationContextClearUpApplicationData(int64_t id, int32_t *errCode)
255 {
256     auto context = FFI::FFIData::GetData<CJApplicationContext>(id);
257     if (context == nullptr) {
258         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
259         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
260         return;
261     }
262     return context->OnClearUpApplicationData(errCode);
263 }
264 
FfiCJApplicationContextSetSupportedProcessCache(int64_t id,bool isSupported,int32_t * errCode)265 void FfiCJApplicationContextSetSupportedProcessCache(int64_t id, bool isSupported, int32_t *errCode)
266 {
267     auto context = FFI::FFIData::GetData<CJApplicationContext>(id);
268     if (context == nullptr) {
269         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
270         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
271         return;
272     }
273     return context->OnSetSupportedProcessCacheSelf(isSupported, errCode);
274 }
275 
FfiConvertApplicationContext2Napi(napi_env env,int64_t id)276 CJ_EXPORT napi_value FfiConvertApplicationContext2Napi(napi_env env, int64_t id)
277 {
278     napi_value undefined = nullptr;
279     napi_get_undefined(env, &undefined);
280     auto cjApplicationContext = FFIData::GetData<CJApplicationContext>(id);
281     if (cjApplicationContext == nullptr || cjApplicationContext->GetApplicationContext() == nullptr) {
282         TAG_LOGE(AAFwkTag::CONTEXT, "cj context null ptr");
283         return undefined;
284     }
285 
286     napi_value result = JsApplicationContextUtils::CreateJsApplicationContext(env);
287     if (result == nullptr) {
288         TAG_LOGE(AAFwkTag::CONTEXT, "null object");
289         return undefined;
290     }
291     auto workContext = new (std::nothrow) std::weak_ptr<ApplicationContext>(
292         cjApplicationContext->GetApplicationContext());
293     if (workContext != nullptr) {
294         auto res = napi_wrap(env, result, workContext,
295             [](napi_env, void *data, void *) {
296               TAG_LOGD(AAFwkTag::APPKIT, "Finalizer for weak_ptr application context is called");
297               delete static_cast<std::weak_ptr<ApplicationContext> *>(data);
298               data = nullptr;
299             },
300             nullptr, nullptr);
301         if (res != napi_ok && workContext != nullptr) {
302             TAG_LOGE(AAFwkTag::APPKIT, "napi_wrap failed:%{public}d", res);
303             delete workContext;
304             return undefined;
305         }
306     }
307     napi_value falseValue = nullptr;
308     napi_get_boolean((napi_env)env, true, &falseValue);
309     napi_set_named_property((napi_env)env, result, "stageMode", falseValue);
310 
311     return result;
312 }
313 
FfiCreateApplicationContextFromNapi(napi_env env,napi_value appContext)314 CJ_EXPORT int64_t FfiCreateApplicationContextFromNapi(napi_env env, napi_value appContext)
315 {
316     if (env == nullptr || appContext == nullptr) {
317         return ERR_INVALID_INSTANCE_CODE;
318     }
319 
320     napi_valuetype type;
321     if (napi_typeof(env, appContext, &type) || type != napi_object) {
322         return ERR_INVALID_INSTANCE_CODE;
323     }
324 
325     std::weak_ptr<ApplicationContext>* context = nullptr;
326     napi_status status = napi_unwrap(env, appContext, reinterpret_cast<void**>(&context));
327     if (status != napi_ok) {
328         return ERR_INVALID_INSTANCE_CODE;
329     }
330 
331     if (context == nullptr || (*context).lock() == nullptr) {
332         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
333         return ERR_INVALID_INSTANCE_CODE;
334     }
335     auto cjContext = FFI::FFIData::Create<CJApplicationContext>((*context).lock());
336     if (cjContext == nullptr) {
337         TAG_LOGE(AAFwkTag::CONTEXT, "null cjContext");
338         return ERR_INVALID_INSTANCE_CODE;
339     }
340 
341     return cjContext->GetID();
342 }
343 }
344 } // namespace ApplicationContextCJ
345 } // namespace OHOS