1 /*
2 * Copyright (c) 2023-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 "js_ability_foreground_state_observer.h"
17
18 #include "hilog_tag_wrapper.h"
19 #include "js_runtime_utils.h"
20
21 namespace OHOS {
22 namespace AbilityRuntime {
23 namespace {
24 constexpr size_t ARGC_ONE = 1;
25 }
JSAbilityForegroundStateObserver(napi_env env)26 JSAbilityForegroundStateObserver::JSAbilityForegroundStateObserver(napi_env env) : env_(env) {}
27
OnAbilityStateChanged(const AbilityStateData & abilityStateData)28 void JSAbilityForegroundStateObserver::OnAbilityStateChanged(const AbilityStateData &abilityStateData)
29 {
30 TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
31 if (!valid_) {
32 TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid appms");
33 return;
34 }
35 wptr<JSAbilityForegroundStateObserver> jsObserver = this;
36 std::unique_ptr<NapiAsyncTask::CompleteCallback> complete = std::make_unique<NapiAsyncTask::CompleteCallback>(
37 [jsObserver, abilityStateData](napi_env env, NapiAsyncTask &task, int32_t status) {
38 sptr<JSAbilityForegroundStateObserver> jsObserverSptr = jsObserver.promote();
39 if (jsObserverSptr == nullptr) {
40 TAG_LOGE(AAFwkTag::ABILITYMGR, "null observer");
41 return;
42 }
43 jsObserverSptr->HandleOnAbilityStateChanged(abilityStateData);
44 });
45 napi_ref callback = nullptr;
46 NapiAsyncTask::Schedule("JSAbilityForegroundStateObserver::OnAbilityStateChanged", env_,
47 std::make_unique<NapiAsyncTask>(callback, nullptr, std::move(complete)));
48 }
49
HandleOnAbilityStateChanged(const AbilityStateData & abilityStateData)50 void JSAbilityForegroundStateObserver::HandleOnAbilityStateChanged(const AbilityStateData &abilityStateData)
51 {
52 TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
53 for (auto &item : jsObserverObjectSet_) {
54 if (item == nullptr) {
55 continue;
56 }
57 napi_value obj = item->GetNapiValue();
58 napi_value argv[] = { CreateJsAbilityStateData(env_, abilityStateData) };
59 CallJsFunction(obj, "onAbilityStateChanged", argv, ARGC_ONE);
60 }
61 }
62
CallJsFunction(const napi_value & value,const char * methodName,const napi_value * argv,const size_t argc)63 void JSAbilityForegroundStateObserver::CallJsFunction(
64 const napi_value &value, const char *methodName, const napi_value *argv, const size_t argc)
65 {
66 TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
67 if (value == nullptr) {
68 TAG_LOGE(AAFwkTag::ABILITYMGR, "null value");
69 return;
70 }
71
72 napi_value method = nullptr;
73 napi_get_named_property(env_, value, methodName, &method);
74 if (method == nullptr) {
75 TAG_LOGE(AAFwkTag::ABILITYMGR, "null method");
76 return;
77 }
78 napi_value callResult = nullptr;
79 napi_status status = napi_call_function(env_, value, method, argc, argv, &callResult);
80 if (status != napi_ok) {
81 TAG_LOGE(AAFwkTag::ABILITYMGR, "call js func failed: %{public}d", status);
82 }
83 TAG_LOGD(AAFwkTag::ABILITYMGR, "end");
84 }
85
IsObserverObjectExsit(const napi_value & jsObserverObject)86 bool JSAbilityForegroundStateObserver::IsObserverObjectExsit(const napi_value &jsObserverObject)
87 {
88 if (jsObserverObject == nullptr) {
89 TAG_LOGE(AAFwkTag::ABILITYMGR, "null observer");
90 return false;
91 }
92
93 if (GetObserverObject(jsObserverObject) == nullptr) {
94 TAG_LOGD(AAFwkTag::ABILITYMGR, "observer not exist");
95 return false;
96 }
97 return true;
98 }
99
AddJsObserverObject(const napi_value & jsObserverObject)100 void JSAbilityForegroundStateObserver::AddJsObserverObject(const napi_value &jsObserverObject)
101 {
102 if (jsObserverObject == nullptr) {
103 TAG_LOGE(AAFwkTag::ABILITYMGR, "null observer");
104 return;
105 }
106
107 if (IsObserverObjectExsit(jsObserverObject)) {
108 TAG_LOGD(AAFwkTag::ABILITYMGR, "observer not exist");
109 return;
110 }
111 napi_ref ref = nullptr;
112 napi_create_reference(env_, jsObserverObject, 1, &ref);
113 jsObserverObjectSet_.emplace(std::shared_ptr<NativeReference>(reinterpret_cast<NativeReference *>(ref)));
114 }
115
RemoveJsObserverObject(const napi_value & jsObserverObject)116 void JSAbilityForegroundStateObserver::RemoveJsObserverObject(const napi_value &jsObserverObject)
117 {
118 if (jsObserverObject == nullptr) {
119 TAG_LOGE(AAFwkTag::ABILITYMGR, "null observer");
120 return;
121 }
122
123 auto observer = GetObserverObject(jsObserverObject);
124 if (observer != nullptr) {
125 jsObserverObjectSet_.erase(observer);
126 }
127 }
128
RemoveAllJsObserverObject()129 void JSAbilityForegroundStateObserver::RemoveAllJsObserverObject()
130 {
131 if (!jsObserverObjectSet_.empty()) {
132 jsObserverObjectSet_.clear();
133 }
134 }
135
GetObserverObject(const napi_value & jsObserverObject)136 std::shared_ptr<NativeReference> JSAbilityForegroundStateObserver::GetObserverObject(const napi_value &jsObserverObject)
137 {
138 if (jsObserverObject == nullptr) {
139 TAG_LOGE(AAFwkTag::ABILITYMGR, "null observer");
140 return nullptr;
141 }
142 for (auto &observer : jsObserverObjectSet_) {
143 if (observer == nullptr) {
144 TAG_LOGE(AAFwkTag::ABILITYMGR, "null observer");
145 continue;
146 }
147
148 napi_value value = observer->GetNapiValue();
149 if (value == nullptr) {
150 TAG_LOGE(AAFwkTag::ABILITYMGR, "get object failed");
151 continue;
152 }
153
154 bool isEqual = false;
155 napi_strict_equals(env_, value, jsObserverObject, &isEqual);
156 if (isEqual) {
157 return observer;
158 }
159 }
160 return nullptr;
161 }
162
SetValid(const bool valid)163 void JSAbilityForegroundStateObserver::SetValid(const bool valid)
164 {
165 valid_ = valid;
166 }
167
IsEmpty()168 bool JSAbilityForegroundStateObserver::IsEmpty()
169 {
170 return jsObserverObjectSet_.empty();
171 }
172 } // namespace AbilityRuntime
173 } // namespace OHOS
174