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.h"
17 
18 #include "ability_delegator_registry.h"
19 #include "application_context.h"
20 #include "cj_utils_ffi.h"
21 #include "cj_lambda.h"
22 #include "hilog_tag_wrapper.h"
23 #include "cj_ability_runtime_error.h"
24 
25 namespace OHOS {
26 namespace ApplicationContextCJ {
27 using namespace OHOS::FFI;
28 using namespace OHOS::AbilityRuntime;
29 
30 std::vector<std::shared_ptr<CjAbilityLifecycleCallback>> CJApplicationContext::callbacks_;
31 CJApplicationContext* CJApplicationContext::cjApplicationContext_ = nullptr;
32 
GetCJApplicationContext( std::weak_ptr<AbilityRuntime::ApplicationContext> &&applicationContext)33 CJApplicationContext* CJApplicationContext::GetCJApplicationContext(
34     std::weak_ptr<AbilityRuntime::ApplicationContext> &&applicationContext)
35 {
36     if (cjApplicationContext_) {
37         return cjApplicationContext_;
38     }
39     cjApplicationContext_ = FFIData::Create<CJApplicationContext>(applicationContext);
40     return cjApplicationContext_;
41 }
42 
GetArea()43 int CJApplicationContext::GetArea()
44 {
45     auto context = applicationContext_.lock();
46     if (context == nullptr) {
47         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
48         return INVALID_CODE;
49     }
50     return context->GetArea();
51 }
52 
GetApplicationInfo()53 std::shared_ptr<AppExecFwk::ApplicationInfo> CJApplicationContext::GetApplicationInfo()
54 {
55     auto context = applicationContext_.lock();
56     if (context == nullptr) {
57         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
58         return nullptr;
59     }
60     return context->GetApplicationInfo();
61 }
62 
IsAbilityLifecycleCallbackEmpty()63 bool CJApplicationContext::IsAbilityLifecycleCallbackEmpty()
64 {
65     std::lock_guard<std::recursive_mutex> lock(callbackLock_);
66     return callbacks_.empty();
67 }
68 
RegisterAbilityLifecycleCallback( const std::shared_ptr<CjAbilityLifecycleCallback> &abilityLifecycleCallback)69 void CJApplicationContext::RegisterAbilityLifecycleCallback(
70     const std::shared_ptr<CjAbilityLifecycleCallback> &abilityLifecycleCallback)
71 {
72     TAG_LOGD(AAFwkTag::CONTEXT, "called");
73     if (abilityLifecycleCallback == nullptr) {
74         return;
75     }
76     std::lock_guard<std::recursive_mutex> lock(callbackLock_);
77     callbacks_.push_back(abilityLifecycleCallback);
78 }
79 
UnregisterAbilityLifecycleCallback( const std::shared_ptr<CjAbilityLifecycleCallback> &abilityLifecycleCallback)80 void CJApplicationContext::UnregisterAbilityLifecycleCallback(
81     const std::shared_ptr<CjAbilityLifecycleCallback> &abilityLifecycleCallback)
82 {
83     TAG_LOGD(AAFwkTag::CONTEXT, "called");
84     std::lock_guard<std::recursive_mutex> lock(callbackLock_);
85     auto it = std::find(callbacks_.begin(), callbacks_.end(), abilityLifecycleCallback);
86     if (it != callbacks_.end()) {
87         callbacks_.erase(it);
88     }
89 }
90 
DispatchOnAbilityCreate(const int64_t &ability)91 void CJApplicationContext::DispatchOnAbilityCreate(const int64_t &ability)
92 {
93     TAG_LOGD(AAFwkTag::APPKIT, "called");
94     if (!ability) {
95         TAG_LOGE(AAFwkTag::CONTEXT, "ability is null");
96         return;
97     }
98     std::lock_guard<std::recursive_mutex> lock(callbackLock_);
99     for (auto callback : callbacks_) {
100         if (callback != nullptr) {
101             callback->OnAbilityCreate(ability);
102         }
103     }
104 }
105 
DispatchOnWindowStageCreate(const int64_t &ability, WindowStagePtr windowStage)106 void CJApplicationContext::DispatchOnWindowStageCreate(const int64_t &ability, WindowStagePtr windowStage)
107 {
108     TAG_LOGD(AAFwkTag::APPKIT, "called");
109     if (!ability || !windowStage) {
110         TAG_LOGE(AAFwkTag::CONTEXT, "ability or windowStage is nullptr");
111         return;
112     }
113     std::lock_guard<std::recursive_mutex> lock(callbackLock_);
114     for (auto callback : callbacks_) {
115         if (callback != nullptr) {
116             callback->OnWindowStageCreate(ability, windowStage);
117         }
118     }
119 }
120 
DispatchWindowStageFocus(const int64_t &ability, WindowStagePtr windowStage)121 void CJApplicationContext::DispatchWindowStageFocus(const int64_t &ability, WindowStagePtr windowStage)
122 {
123     TAG_LOGD(AAFwkTag::APPKIT, "called");
124     if (!ability || !windowStage) {
125         TAG_LOGE(AAFwkTag::APPKIT, "ability or windowStage is null");
126         return;
127     }
128     std::lock_guard<std::recursive_mutex> lock(callbackLock_);
129     for (auto callback : callbacks_) {
130         if (callback != nullptr) {
131             callback->OnWindowStageActive(ability, windowStage);
132         }
133     }
134 }
135 
DispatchWindowStageUnfocus(const int64_t &ability, WindowStagePtr windowStage)136 void CJApplicationContext::DispatchWindowStageUnfocus(const int64_t &ability, WindowStagePtr windowStage)
137 {
138     TAG_LOGD(AAFwkTag::APPKIT, "called");
139     if (!ability || !windowStage) {
140         TAG_LOGE(AAFwkTag::APPKIT, "ability or windowStage is nullptr");
141         return;
142     }
143     std::lock_guard<std::recursive_mutex> lock(callbackLock_);
144     for (auto callback : callbacks_) {
145         if (callback != nullptr) {
146             callback->OnWindowStageInactive(ability, windowStage);
147         }
148     }
149 }
150 
DispatchOnWindowStageDestroy(const int64_t &ability, WindowStagePtr windowStage)151 void CJApplicationContext::DispatchOnWindowStageDestroy(const int64_t &ability, WindowStagePtr windowStage)
152 {
153     TAG_LOGD(AAFwkTag::APPKIT, "called");
154     if (!ability || !windowStage) {
155         TAG_LOGE(AAFwkTag::CONTEXT, "ability or windowStage is nullptr");
156         return;
157     }
158     std::lock_guard<std::recursive_mutex> lock(callbackLock_);
159     for (auto callback : callbacks_) {
160         if (callback != nullptr) {
161             callback->OnWindowStageDestroy(ability, windowStage);
162         }
163     }
164 }
165 
DispatchOnAbilityDestroy(const int64_t &ability)166 void CJApplicationContext::DispatchOnAbilityDestroy(const int64_t &ability)
167 {
168     TAG_LOGD(AAFwkTag::APPKIT, "called");
169     if (!ability) {
170         TAG_LOGE(AAFwkTag::APPKIT, "ability is null");
171         return;
172     }
173     std::lock_guard<std::recursive_mutex> lock(callbackLock_);
174     for (auto callback : callbacks_) {
175         if (callback != nullptr) {
176             callback->OnAbilityDestroy(ability);
177         }
178     }
179 }
180 
DispatchOnAbilityForeground(const int64_t &ability)181 void CJApplicationContext::DispatchOnAbilityForeground(const int64_t &ability)
182 {
183     TAG_LOGD(AAFwkTag::APPKIT, "called");
184     if (!ability) {
185         TAG_LOGE(AAFwkTag::CONTEXT, "ability is null");
186         return;
187     }
188     std::lock_guard<std::recursive_mutex> lock(callbackLock_);
189     for (auto callback : callbacks_) {
190         if (callback != nullptr) {
191             callback->OnAbilityForeground(ability);
192         }
193     }
194 }
195 
DispatchOnAbilityBackground(const int64_t &ability)196 void CJApplicationContext::DispatchOnAbilityBackground(const int64_t &ability)
197 {
198     TAG_LOGD(AAFwkTag::APPKIT, "called");
199     if (!ability) {
200         TAG_LOGE(AAFwkTag::CONTEXT, "ability is null");
201         return;
202     }
203     std::lock_guard<std::recursive_mutex> lock(callbackLock_);
204     for (auto callback : callbacks_) {
205         if (callback != nullptr) {
206             callback->OnAbilityBackground(ability);
207         }
208     }
209 }
210 
DispatchOnAbilityContinue(const int64_t &ability)211 void CJApplicationContext::DispatchOnAbilityContinue(const int64_t &ability)
212 {
213     TAG_LOGD(AAFwkTag::APPKIT, "called");
214     if (!ability) {
215         TAG_LOGE(AAFwkTag::APPKIT, "ability is null");
216         return;
217     }
218     std::lock_guard<std::recursive_mutex> lock(callbackLock_);
219     for (auto callback : callbacks_) {
220         if (callback != nullptr) {
221             callback->OnAbilityContinue(ability);
222         }
223     }
224 }
225 
DispatchOnAbilityWillCreate(const int64_t &ability)226 void CJApplicationContext::DispatchOnAbilityWillCreate(const int64_t &ability)
227 {
228     TAG_LOGD(AAFwkTag::APPKIT, "called");
229     if (!ability) {
230         TAG_LOGE(AAFwkTag::APPKIT, "ability is null");
231         return;
232     }
233     std::lock_guard<std::recursive_mutex> lock(callbackLock_);
234     for (auto callback : callbacks_) {
235         if (callback != nullptr) {
236             callback->OnAbilityWillCreate(ability);
237         }
238     }
239 }
240 
DispatchOnWindowStageWillCreate(const int64_t &ability, WindowStagePtr windowStage)241 void CJApplicationContext::DispatchOnWindowStageWillCreate(const int64_t &ability, WindowStagePtr windowStage)
242 {
243     TAG_LOGD(AAFwkTag::APPKIT, "called");
244     if (!ability || !windowStage) {
245         TAG_LOGE(AAFwkTag::APPKIT, "ability or windowStage is null");
246         return;
247     }
248     std::lock_guard<std::recursive_mutex> lock(callbackLock_);
249     for (auto callback : callbacks_) {
250         if (callback != nullptr) {
251             callback->OnWindowStageWillCreate(ability, windowStage);
252         }
253     }
254 }
255 
DispatchOnWindowStageWillDestroy(const int64_t &ability, WindowStagePtr windowStage)256 void CJApplicationContext::DispatchOnWindowStageWillDestroy(const int64_t &ability, WindowStagePtr windowStage)
257 {
258     TAG_LOGD(AAFwkTag::APPKIT, "called");
259     if (!ability || !windowStage) {
260         TAG_LOGE(AAFwkTag::APPKIT, "ability or windowStage is null");
261         return;
262     }
263     std::lock_guard<std::recursive_mutex> lock(callbackLock_);
264     for (auto callback : callbacks_) {
265         if (callback != nullptr) {
266             callback->OnWindowStageWillDestroy(ability, windowStage);
267         }
268     }
269 }
270 
DispatchOnAbilityWillDestroy(const int64_t &ability)271 void CJApplicationContext::DispatchOnAbilityWillDestroy(const int64_t &ability)
272 {
273     TAG_LOGD(AAFwkTag::APPKIT, "called");
274     if (!ability) {
275         TAG_LOGE(AAFwkTag::APPKIT, "ability is null");
276         return;
277     }
278     std::lock_guard<std::recursive_mutex> lock(callbackLock_);
279     for (auto callback : callbacks_) {
280         if (callback != nullptr) {
281             callback->OnAbilityWillDestroy(ability);
282         }
283     }
284 }
285 
DispatchOnAbilityWillForeground(const int64_t &ability)286 void CJApplicationContext::DispatchOnAbilityWillForeground(const int64_t &ability)
287 {
288     TAG_LOGD(AAFwkTag::APPKIT, "called");
289     if (!ability) {
290         TAG_LOGE(AAFwkTag::APPKIT, "ability is null");
291         return;
292     }
293     std::lock_guard<std::recursive_mutex> lock(callbackLock_);
294     for (auto callback : callbacks_) {
295         if (callback != nullptr) {
296             callback->OnAbilityWillForeground(ability);
297         }
298     }
299 }
300 
DispatchOnAbilityWillBackground(const int64_t &ability)301 void CJApplicationContext::DispatchOnAbilityWillBackground(const int64_t &ability)
302 {
303     TAG_LOGD(AAFwkTag::APPKIT, "called");
304     if (!ability) {
305         TAG_LOGE(AAFwkTag::APPKIT, "ability is null");
306         return;
307     }
308     std::lock_guard<std::recursive_mutex> lock(callbackLock_);
309     for (auto callback : callbacks_) {
310         if (callback != nullptr) {
311             callback->OnAbilityWillBackground(ability);
312         }
313     }
314 }
315 
DispatchOnNewWant(const int64_t &ability)316 void CJApplicationContext::DispatchOnNewWant(const int64_t &ability)
317 {
318     TAG_LOGD(AAFwkTag::APPKIT, "called");
319     if (!ability) {
320         TAG_LOGE(AAFwkTag::APPKIT, "ability is null");
321         return;
322     }
323     std::lock_guard<std::recursive_mutex> lock(callbackLock_);
324     for (auto callback : callbacks_) {
325         if (callback != nullptr) {
326             callback->OnNewWant(ability);
327         }
328     }
329 }
330 
DispatchOnWillNewWant(const int64_t &ability)331 void CJApplicationContext::DispatchOnWillNewWant(const int64_t &ability)
332 {
333     TAG_LOGD(AAFwkTag::APPKIT, "called");
334     if (!ability) {
335         TAG_LOGE(AAFwkTag::APPKIT, "ability is null");
336         return;
337     }
338     std::lock_guard<std::recursive_mutex> lock(callbackLock_);
339     for (auto callback : callbacks_) {
340         if (callback != nullptr) {
341             callback->OnWillNewWant(ability);
342         }
343     }
344 }
345 
DispatchOnAbilityWillContinue(const int64_t &ability)346 void CJApplicationContext::DispatchOnAbilityWillContinue(const int64_t &ability)
347 {
348     TAG_LOGD(AAFwkTag::APPKIT, "Dispatch onAbilityWillContinue");
349     if (!ability) {
350         TAG_LOGE(AAFwkTag::APPKIT, "ability is null");
351         return;
352     }
353 
354     std::lock_guard<std::recursive_mutex> lock(callbackLock_);
355     for (auto callback : callbacks_) {
356         if (callback != nullptr) {
357             callback->OnAbilityWillContinue(ability);
358         }
359     }
360 }
361 
DispatchOnWindowStageWillRestore(const int64_t &ability, WindowStagePtr windowStage)362 void CJApplicationContext::DispatchOnWindowStageWillRestore(const int64_t &ability, WindowStagePtr windowStage)
363 {
364     TAG_LOGD(AAFwkTag::APPKIT, "Dispatch onWindowStageWillRestore");
365     if (!ability || windowStage == nullptr) {
366         TAG_LOGE(AAFwkTag::APPKIT, "ability or windowStage is null");
367         return;
368     }
369 
370     std::lock_guard<std::recursive_mutex> lock(callbackLock_);
371     for (auto callback : callbacks_) {
372         if (callback != nullptr) {
373             callback->OnWindowStageWillRestore(ability, windowStage);
374         }
375     }
376 }
377 
DispatchOnWindowStageRestore(const int64_t &ability, WindowStagePtr windowStage)378 void CJApplicationContext::DispatchOnWindowStageRestore(const int64_t &ability, WindowStagePtr windowStage)
379 {
380     TAG_LOGD(AAFwkTag::APPKIT, "Dispatch onWindowStageRestore");
381     if (!ability || windowStage == nullptr) {
382         TAG_LOGE(AAFwkTag::APPKIT, "ability or windowStage is null");
383         return;
384     }
385 
386     std::lock_guard<std::recursive_mutex> lock(callbackLock_);
387     for (auto callback : callbacks_) {
388         if (callback != nullptr) {
389             callback->OnWindowStageRestore(ability, windowStage);
390         }
391     }
392 }
393 
DispatchOnAbilityWillSaveState(const int64_t &ability)394 void CJApplicationContext::DispatchOnAbilityWillSaveState(const int64_t &ability)
395 {
396     TAG_LOGD(AAFwkTag::APPKIT, "Dispatch onAbilityWillSaveState");
397     if (!ability) {
398         TAG_LOGE(AAFwkTag::APPKIT, "ability is null");
399         return;
400     }
401 
402     std::lock_guard<std::recursive_mutex> lock(callbackLock_);
403     for (auto callback : callbacks_) {
404         if (callback != nullptr) {
405             callback->OnAbilityWillSaveState(ability);
406         }
407     }
408 }
409 
DispatchOnAbilitySaveState(const int64_t &ability)410 void CJApplicationContext::DispatchOnAbilitySaveState(const int64_t &ability)
411 {
412     TAG_LOGD(AAFwkTag::APPKIT, "called");
413     if (!ability) {
414         TAG_LOGE(AAFwkTag::APPKIT, "ability is null");
415         return;
416     }
417 
418     std::lock_guard<std::recursive_mutex> lock(callbackLock_);
419     for (auto callback : callbacks_) {
420         if (callback != nullptr) {
421             callback->OnAbilitySaveState(ability);
422         }
423     }
424 }
425 
OnOnEnvironment(void (*cfgCallback)(CConfiguration), void (*memCallback)(int32_t), bool isSync, int32_t *errCode)426 int32_t CJApplicationContext::OnOnEnvironment(void (*cfgCallback)(CConfiguration),
427     void (*memCallback)(int32_t), bool isSync, int32_t *errCode)
428 {
429     auto context = applicationContext_.lock();
430     if (context == nullptr) {
431         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
432         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
433         return -1;
434     }
435     if (envCallback_ != nullptr) {
436         TAG_LOGD(AAFwkTag::CONTEXT, "envCallback_ is not nullptr.");
437         return envCallback_->Register(CJLambda::Create(cfgCallback), CJLambda::Create(memCallback), isSync);
438     }
439     envCallback_ = std::make_shared<CjEnvironmentCallback>();
440     int32_t callbackId = envCallback_->Register(CJLambda::Create(cfgCallback), CJLambda::Create(memCallback), isSync);
441     context->RegisterEnvironmentCallback(envCallback_);
442     TAG_LOGD(AAFwkTag::CONTEXT, "OnOnEnvironment is end");
443     return callbackId;
444 }
445 
OnOnAbilityLifecycle(CArrI64 cFuncIds, bool isSync, int32_t *errCode)446 int32_t CJApplicationContext::OnOnAbilityLifecycle(CArrI64 cFuncIds, bool isSync, int32_t *errCode)
447 {
448     auto context = applicationContext_.lock();
449     if (context == nullptr) {
450         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
451         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
452         return -1;
453     }
454     if (callback_ != nullptr) {
455         TAG_LOGD(AAFwkTag::CONTEXT, "callback_ is not nullptr.");
456         return callback_->Register(cFuncIds, isSync);
457     }
458     callback_ = std::make_shared<CjAbilityLifecycleCallback>();
459     int32_t callbackId = callback_->Register(cFuncIds, isSync);
460     RegisterAbilityLifecycleCallback(callback_);
461     return callbackId;
462 }
463 
OnOnApplicationStateChange(void (*foregroundCallback)(void), void (*backgroundCallback)(void), int32_t *errCode)464 int32_t CJApplicationContext::OnOnApplicationStateChange(void (*foregroundCallback)(void),
465     void (*backgroundCallback)(void), int32_t *errCode)
466 {
467     auto context = applicationContext_.lock();
468     if (context == nullptr) {
469         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
470         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
471         return -1;
472     }
473     std::lock_guard<std::mutex> lock(applicationStateCallbackLock_);
474     if (applicationStateCallback_ != nullptr) {
475         return applicationStateCallback_->Register(CJLambda::Create(foregroundCallback),
476             CJLambda::Create(backgroundCallback));
477     }
478     applicationStateCallback_ = std::make_shared<CjApplicationStateChangeCallback>();
479     int32_t callbackId = applicationStateCallback_->Register(CJLambda::Create(foregroundCallback),
480         CJLambda::Create(backgroundCallback));
481     context->RegisterApplicationStateChangeCallback(applicationStateCallback_);
482     return callbackId;
483 }
484 
OnOffEnvironment(int32_t callbackId, int32_t *errCode)485 void CJApplicationContext::OnOffEnvironment(int32_t callbackId, int32_t *errCode)
486 {
487     auto context = applicationContext_.lock();
488     if (context == nullptr) {
489         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
490         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
491         return;
492     }
493     std::weak_ptr<CjEnvironmentCallback> envCallbackWeak(envCallback_);
494     auto env_callback = envCallbackWeak.lock();
495     if (env_callback == nullptr) {
496         TAG_LOGD(AAFwkTag::CONTEXT, "env_callback is not nullptr.");
497         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
498         return;
499     }
500     TAG_LOGD(AAFwkTag::CONTEXT, "OnOffEnvironment begin");
501     if (!env_callback->UnRegister(callbackId, false)) {
502         TAG_LOGE(AAFwkTag::CONTEXT, "call UnRegister failed");
503         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
504         return;
505     }
506 }
507 
OnOffAbilityLifecycle(int32_t callbackId, int32_t *errCode)508 void CJApplicationContext::OnOffAbilityLifecycle(int32_t callbackId, int32_t *errCode)
509 {
510     auto context = applicationContext_.lock();
511     if (context == nullptr) {
512         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
513         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
514         return;
515     }
516     std::weak_ptr<CjAbilityLifecycleCallback> callbackWeak(callback_);
517     auto lifecycle_callback = callbackWeak.lock();
518     if (lifecycle_callback == nullptr) {
519         TAG_LOGD(AAFwkTag::CONTEXT, "env_callback is not nullptr.");
520         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
521         return;
522     }
523     TAG_LOGD(AAFwkTag::CONTEXT, "OnOffAbilityLifecycle begin");
524     if (!lifecycle_callback->UnRegister(callbackId, false)) {
525         TAG_LOGE(AAFwkTag::CONTEXT, "call UnRegister failed");
526         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
527         return;
528     }
529 }
530 
OnOffApplicationStateChange(int32_t callbackId, int32_t *errCode)531 void CJApplicationContext::OnOffApplicationStateChange(int32_t callbackId, int32_t *errCode)
532 {
533     auto context = applicationContext_.lock();
534     if (context == nullptr) {
535         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
536         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
537         return;
538     }
539     std::lock_guard<std::mutex> lock(applicationStateCallbackLock_);
540     if (applicationStateCallback_ == nullptr) {
541         TAG_LOGD(AAFwkTag::CONTEXT, "env_callback is not nullptr.");
542         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
543         return;
544     }
545     TAG_LOGD(AAFwkTag::CONTEXT, "OnOffApplicationStateChange begin");
546     if (!applicationStateCallback_->UnRegister(callbackId)) {
547         TAG_LOGE(AAFwkTag::CONTEXT, "call UnRegister failed");
548         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
549         return;
550     }
551     if (applicationStateCallback_->IsEmpty()) {
552         applicationStateCallback_.reset();
553     }
554 }
555 
556 extern "C" {
FFIGetArea(int64_t id)557 int64_t FFIGetArea(int64_t id)
558 {
559     auto context = FFI::FFIData::GetData<CJApplicationContext>(id);
560     if (context == nullptr) {
561         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
562         return INVALID_CODE;
563     }
564     return context->GetArea();
565 }
566 
FFICJApplicationInfo(int64_t id)567 CApplicationInfo* FFICJApplicationInfo(int64_t id)
568 {
569     auto context = FFI::FFIData::GetData<CJApplicationContext>(id);
570     if (context == nullptr) {
571         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
572         return nullptr;
573     }
574     auto appInfo = context->GetApplicationInfo();
575     CApplicationInfo* buffer = static_cast<CApplicationInfo*>(malloc(sizeof(CApplicationInfo)));
576     if (buffer == nullptr) {
577         TAG_LOGE(AAFwkTag::CONTEXT, "malloc appinfo fail");
578         return nullptr;
579     }
580     buffer->name = CreateCStringFromString(appInfo->name);
581     buffer->bundleName = CreateCStringFromString(appInfo->bundleName);
582     return buffer;
583 }
584 
FfiCJApplicationContextOnOnEnvironment(int64_t id, void (*cfgCallback)(CConfiguration), void (*memCallback)(int32_t), int32_t *errCode)585 int32_t FfiCJApplicationContextOnOnEnvironment(int64_t id, void (*cfgCallback)(CConfiguration),
586     void (*memCallback)(int32_t), int32_t *errCode)
587 {
588     auto context = FFI::FFIData::GetData<CJApplicationContext>(id);
589     if (context == nullptr) {
590         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
591         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
592         return -1;
593     }
594     return context->OnOnEnvironment(cfgCallback, memCallback, false, errCode);
595 }
596 
FfiCJApplicationContextOnOnAbilityLifecycle(int64_t id, CArrI64 cFuncIds, int32_t *errCode)597 int32_t FfiCJApplicationContextOnOnAbilityLifecycle(int64_t id, CArrI64 cFuncIds, int32_t *errCode)
598 {
599     auto context = FFI::FFIData::GetData<CJApplicationContext>(id);
600     if (context == nullptr) {
601         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
602         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
603         return -1;
604     }
605     return context->OnOnAbilityLifecycle(cFuncIds, false, errCode);
606 }
607 
FfiCJApplicationContextOnOnApplicationStateChange(int64_t id, void (*foregroundCallback)(void), void (*backgroundCallback)(void), int32_t *errCode)608 int32_t FfiCJApplicationContextOnOnApplicationStateChange(int64_t id, void (*foregroundCallback)(void),
609     void (*backgroundCallback)(void), int32_t *errCode)
610 {
611     auto context = FFI::FFIData::GetData<CJApplicationContext>(id);
612     if (context == nullptr) {
613         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
614         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
615         return -1;
616     }
617     return context->OnOnApplicationStateChange(foregroundCallback, backgroundCallback, errCode);
618 }
619 
FfiCJApplicationContextOnOff(int64_t id, const char* type, int32_t callbackId, int32_t *errCode)620 void FfiCJApplicationContextOnOff(int64_t id, const char* type, int32_t callbackId, int32_t *errCode)
621 {
622     auto context = FFI::FFIData::GetData<CJApplicationContext>(id);
623     if (context == nullptr) {
624         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
625         *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
626         return;
627     }
628     auto typeString = std::string(type);
629     if (typeString == "environment") {
630         return context->OnOffEnvironment(callbackId, errCode);
631     }
632     if (typeString == "abilityLifecycle") {
633         return context->OnOffAbilityLifecycle(callbackId, errCode);
634     }
635     if (typeString == "applicationStateChange") {
636         return context->OnOffApplicationStateChange(callbackId, errCode);
637     }
638     TAG_LOGE(AAFwkTag::CONTEXT, "off function type not match");
639     *errCode = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
640     return;
641 }
642 }
643 }
644 }