• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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 #include "frameworks/bridge/declarative_frontend/engine/jsi/modules/jsi_context_module.h"
16 
17 #include "base/log/log.h"
18 #include "base/subwindow/subwindow_manager.h"
19 #include "frameworks/core/common/container.h"
20 
21 #ifdef PLUGIN_COMPONENT_SUPPORTED
22 #include "core/common/plugin_manager.h"
23 #endif
24 namespace OHOS::Ace::Framework {
25 
26 thread_local std::unordered_map<int32_t, std::shared_ptr<JsValue>> JsiContextModule::contexts_;
27 std::unordered_map<int32_t, std::weak_ptr<JsValue>> JsiContextModule::weakptrContexts_;
28 #ifdef PREVIEW
29 bool JsiContextModule::normalPreview = false;
30 #endif
31 namespace {
IsDynamicComponentUiContentType(int32_t instanceId)32 bool IsDynamicComponentUiContentType(int32_t instanceId)
33 {
34     return false;
35 }
36 }
37 
GetInstance()38 JsiContextModule* JsiContextModule::GetInstance()
39 {
40     static JsiContextModule instance;
41     return &instance;
42 }
43 
GetInstanceIdByThis(const std::shared_ptr<JsRuntime> & runtime,const std::vector<std::shared_ptr<JsValue>> & argv,int32_t argc)44 int32_t JsiContextModule::GetInstanceIdByThis(
45     const std::shared_ptr<JsRuntime>& runtime, const std::vector<std::shared_ptr<JsValue>>& argv, int32_t argc)
46 {
47     if (argc <= 0) {
48         return INSTANCE_ID_UNDEFINED;
49     }
50     const auto& obj = argv[0];
51     if (!obj || !obj->IsObject(runtime) || !obj->HasProperty(runtime, "getInstanceId")) {
52         return INSTANCE_ID_UNDEFINED;
53     }
54     auto getIdFunc = obj->GetProperty(runtime, "getInstanceId");
55     auto retId = getIdFunc->Call(runtime, obj, {}, 0);
56     if (!retId->IsInt32(runtime)) {
57         return INSTANCE_ID_UNDEFINED;
58     }
59     return retId->ToInt32(runtime);
60 }
61 
GetContext(const std::shared_ptr<JsRuntime> & runtime,const std::shared_ptr<JsValue> & thisObj,const std::vector<std::shared_ptr<JsValue>> & argv,int32_t argc)62 std::shared_ptr<JsValue> JsiContextModule::GetContext(const std::shared_ptr<JsRuntime>& runtime,
63     const std::shared_ptr<JsValue>& thisObj, const std::vector<std::shared_ptr<JsValue>>& argv, int32_t argc)
64 {
65     int32_t currentInstance = GetInstanceIdByThis(runtime, argv, argc);
66     if (currentInstance < 0) {
67         currentInstance = Container::CurrentIdSafely();
68     }
69 
70 #ifdef PLUGIN_COMPONENT_SUPPORTED
71     if (currentInstance >= MIN_PLUGIN_SUBCONTAINER_ID) {
72         currentInstance = PluginManager::GetInstance().GetPluginParentContainerId(currentInstance);
73     }
74 #endif
75 
76     if (currentInstance >= MIN_SUBCONTAINER_ID && currentInstance < MIN_PLUGIN_SUBCONTAINER_ID) {
77         currentInstance = SubwindowManager::GetInstance()->GetParentContainerId(currentInstance);
78     }
79 
80     if (IsDynamicComponentUiContentType(currentInstance)) {
81         return GetDynamicComponentContext(currentInstance, runtime);
82     }
83 
84     auto it = contexts_.find(currentInstance);
85     if (it != contexts_.end()) {
86         return it->second;
87     }
88     int32_t currentInstanceBak = currentInstance;
89 
90     // Try to get the active container.
91     auto container = Container::GetActive();
92     if (container) {
93         currentInstance = container->GetInstanceId();
94         it = contexts_.find(currentInstance);
95         if (it != contexts_.end()) {
96             return it->second;
97         } else {
98             TAG_LOGW(AceLogTag::ACE_DEFAULT_DOMAIN, "Context not found, id:%{public}d, active:%{public}d",
99                 currentInstanceBak, currentInstance);
100         }
101     }
102 
103     return runtime->NewUndefined();
104 }
105 
InitContextModule(const std::shared_ptr<JsRuntime> & runtime,std::shared_ptr<JsValue> moduleObj)106 void JsiContextModule::InitContextModule(const std::shared_ptr<JsRuntime>& runtime, std::shared_ptr<JsValue> moduleObj)
107 {
108 #ifdef PREVIEW
109     if (!normalPreview) {
110         moduleObj->SetProperty(runtime, "getContext", runtime->NewFunction(JsiContextModule::GetContext));
111     }
112 #else
113     moduleObj->SetProperty(runtime, "getContext", runtime->NewFunction(JsiContextModule::GetContext));
114 #endif
115 }
116 
AddContext(int32_t key,const std::shared_ptr<JsValue> & value)117 void JsiContextModule::AddContext(int32_t key, const std::shared_ptr<JsValue>& value)
118 {
119     if (IsDynamicComponentUiContentType(key)) {
120         AddDynamicComponentContext(key, value);
121         return;
122     }
123 
124     if (contexts_.find(key) != contexts_.end()) {
125         LOGW("Context exists for key %d", key);
126         return;
127     }
128     contexts_.emplace(key, value);
129 }
130 
GetDynamicComponentContext(int32_t instanceId,const std::shared_ptr<JsRuntime> & runtime)131 std::shared_ptr<JsValue> JsiContextModule::GetDynamicComponentContext(
132     int32_t instanceId, const std::shared_ptr<JsRuntime>& runtime)
133 {
134     auto it = weakptrContexts_.find(instanceId);
135     if (it == weakptrContexts_.end()) {
136         return runtime->NewUndefined();
137     }
138 
139     auto jsContext = it->second.lock();
140     if (jsContext == nullptr) {
141         return runtime->NewUndefined();
142     }
143 
144     return jsContext;
145 }
146 
AddDynamicComponentContext(int32_t key,const std::shared_ptr<JsValue> & value)147 void JsiContextModule::AddDynamicComponentContext(int32_t key, const std::shared_ptr<JsValue>& value)
148 {
149     if (weakptrContexts_.find(key) != weakptrContexts_.end()) {
150         LOGW("Context exists for key %d", key);
151         return;
152     }
153     weakptrContexts_.emplace(key, value);
154 }
155 
RemoveDynamicComponentContext(int32_t key)156 void JsiContextModule::RemoveDynamicComponentContext(int32_t key)
157 {
158     auto it = weakptrContexts_.find(key);
159     if (it != weakptrContexts_.end()) {
160         weakptrContexts_.erase(it);
161     }
162 }
163 
RemoveContext(int32_t key)164 void JsiContextModule::RemoveContext(int32_t key)
165 {
166     if (IsDynamicComponentUiContentType(key)) {
167         RemoveDynamicComponentContext(key);
168         return;
169     }
170 
171     auto it = contexts_.find(key);
172     if (it != contexts_.end()) {
173         contexts_.erase(it);
174     }
175 }
176 
177 #ifdef PREVIEW
IsPreview()178 void JsiContextModule::IsPreview()
179 {
180     normalPreview = true;
181 }
182 #endif
183 
184 } // namespace OHOS::Ace::Framework
185