1a69a01cdSopenharmony_ci/* 2a69a01cdSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 3a69a01cdSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4a69a01cdSopenharmony_ci * you may not use this file except in compliance with the License. 5a69a01cdSopenharmony_ci * You may obtain a copy of the License at 6a69a01cdSopenharmony_ci * 7a69a01cdSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8a69a01cdSopenharmony_ci * 9a69a01cdSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10a69a01cdSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11a69a01cdSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12a69a01cdSopenharmony_ci * See the License for the specific language governing permissions and 13a69a01cdSopenharmony_ci * limitations under the License. 14a69a01cdSopenharmony_ci */ 15a69a01cdSopenharmony_ci 16a69a01cdSopenharmony_ci#include "component_manager.h" 17a69a01cdSopenharmony_ci 18a69a01cdSopenharmony_ci#include "accessibility_ui_test_ability.h" 19a69a01cdSopenharmony_ci#include "multimode_manager.h" 20a69a01cdSopenharmony_ci 21a69a01cdSopenharmony_cinamespace OHOS { 22a69a01cdSopenharmony_cinamespace WuKong { 23a69a01cdSopenharmony_cinamespace { 24a69a01cdSopenharmony_ciconst std::string permissionBundleName = "com.ohos.permissionmanager"; 25a69a01cdSopenharmony_ciconst int DIV = 2; 26a69a01cdSopenharmony_ciconst int DOWNTIME = 10; 27a69a01cdSopenharmony_ciconst int ONESECOND = 1000000; 28a69a01cdSopenharmony_ciconst int TWOSECONDS = 2000000; 29a69a01cdSopenharmony_ciconst int OFFSET = 10; 30a69a01cdSopenharmony_ci} // namespace 31a69a01cdSopenharmony_ci 32a69a01cdSopenharmony_ciclass ComponentEventMonitor : public Accessibility::AccessibleAbilityListener { 33a69a01cdSopenharmony_cipublic: 34a69a01cdSopenharmony_ci virtual ~ComponentEventMonitor() = default; 35a69a01cdSopenharmony_ci 36a69a01cdSopenharmony_ci void OnAbilityConnected() override; 37a69a01cdSopenharmony_ci 38a69a01cdSopenharmony_ci void OnAbilityDisconnected() override; 39a69a01cdSopenharmony_ci 40a69a01cdSopenharmony_ci void OnAccessibilityEvent(const Accessibility::AccessibilityEventInfo& eventInfo) override; 41a69a01cdSopenharmony_ci 42a69a01cdSopenharmony_ci void SetOnAbilityConnectCallback(std::function<void()> onConnectCb); 43a69a01cdSopenharmony_ci 44a69a01cdSopenharmony_ci void SetOnAbilityDisConnectCallback(std::function<void()> onDisConnectCb); 45a69a01cdSopenharmony_ci 46a69a01cdSopenharmony_ci bool OnKeyPressEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent) override 47a69a01cdSopenharmony_ci { 48a69a01cdSopenharmony_ci return false; 49a69a01cdSopenharmony_ci } 50a69a01cdSopenharmony_ci 51a69a01cdSopenharmony_ci uint64_t GetLastEventMillis(); 52a69a01cdSopenharmony_ci 53a69a01cdSopenharmony_ci bool WaitEventIdle(uint32_t idleThresholdMs, uint32_t timeoutMs); 54a69a01cdSopenharmony_ci 55a69a01cdSopenharmony_ciprivate: 56a69a01cdSopenharmony_ci std::function<void()> onConnectCallback_ = nullptr; 57a69a01cdSopenharmony_ci std::function<void()> onDisConnectCallback_ = nullptr; 58a69a01cdSopenharmony_ci std::atomic<uint64_t> lastEventMillis_ = 0; 59a69a01cdSopenharmony_ci}; 60a69a01cdSopenharmony_ci 61a69a01cdSopenharmony_civoid ComponentEventMonitor::SetOnAbilityConnectCallback(std::function<void()> onConnectCb) 62a69a01cdSopenharmony_ci{ 63a69a01cdSopenharmony_ci onConnectCallback_ = std::move(onConnectCb); 64a69a01cdSopenharmony_ci} 65a69a01cdSopenharmony_ci 66a69a01cdSopenharmony_civoid ComponentEventMonitor::SetOnAbilityDisConnectCallback(std::function<void()> onDisConnectCb) 67a69a01cdSopenharmony_ci{ 68a69a01cdSopenharmony_ci onDisConnectCallback_ = std::move(onDisConnectCb); 69a69a01cdSopenharmony_ci} 70a69a01cdSopenharmony_ci 71a69a01cdSopenharmony_civoid ComponentEventMonitor::OnAbilityConnected() 72a69a01cdSopenharmony_ci{ 73a69a01cdSopenharmony_ci if (onConnectCallback_ != nullptr) { 74a69a01cdSopenharmony_ci onConnectCallback_(); 75a69a01cdSopenharmony_ci } 76a69a01cdSopenharmony_ci} 77a69a01cdSopenharmony_ci 78a69a01cdSopenharmony_civoid ComponentEventMonitor::OnAbilityDisconnected() 79a69a01cdSopenharmony_ci{ 80a69a01cdSopenharmony_ci if (onDisConnectCallback_ != nullptr) { 81a69a01cdSopenharmony_ci onDisConnectCallback_(); 82a69a01cdSopenharmony_ci } 83a69a01cdSopenharmony_ci} 84a69a01cdSopenharmony_ci 85a69a01cdSopenharmony_civoid ComponentEventMonitor::OnAccessibilityEvent(const Accessibility::AccessibilityEventInfo& eventInfo) 86a69a01cdSopenharmony_ci{ 87a69a01cdSopenharmony_ci TRACK_LOG_STR("OnAccessibilityEvent Start %u", eventInfo.GetEventType()); 88a69a01cdSopenharmony_ci TRACK_LOG_STR("current bundle: %s", eventInfo.GetBundleName().c_str()); 89a69a01cdSopenharmony_ci if (eventInfo.GetBundleName() == permissionBundleName) { 90a69a01cdSopenharmony_ci auto listenerlist = ComponentManager::GetInstance()->GetListenerList(); 91a69a01cdSopenharmony_ci for (auto it : listenerlist) { 92a69a01cdSopenharmony_ci it->OnPermissionScreenShown(); 93a69a01cdSopenharmony_ci } 94a69a01cdSopenharmony_ci } 95a69a01cdSopenharmony_ci} 96a69a01cdSopenharmony_ci 97a69a01cdSopenharmony_ciuint64_t ComponentEventMonitor::GetLastEventMillis() 98a69a01cdSopenharmony_ci{ 99a69a01cdSopenharmony_ci return 0; 100a69a01cdSopenharmony_ci} 101a69a01cdSopenharmony_ci 102a69a01cdSopenharmony_cibool ComponentEventMonitor::WaitEventIdle(uint32_t idleThresholdMs, uint32_t timeoutMs) 103a69a01cdSopenharmony_ci{ 104a69a01cdSopenharmony_ci return true; 105a69a01cdSopenharmony_ci} 106a69a01cdSopenharmony_ci 107a69a01cdSopenharmony_ciComponentManager::ComponentManager() 108a69a01cdSopenharmony_ci{ 109a69a01cdSopenharmony_ci componentMap_ = { 110a69a01cdSopenharmony_ci {Accessibility::ACCESSIBILITY_ACTION_CLICK, 111a69a01cdSopenharmony_ci [this] (Accessibility::AccessibilityElementInfo& elementInfo) -> ErrCode { 112a69a01cdSopenharmony_ci return ComponentManager::ComponentTouchInput(elementInfo); 113a69a01cdSopenharmony_ci }}, 114a69a01cdSopenharmony_ci {Accessibility::ACCESSIBILITY_ACTION_SCROLL_FORWARD, 115a69a01cdSopenharmony_ci [this] (Accessibility::AccessibilityElementInfo& elementInfo) -> ErrCode { 116a69a01cdSopenharmony_ci return ComponentManager::ComponentUpSwapInput(elementInfo); 117a69a01cdSopenharmony_ci }}, 118a69a01cdSopenharmony_ci {Accessibility::ACCESSIBILITY_ACTION_SCROLL_BACKWARD, 119a69a01cdSopenharmony_ci [this] (Accessibility::AccessibilityElementInfo& elementInfo) -> ErrCode { 120a69a01cdSopenharmony_ci return ComponentManager::ComponentDownSwapInput(elementInfo); 121a69a01cdSopenharmony_ci }}, 122a69a01cdSopenharmony_ci {Accessibility::ACCESSIBILITY_ACTION_SET_TEXT, 123a69a01cdSopenharmony_ci [this] (Accessibility::AccessibilityElementInfo& elementInfo) -> ErrCode { 124a69a01cdSopenharmony_ci return ComponentManager::ComponentMultikeyInput(elementInfo); 125a69a01cdSopenharmony_ci }}, 126a69a01cdSopenharmony_ci {COMPONENT_LEFT_SWAP, 127a69a01cdSopenharmony_ci [this] (Accessibility::AccessibilityElementInfo& elementInfo) -> ErrCode { 128a69a01cdSopenharmony_ci return ComponentManager::ComponentLeftSwapInput(elementInfo); 129a69a01cdSopenharmony_ci }}, 130a69a01cdSopenharmony_ci }; 131a69a01cdSopenharmony_ci} 132a69a01cdSopenharmony_ciComponentManager::~ComponentManager() 133a69a01cdSopenharmony_ci{ 134a69a01cdSopenharmony_ci} 135a69a01cdSopenharmony_ci 136a69a01cdSopenharmony_cibool ComponentManager::Connect() 137a69a01cdSopenharmony_ci{ 138a69a01cdSopenharmony_ci if (connected_ == true) { 139a69a01cdSopenharmony_ci return true; 140a69a01cdSopenharmony_ci } 141a69a01cdSopenharmony_ci std::mutex mtx; 142a69a01cdSopenharmony_ci std::unique_lock<std::mutex> uLock(mtx); 143a69a01cdSopenharmony_ci std::shared_ptr<ComponentEventMonitor> g_monitorInstance_ = std::make_shared<ComponentEventMonitor>(); 144a69a01cdSopenharmony_ci std::condition_variable condition; 145a69a01cdSopenharmony_ci auto onConnectCallback = [&condition]() { 146a69a01cdSopenharmony_ci std::cout << "Success connect to AAMS" << std::endl; 147a69a01cdSopenharmony_ci condition.notify_all(); 148a69a01cdSopenharmony_ci }; 149a69a01cdSopenharmony_ci 150a69a01cdSopenharmony_ci g_monitorInstance_->SetOnAbilityConnectCallback(onConnectCallback); 151a69a01cdSopenharmony_ci auto ability = Accessibility::AccessibilityUITestAbility::GetInstance(); 152a69a01cdSopenharmony_ci if (ability->RegisterAbilityListener(g_monitorInstance_) != Accessibility::RET_OK) { 153a69a01cdSopenharmony_ci std::cout << "Failed to register ComponentEventMonitor" << std::endl; 154a69a01cdSopenharmony_ci return false; 155a69a01cdSopenharmony_ci } 156a69a01cdSopenharmony_ci std::cout << "Start connect to AAMS" << std::endl; 157a69a01cdSopenharmony_ci if (ability->Connect() != Accessibility::RET_OK) { 158a69a01cdSopenharmony_ci std::cout << "Failed to connect to AAMS" << std::endl; 159a69a01cdSopenharmony_ci return false; 160a69a01cdSopenharmony_ci } 161a69a01cdSopenharmony_ci const auto timeout = std::chrono::milliseconds(1000); 162a69a01cdSopenharmony_ci if (condition.wait_for(uLock, timeout) == std::cv_status::timeout) { 163a69a01cdSopenharmony_ci std::cout << "Wait connection to AAMS timed out" << std::endl; 164a69a01cdSopenharmony_ci return false; 165a69a01cdSopenharmony_ci } 166a69a01cdSopenharmony_ci connected_ = true; 167a69a01cdSopenharmony_ci return true; 168a69a01cdSopenharmony_ci} 169a69a01cdSopenharmony_ci 170a69a01cdSopenharmony_civoid ComponentManager::Disconnect() 171a69a01cdSopenharmony_ci{ 172a69a01cdSopenharmony_ci auto auita = Accessibility::AccessibilityUITestAbility::GetInstance(); 173a69a01cdSopenharmony_ci if (auita != nullptr) { 174a69a01cdSopenharmony_ci auita->Disconnect(); 175a69a01cdSopenharmony_ci } 176a69a01cdSopenharmony_ci connected_ = false; 177a69a01cdSopenharmony_ci} 178a69a01cdSopenharmony_ciuint32_t ComponentManager::AddRegisterListener(std::shared_ptr<ComponentManagerListener> listener) 179a69a01cdSopenharmony_ci{ 180a69a01cdSopenharmony_ci TRACK_LOG_STD(); 181a69a01cdSopenharmony_ci listenerList_.push_back(listener); 182a69a01cdSopenharmony_ci TRACK_LOG_STR("Add linstener count (%d)", listenerList_.size()); 183a69a01cdSopenharmony_ci return listenerList_.size() - 1; 184a69a01cdSopenharmony_ci} 185a69a01cdSopenharmony_ci 186a69a01cdSopenharmony_civoid ComponentManager::DeleteRegisterListener(const uint32_t handle) 187a69a01cdSopenharmony_ci{ 188a69a01cdSopenharmony_ci if (listenerList_.size() > handle) { 189a69a01cdSopenharmony_ci listenerList_.erase(listenerList_.begin() + handle); 190a69a01cdSopenharmony_ci } 191a69a01cdSopenharmony_ci} 192a69a01cdSopenharmony_ci 193a69a01cdSopenharmony_cistd::vector<std::shared_ptr<ComponentManagerListener>> ComponentManager::GetListenerList() 194a69a01cdSopenharmony_ci{ 195a69a01cdSopenharmony_ci return listenerList_; 196a69a01cdSopenharmony_ci} 197a69a01cdSopenharmony_ci 198a69a01cdSopenharmony_ciErrCode ComponentManager::GetReportInfo(std::string& info) 199a69a01cdSopenharmony_ci{ 200a69a01cdSopenharmony_ci ErrCode result = OHOS::ERR_OK; 201a69a01cdSopenharmony_ci return result; 202a69a01cdSopenharmony_ci} 203a69a01cdSopenharmony_ci 204a69a01cdSopenharmony_ciErrCode ComponentManager::PermoissionInput() 205a69a01cdSopenharmony_ci{ 206a69a01cdSopenharmony_ci DEBUG_LOG("handle permission window"); 207a69a01cdSopenharmony_ci return OHOS::ERR_OK; 208a69a01cdSopenharmony_ci} 209a69a01cdSopenharmony_ci 210a69a01cdSopenharmony_ciErrCode ComponentManager::CreateEventInputMap() 211a69a01cdSopenharmony_ci{ 212a69a01cdSopenharmony_ci return OHOS::ERR_OK; 213a69a01cdSopenharmony_ci} 214a69a01cdSopenharmony_ci 215a69a01cdSopenharmony_ciErrCode ComponentManager::ComponentEventInput(OHOS::Accessibility::AccessibilityElementInfo& elementInfo, 216a69a01cdSopenharmony_ci const int actionType) 217a69a01cdSopenharmony_ci{ 218a69a01cdSopenharmony_ci CreateEventInputMap(); 219a69a01cdSopenharmony_ci // get position of current component 220a69a01cdSopenharmony_ci GetComponentPosition(elementInfo); 221a69a01cdSopenharmony_ci auto componentRespond = componentMap_[actionType]; 222a69a01cdSopenharmony_ci if (componentRespond == nullptr) { 223a69a01cdSopenharmony_ci componentRespond = componentMap_[Accessibility::ACCESSIBILITY_ACTION_CLICK]; 224a69a01cdSopenharmony_ci } 225a69a01cdSopenharmony_ci ErrCode result = componentRespond(elementInfo); 226a69a01cdSopenharmony_ci return result; 227a69a01cdSopenharmony_ci} 228a69a01cdSopenharmony_ci 229a69a01cdSopenharmony_ciErrCode ComponentManager::ComponentTouchInput(Accessibility::AccessibilityElementInfo& elementInfo) 230a69a01cdSopenharmony_ci{ 231a69a01cdSopenharmony_ci ErrCode result; 232a69a01cdSopenharmony_ci auto touchInput = MultimodeManager::GetInstance(); 233a69a01cdSopenharmony_ci // Calculate touch position 234a69a01cdSopenharmony_ci int32_t elementTouchX = startX_ + (endX_ - startX_) / DIV; 235a69a01cdSopenharmony_ci int32_t elementTouchY = startY_ + (endY_ - startY_) / DIV; 236a69a01cdSopenharmony_ci std::string type = elementInfo.GetContent(); 237a69a01cdSopenharmony_ci INFO_LOG_STR("component Content: Touch Position: (%d, %d)", elementTouchX, elementTouchY); 238a69a01cdSopenharmony_ci DEBUG_LOG_STR("component Content: (%s), Touch Position: (%d, %d)", type.c_str(), elementTouchX, elementTouchY); 239a69a01cdSopenharmony_ci result = touchInput->PointerInput(elementTouchX, elementTouchY, MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN, 240a69a01cdSopenharmony_ci MMI::PointerEvent::POINTER_ACTION_DOWN); 241a69a01cdSopenharmony_ci if (result == OHOS::ERR_OK) { 242a69a01cdSopenharmony_ci result = touchInput->PointerInput(elementTouchX, elementTouchY, MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN, 243a69a01cdSopenharmony_ci MMI::PointerEvent::POINTER_ACTION_UP); 244a69a01cdSopenharmony_ci } 245a69a01cdSopenharmony_ci return result; 246a69a01cdSopenharmony_ci} 247a69a01cdSopenharmony_ci 248a69a01cdSopenharmony_ciErrCode ComponentManager::BackToPrePage() 249a69a01cdSopenharmony_ci{ 250a69a01cdSopenharmony_ci ErrCode result = ERR_OK; 251a69a01cdSopenharmony_ci int backKeyCode = OHOS::MMI::KeyEvent::KEYCODE_BACK; 252a69a01cdSopenharmony_ci result = MultimodeManager::GetInstance()->SingleKeyCodeInput(backKeyCode, DOWNTIME); 253a69a01cdSopenharmony_ci return result; 254a69a01cdSopenharmony_ci} 255a69a01cdSopenharmony_ci 256a69a01cdSopenharmony_ciErrCode ComponentManager::ComponentUpSwapInput(Accessibility::AccessibilityElementInfo& elementInfo) 257a69a01cdSopenharmony_ci{ 258a69a01cdSopenharmony_ci // Calculate swap position 259a69a01cdSopenharmony_ci int32_t componentUpSwapStartX = startX_ + (endX_ - startX_) / DIV; 260a69a01cdSopenharmony_ci int32_t componentUpSwapStartY = endY_ - OFFSET; 261a69a01cdSopenharmony_ci int32_t componentUpSwapEndX = componentUpSwapStartX; 262a69a01cdSopenharmony_ci int32_t componentUpSwapEndY = startY_ + OFFSET; 263a69a01cdSopenharmony_ci INFO_LOG_STR("Component Up Swap: (%d, %d) -> (%d, %d)", componentUpSwapStartX, componentUpSwapStartY, 264a69a01cdSopenharmony_ci componentUpSwapEndX, componentUpSwapEndY); 265a69a01cdSopenharmony_ci ErrCode result = MultimodeManager::GetInstance()->IntervalSwap(componentUpSwapStartX, componentUpSwapStartY, 266a69a01cdSopenharmony_ci componentUpSwapEndX, componentUpSwapEndY); 267a69a01cdSopenharmony_ci usleep(TWOSECONDS); 268a69a01cdSopenharmony_ci return result; 269a69a01cdSopenharmony_ci} 270a69a01cdSopenharmony_ci 271a69a01cdSopenharmony_ciErrCode ComponentManager::ComponentDownSwapInput(Accessibility::AccessibilityElementInfo& elementInfo) 272a69a01cdSopenharmony_ci{ 273a69a01cdSopenharmony_ci // Calculate swap position 274a69a01cdSopenharmony_ci int32_t componentDownSwapStartX = startX_ + (endX_ - startX_) / DIV; 275a69a01cdSopenharmony_ci int32_t componentDownSwapStartY = startY_ + OFFSET; 276a69a01cdSopenharmony_ci int32_t componentDownSwapEndX = componentDownSwapStartX; 277a69a01cdSopenharmony_ci int32_t componentDownSwapEndY = endY_ - OFFSET; 278a69a01cdSopenharmony_ci INFO_LOG_STR("Component Down Swap: (%d, %d) -> (%d, %d)", componentDownSwapStartX, componentDownSwapStartY, 279a69a01cdSopenharmony_ci componentDownSwapEndX, componentDownSwapEndY); 280a69a01cdSopenharmony_ci ErrCode result = MultimodeManager::GetInstance()->IntervalSwap(componentDownSwapStartX, componentDownSwapStartY, 281a69a01cdSopenharmony_ci componentDownSwapEndX, componentDownSwapEndY); 282a69a01cdSopenharmony_ci usleep(TWOSECONDS); 283a69a01cdSopenharmony_ci return result; 284a69a01cdSopenharmony_ci} 285a69a01cdSopenharmony_ci 286a69a01cdSopenharmony_ciErrCode ComponentManager::ComponentMultikeyInput(Accessibility::AccessibilityElementInfo& elementInfo) 287a69a01cdSopenharmony_ci{ 288a69a01cdSopenharmony_ci ErrCode result = ComponentTouchInput(elementInfo); 289a69a01cdSopenharmony_ci if (result != OHOS::ERR_OK) { 290a69a01cdSopenharmony_ci return result; 291a69a01cdSopenharmony_ci } 292a69a01cdSopenharmony_ci usleep(ONESECOND); 293a69a01cdSopenharmony_ci result = MultimodeManager::GetInstance()->MultiKeyCodeInput(DOWNTIME); 294a69a01cdSopenharmony_ci return result; 295a69a01cdSopenharmony_ci} 296a69a01cdSopenharmony_ci 297a69a01cdSopenharmony_ciErrCode ComponentManager::ComponentLeftSwapInput(Accessibility::AccessibilityElementInfo& elementInfo) 298a69a01cdSopenharmony_ci{ 299a69a01cdSopenharmony_ci ErrCode result; 300a69a01cdSopenharmony_ci // Calculate swap position 301a69a01cdSopenharmony_ci int32_t leftSwapStartX = startX_ + OFFSET; 302a69a01cdSopenharmony_ci int32_t leftSwapEndX = endX_ + OFFSET; 303a69a01cdSopenharmony_ci int32_t leftSwapStartY = startY_ + (endY_ - startY_) / DIV; 304a69a01cdSopenharmony_ci int32_t leftSwapEndY = leftSwapStartY; 305a69a01cdSopenharmony_ci INFO_LOG_STR("Component Left Swap: (%d, %d) -> (%d, %d)", leftSwapStartX, leftSwapStartY, leftSwapEndX, 306a69a01cdSopenharmony_ci leftSwapEndY); 307a69a01cdSopenharmony_ci result = MultimodeManager::GetInstance()->IntervalSwap(leftSwapStartX, leftSwapStartY, leftSwapEndX, leftSwapEndY); 308a69a01cdSopenharmony_ci return result; 309a69a01cdSopenharmony_ci} 310a69a01cdSopenharmony_ci 311a69a01cdSopenharmony_civoid ComponentManager::GetComponentPosition(Accessibility::AccessibilityElementInfo& elementInfo) 312a69a01cdSopenharmony_ci{ 313a69a01cdSopenharmony_ci Accessibility::Rect componentBounds = elementInfo.GetRectInScreen(); 314a69a01cdSopenharmony_ci startX_ = componentBounds.GetLeftTopXScreenPostion(); 315a69a01cdSopenharmony_ci startY_ = componentBounds.GetLeftTopYScreenPostion(); 316a69a01cdSopenharmony_ci endX_ = componentBounds.GetRightBottomXScreenPostion(); 317a69a01cdSopenharmony_ci endY_ = componentBounds.GetRightBottomYScreenPostion(); 318a69a01cdSopenharmony_ci} 319a69a01cdSopenharmony_ci} // namespace WuKong 320a69a01cdSopenharmony_ci} // namespace OHOS 321