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