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)31 void JsEnvironmentCallback::CallConfigurationUpdatedInner(
32 const std::string &methodName, const AppExecFwk::Configuration &config)
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](NativeEngine &engine, AsyncTask &task, int32_t status) {
64 std::shared_ptr<JsEnvironmentCallback> jsEnvCallback = thisWeakPtr.lock();
65 if (jsEnvCallback) {
66 jsEnvCallback->CallConfigurationUpdatedInner("onConfigurationUpdated", config);
67 }
68 }
69 );
70 NativeReference *callback = nullptr;
71 std::unique_ptr<AsyncTask::ExecuteCallback> execute = nullptr;
72 AsyncTask::Schedule("JsEnvironmentCallback::OnConfigurationUpdated",
73 *engine_, std::make_unique<AsyncTask>(callback, std::move(execute), std::move(complete)));
74 }
75
CallMemoryLevelInner(const std::string & methodName,const int level)76 void JsEnvironmentCallback::CallMemoryLevelInner(const std::string &methodName, const int level)
77 {
78 HILOG_DEBUG("CallMemoryLevelInner methodName = %{public}s", methodName.c_str());
79 for (auto &callback : callbacks_) {
80 if (!callback.second) {
81 HILOG_ERROR("CallMemoryLevelInner, Invalid jsCallback");
82 return;
83 }
84
85 auto value = callback.second->Get();
86 auto obj = ConvertNativeValueTo<NativeObject>(value);
87 if (obj == nullptr) {
88 HILOG_ERROR("CallMemoryLevelInner, Failed to get object");
89 return;
90 }
91
92 auto method = obj->GetProperty(methodName.data());
93 if (method == nullptr) {
94 HILOG_ERROR("CallMemoryLevelInner, Failed to get %{public}s from object", methodName.data());
95 return;
96 }
97
98 NativeValue *argv[] = { CreateJsValue(*engine_, level) };
99 engine_->CallFunction(value, method, argv, ArraySize(argv));
100 }
101 }
102
OnMemoryLevel(const int level)103 void JsEnvironmentCallback::OnMemoryLevel(const int level)
104 {
105 std::weak_ptr<JsEnvironmentCallback> thisWeakPtr(shared_from_this());
106 std::unique_ptr<AsyncTask::CompleteCallback> complete = std::make_unique<AsyncTask::CompleteCallback>(
107 [thisWeakPtr, level](NativeEngine &engine, AsyncTask &task, int32_t status) {
108 std::shared_ptr<JsEnvironmentCallback> jsEnvCallback = thisWeakPtr.lock();
109 if (jsEnvCallback) {
110 jsEnvCallback->CallMemoryLevelInner("onMemoryLevel", level);
111 }
112 }
113 );
114 NativeReference *callback = nullptr;
115 std::unique_ptr<AsyncTask::ExecuteCallback> execute = nullptr;
116 AsyncTask::Schedule("JsEnvironmentCallback::OnMemoryLevel",
117 *engine_, std::make_unique<AsyncTask>(callback, std::move(execute), std::move(complete)));
118 }
119
Register(NativeValue * jsCallback)120 int32_t JsEnvironmentCallback::Register(NativeValue *jsCallback)
121 {
122 if (engine_ == nullptr) {
123 return -1;
124 }
125 int32_t callbackId = serialNumber_;
126 if (serialNumber_ < INT32_MAX) {
127 serialNumber_++;
128 } else {
129 serialNumber_ = 0;
130 }
131 callbacks_.emplace(callbackId, std::shared_ptr<NativeReference>(engine_->CreateReference(jsCallback, 1)));
132 return callbackId;
133 }
134
UnRegister(int32_t callbackId)135 bool JsEnvironmentCallback::UnRegister(int32_t callbackId)
136 {
137 HILOG_DEBUG("UnRegister called, env callbackId : %{public}d", callbackId);
138 auto it = callbacks_.find(callbackId);
139 if (it == callbacks_.end()) {
140 HILOG_ERROR("UnRegister env callbackId: %{public}d is not in callbacks_", callbackId);
141 return false;
142 }
143 HILOG_DEBUG("callbacks_.callbackId : %{public}d", it->first);
144 return callbacks_.erase(callbackId) == 1;
145 }
146
IsEmpty() const147 bool JsEnvironmentCallback::IsEmpty() const
148 {
149 return callbacks_.empty();
150 }
151 } // namespace AbilityRuntime
152 } // namespace OHOS