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