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 "scene_delegate.h"
17
18 #include "normal_scene.h"
19 #include "wukong_util.h"
20
21 namespace OHOS {
22 namespace WuKong {
23 namespace {
24 const float SAMEPERCENT = 0.8;
25 const int ONELAYER = 1;
26 const int ZEROLAYER = 0;
27 const float MINCOVERAGE = 0.9;
28 uint8_t LISTITEM_COUNT = 0;
29 uint8_t GRID_COUNT = 0;
30 uint8_t NUMBER_ZERO = 0;
31 uint8_t NUMBER_FOUR = 4;
32 uint8_t NUMBER_FIVE = 5;
33 } // namespace
SceneDelegate()34 SceneDelegate::SceneDelegate()
35 {
36 }
~SceneDelegate()37 SceneDelegate::~SceneDelegate()
38 {
39 }
40
GetCurrentComponentInfo(std::shared_ptr<ComponentTree> componentinfo,std::vector<std::shared_ptr<ComponentTree>> & componentlist)41 ErrCode SceneDelegate::GetCurrentComponentInfo(std::shared_ptr<ComponentTree> componentinfo,
42 std::vector<std::shared_ptr<ComponentTree>> &componentlist)
43 {
44 ErrCode result = OHOS::ERR_OK;
45 if (componentinfo == nullptr) {
46 return OHOS::ERR_NO_INIT;
47 }
48 auto componentinfos = componentinfo->GetChildren();
49 if (componentinfos.size() > 0) {
50 bool isListItem = false;
51 for (auto it : componentinfos) {
52 auto componenttree = std::static_pointer_cast<ComponentTree>(it);
53 if (componenttree->GetType() == "GridContainer") {
54 componentlist.push_back(componenttree);
55 componentType_.push_back("GridContainer");
56 GRID_COUNT++;
57 TRACK_LOG_STR("GridContainer count %u", GRID_COUNT);
58 }
59 if (componenttree->GetType() == "List") {
60 LISTITEM_COUNT = NUMBER_ZERO;
61 }
62 if (componenttree->GetType() == "ListItem") {
63 isListItem = true;
64 LISTITEM_COUNT++;
65 }
66 if (isListItem && LISTITEM_COUNT > NUMBER_FOUR) {
67 componenttree = std::static_pointer_cast<ComponentTree>(componentinfos[componentinfos.size() - 1]);
68 }
69 GetCurrentComponentInfo(componenttree, componentlist);
70 if (isListItem && LISTITEM_COUNT >= NUMBER_FIVE) {
71 break;
72 }
73 }
74 } else if (GRID_COUNT <= componentlist.size() &&
75 std::static_pointer_cast<ComponentTree>(componentinfo)->IsVisible() &&
76 IsComponentInScreen(std::static_pointer_cast<ComponentTree>(componentinfo))) {
77 componentlist.emplace(componentlist.end() - GRID_COUNT, componentinfo);
78 componentType_.push_back(std::static_pointer_cast<ComponentTree>(componentinfo)->GetType());
79 }
80 return result;
81 }
82
ChooseScene(bool isRandom)83 ErrCode SceneDelegate::ChooseScene(bool isRandom)
84 {
85 ErrCode result;
86 GRID_COUNT = 0;
87 componentType_.clear();
88 auto treemanager = TreeManager::GetInstance();
89 auto newpage = treemanager->GetNewPage();
90 if (newpage == nullptr) {
91 ERROR_LOG("newpage is nullptr");
92 return OHOS::ERR_NO_INIT;
93 }
94 auto newcomponents = treemanager->GetNewComponents();
95 if (newcomponents == nullptr) {
96 ERROR_LOG("newcomponents is nullptr");
97 return OHOS::ERR_NO_INIT;
98 }
99 std::vector<std::shared_ptr<ComponentTree>> allcomponentlist;
100 // get current component list
101 GetCurrentComponentInfo(newcomponents, allcomponentlist);
102 // set all component counts of new page
103 newpage->SetAllComponentCount(allcomponentlist.size());
104 // set valid component counts of new page
105 newpage->SetValidComponentCount(allcomponentlist.size());
106 // get current page node
107 std::shared_ptr<WuKongTree> currentpage = treemanager->GetCurrentPage();
108 if (currentpage == nullptr) {
109 DEBUG_LOG("first page");
110 treemanager->AddPage();
111 // set available component list of current page
112 result = SetAvailableComponentList(newcomponents, isRandom);
113 TRACK_LOG_STR("new component Node Id: %016llX", newcomponents->GetNodeId());
114 return result;
115 }
116 DEBUG_LOG_STR("new ID: %016llX ,old ID: %016llX", newpage->GetNodeId(), currentpage->GetNodeId());
117 auto currentcomponents = treemanager->GetCurrentComponents();
118 if (currentcomponents == nullptr) {
119 ERROR_LOG("currentcomponents is nullptr");
120 return OHOS::ERR_NO_INIT;
121 }
122 if (newpage->IsEqual(currentpage)) {
123 treemanager->SamePage();
124 DEBUG_LOG("at same page");
125 result = SetAvailableComponentList(currentcomponents, isRandom);
126 return result;
127 } else {
128 bool isFoundParent = false;
129 // find the same page in parent list
130 result = FindSamePageInParent(isFoundParent, isRandom);
131 if (result != OHOS::ERR_OK || isFoundParent) {
132 return result;
133 }
134 bool isFoundChildren = false;
135 // find the same page in chidren list
136 result = FindSamePageInChildren(isFoundChildren, isRandom);
137 if (result != OHOS::ERR_OK) {
138 return result;
139 }
140 if (!isFoundChildren) {
141 auto currentcomponentinfo = treemanager->GetCurrentComponents();
142 if (currentcomponentinfo == nullptr) {
143 ERROR_LOG("currentcomponentinfo is nullptr");
144 return OHOS::ERR_NO_INIT;
145 }
146 // compare new component tree and current component tree
147 CompareComponentInfos(newcomponents, currentcomponentinfo, isRandom);
148 }
149 }
150 return result;
151 }
152
CompareComponentInfos(std::shared_ptr<ComponentTree> & newcomponentinfo,std::shared_ptr<ComponentTree> & oldcomponentinfo,bool isRandom)153 ErrCode SceneDelegate::CompareComponentInfos(std::shared_ptr<ComponentTree> &newcomponentinfo,
154 std::shared_ptr<ComponentTree> &oldcomponentinfo, bool isRandom)
155 {
156 ErrCode result;
157 DEBUG_LOG("compare page");
158 GRID_COUNT = 0;
159 componentType_.clear();
160 std::vector<std::shared_ptr<ComponentTree>> newChildList;
161 GetCurrentComponentInfo(newcomponentinfo, newChildList);
162 GRID_COUNT = 0;
163 componentType_.clear();
164 std::vector<std::shared_ptr<ComponentTree>> currentChildList;
165 GetCurrentComponentInfo(oldcomponentinfo, currentChildList);
166 auto treemanager = TreeManager::GetInstance();
167 DEBUG_LOG_STR("childlist size %d", currentChildList.size());
168 float samePercent = 0.0;
169 // get the same count in new component list and current component list
170 uint32_t samecount = FindSame(newChildList, currentChildList);
171 if (newChildList.size() > currentChildList.size()) {
172 samePercent = (float)samecount / (float)currentChildList.size();
173 } else {
174 samePercent = (float)samecount / (float)newChildList.size();
175 }
176
177 DEBUG_LOG_STR("same percent: %2f", samePercent);
178 if (samePercent > SAMEPERCENT) {
179 if (!treemanager->UpdatePage(ZEROLAYER)) {
180 DEBUG_LOG("update failed");
181 return OHOS::ERR_NO_INIT;
182 }
183 auto currentComponentinfo = treemanager->GetCurrentComponents();
184 if (currentComponentinfo == nullptr) {
185 ERROR_LOG("current component is nullptr");
186 return OHOS::ERR_NO_INIT;
187 }
188 result = SetAvailableComponentList(currentComponentinfo, isRandom);
189 } else {
190 auto newcomponent = treemanager->GetNewComponents();
191 DEBUG_LOG("add new page");
192 treemanager->AddPage();
193 result = SetAvailableComponentList(newcomponent, isRandom);
194 }
195 return result;
196 }
197
SetAvailableComponentList(std::shared_ptr<ComponentTree> componentinfo,bool isRandom)198 ErrCode SceneDelegate::SetAvailableComponentList(std::shared_ptr<ComponentTree> componentinfo, bool isRandom)
199 {
200 GRID_COUNT = 0;
201 componentType_.clear();
202 ErrCode result = OHOS::ERR_OK;
203 NormalScene normalscene;
204 std::vector<std::shared_ptr<ComponentTree>> componentlist;
205 std::shared_ptr<ComponentTree> inputcomponent = nullptr;
206 auto treemanager = TreeManager::GetInstance();
207 GetCurrentComponentInfo(componentinfo, componentlist);
208 if (isRandom) {
209 // get valid components from scene
210 normalscene.SetInputComponentList(componentlist);
211 isBack_ = normalscene.IsBackToPrePage();
212 TRACK_LOG_STR("is random back: %d", isBack_);
213 // set valid components to tree manager
214 treemanager->SetActiveComponent(componentlist);
215 } else {
216 // get valid component from scene
217 normalscene.SetInputComponent(componentlist, inputcomponent);
218 isBack_ = normalscene.IsBackToPrePage();
219 TRACK_LOG_STR("is special back: %d", isBack_);
220 if (inputcomponent != nullptr) {
221 // set valid component to tree manager
222 treemanager->SetActiveComponent(inputcomponent);
223 }
224 }
225 return result;
226 }
227
FindSame(const std::vector<std::shared_ptr<ComponentTree>> & newcomponentlist,const std::vector<std::shared_ptr<ComponentTree>> & oldcomponentlist)228 uint32_t SceneDelegate::FindSame(const std::vector<std::shared_ptr<ComponentTree>> &newcomponentlist,
229 const std::vector<std::shared_ptr<ComponentTree>> &oldcomponentlist)
230 {
231 uint32_t count = 0;
232 for (auto newIt : newcomponentlist) {
233 for (auto oldIt : oldcomponentlist) {
234 if (newIt->IsEqual(oldIt)) {
235 count++;
236 }
237 }
238 }
239 return count;
240 }
241
FindSamePageInChildren(bool & isFound,bool isRandom)242 ErrCode SceneDelegate::FindSamePageInChildren(bool &isFound, bool isRandom)
243 {
244 ErrCode result = OHOS::ERR_OK;
245 auto treemanager = TreeManager::GetInstance();
246 auto newpage = treemanager->GetNewPage();
247 std::shared_ptr<WuKongTree> currentpage = treemanager->GetCurrentPage();
248 auto pagechild = currentpage->GetChildren();
249 if (pagechild.empty()) {
250 return result;
251 }
252 int childIndex = -1;
253 for (auto it : pagechild) {
254 TRACK_LOG_STR("current child ID: %016llX ", it->GetNodeId());
255 childIndex++;
256 if (newpage->IsEqual(it)) {
257 DEBUG_LOG("go to same page");
258 if (!treemanager->UpdatePage(ONELAYER, childIndex)) {
259 DEBUG_LOG("update failed");
260 return OHOS::ERR_NO_INIT;
261 }
262 auto gotocurrent = treemanager->GetCurrentComponents();
263 if (gotocurrent == nullptr) {
264 ERROR_LOG("goto current is nullptr");
265 return OHOS::ERR_NO_INIT;
266 }
267 result = SetAvailableComponentList(gotocurrent, isRandom);
268 isFound = true;
269 return result;
270 }
271 }
272 return result;
273 }
274
FindSamePageInParent(bool & isFound,bool isRandom)275 ErrCode SceneDelegate::FindSamePageInParent(bool &isFound, bool isRandom)
276 {
277 ErrCode result = OHOS::ERR_OK;
278 auto treemanager = TreeManager::GetInstance();
279 auto newpage = treemanager->GetNewPage();
280 std::shared_ptr<WuKongTree> currentpage = treemanager->GetCurrentPage();
281 int layer = 0;
282 auto parentpage = currentpage->GetParent();
283 while (parentpage != nullptr) {
284 TRACK_LOG_STR("current parent ID: %016llX ", parentpage->GetNodeId());
285 layer--;
286 if (newpage->IsEqual(parentpage)) {
287 auto oldpage = treemanager->GetCurrentPage();
288 if (oldpage == nullptr) {
289 ERROR_LOG("old page is nullptr");
290 return OHOS::ERR_NO_INIT;
291 }
292 float coverage = (float)oldpage->GetInputCount() / (float)oldpage->GetValidComponentCount();
293
294 TRACK_LOG_STR("layer: (%d)", layer);
295 if (!treemanager->UpdatePage(layer)) {
296 DEBUG_LOG("update failed");
297 return OHOS::ERR_NO_INIT;
298 }
299 if (coverage < MINCOVERAGE && !isRandom) {
300 DEBUG_LOG("continue to same page");
301 treemanager->SetActiveComponent(
302 std::static_pointer_cast<PageTree>(parentpage)->GetCurrentComponentNode());
303 } else {
304 DEBUG_LOG("back to same page");
305 result = SetAvailableComponentList(treemanager->GetCurrentComponents(), isRandom);
306 }
307 isFound = true;
308 return result;
309 }
310 parentpage = parentpage->GetParent();
311 }
312 return result;
313 }
314
IsComponentInScreen(const std::shared_ptr<ComponentTree> componentinfo)315 bool SceneDelegate::IsComponentInScreen(const std::shared_ptr<ComponentTree> componentinfo)
316 {
317 int32_t width = -1;
318 int32_t height = -1;
319 ErrCode result = WuKongUtil::GetInstance()->GetScreenSize(width, height);
320 if (result != OHOS::ERR_OK) {
321 ERROR_LOG("failed to determine component position");
322 return false;
323 }
324 auto rect = componentinfo->GetPosition();
325 if ((rect.GetRightBottomXScreenPostion() <= width) && (rect.GetLeftTopXScreenPostion() <= width) &&
326 (rect.GetRightBottomYScreenPostion() <= height) && (rect.GetLeftTopYScreenPostion() <= height) &&
327 (rect.GetRightBottomXScreenPostion() > 0) && (rect.GetLeftTopXScreenPostion() > 0) &&
328 (rect.GetRightBottomYScreenPostion() > 0) && (rect.GetLeftTopYScreenPostion() > 0)) {
329 return true;
330 }
331 return false;
332 }
333 } // namespace WuKong
334 } // namespace OHOS
335