已开启
修复napi侧回调接口存在的referencce泄露的问题 #2724
taojuncun创建于 6 天前
修复napi侧回调接口存在的referencce泄露的问题 #2724
已开启
共 4 个文件变更+166-141
| @@ -58,6 +58,7 @@ public: | |||
| 58 | void SubscribeObserver(napi_env env, OHOS::AccessibilityConfig::CONFIG_ID id, napi_value observer); | 58 | void SubscribeObserver(napi_env env, OHOS::AccessibilityConfig::CONFIG_ID id, napi_value observer); |
| 59 | void UnsubscribeObserver(napi_env env, OHOS::AccessibilityConfig::CONFIG_ID id, napi_value observer); | 59 | void UnsubscribeObserver(napi_env env, OHOS::AccessibilityConfig::CONFIG_ID id, napi_value observer); |
| 60 | void UnsubscribeObservers(OHOS::AccessibilityConfig::CONFIG_ID id); | 60 | void UnsubscribeObservers(OHOS::AccessibilityConfig::CONFIG_ID id); |
| 61 | + void DeleteObserverReference(napi_env env, std::shared_ptr<NAccessibilityConfigObserver> observer); | ||
| 61 | 62 | ||
| 62 | private: | 63 | private: |
| 63 | ffrt::mutex mutex_; | 64 | ffrt::mutex mutex_; |
| @@ -28,7 +28,6 @@ | |||
| 28 | struct EnableAbilityListsObserver { | 28 | struct EnableAbilityListsObserver { |
| 29 | EnableAbilityListsObserver(napi_env env, napi_ref callback) : env_(env), callback_(callback) {}; | 29 | EnableAbilityListsObserver(napi_env env, napi_ref callback) : env_(env), callback_(callback) {}; |
| 30 | void OnEnableAbilityListsStateChanged(); | 30 | void OnEnableAbilityListsStateChanged(); |
| 31 | - int OnEnableAbilityListsStateChangedWork(uv_work_t *work); | ||
| 32 | napi_env env_ = nullptr; | 31 | napi_env env_ = nullptr; |
| 33 | napi_ref callback_ = nullptr; | 32 | napi_ref callback_ = nullptr; |
| 34 | }; | 33 | }; |
| @@ -46,7 +45,6 @@ struct EnableAbilityCallbackObserver { | |||
| 46 | struct SeniorModeStateObserver { | 45 | struct SeniorModeStateObserver { |
| 47 | SeniorModeStateObserver(napi_env env, napi_ref callback) : env_(env), callback_(callback) {}; | 46 | SeniorModeStateObserver(napi_env env, napi_ref callback) : env_(env), callback_(callback) {}; |
| 48 | void OnSeniorModeStateChanged(const std::string& bundleName, int32_t appIndex, bool state); | 47 | void OnSeniorModeStateChanged(const std::string& bundleName, int32_t appIndex, bool state); |
| 49 | - int OnSeniorModeStateChangedWork(uv_work_t *work); | ||
| 50 | napi_env env_ = nullptr; | 48 | napi_env env_ = nullptr; |
| 51 | napi_ref callback_ = nullptr; | 49 | napi_ref callback_ = nullptr; |
| 52 | }; | 50 | }; |
| @@ -65,6 +63,7 @@ public: | |||
| 65 | void UnsubscribeObservers(); | 63 | void UnsubscribeObservers(); |
| 66 | void UnsubscribeInstallObserver(napi_env env, napi_value observer); | 64 | void UnsubscribeInstallObserver(napi_env env, napi_value observer); |
| 67 | void UnsubscribeInstallObservers(); | 65 | void UnsubscribeInstallObservers(); |
| 66 | + void DeleteObserverReference(napi_env env, std::shared_ptr<EnableAbilityListsObserver> observer); | ||
| 68 | 67 | ||
| 69 | private: | 68 | private: |
| 70 | ffrt::mutex mutex_; | 69 | ffrt::mutex mutex_; |
| @@ -82,6 +81,7 @@ public: | |||
| 82 | void UnsubscribeFromFramework(); | 81 | void UnsubscribeFromFramework(); |
| 83 | void SubscribeObserver(napi_env env, const std::string& name, napi_value observer); | 82 | void SubscribeObserver(napi_env env, const std::string& name, napi_value observer); |
| 84 | void UnsubscribeObserver(napi_env env, const std::string& name); | 83 | void UnsubscribeObserver(napi_env env, const std::string& name); |
| 84 | + void DeleteObserverReference(napi_env env, std::shared_ptr<EnableAbilityCallbackObserver> observer); | ||
| 85 | 85 | ||
| 86 | private: | 86 | private: |
| 87 | ffrt::mutex mutex_; | 87 | ffrt::mutex mutex_; |
| @@ -98,6 +98,7 @@ public: | |||
| 98 | void SubscribeObserver(napi_env env, napi_value observer); | 98 | void SubscribeObserver(napi_env env, napi_value observer); |
| 99 | void UnsubscribeObserver(napi_env env, napi_value observer); | 99 | void UnsubscribeObserver(napi_env env, napi_value observer); |
| 100 | void UnsubscribeObservers(); | 100 | void UnsubscribeObservers(); |
| 101 | + void DeleteObserverReference(napi_env env, std::shared_ptr<SeniorModeStateObserver> observer); | ||
| 101 | 102 | ||
| 102 | private: | 103 | private: |
| 103 | ffrt::mutex mutex_; | 104 | ffrt::mutex mutex_; |
| @@ -90,6 +90,32 @@ static napi_handle_scope TmpOpenScope(napi_env env) | |||
| 90 | NAPI_CALL(env, napi_open_handle_scope(env, &scope)); | 90 | NAPI_CALL(env, napi_open_handle_scope(env, &scope)); |
| 91 | return scope; | 91 | return scope; |
| 92 | } | 92 | } |
| 93 | + | ||
| 94 | +static void SendDeleteReferenceEvent(napi_env env, napi_env refEnv, napi_ref ref, const char* eventName) | ||
| 95 | +{ | ||
| 96 | + std::shared_ptr<AccessibilityCallbackInfo> callbackInfo = std::make_shared<AccessibilityCallbackInfo>(); | ||
| 97 | + if (callbackInfo == nullptr) { | ||
| 98 | + HILOG_ERROR("failed to create callbackInfo"); | ||
| 99 | + return; | ||
| 100 | + } | ||
| 101 | + callbackInfo->env_ = refEnv; | ||
| 102 | + callbackInfo->ref_ = ref; | ||
| 103 | + auto task = [callbackInfo]() { | ||
| 104 | + if (callbackInfo == nullptr) { | ||
| 105 | + return; | ||
| 106 | + } | ||
| 107 | + napi_env tmpEnv = callbackInfo->env_; | ||
| 108 | + auto closeScope = [tmpEnv](napi_handle_scope scope) { | ||
| 109 | + napi_close_handle_scope(tmpEnv, scope); | ||
| 110 | + }; | ||
| 111 | + std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scope( | ||
| 112 | + OHOS::Accessibility::TmpOpenScope(callbackInfo->env_), closeScope); | ||
| 113 | + napi_delete_reference(tmpEnv, callbackInfo->ref_); | ||
| 114 | + }; | ||
| 115 | + if (napi_send_event(env, task, napi_eprio_high, eventName) != napi_status::napi_ok) { | ||
| 116 | + HILOG_ERROR("failed to send event"); | ||
| 117 | + } | ||
| 118 | +} | ||
| 93 | } // namespace Accessibility | 119 | } // namespace Accessibility |
| 94 | } // namespace OHOS | 120 | } // namespace OHOS |
| 95 | 121 | ||
| @@ -1228,72 +1254,36 @@ napi_value NAccessibilityConfig::UnSubscribeConfigObserver(napi_env env, napi_ca | |||
| 1228 | void EnableAbilityListsObserver::OnEnableAbilityListsStateChanged() | 1254 | void EnableAbilityListsObserver::OnEnableAbilityListsStateChanged() |
| 1229 | { | 1255 | { |
| 1230 | HILOG_DEBUG(); | 1256 | HILOG_DEBUG(); |
| 1231 | - | 1257 | + std::shared_ptr<AccessibilityCallbackInfo> callbackInfo = std::make_shared<AccessibilityCallbackInfo>(); |
| 1232 | - AccessibilityCallbackInfo *callbackInfo = new(std::nothrow) AccessibilityCallbackInfo(); | ||
| 1233 | if (callbackInfo == nullptr) { | 1258 | if (callbackInfo == nullptr) { |
| 1234 | - HILOG_ERROR("callbackInfo is nullptr"); | 1259 | + HILOG_ERROR("Failed to create callbackInfo."); |
| 1235 | return; | 1260 | return; |
| 1236 | } | 1261 | } |
| 1237 | - | ||
| 1238 | - uv_work_t *work = new(std::nothrow) uv_work_t; | ||
| 1239 | - if (!work) { | ||
| 1240 | - HILOG_ERROR("Failed to create work."); | ||
| 1241 | - delete callbackInfo; | ||
| 1242 | - callbackInfo = nullptr; | ||
| 1243 | - return; | ||
| 1244 | - } | ||
| 1245 | - | ||
| 1246 | callbackInfo->env_ = env_; | 1262 | callbackInfo->env_ = env_; |
| 1247 | callbackInfo->ref_ = callback_; | 1263 | callbackInfo->ref_ = callback_; |
| 1248 | - work->data = static_cast<void*>(callbackInfo); | 1264 | + auto task = [callbackInfo]() { |
| 1249 | - | 1265 | + if (callbackInfo == nullptr) { |
| 1250 | - int ret = OnEnableAbilityListsStateChangedWork(work); | 1266 | + return; |
| 1251 | - if (ret != 0) { | 1267 | + } |
| 1252 | - HILOG_ERROR("Failed to execute OnEnableAbilityListsStateChanged work queue"); | 1268 | + napi_env env = callbackInfo->env_; |
| 1253 | - delete callbackInfo; | 1269 | + auto closeScope = [env](napi_handle_scope scope) { |
| 1254 | - callbackInfo = nullptr; | 1270 | + napi_close_handle_scope(env, scope); |
| 1255 | - delete work; | 1271 | + }; |
| 1256 | - work = nullptr; | 1272 | + std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scope( |
| 1273 | + OHOS::Accessibility::TmpOpenScope(callbackInfo->env_), closeScope); | ||
| 1274 | + napi_value handler = nullptr; | ||
| 1275 | + napi_value callResult = nullptr; | ||
| 1276 | + napi_value jsEvent = nullptr; | ||
| 1277 | + napi_value undefined = nullptr; | ||
| 1278 | + napi_get_reference_value(callbackInfo->env_, callbackInfo->ref_, &handler); | ||
| 1279 | + napi_get_undefined(callbackInfo->env_, &undefined); | ||
| 1280 | + napi_call_function(callbackInfo->env_, undefined, handler, 1, &jsEvent, &callResult); | ||
| 1281 | + }; | ||
| 1282 | + if (napi_send_event(env_, task, napi_eprio_high, "OnEnableAbilityListsStateChanged") != napi_status::napi_ok) { | ||
| 1283 | + HILOG_ERROR("failed to send event"); | ||
| 1257 | } | 1284 | } |
| 1258 | } | 1285 | } |
| 1259 | 1286 | ||
| 1260 | -int EnableAbilityListsObserver::OnEnableAbilityListsStateChangedWork(uv_work_t *work) | ||
| 1261 | -{ | ||
| 1262 | - uv_loop_s *loop = nullptr; | ||
| 1263 | - napi_get_uv_event_loop(env_, &loop); | ||
| 1264 | - if (loop == nullptr || work == nullptr) { | ||
| 1265 | - HILOG_ERROR("loop or work is nullptr."); | ||
| 1266 | - return RET_ERR_FAILED; | ||
| 1267 | - } | ||
| 1268 | - int ret = uv_queue_work_with_qos_internal( | ||
| 1269 | - loop, | ||
| 1270 | - work, | ||
| 1271 | - [](uv_work_t *work) {}, | ||
| 1272 | - [](uv_work_t *work, int status) { | ||
| 1273 | - AccessibilityCallbackInfo *callbackInfo = static_cast<AccessibilityCallbackInfo*>(work->data); | ||
| 1274 | - napi_env env = callbackInfo->env_; | ||
| 1275 | - auto closeScope = [env](napi_handle_scope scope) { | ||
| 1276 | - napi_close_handle_scope(env, scope); | ||
| 1277 | - }; | ||
| 1278 | - std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scopes( | ||
| 1279 | - OHOS::Accessibility::TmpOpenScope(callbackInfo->env_), closeScope); | ||
| 1280 | - napi_value handler = nullptr; | ||
| 1281 | - napi_value callResult = nullptr; | ||
| 1282 | - napi_value jsEvent = nullptr; | ||
| 1283 | - napi_value undefined = nullptr; | ||
| 1284 | - napi_get_reference_value(callbackInfo->env_, callbackInfo->ref_, &handler); | ||
| 1285 | - napi_get_undefined(callbackInfo->env_, &undefined); | ||
| 1286 | - napi_call_function(callbackInfo->env_, undefined, handler, 1, &jsEvent, &callResult); | ||
| 1287 | - delete callbackInfo; | ||
| 1288 | - callbackInfo = nullptr; | ||
| 1289 | - delete work; | ||
| 1290 | - work = nullptr; | ||
| 1291 | - }, | ||
| 1292 | - uv_qos_default, | ||
| 1293 | - "OnEnableAbilityListsStateChangedWork"); | ||
| 1294 | - return ret; | ||
| 1295 | -} | ||
| 1296 | - | ||
| 1297 | void EnableAbilityCallbackObserver::OnEnableAbilityRemoteDied(const std::string& name) | 1287 | void EnableAbilityCallbackObserver::OnEnableAbilityRemoteDied(const std::string& name) |
| 1298 | { | 1288 | { |
| 1299 | HILOG_DEBUG(); | 1289 | HILOG_DEBUG(); |
| @@ -1435,6 +1425,7 @@ void EnableAbilityCallbackObserverImpl::OnEnableAbilityRemoteDied(const std::str | |||
| 1435 | return; | 1425 | return; |
| 1436 | } | 1426 | } |
| 1437 | observerPtr->OnEnableAbilityRemoteDied(name); | 1427 | observerPtr->OnEnableAbilityRemoteDied(name); |
| 1428 | + DeleteObserverReference(observerPtr->env_, observerPtr); | ||
| 1438 | enableAbilityCallbackObservers_.erase(iter); | 1429 | enableAbilityCallbackObservers_.erase(iter); |
| 1439 | return; | 1430 | return; |
| 1440 | } | 1431 | } |
| @@ -1466,6 +1457,7 @@ void EnableAbilityCallbackObserverImpl::UnsubscribeObserver(napi_env env, const | |||
| 1466 | std::lock_guard<ffrt::mutex> lock(mutex_); | 1457 | std::lock_guard<ffrt::mutex> lock(mutex_); |
| 1467 | auto iter = enableAbilityCallbackObservers_.find(name); | 1458 | auto iter = enableAbilityCallbackObservers_.find(name); |
| 1468 | if (iter != enableAbilityCallbackObservers_.end()) { | 1459 | if (iter != enableAbilityCallbackObservers_.end()) { |
| 1460 | + DeleteObserverReference(iter->second->env_, iter->second); | ||
| 1469 | enableAbilityCallbackObservers_.erase(iter); | 1461 | enableAbilityCallbackObservers_.erase(iter); |
| 1470 | return; | 1462 | return; |
| 1471 | } | 1463 | } |
| @@ -1484,6 +1476,16 @@ void EnableAbilityCallbackObserverImpl::UnsubscribeFromFramework() | |||
| 1484 | instance.UnsubscribeEnableAbilityCallbackObserver(shared_from_this()); | 1476 | instance.UnsubscribeEnableAbilityCallbackObserver(shared_from_this()); |
| 1485 | } | 1477 | } |
| 1486 | 1478 | ||
| 1479 | +void EnableAbilityCallbackObserverImpl::DeleteObserverReference( | ||
| 1480 | + napi_env env, std::shared_ptr<EnableAbilityCallbackObserver> observer) | ||
| 1481 | +{ | ||
| 1482 | + if (observer == nullptr) { | ||
| 1483 | + return; | ||
| 1484 | + } | ||
| 1485 | + SendDeleteReferenceEvent(env, observer->env_, observer->notifyCallback_, | ||
| 1486 | + "EnableAbilityCallback_DeleteObserverReference"); | ||
| 1487 | +} | ||
| 1488 | + | ||
| 1487 | void EnableAbilityListsObserverImpl::SubscribeInstallObserver(napi_env env, napi_value observer) | 1489 | void EnableAbilityListsObserverImpl::SubscribeInstallObserver(napi_env env, napi_value observer) |
| 1488 | { | 1490 | { |
| 1489 | HILOG_DEBUG(); | 1491 | HILOG_DEBUG(); |
| @@ -1514,6 +1516,7 @@ void EnableAbilityListsObserverImpl::UnsubscribeObserver(napi_env env, napi_valu | |||
| 1514 | std::lock_guard<ffrt::mutex> lock(mutex_); | 1516 | std::lock_guard<ffrt::mutex> lock(mutex_); |
| 1515 | for (auto iter = enableAbilityListsObservers_.begin(); iter != enableAbilityListsObservers_.end();) { | 1517 | for (auto iter = enableAbilityListsObservers_.begin(); iter != enableAbilityListsObservers_.end();) { |
| 1516 | if (CheckObserverEqual(env, observer, (*iter)->env_, (*iter)->callback_)) { | 1518 | if (CheckObserverEqual(env, observer, (*iter)->env_, (*iter)->callback_)) { |
| 1519 | + DeleteObserverReference(env, *iter); | ||
| 1517 | enableAbilityListsObservers_.erase(iter); | 1520 | enableAbilityListsObservers_.erase(iter); |
| 1518 | return; | 1521 | return; |
| 1519 | } else { | 1522 | } else { |
| @@ -1526,7 +1529,10 @@ void EnableAbilityListsObserverImpl::UnsubscribeObservers() | |||
| 1526 | { | 1529 | { |
| 1527 | HILOG_INFO("SubEvent op=off_all kit=AccessibilityKit event=enabledAccessibilityExtensionListChange"); | 1530 | HILOG_INFO("SubEvent op=off_all kit=AccessibilityKit event=enabledAccessibilityExtensionListChange"); |
| 1528 | std::lock_guard<ffrt::mutex> lock(mutex_); | 1531 | std::lock_guard<ffrt::mutex> lock(mutex_); |
| 1529 | - enableAbilityListsObservers_.clear(); | 1532 | + for (auto iter = enableAbilityListsObservers_.begin(); iter != enableAbilityListsObservers_.end();) { |
| 1533 | + DeleteObserverReference((*iter)->env_, *iter); | ||
| 1534 | + iter = enableAbilityListsObservers_.erase(iter); | ||
| 1535 | + } | ||
| 1530 | } | 1536 | } |
| 1531 | 1537 | ||
| 1532 | void EnableAbilityListsObserverImpl::UnsubscribeInstallObserver(napi_env env, napi_value observer) | 1538 | void EnableAbilityListsObserverImpl::UnsubscribeInstallObserver(napi_env env, napi_value observer) |
| @@ -1535,6 +1541,7 @@ void EnableAbilityListsObserverImpl::UnsubscribeInstallObserver(napi_env env, na | |||
| 1535 | std::lock_guard<ffrt::mutex> lock(mutex_); | 1541 | std::lock_guard<ffrt::mutex> lock(mutex_); |
| 1536 | for (auto iter = installAbilityListsObservers_.begin(); iter != installAbilityListsObservers_.end(); iter++) { | 1542 | for (auto iter = installAbilityListsObservers_.begin(); iter != installAbilityListsObservers_.end(); iter++) { |
| 1537 | if (CheckObserverEqual(env, observer, (*iter)->env_, (*iter)->callback_)) { | 1543 | if (CheckObserverEqual(env, observer, (*iter)->env_, (*iter)->callback_)) { |
| 1544 | + DeleteObserverReference(env, *iter); | ||
| 1538 | installAbilityListsObservers_.erase(iter); | 1545 | installAbilityListsObservers_.erase(iter); |
| 1539 | return; | 1546 | return; |
| 1540 | } | 1547 | } |
| @@ -1545,7 +1552,20 @@ void EnableAbilityListsObserverImpl::UnsubscribeInstallObservers() | |||
| 1545 | { | 1552 | { |
| 1546 | HILOG_INFO("SubEvent op=off_all kit=AccessibilityKit event=installedAccessibilityListChange"); | 1553 | HILOG_INFO("SubEvent op=off_all kit=AccessibilityKit event=installedAccessibilityListChange"); |
| 1547 | std::lock_guard<ffrt::mutex> lock(mutex_); | 1554 | std::lock_guard<ffrt::mutex> lock(mutex_); |
| 1548 | - installAbilityListsObservers_.clear(); | 1555 | + for (auto iter = installAbilityListsObservers_.begin(); iter != installAbilityListsObservers_.end();) { |
| 1556 | + DeleteObserverReference((*iter)->env_, *iter); | ||
| 1557 | + iter = installAbilityListsObservers_.erase(iter); | ||
| 1558 | + } | ||
| 1559 | +} | ||
| 1560 | + | ||
| 1561 | +void EnableAbilityListsObserverImpl::DeleteObserverReference( | ||
| 1562 | + napi_env env, std::shared_ptr<EnableAbilityListsObserver> observer) | ||
| 1563 | +{ | ||
| 1564 | + if (observer == nullptr) { | ||
| 1565 | + return; | ||
| 1566 | + } | ||
| 1567 | + SendDeleteReferenceEvent(env, observer->env_, observer->callback_, | ||
| 1568 | + "EnableAbilityLists_DeleteObserverReference"); | ||
| 1549 | } | 1569 | } |
| 1550 | 1570 | ||
| 1551 | napi_value NAccessibilityConfig::SubscribeSelfSeniorMode(napi_env env, napi_callback_info info) | 1571 | napi_value NAccessibilityConfig::SubscribeSelfSeniorMode(napi_env env, napi_callback_info info) |
| @@ -1831,95 +1851,52 @@ void SeniorModeStateObserver::OnSeniorModeStateChanged(const std::string& bundle | |||
| 1831 | { | 1851 | { |
| 1832 | HILOG_INFO("bundleName: %{public}s, appIndex: %{public}d, state: %{public}d", | 1852 | HILOG_INFO("bundleName: %{public}s, appIndex: %{public}d, state: %{public}d", |
| 1833 | bundleName.c_str(), appIndex, state); | 1853 | bundleName.c_str(), appIndex, state); |
| 1834 | - | 1854 | + std::shared_ptr<StateCallbackInfo> callbackInfo = std::make_shared<StateCallbackInfo>(); |
| 1835 | - StateCallbackInfo *callbackInfo = new(std::nothrow) StateCallbackInfo(); | ||
| 1836 | if (callbackInfo == nullptr) { | 1855 | if (callbackInfo == nullptr) { |
| 1837 | - HILOG_ERROR("callbackInfo is nullptr"); | 1856 | + HILOG_ERROR("Failed to create callbackInfo."); |
| 1838 | return; | 1857 | return; |
| 1839 | } | 1858 | } |
| 1840 | - | ||
| 1841 | - uv_work_t *work = new(std::nothrow) uv_work_t; | ||
| 1842 | - if (!work) { | ||
| 1843 | - HILOG_ERROR("Failed to create work."); | ||
| 1844 | - delete callbackInfo; | ||
| 1845 | - callbackInfo = nullptr; | ||
| 1846 | - return; | ||
| 1847 | - } | ||
| 1848 | - | ||
| 1849 | callbackInfo->env_ = env_; | 1859 | callbackInfo->env_ = env_; |
| 1850 | callbackInfo->ref_ = callback_; | 1860 | callbackInfo->ref_ = callback_; |
| 1851 | callbackInfo->stringValue_ = bundleName; | 1861 | callbackInfo->stringValue_ = bundleName; |
| 1852 | callbackInfo->int32Value_ = appIndex; | 1862 | callbackInfo->int32Value_ = appIndex; |
| 1853 | callbackInfo->state_ = state; | 1863 | callbackInfo->state_ = state; |
| 1854 | - work->data = static_cast<void*>(callbackInfo); | 1864 | + auto task = [callbackInfo]() { |
| 1855 | - | 1865 | + if (callbackInfo == nullptr) { |
| 1856 | - int ret = OnSeniorModeStateChangedWork(work); | 1866 | + return; |
| 1857 | - if (ret != 0) { | 1867 | + } |
| 1858 | - HILOG_ERROR("Failed to execute OnSeniorModeStateChanged work queue"); | 1868 | + napi_env env = callbackInfo->env_; |
| 1859 | - delete callbackInfo; | 1869 | + auto closeScope = [env](napi_handle_scope scope) { |
| 1860 | - callbackInfo = nullptr; | 1870 | + napi_close_handle_scope(env, scope); |
| 1861 | - delete work; | 1871 | + }; |
| 1862 | - work = nullptr; | 1872 | + std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scope( |
| 1873 | + OHOS::Accessibility::TmpOpenScope(callbackInfo->env_), closeScope); | ||
| 1874 | + napi_value handler = nullptr; | ||
| 1875 | + napi_value callResult = nullptr; | ||
| 1876 | + napi_value jsEvent = nullptr; | ||
| 1877 | + napi_value undefined = nullptr; | ||
| 1878 | + napi_create_object(callbackInfo->env_, &jsEvent); | ||
| 1879 | + napi_value jsBundleName = nullptr; | ||
| 1880 | + napi_create_string_utf8(callbackInfo->env_, callbackInfo->stringValue_.c_str(), | ||
| 1881 | + NAPI_AUTO_LENGTH, &jsBundleName); | ||
| 1882 | + napi_set_named_property(callbackInfo->env_, jsEvent, "bundleName", jsBundleName); | ||
| 1883 | + if (callbackInfo->int32Value_ >= 0) { | ||
| 1884 | + napi_value jsAppIndex = nullptr; | ||
| 1885 | + napi_create_int32(callbackInfo->env_, callbackInfo->int32Value_, &jsAppIndex); | ||
| 1886 | + napi_set_named_property(callbackInfo->env_, jsEvent, "appIndex", jsAppIndex); | ||
| 1887 | + } | ||
| 1888 | + napi_value jsState = nullptr; | ||
| 1889 | + napi_get_boolean(callbackInfo->env_, callbackInfo->state_, &jsState); | ||
| 1890 | + napi_set_named_property(callbackInfo->env_, jsEvent, "seniorModeState", jsState); | ||
| 1891 | + napi_get_reference_value(callbackInfo->env_, callbackInfo->ref_, &handler); | ||
| 1892 | + napi_get_undefined(callbackInfo->env_, &undefined); | ||
| 1893 | + napi_call_function(callbackInfo->env_, undefined, handler, 1, &jsEvent, &callResult); | ||
| 1894 | + }; | ||
| 1895 | + if (napi_send_event(env_, task, napi_eprio_high, "OnSeniorModeStateChanged") != napi_status::napi_ok) { | ||
| 1896 | + HILOG_ERROR("failed to send event"); | ||
| 1863 | } | 1897 | } |
| 1864 | } | 1898 | } |
| 1865 | 1899 | ||
| 1866 | -int SeniorModeStateObserver::OnSeniorModeStateChangedWork(uv_work_t *work) | ||
| 1867 | -{ | ||
| 1868 | - uv_loop_s *loop = nullptr; | ||
| 1869 | - napi_get_uv_event_loop(env_, &loop); | ||
| 1870 | - if (loop == nullptr || work == nullptr) { | ||
| 1871 | - HILOG_ERROR("loop or work is nullptr."); | ||
| 1872 | - return RET_ERR_FAILED; | ||
| 1873 | - } | ||
| 1874 | - | ||
| 1875 | - int ret = uv_queue_work_with_qos_internal( | ||
| 1876 | - loop, | ||
| 1877 | - work, | ||
| 1878 | - [](uv_work_t *work) {}, | ||
| 1879 | - [](uv_work_t *work, int status) { | ||
| 1880 | - StateCallbackInfo *callbackInfo = static_cast<StateCallbackInfo*>(work->data); | ||
| 1881 | - napi_env env = callbackInfo->env_; | ||
| 1882 | - auto closeScope = [env](napi_handle_scope scope) { | ||
| 1883 | - napi_close_handle_scope(env, scope); | ||
| 1884 | - }; | ||
| 1885 | - std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scopes( | ||
| 1886 | - OHOS::Accessibility::TmpOpenScope(callbackInfo->env_), closeScope); | ||
| 1887 | - | ||
| 1888 | - napi_value handler = nullptr; | ||
| 1889 | - napi_value callResult = nullptr; | ||
| 1890 | - napi_value jsEvent = nullptr; | ||
| 1891 | - napi_value undefined = nullptr; | ||
| 1892 | - | ||
| 1893 | - napi_create_object(env, &jsEvent); | ||
| 1894 | - | ||
| 1895 | - napi_value jsBundleName = nullptr; | ||
| 1896 | - napi_create_string_utf8(env, callbackInfo->stringValue_.c_str(), NAPI_AUTO_LENGTH, &jsBundleName); | ||
| 1897 | - napi_set_named_property(env, jsEvent, "bundleName", jsBundleName); | ||
| 1898 | - | ||
| 1899 | - if (callbackInfo->int32Value_ >= 0) { | ||
| 1900 | - napi_value jsAppIndex = nullptr; | ||
| 1901 | - napi_create_int32(env, callbackInfo->int32Value_, &jsAppIndex); | ||
| 1902 | - napi_set_named_property(env, jsEvent, "appIndex", jsAppIndex); | ||
| 1903 | - } | ||
| 1904 | - | ||
| 1905 | - napi_value jsState = nullptr; | ||
| 1906 | - napi_get_boolean(env, callbackInfo->state_, &jsState); | ||
| 1907 | - napi_set_named_property(env, jsEvent, "seniorModeState", jsState); | ||
| 1908 | - | ||
| 1909 | - napi_get_reference_value(callbackInfo->env_, callbackInfo->ref_, &handler); | ||
| 1910 | - napi_get_undefined(callbackInfo->env_, &undefined); | ||
| 1911 | - napi_call_function(callbackInfo->env_, undefined, handler, 1, &jsEvent, &callResult); | ||
| 1912 | - | ||
| 1913 | - delete callbackInfo; | ||
| 1914 | - callbackInfo = nullptr; | ||
| 1915 | - delete work; | ||
| 1916 | - work = nullptr; | ||
| 1917 | - }, | ||
| 1918 | - uv_qos_default, | ||
| 1919 | - "OnSeniorModeStateChangedWork"); | ||
| 1920 | - return ret; | ||
| 1921 | -} | ||
| 1922 | - | ||
| 1923 | void SeniorModeStateObserverImpl::OnSeniorModeStateChanged(const std::string& bundleName, int32_t appIndex, bool state) | 1900 | void SeniorModeStateObserverImpl::OnSeniorModeStateChanged(const std::string& bundleName, int32_t appIndex, bool state) |
| 1924 | { | 1901 | { |
| 1925 | HILOG_INFO("bundleName: %{public}s, appIndex: %{public}d, state: %{public}d", | 1902 | HILOG_INFO("bundleName: %{public}s, appIndex: %{public}d, state: %{public}d", |
| @@ -1978,6 +1955,7 @@ void SeniorModeStateObserverImpl::UnsubscribeObserver(napi_env env, napi_value o | |||
| 1978 | std::lock_guard<ffrt::mutex> lock(mutex_); | 1955 | std::lock_guard<ffrt::mutex> lock(mutex_); |
| 1979 | for (auto iter = observers_.begin(); iter != observers_.end();) { | 1956 | for (auto iter = observers_.begin(); iter != observers_.end();) { |
| 1980 | if (CheckObserverEqual(env, observer, (*iter)->env_, (*iter)->callback_)) { | 1957 | if (CheckObserverEqual(env, observer, (*iter)->env_, (*iter)->callback_)) { |
| 1958 | + DeleteObserverReference(env, *iter); | ||
| 1981 | observers_.erase(iter); | 1959 | observers_.erase(iter); |
| 1982 | return; | 1960 | return; |
| 1983 | } else { | 1961 | } else { |
| @@ -1990,7 +1968,20 @@ void SeniorModeStateObserverImpl::UnsubscribeObservers() | |||
| 1990 | { | 1968 | { |
| 1991 | HILOG_INFO(); | 1969 | HILOG_INFO(); |
| 1992 | std::lock_guard<ffrt::mutex> lock(mutex_); | 1970 | std::lock_guard<ffrt::mutex> lock(mutex_); |
| 1993 | - observers_.clear(); | 1971 | + for (auto iter = observers_.begin(); iter != observers_.end();) { |
| 1972 | + DeleteObserverReference((*iter)->env_, *iter); | ||
| 1973 | + iter = observers_.erase(iter); | ||
| 1974 | + } | ||
| 1975 | +} | ||
| 1976 | + | ||
| 1977 | +void SeniorModeStateObserverImpl::DeleteObserverReference( | ||
| 1978 | + napi_env env, std::shared_ptr<SeniorModeStateObserver> observer) | ||
| 1979 | +{ | ||
| 1980 | + if (observer == nullptr) { | ||
| 1981 | + return; | ||
| 1982 | + } | ||
| 1983 | + SendDeleteReferenceEvent(env, observer->env_, observer->callback_, | ||
| 1984 | + "SeniorModeState_DeleteObserverReference"); | ||
| 1994 | } | 1985 | } |
| 1995 | 1986 | ||
| 1996 | napi_value NAccessibilityConfig::StartBlinking(napi_env env, napi_callback_info info) | 1987 | napi_value NAccessibilityConfig::StartBlinking(napi_env env, napi_callback_info info) |
| @@ -473,6 +473,7 @@ void NAccessibilityConfigObserverImpl::UnsubscribeObserver(napi_env env, | |||
| 473 | for (auto iter = observers_.begin(); iter != observers_.end();) { | 473 | for (auto iter = observers_.begin(); iter != observers_.end();) { |
| 474 | if ((*iter)->configId_ == id) { | 474 | if ((*iter)->configId_ == id) { |
| 475 | if (CheckObserverEqual(env, observer, (*iter)->env_, (*iter)->handlerRef_)) { | 475 | if (CheckObserverEqual(env, observer, (*iter)->env_, (*iter)->handlerRef_)) { |
| 476 | + DeleteObserverReference(env, *iter); | ||
| 476 | observers_.erase(iter); | 477 | observers_.erase(iter); |
| 477 | return; | 478 | return; |
| 478 | } else { | 479 | } else { |
| @@ -491,9 +492,40 @@ void NAccessibilityConfigObserverImpl::UnsubscribeObservers(OHOS::AccessibilityC | |||
| 491 | std::lock_guard<ffrt::mutex> lock(mutex_); | 492 | std::lock_guard<ffrt::mutex> lock(mutex_); |
| 492 | for (auto iter = observers_.begin(); iter != observers_.end();) { | 493 | for (auto iter = observers_.begin(); iter != observers_.end();) { |
| 493 | if ((*iter)->configId_ == id) { | 494 | if ((*iter)->configId_ == id) { |
| 495 | + DeleteObserverReference((*iter)->env_, *iter); | ||
| 494 | iter = observers_.erase(iter); | 496 | iter = observers_.erase(iter); |
| 495 | } else { | 497 | } else { |
| 496 | iter++; | 498 | iter++; |
| 497 | } | 499 | } |
| 498 | } | 500 | } |
| 499 | } | 501 | } |
| 502 | + | ||
| 503 | +void NAccessibilityConfigObserverImpl::DeleteObserverReference( | ||
| 504 | + napi_env env, std::shared_ptr<NAccessibilityConfigObserver> observer) | ||
| 505 | +{ | ||
| 506 | + if (observer == nullptr) { | ||
| 507 | + return; | ||
| 508 | + } | ||
| 509 | + std::shared_ptr<AccessibilityCallbackInfo> callbackInfo = std::make_shared<AccessibilityCallbackInfo>(); | ||
| 510 | + if (callbackInfo == nullptr) { | ||
| 511 | + HILOG_ERROR("failed to create callbackInfo"); | ||
| 512 | + return; | ||
| 513 | + } | ||
| 514 | + callbackInfo->env_ = observer->env_; | ||
| 515 | + callbackInfo->ref_ = observer->handlerRef_; | ||
| 516 | + auto task = [callbackInfo]() { | ||
| 517 | + if (callbackInfo == nullptr) { | ||
| 518 | + return; | ||
| 519 | + } | ||
| 520 | + napi_env tmpEnv = callbackInfo->env_; | ||
| 521 | + auto closeScope = [tmpEnv](napi_handle_scope scope) { | ||
| 522 | + napi_close_handle_scope(tmpEnv, scope); | ||
| 523 | + }; | ||
| 524 | + std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scope( | ||
| 525 | + OHOS::Accessibility::TmpOpenScope(callbackInfo->env_), closeScope); | ||
| 526 | + napi_delete_reference(tmpEnv, callbackInfo->ref_); | ||
| 527 | + }; | ||
| 528 | + if (napi_send_event(env, task, napi_eprio_high, "DeleteObserverReference") != napi_status::napi_ok) { | ||
| 529 | + HILOG_ERROR("failed to send event"); | ||
| 530 | + } | ||
| 531 | +} | ||