• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "environment_callback.h"
17 
18 #include "hilog_wrapper.h"
19 #include "js_data_struct_converter.h"
20 #include "js_runtime_utils.h"
21 
22 namespace OHOS {
23 namespace AbilityRuntime {
JsEnvironmentCallback(NativeEngine * engine)24 JsEnvironmentCallback::JsEnvironmentCallback(NativeEngine* engine)
25     : engine_(engine)
26 {
27 }
28 
29 int32_t JsEnvironmentCallback::serialNumber_ = 0;
30 
CallConfigurationUpdatedInner(const std::string & methodName,const AppExecFwk::Configuration & config,const std::map<int32_t,std::shared_ptr<NativeReference>> callbacks)31 void JsEnvironmentCallback::CallConfigurationUpdatedInner(const std::string &methodName,
32     const AppExecFwk::Configuration &config, const std::map<int32_t, std::shared_ptr<NativeReference>> callbacks)
33 {
34     HILOG_DEBUG("CallConfigurationUpdatedInner methodName = %{public}s", methodName.c_str());
35     for (auto &callback : callbacks) {
36         if (!callback.second) {
37             HILOG_ERROR("CallConfigurationUpdatedInner, Invalid jsCallback");
38             return;
39         }
40 
41         auto value = callback.second->Get();
42         auto obj = ConvertNativeValueTo<NativeObject>(value);
43         if (obj == nullptr) {
44             HILOG_ERROR("CallConfigurationUpdatedInner, Failed to get object");
45             return;
46         }
47 
48         auto method = obj->GetProperty(methodName.data());
49         if (method == nullptr) {
50             HILOG_ERROR("CallConfigurationUpdatedInner, Failed to get %{public}s from object", methodName.data());
51             return;
52         }
53 
54         NativeValue *argv[] = { CreateJsConfiguration(*engine_, config) };
55         engine_->CallFunction(value, method, argv, ArraySize(argv));
56     }
57 }
58 
OnConfigurationUpdated(const AppExecFwk::Configuration & config)59 void JsEnvironmentCallback::OnConfigurationUpdated(const AppExecFwk::Configuration &config)
60 {
61     std::weak_ptr<JsEnvironmentCallback> thisWeakPtr(shared_from_this());
62     std::unique_ptr<AsyncTask::CompleteCallback> complete = std::make_unique<AsyncTask::CompleteCallback>(
63         [thisWeakPtr, config, callbacks = callbacks_, callbacksSync = callbacksSync_]
64         (NativeEngine &engine, AsyncTask &task, int32_t status) {
65             std::shared_ptr<JsEnvironmentCallback> jsEnvCallback = thisWeakPtr.lock();
66             if (jsEnvCallback) {
67                 jsEnvCallback->CallConfigurationUpdatedInner("onConfigurationUpdated", config, callbacks);
68                 jsEnvCallback->CallConfigurationUpdatedInner("onConfigurationUpdated", config, callbacksSync);
69             }
70         }
71     );
72     NativeReference *callback = nullptr;
73     std::unique_ptr<AsyncTask::ExecuteCallback> execute = nullptr;
74     AsyncTask::Schedule("JsEnvironmentCallback::OnConfigurationUpdated",
75         *engine_, std::make_unique<AsyncTask>(callback, std::move(execute), std::move(complete)));
76 }
77 
CallMemoryLevelInner(const std::string & methodName,const int level,const std::map<int32_t,std::shared_ptr<NativeReference>> callbacks)78 void JsEnvironmentCallback::CallMemoryLevelInner(const std::string &methodName, const int level,
79     const std::map<int32_t, std::shared_ptr<NativeReference>> callbacks)
80 {
81     HILOG_DEBUG("CallMemoryLevelInner methodName = %{public}s", methodName.c_str());
82     for (auto &callback : callbacks) {
83         if (!callback.second) {
84             HILOG_ERROR("CallMemoryLevelInner, Invalid jsCallback");
85             return;
86         }
87 
88         auto value = callback.second->Get();
89         auto obj = ConvertNativeValueTo<NativeObject>(value);
90         if (obj == nullptr) {
91             HILOG_ERROR("CallMemoryLevelInner, Failed to get object");
92             return;
93         }
94 
95         auto method = obj->GetProperty(methodName.data());
96         if (method == nullptr) {
97             HILOG_ERROR("CallMemoryLevelInner, Failed to get %{public}s from object", methodName.data());
98             return;
99         }
100 
101         NativeValue *argv[] = { CreateJsValue(*engine_, level) };
102         engine_->CallFunction(value, method, argv, ArraySize(argv));
103     }
104 }
105 
OnMemoryLevel(const int level)106 void JsEnvironmentCallback::OnMemoryLevel(const int level)
107 {
108     std::weak_ptr<JsEnvironmentCallback> thisWeakPtr(shared_from_this());
109     std::unique_ptr<AsyncTask::CompleteCallback> complete = std::make_unique<AsyncTask::CompleteCallback>(
110         [thisWeakPtr, level, callbacks = callbacks_, callbacksSync = callbacksSync_]
111         (NativeEngine &engine, AsyncTask &task, int32_t status) {
112             std::shared_ptr<JsEnvironmentCallback> jsEnvCallback = thisWeakPtr.lock();
113             if (jsEnvCallback) {
114                 jsEnvCallback->CallMemoryLevelInner("onMemoryLevel", level, callbacks);
115                 jsEnvCallback->CallMemoryLevelInner("onMemoryLevel", level, callbacksSync);
116             }
117         }
118     );
119     NativeReference *callback = nullptr;
120     std::unique_ptr<AsyncTask::ExecuteCallback> execute = nullptr;
121     AsyncTask::Schedule("JsEnvironmentCallback::OnMemoryLevel",
122         *engine_, std::make_unique<AsyncTask>(callback, std::move(execute), std::move(complete)));
123 }
124 
Register(NativeValue * jsCallback,bool isSync)125 int32_t JsEnvironmentCallback::Register(NativeValue *jsCallback, bool isSync)
126 {
127     if (engine_ == nullptr) {
128         return -1;
129     }
130     int32_t callbackId = serialNumber_;
131     if (serialNumber_ < INT32_MAX) {
132         serialNumber_++;
133     } else {
134         serialNumber_ = 0;
135     }
136     if (isSync) {
137         callbacksSync_.emplace(callbackId, std::shared_ptr<NativeReference>(engine_->CreateReference(jsCallback, 1)));
138     } else {
139         callbacks_.emplace(callbackId, std::shared_ptr<NativeReference>(engine_->CreateReference(jsCallback, 1)));
140     }
141     return callbackId;
142 }
143 
UnRegister(int32_t callbackId,bool isSync)144 bool JsEnvironmentCallback::UnRegister(int32_t callbackId, bool isSync)
145 {
146     HILOG_DEBUG("UnRegister called, env callbackId : %{public}d", callbackId);
147     if (isSync) {
148         auto it = callbacksSync_.find(callbackId);
149         if (it == callbacksSync_.end()) {
150             HILOG_ERROR("UnRegister env callbackId: %{public}d is not in callbacksSync_", callbackId);
151             return false;
152         }
153         HILOG_DEBUG("callbacksSync_.callbackId : %{public}d", it->first);
154         return callbacksSync_.erase(callbackId) == 1;
155     }
156     auto it = callbacks_.find(callbackId);
157     if (it == callbacks_.end()) {
158         HILOG_ERROR("UnRegister env callbackId: %{public}d is not in callbacks_", callbackId);
159         return false;
160     }
161     HILOG_DEBUG("callbacks_.callbackId : %{public}d", it->first);
162     return callbacks_.erase(callbackId) == 1;
163 }
164 
IsEmpty() const165 bool JsEnvironmentCallback::IsEmpty() const
166 {
167     return callbacks_.empty() && callbacksSync_.empty();
168 }
169 }  // namespace AbilityRuntime
170 }  // namespace OHOS