1886da342Sopenharmony_ci/* 2886da342Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3886da342Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4886da342Sopenharmony_ci * you may not use this file except in compliance with the License. 5886da342Sopenharmony_ci * You may obtain a copy of the License at 6886da342Sopenharmony_ci * 7886da342Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8886da342Sopenharmony_ci * 9886da342Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10886da342Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11886da342Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12886da342Sopenharmony_ci * See the License for the specific language governing permissions and 13886da342Sopenharmony_ci * limitations under the License. 14886da342Sopenharmony_ci */ 15886da342Sopenharmony_ci 16886da342Sopenharmony_ci#include "json.hpp" 17886da342Sopenharmony_ci#include "ui_model.h" 18886da342Sopenharmony_ci 19886da342Sopenharmony_cinamespace OHOS::uitest { 20886da342Sopenharmony_ci using namespace std; 21886da342Sopenharmony_ci using namespace nlohmann; 22886da342Sopenharmony_ci 23886da342Sopenharmony_ci struct DumperCache { 24886da342Sopenharmony_ci std::map<std::string, int> visitWidgetMap_; 25886da342Sopenharmony_ci std::map<std::string, int> widgetCountMap_; 26886da342Sopenharmony_ci std::set<std::string> visibleWidgetHies_; 27886da342Sopenharmony_ci }; 28886da342Sopenharmony_ci 29886da342Sopenharmony_ci static string_view GetMiddleStr(string_view str, size_t &index, string_view startStr, string_view endStr) 30886da342Sopenharmony_ci { 31886da342Sopenharmony_ci size_t ori = index; 32886da342Sopenharmony_ci auto begin = str.find(startStr, index); 33886da342Sopenharmony_ci if (begin != string::npos) { 34886da342Sopenharmony_ci index = begin + startStr.size(); 35886da342Sopenharmony_ci auto end = str.find(endStr, index); 36886da342Sopenharmony_ci if (end != string::npos) { 37886da342Sopenharmony_ci string_view result = str.substr(index, end - index); 38886da342Sopenharmony_ci index = end; 39886da342Sopenharmony_ci return result; 40886da342Sopenharmony_ci } 41886da342Sopenharmony_ci } 42886da342Sopenharmony_ci index = ori; 43886da342Sopenharmony_ci return ""; 44886da342Sopenharmony_ci } 45886da342Sopenharmony_ci 46886da342Sopenharmony_ci static bool HasVisibleChild(const std::set<std::string> &visibleWidgetHies, const string &hie) 47886da342Sopenharmony_ci { 48886da342Sopenharmony_ci for (auto visibleHie : visibleWidgetHies) { 49886da342Sopenharmony_ci if (visibleHie.find(hie) != string::npos) { 50886da342Sopenharmony_ci return true; 51886da342Sopenharmony_ci } 52886da342Sopenharmony_ci } 53886da342Sopenharmony_ci return false; 54886da342Sopenharmony_ci } 55886da342Sopenharmony_ci 56886da342Sopenharmony_ci static void DFSMarshalWidget(std::vector<Widget> &allWidget, int index, nlohmann::json &dom, 57886da342Sopenharmony_ci const DumperCache &cache) 58886da342Sopenharmony_ci { 59886da342Sopenharmony_ci auto attrData = json(); 60886da342Sopenharmony_ci allWidget.at(index).WrapperWidgetToJson(attrData); 61886da342Sopenharmony_ci auto childrenData = json::array(); 62886da342Sopenharmony_ci int childIndex = 0; 63886da342Sopenharmony_ci int childCount = 0; 64886da342Sopenharmony_ci int childVisit = 0; 65886da342Sopenharmony_ci auto hierarchy = allWidget.at(index).GetHierarchy(); 66886da342Sopenharmony_ci if (cache.widgetCountMap_.find(hierarchy) != cache.widgetCountMap_.cend()) { 67886da342Sopenharmony_ci childCount = cache.widgetCountMap_.at(hierarchy); 68886da342Sopenharmony_ci } 69886da342Sopenharmony_ci while (childVisit < childCount) { 70886da342Sopenharmony_ci auto tempChildHierarchy = WidgetHierarchyBuilder::GetChildHierarchy(hierarchy, childIndex); 71886da342Sopenharmony_ci ++childIndex; 72886da342Sopenharmony_ci if (cache.visitWidgetMap_.find(tempChildHierarchy) == cache.visitWidgetMap_.cend()) { 73886da342Sopenharmony_ci continue; 74886da342Sopenharmony_ci } 75886da342Sopenharmony_ci auto childWidIndex = cache.visitWidgetMap_.at(tempChildHierarchy); 76886da342Sopenharmony_ci if (!allWidget.at(childWidIndex).IsVisible()) { 77886da342Sopenharmony_ci if (!HasVisibleChild(cache.visibleWidgetHies_, tempChildHierarchy)) { 78886da342Sopenharmony_ci ++childVisit; 79886da342Sopenharmony_ci continue; 80886da342Sopenharmony_ci } 81886da342Sopenharmony_ci } 82886da342Sopenharmony_ci auto childData = json(); 83886da342Sopenharmony_ci DFSMarshalWidget(allWidget, childWidIndex, childData, cache); 84886da342Sopenharmony_ci childrenData.emplace_back(childData); 85886da342Sopenharmony_ci ++childVisit; 86886da342Sopenharmony_ci } 87886da342Sopenharmony_ci dom["attributes"] = attrData; 88886da342Sopenharmony_ci dom["children"] = childrenData; 89886da342Sopenharmony_ci } 90886da342Sopenharmony_ci 91886da342Sopenharmony_ci void DumpHandler::AddExtraAttrs(nlohmann::json &root, const map<int32_t, string_view> &elementTrees, size_t index) 92886da342Sopenharmony_ci { 93886da342Sopenharmony_ci auto windowIdValue = root["attributes"]["hostWindowId"].dump(); 94886da342Sopenharmony_ci auto windowId = atoi(windowIdValue.substr(1, windowIdValue.size() - 2).c_str()); 95886da342Sopenharmony_ci auto find = elementTrees.find(windowId); 96886da342Sopenharmony_ci auto elementTree = (find != elementTrees.end()) ? find->second : ""; 97886da342Sopenharmony_ci string_view nodeEndStr = "|->"; 98886da342Sopenharmony_ci auto accessibilityIdInfo = root["attributes"]["accessibilityId"].dump(); 99886da342Sopenharmony_ci auto accessibilityId = accessibilityIdInfo.substr(1, accessibilityIdInfo.size() - 2); 100886da342Sopenharmony_ci string_view accessibilityIdStr = "AccessibilityId: " + accessibilityId; 101886da342Sopenharmony_ci string_view nodeAttrStr = GetMiddleStr(elementTree, index, accessibilityIdStr, nodeEndStr); 102886da342Sopenharmony_ci auto extraAttrs = json(); 103886da342Sopenharmony_ci size_t nodeAttrTraverlIndex = 0; 104886da342Sopenharmony_ci auto backgroundColor = GetMiddleStr(nodeAttrStr, nodeAttrTraverlIndex, "BackgroundColor: ", "\n"); 105886da342Sopenharmony_ci auto content = GetMiddleStr(nodeAttrStr, nodeAttrTraverlIndex, "Content: ", "\n"); 106886da342Sopenharmony_ci auto fontColor = GetMiddleStr(nodeAttrStr, nodeAttrTraverlIndex, "FontColor: ", "\n"); 107886da342Sopenharmony_ci auto fontSize = GetMiddleStr(nodeAttrStr, nodeAttrTraverlIndex, "FontSize: ", "\n"); 108886da342Sopenharmony_ci if (!backgroundColor.empty()) { 109886da342Sopenharmony_ci extraAttrs["BackgroundColor"] = backgroundColor; 110886da342Sopenharmony_ci } 111886da342Sopenharmony_ci if (!content.empty()) { 112886da342Sopenharmony_ci extraAttrs["Content"] = move(content); 113886da342Sopenharmony_ci } 114886da342Sopenharmony_ci if (!fontColor.empty()) { 115886da342Sopenharmony_ci extraAttrs["FontColor"] = move(fontColor); 116886da342Sopenharmony_ci } 117886da342Sopenharmony_ci if (!fontSize.empty()) { 118886da342Sopenharmony_ci extraAttrs["FontSize"] = move(fontSize); 119886da342Sopenharmony_ci } 120886da342Sopenharmony_ci if (!extraAttrs.empty()) { 121886da342Sopenharmony_ci root["extraAttrs"] = extraAttrs; 122886da342Sopenharmony_ci } 123886da342Sopenharmony_ci auto &childrenData = root["children"]; 124886da342Sopenharmony_ci auto childCount = childrenData.size(); 125886da342Sopenharmony_ci for (size_t idx = 0; idx < childCount; idx++) { 126886da342Sopenharmony_ci auto &child = childrenData.at(idx); 127886da342Sopenharmony_ci AddExtraAttrs(child, elementTrees, index); 128886da342Sopenharmony_ci } 129886da342Sopenharmony_ci } 130886da342Sopenharmony_ci 131886da342Sopenharmony_ci void DumpHandler::DumpWindowInfoToJson(vector<Widget> &allWidget, nlohmann::json &root) 132886da342Sopenharmony_ci { 133886da342Sopenharmony_ci DumperCache cache; 134886da342Sopenharmony_ci for (size_t i = 0; i < allWidget.size(); ++i) { 135886da342Sopenharmony_ci const Widget &wid = allWidget.at(i); 136886da342Sopenharmony_ci std::string hie = wid.GetHierarchy(); 137886da342Sopenharmony_ci cache.visitWidgetMap_.emplace(hie, i); 138886da342Sopenharmony_ci std::string parentHie = WidgetHierarchyBuilder::GetParentWidgetHierarchy(hie); 139886da342Sopenharmony_ci if (cache.widgetCountMap_.find(parentHie) == cache.widgetCountMap_.cend()) { 140886da342Sopenharmony_ci cache.widgetCountMap_[parentHie] = 1; 141886da342Sopenharmony_ci } else { 142886da342Sopenharmony_ci cache.widgetCountMap_[parentHie] = cache.widgetCountMap_[parentHie] + 1; 143886da342Sopenharmony_ci } 144886da342Sopenharmony_ci if (wid.IsVisible()) { 145886da342Sopenharmony_ci cache.visibleWidgetHies_.insert(hie); 146886da342Sopenharmony_ci } 147886da342Sopenharmony_ci } 148886da342Sopenharmony_ci DFSMarshalWidget(allWidget, 0, root, cache); 149886da342Sopenharmony_ci } 150886da342Sopenharmony_ci} // namespace OHOS::uitest