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 "background_task_mgr_ffi.h"
17 #include "singleton.h"
18 #include "background_task_manager.h"
19 #include "transient_task_log.h"
20 #include "bgtaskmgr_inner_errors.h"
21 #include "background_task_mgr_helper.h"
22 #include "string_ex.h"
23 #include "cj_lambda.h"
24 #include "cj_fn_invoker.h"
25 #include "callback_ffi.h"
26 #include "background_task_mgr_log.h"
27 
28 namespace OHOS {
29 namespace BackgroundTaskMgr {
30 std::map<int32_t, std::shared_ptr<CallbackFFI>> callbackInstances_;
31 std::mutex callbackLock_;
32 
33 extern "C" {
CJ_RequestSuspendDelay(void (* callback)(),const char * reason,RetDelaySuspendInfo * ret)34     int32_t CJ_RequestSuspendDelay(void (*callback)(), const char* reason, RetDelaySuspendInfo* ret)
35     {
36         LOGI("CJ_RequestSuspendDelay start");
37         std::string tmp(reason);
38         std::u16string reasonu16(Str8ToStr16(tmp));
39         std::shared_ptr<DelaySuspendInfo> delaySuspendInfo {nullptr};
40         std::shared_ptr<CallbackFFI> callbackffi = std::make_shared<CallbackFFI>();
41         callbackffi->Init();
42         callbackffi->SetCallbackInfo(callback);
43 
44         ErrCode errCode = DelayedSingleton<BackgroundTaskManager>::GetInstance()->
45         RequestSuspendDelay(reasonu16, *callbackffi, delaySuspendInfo);
46         if (errCode != SUCCESS_CODE) {
47             return errCode;
48         }
49         ret->requestId = delaySuspendInfo->GetRequestId();
50         ret->actualDelayTime = delaySuspendInfo->GetActualDelayTime();
51 
52         {
53             std::lock_guard<std::mutex> lock(callbackLock_);
54             callbackInstances_[delaySuspendInfo->GetRequestId()] = callbackffi;
55         }
56         return errCode;
57     }
58 
CJ_GetRemainingDelayTime(int32_t requestId,int32_t & delayTime)59     int32_t CJ_GetRemainingDelayTime(int32_t requestId, int32_t& delayTime)
60     {
61         return DelayedSingleton<BackgroundTaskManager>::GetInstance()->
62             GetRemainingDelayTime(requestId, delayTime);
63     }
64 
CJ_CancelSuspendDelay(int32_t requestId)65     int32_t CJ_CancelSuspendDelay(int32_t requestId)
66     {
67         auto errCode = DelayedSingleton<BackgroundTaskManager>::GetInstance()->CancelSuspendDelay(requestId);
68         std::lock_guard<std::mutex> lock(callbackLock_);
69         auto findCallback = callbackInstances_.find(requestId);
70         if (findCallback != callbackInstances_.end()) {
71             LOGI("CJ_CancelSuspendDelay erase");
72             callbackInstances_.erase(findCallback);
73             LOGI("CJ_CancelSuspendDelay erase ok");
74         }
75         return errCode;
76     }
77 
CJ_StopBackgroundRunning(OHOS::AbilityRuntime::AbilityContext * context)78     int32_t CJ_StopBackgroundRunning(OHOS::AbilityRuntime::AbilityContext* context)
79     {
80         const std::shared_ptr<AppExecFwk::AbilityInfo> info = context->GetAbilityInfo();
81         sptr<IRemoteObject> token = context->GetToken();
82         return BackgroundTaskMgrHelper::RequestStopBackgroundRunning(info->name, token);
83     }
84 
CJ_ApplyEfficiencyResources(RetEfficiencyResourcesRequest request)85     int32_t CJ_ApplyEfficiencyResources(RetEfficiencyResourcesRequest request)
86     {
87         EfficiencyResourceInfo params{request.resourceTypes, request.isApply, request.timeOut, request.reason,
88             request.isPersist, request.isProcess};
89         return DelayedSingleton<BackgroundTaskManager>::GetInstance()->ApplyEfficiencyResources(params);
90     }
91 
CallbackFFI()92     CallbackFFI::CallbackFFI() {}
93 
~CallbackFFI()94     CallbackFFI::~CallbackFFI()
95     {
96         LOGI("~CallbackFFI");
97     }
98 
OnExpired()99     void CallbackFFI::OnExpired()
100     {
101         LOGI("OnExpired start");
102         std::lock_guard<std::mutex> lock(callbackLock_);
103         auto findCallback = std::find_if(callbackInstances_.begin(), callbackInstances_.end(),
104             [&](const auto& callbackInstance) { return callbackInstance.second.get() == this; }
105         );
106         if (findCallback == callbackInstances_.end()) {
107             LOGI("expired callback not found");
108             return;
109         }
110         LOGI("call CJ callback");
111         findCallback->second->ffiCallback_();
112         LOGI("OnExpired end");
113         callbackInstances_.erase(findCallback);
114         return;
115     }
116 
SetCallbackInfo(void (* callback)())117     void CallbackFFI::SetCallbackInfo(void (*callback)())
118     {
119         ffiCallback_ = CJLambda::Create(callback);
120     }
121 }
122 
123 }
124 }