mirror of
https://gitee.com/openharmony/arkui_ace_engine
synced 2024-11-23 07:01:24 +00:00
!41809 【mediaQuery】解决on回调中重入on或off引起appfreeze的问题
Merge pull request !41809 from 冯纪拓/media_pls
This commit is contained in:
commit
e8d8451d04
@ -13,10 +13,20 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "napi/native_api.h"
|
||||
#include "napi/native_common.h"
|
||||
#include "napi/native_node_api.h"
|
||||
|
||||
#include "bridge/common/media_query/media_queryer.h"
|
||||
#include "bridge/common/utils/engine_helper.h"
|
||||
#include "bridge/js_frontend/engine/common/js_engine.h"
|
||||
#include "core/common/container.h"
|
||||
|
||||
namespace OHOS::Ace::Napi {
|
||||
namespace {
|
||||
@ -76,20 +86,52 @@ public:
|
||||
|
||||
static void OnNapiCallback(JsEngine* jsEngine)
|
||||
{
|
||||
MediaQueryer queryer;
|
||||
std::set<std::unique_ptr<MediaQueryListener>> delayDeleteListenerSets;
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
std::set<napi_ref> delayDeleteCallbacks;
|
||||
std::vector<MediaQueryListener*> copyListeners;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
auto& currentListeners = listenerSets_[AceType::WeakClaim(jsEngine)];
|
||||
copyListeners.insert(copyListeners.end(), currentListeners.begin(), currentListeners.end());
|
||||
}
|
||||
struct Leave {
|
||||
~Leave()
|
||||
{
|
||||
if (delayDeleteEnv_) {
|
||||
for (auto& cbRef : *delayDeleteCallbacks_) {
|
||||
napi_delete_reference(delayDeleteEnv_, cbRef);
|
||||
}
|
||||
}
|
||||
delayDeleteEnv_ = nullptr;
|
||||
delayDeleteCallbacks_ = nullptr;
|
||||
delayDeleteListenerSets_ = nullptr;
|
||||
}
|
||||
} leave;
|
||||
|
||||
delayDeleteCallbacks_ = &delayDeleteCallbacks;
|
||||
delayDeleteListenerSets_ = &delayDeleteListenerSets;
|
||||
for (auto listener : listenerSets_[AceType::WeakClaim(jsEngine)]) {
|
||||
|
||||
TriggerAllCallbacks(copyListeners);
|
||||
}
|
||||
|
||||
static void TriggerAllCallbacks(std::vector<MediaQueryListener*>& copyListeners)
|
||||
{
|
||||
MediaQueryer queryer;
|
||||
for (auto& listener : copyListeners) {
|
||||
auto json = MediaQueryInfo::GetMediaQueryJsonInfo();
|
||||
listener->matches_ = queryer.MatchCondition(listener->media_, json);
|
||||
for (auto& cbRef : listener->cbList_) {
|
||||
std::set<napi_ref> delayDeleteCallbacks;
|
||||
std::vector<napi_ref> copyCallbacks;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
auto& currentCallbacks = listener->cbList_;
|
||||
copyCallbacks.insert(copyCallbacks.end(), currentCallbacks.begin(), currentCallbacks.end());
|
||||
}
|
||||
|
||||
for (const auto& cbRef : copyCallbacks) {
|
||||
if (delayDeleteCallbacks_->find(cbRef) != delayDeleteCallbacks_->end()) {
|
||||
continue;
|
||||
}
|
||||
napi_handle_scope scope = nullptr;
|
||||
napi_open_handle_scope(listener->env_, &scope);
|
||||
if (scope == nullptr) {
|
||||
@ -159,17 +201,29 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
if (argc == 1) {
|
||||
for (auto& item : listener->cbList_) {
|
||||
napi_delete_reference(listener->env_, item);
|
||||
if (delayDeleteCallbacks_) {
|
||||
delayDeleteEnv_ = env;
|
||||
for (auto& item : listener->cbList_) {
|
||||
(*delayDeleteCallbacks_).emplace(item);
|
||||
}
|
||||
} else {
|
||||
for (auto& item : listener->cbList_) {
|
||||
napi_delete_reference(listener->env_, item);
|
||||
}
|
||||
}
|
||||
listener->cbList_.clear();
|
||||
} else {
|
||||
NAPI_ASSERT(env, (argc == 2 && listener != nullptr && cb != nullptr), "Invalid arguments");
|
||||
auto iter = listener->FindCbList(cb);
|
||||
if (iter != listener->cbList_.end()) {
|
||||
napi_delete_reference(listener->env_, *iter);
|
||||
listener->cbList_.erase(iter);
|
||||
if (delayDeleteCallbacks_) {
|
||||
delayDeleteEnv_ = env;
|
||||
(*delayDeleteCallbacks_).emplace(*iter);
|
||||
} else {
|
||||
napi_delete_reference(listener->env_, *iter);
|
||||
}
|
||||
}
|
||||
listener->cbList_.erase(iter);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@ -290,10 +344,14 @@ private:
|
||||
napi_env env_ = nullptr;
|
||||
std::list<napi_ref> cbList_;
|
||||
static std::set<std::unique_ptr<MediaQueryListener>>* delayDeleteListenerSets_;
|
||||
static napi_env delayDeleteEnv_;
|
||||
static std::set<napi_ref>* delayDeleteCallbacks_;
|
||||
static std::map<WeakPtr<JsEngine>, std::set<MediaQueryListener*>> listenerSets_;
|
||||
static std::mutex mutex_;
|
||||
};
|
||||
std::set<std::unique_ptr<MediaQueryListener>>* MediaQueryListener::delayDeleteListenerSets_;
|
||||
napi_env MediaQueryListener::delayDeleteEnv_ = nullptr;
|
||||
std::set<napi_ref>* MediaQueryListener::delayDeleteCallbacks_;
|
||||
std::map<WeakPtr<JsEngine>, std::set<MediaQueryListener*>> MediaQueryListener::listenerSets_;
|
||||
std::mutex MediaQueryListener::mutex_;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user