1 /*
2 * Copyright (c) 2025 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 "core/common/ace_translate_manager.h"
17
18 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
19
20 #include "core/components_ng/pattern/image/image_pattern.h"
21 #include "core/components_ng/pattern/web/web_pattern.h"
22
23 namespace OHOS::Ace {
24 const std::set<std::string> UiTranslateManagerImpl::layoutTags_ = { "Flex", "Stack", "Row", "Column", "WindowScene",
25 "root", "__Common__", "Swiper", "Grid", "GridItem", "page", "stage", "FormComponent", "Tabs", "TabContent" };
AddTranslateListener(const WeakPtr<NG::FrameNode> node)26 void UiTranslateManagerImpl::AddTranslateListener(const WeakPtr<NG::FrameNode> node)
27 {
28 auto frameNode = node.Upgrade();
29 CHECK_NULL_VOID(frameNode);
30 int32_t nodeId = frameNode->GetId();
31 listenerMap_[nodeId] = node;
32 LOGI("AddTranslateListener WebView nodeId:%{public}d", nodeId);
33 }
RemoveTranslateListener(int32_t nodeId)34 void UiTranslateManagerImpl::RemoveTranslateListener(int32_t nodeId)
35 {
36 listenerMap_.erase(nodeId);
37 LOGI("RemoveTranslateListener WebView nodeId:%{public}d", nodeId);
38 }
39
GetWebViewCurrentLanguage()40 void UiTranslateManagerImpl::GetWebViewCurrentLanguage()
41 {
42 for (auto listener : listenerMap_) {
43 auto frameNode = listener.second.Upgrade();
44 if (!frameNode) {
45 continue;
46 }
47 int32_t nodeId = frameNode->GetId();
48 auto pattern = frameNode->GetPattern<NG::WebPattern>();
49 if (!pattern) {
50 continue;
51 }
52 std::string currentLanguage = pattern->GetCurrentLanguage();
53 auto result = JsonUtil::Create();
54 result->Put("nodeId", nodeId);
55 result->Put("currentLanguage", currentLanguage.c_str());
56 UiSessionManager::GetInstance()->SendCurrentLanguage(result->ToString());
57 }
58 }
59
GetTranslateText(std::string extraData,bool isContinued)60 void UiTranslateManagerImpl::GetTranslateText(std::string extraData, bool isContinued)
61 {
62 if (listenerMap_.empty()) {
63 UiSessionManager::GetInstance()->SendWebTextToAI(-1, "empty");
64 } else {
65 UiSessionManager::GetInstance()->SendWebTextToAI(-1, "non-empty");
66 }
67 for (auto listener : listenerMap_) {
68 auto frameNode = listener.second.Upgrade();
69 if (!frameNode) {
70 continue;
71 }
72 int32_t nodeId = frameNode->GetId();
73 auto cb = [nodeId](std::string res) { UiSessionManager::GetInstance()->SendWebTextToAI(nodeId, res); };
74 auto pattern = frameNode->GetPattern<NG::WebPattern>();
75 if (!pattern) {
76 continue;
77 }
78 pattern->GetTranslateText(extraData, cb, isContinued);
79 }
80 }
81
SendTranslateResult(int32_t nodeId,std::vector<std::string> results,std::vector<int32_t> ids)82 void UiTranslateManagerImpl::SendTranslateResult(
83 int32_t nodeId, std::vector<std::string> results, std::vector<int32_t> ids)
84 {
85 auto iter = listenerMap_.find(nodeId);
86 if (iter != listenerMap_.end()) {
87 auto frameNode = iter->second.Upgrade();
88 CHECK_NULL_VOID(frameNode);
89 auto pattern = frameNode->GetPattern<NG::WebPattern>();
90 CHECK_NULL_VOID(pattern);
91 pattern->SendTranslateResult(results, ids);
92 }
93 }
94
SendTranslateResult(int32_t nodeId,std::string res)95 void UiTranslateManagerImpl::SendTranslateResult(int32_t nodeId, std::string res)
96 {
97 auto iter = listenerMap_.find(nodeId);
98 if (iter != listenerMap_.end()) {
99 auto frameNode = iter->second.Upgrade();
100 CHECK_NULL_VOID(frameNode);
101 auto pattern = frameNode->GetPattern<NG::WebPattern>();
102 CHECK_NULL_VOID(pattern);
103 pattern->SendTranslateResult(res);
104 } else {
105 LOGW("SendTranslateResult can not find WebView nodeId:%{public}d", nodeId);
106 }
107 }
108
ResetTranslate(int32_t nodeId)109 void UiTranslateManagerImpl::ResetTranslate(int32_t nodeId)
110 {
111 if (nodeId == -1) {
112 for (auto listener : listenerMap_) {
113 auto frameNode = listener.second.Upgrade();
114 if (!frameNode) {
115 continue;
116 }
117 auto pattern = frameNode->GetPattern<NG::WebPattern>();
118 if (!pattern) {
119 continue;
120 }
121 pattern->EndTranslate();
122 }
123 } else {
124 auto iter = listenerMap_.find(nodeId);
125 if (iter != listenerMap_.end()) {
126 auto frameNode = iter->second.Upgrade();
127 CHECK_NULL_VOID(frameNode);
128 auto pattern = frameNode->GetPattern<NG::WebPattern>();
129 CHECK_NULL_VOID(pattern);
130 pattern->EndTranslate();
131 } else {
132 LOGW("ResetTranslate can not find WebView nodeId:%{public}d", nodeId);
133 }
134 }
135 }
136
ClearMap()137 void UiTranslateManagerImpl::ClearMap()
138 {
139 pixelMap_.clear();
140 }
141
SendPixelMap()142 void UiTranslateManagerImpl::SendPixelMap()
143 {
144 LOGI("manager start sendPixelMap");
145 UiSessionManager::GetInstance()->SendPixelMap(pixelMap_);
146 }
147
AddPixelMap(int32_t nodeId,RefPtr<PixelMap> pixelMap)148 void UiTranslateManagerImpl::AddPixelMap(int32_t nodeId, RefPtr<PixelMap> pixelMap)
149 {
150 CHECK_NULL_VOID(pixelMap);
151 std::pair<int32_t, std::shared_ptr<Media::PixelMap>> value = { nodeId, pixelMap->GetPixelMapSharedPtr() };
152 pixelMap_.push_back(value);
153 }
154
GetAllPixelMap(RefPtr<NG::FrameNode> pageNode)155 void UiTranslateManagerImpl::GetAllPixelMap(RefPtr<NG::FrameNode> pageNode)
156 {
157 RefPtr<NG::FrameNode> result;
158 FindTopNavDestination(pageNode, result);
159 if (result != nullptr) {
160 TravelFindPixelMap(result);
161 } else {
162 TravelFindPixelMap(pageNode);
163 }
164 SendPixelMap();
165 }
166
TravelFindPixelMap(RefPtr<NG::UINode> currentNode)167 void UiTranslateManagerImpl::TravelFindPixelMap(RefPtr<NG::UINode> currentNode)
168 {
169 for (const auto& item : currentNode->GetChildren()) {
170 auto node = AceType::DynamicCast<NG::FrameNode>(item);
171 if (node) {
172 if (!node->CheckVisibleOrActive()) {
173 continue;
174 }
175 auto property = node->GetLayoutProperty();
176 if (node->GetTag() == V2::IMAGE_ETS_TAG && property &&
177 (static_cast<int32_t>(property->GetVisibility().value_or(VisibleType::VISIBLE)) == 0) &&
178 node->IsActive()) {
179 auto imagePattern = node->GetPattern<NG::ImagePattern>();
180 CHECK_NULL_VOID(imagePattern);
181 imagePattern->AddPixelMapToUiManager();
182 }
183 }
184 TravelFindPixelMap(item);
185 }
186 }
187
PostToUI(const std::function<void ()> & task)188 void UiTranslateManagerImpl::PostToUI(const std::function<void()>& task)
189 {
190 if (taskExecutor_) {
191 taskExecutor_->PostTask(task, TaskExecutor::TaskType::UI, "ArkUIHandleUiTranslateManager");
192 }
193 }
194
FindTopNavDestination(RefPtr<NG::UINode> currentNode,RefPtr<NG::FrameNode> & result)195 void UiTranslateManagerImpl::FindTopNavDestination(RefPtr<NG::UINode> currentNode, RefPtr<NG::FrameNode>& result)
196 {
197 for (const auto& item : currentNode->GetChildren()) {
198 auto node = AceType::DynamicCast<NG::FrameNode>(item);
199 if (node && node->GetTag() == V2::NAVIGATION_VIEW_ETS_TAG) {
200 auto navigationGroupNode = AceType::DynamicCast<NG::NavigationGroupNode>(node);
201 CHECK_NULL_VOID(navigationGroupNode);
202 result = navigationGroupNode->GetTopDestination();
203 return;
204 }
205 FindTopNavDestination(item, result);
206 }
207 }
208 } // namespace OHOS::Ace
209