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 21namespace OHOS { 22namespace WuKong { 23namespace { 24const float SAMEPERCENT = 0.8; 25const int ONELAYER = 1; 26const int ZEROLAYER = 0; 27const float MINCOVERAGE = 0.9; 28uint8_t LISTITEM_COUNT = 0; 29uint8_t GRID_COUNT = 0; 30uint8_t NUMBER_ZERO = 0; 31uint8_t LISTITEM_COUNT_LIMIT = 10; 32} // namespace 33SceneDelegate::SceneDelegate() 34{ 35} 36SceneDelegate::~SceneDelegate() 37{ 38} 39 40ErrCode 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 79ErrCode 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 149ErrCode 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 196ErrCode 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 226uint32_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 240ErrCode 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 273ErrCode 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 316bool 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