| 267 | } |
| 268 | |
| 269 | void Preference::resolveBlackWidgets(const ElementPtr &rootXML, const std::string &activity) { |
| 270 | // black widgets |
| 271 | if (!this->_blackWidgetActions.empty()) { |
| 272 | for (const CustomActionPtr &blackWidgetAction: this->_blackWidgetActions) { |
| 273 | if (!activity.empty() && blackWidgetAction->activity != activity) |
| 274 | continue; |
| 275 | XpathPtr xpath = blackWidgetAction->xpath; |
| 276 | // read the bounds of black widget from the config |
| 277 | std::vector<float> bounds = blackWidgetAction->bounds; |
| 278 | bool hasBoundingBox = bounds.size() >= 4; |
| 279 | if (nullptr == this->_rootScreenSize) { |
| 280 | BLOGE("black widget match failed %s", "No root node in current page"); |
| 281 | return; |
| 282 | } |
| 283 | if (hasBoundingBox && bounds[1] <= 1.1 && bounds[3] <= 1.1) { |
| 284 | int rootWidth = this->_rootScreenSize->right;// - rootSize->left; |
| 285 | int rootHeight = this->_rootScreenSize->bottom;// - rootSize->top; |
| 286 | bounds[0] = bounds[0] * static_cast<float>(rootWidth); |
| 287 | bounds[1] = bounds[1] * static_cast<float>(rootHeight); |
| 288 | bounds[2] = bounds[2] * static_cast<float>(rootWidth); |
| 289 | bounds[3] = bounds[3] * static_cast<float>(rootHeight); |
| 290 | } |
| 291 | bool xpathExistsInPage; |
| 292 | std::vector<ElementPtr> xpathElements; |
| 293 | if (xpath) { |
| 294 | this->findMatchedElements(xpathElements, xpath, rootXML); |
| 295 | BDLOG("find black widget %s %d", xpath->toString().c_str(), |
| 296 | (int) xpathElements.size()); |
| 297 | } |
| 298 | xpathExistsInPage = xpath && !xpathElements.empty(); |
| 299 | std::vector<RectPtr> cachedRects; // cache black widgets |
| 300 | |
| 301 | if (xpathExistsInPage && !hasBoundingBox) { |
| 302 | BLOG("black widget xpath %s, has no bounds matched %d nodes", |
| 303 | xpath->toString().c_str(), (int) xpathElements.size()); |
| 304 | for (const auto &matchedElement: xpathElements) { |
| 305 | BLOG("black widget, delete node: %s depends xpath", |
| 306 | matchedElement->getResourceID().c_str()); |
| 307 | cachedRects.push_back(matchedElement->getBounds()); |
| 308 | matchedElement->deleteElement(); |
| 309 | } |
| 310 | } |
| 311 | else if (xpathExistsInPage || (!xpath && hasBoundingBox)) { |
| 312 | RectPtr rejectRect = std::make_shared<Rect>(bounds[0], bounds[1], bounds[2], |
| 313 | bounds[3]); |
| 314 | cachedRects.push_back(rejectRect); |
| 315 | std::vector<ElementPtr> elementsInRejectRect; |
| 316 | rootXML->recursiveElements([&rejectRect](const ElementPtr &child) -> bool { |
| 317 | return rejectRect->contains(child->getBounds()->center()); |
| 318 | }, elementsInRejectRect); |
| 319 | BLOG("black widget xpath %s, with bounds matched %d nodes", |
| 320 | xpath ? xpath->toString().c_str() : "none", |
| 321 | (int) elementsInRejectRect.size()); |
| 322 | for (const auto &elementInRejectRect: elementsInRejectRect) { |
| 323 | if (elementInRejectRect) { |
| 324 | BLOG("black widget, delete node: %s depends xpath", |
| 325 | elementInRejectRect->getResourceID().c_str()); |
| 326 | elementInRejectRect->deleteElement(); |
no test coverage detected