• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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