!2265 【账号iam】napi层callbackRef生命周期管理问题修复

Merge pull request !2265 from lichenchen/master
This commit is contained in:
openharmony_ci 2024-11-16 08:53:56 +00:00 committed by Gitee
commit 169d9c6d43
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
3 changed files with 105 additions and 64 deletions

View File

@ -56,6 +56,16 @@ struct JsIAMCallback {
bool hasOnAcquireInfo = false; bool hasOnAcquireInfo = false;
}; };
struct CommonCallbackInfo {
CommonCallbackInfo(napi_env env) : env(env) {}
napi_env env;
napi_ref callbackRef = nullptr;
napi_deferred deferred = nullptr;
napi_value errJs = nullptr;
napi_value dataJs = nullptr;
int32_t errCode;
};
#ifdef HAS_USER_AUTH_PART #ifdef HAS_USER_AUTH_PART
struct IDMCallbackParam : public CommonAsyncContext { struct IDMCallbackParam : public CommonAsyncContext {
explicit IDMCallbackParam(napi_env napiEnv) : CommonAsyncContext(napiEnv) {}; explicit IDMCallbackParam(napi_env napiEnv) : CommonAsyncContext(napiEnv) {};
@ -136,6 +146,7 @@ struct GetAuthInfoContext : public CommonAsyncContext {
bool parseHasAccountId = false; bool parseHasAccountId = false;
AccountSA::AuthType authType {0}; AccountSA::AuthType authType {0};
std::vector<AccountSA::CredentialInfo> credInfo; std::vector<AccountSA::CredentialInfo> credInfo;
std::shared_ptr<NapiCallbackRef> callback;
}; };
struct GetEnrolledIdContext : public CommonAsyncContext { struct GetEnrolledIdContext : public CommonAsyncContext {
@ -158,6 +169,7 @@ struct GetPropertyContext : public CommonAsyncContext {
int32_t accountId = -1; int32_t accountId = -1;
bool parseHasAccountId = false; bool parseHasAccountId = false;
int32_t nextPhaseFreezingTime = -1; int32_t nextPhaseFreezingTime = -1;
std::shared_ptr<NapiCallbackRef> callback;
}; };
struct SetPropertyContext : public CommonAsyncContext { struct SetPropertyContext : public CommonAsyncContext {
@ -165,6 +177,7 @@ struct SetPropertyContext : public CommonAsyncContext {
AccountSA::SetPropertyRequest request; AccountSA::SetPropertyRequest request;
int32_t result = 0; int32_t result = 0;
int32_t accountId = -1; int32_t accountId = -1;
std::shared_ptr<NapiCallbackRef> callback;
}; };
class NapiIDMCallback : public AccountSA::IDMCallback { class NapiIDMCallback : public AccountSA::IDMCallback {
@ -187,10 +200,13 @@ public:
virtual ~NapiGetInfoCallback(); virtual ~NapiGetInfoCallback();
void OnCredentialInfo(int32_t result, const std::vector<AccountSA::CredentialInfo> &infoList) override; void OnCredentialInfo(int32_t result, const std::vector<AccountSA::CredentialInfo> &infoList) override;
private: private:
napi_env env_; napi_env env_;
napi_ref callbackRef_; std::shared_ptr<NapiCallbackRef> callback_;
napi_deferred deferred_; napi_deferred deferred_;
std::mutex mutex_;
bool onResultCalled_ = false;
}; };
class NapiGetEnrolledIdCallback : public AccountSA::GetEnrolledIdCallback { class NapiGetEnrolledIdCallback : public AccountSA::GetEnrolledIdCallback {
@ -228,12 +244,14 @@ public:
virtual ~NapiGetPropCallback(); virtual ~NapiGetPropCallback();
void GetContextParams(const UserIam::UserAuth::Attributes &extraInfo, GetPropertyContext &context); void GetContextParams(const UserIam::UserAuth::Attributes &extraInfo, GetPropertyContext &context);
void OnResult(int32_t result, const AccountSA::Attributes &extraInfo) override; void OnResult(int32_t result, const AccountSA::Attributes &extraInfo) override;
private: private:
napi_env env_ = nullptr; napi_env env_ = nullptr;
napi_ref callbackRef_ = nullptr; std::shared_ptr<NapiCallbackRef> callback_;
napi_deferred deferred_ = nullptr; napi_deferred deferred_ = nullptr;
AccountSA::GetPropertyRequest request_; AccountSA::GetPropertyRequest request_;
std::mutex mutex_; std::mutex mutex_;
bool onResultCalled_ = false;
}; };
class NapiSetPropCallback : public AccountSA::GetSetPropCallback { class NapiSetPropCallback : public AccountSA::GetSetPropCallback {
@ -245,9 +263,10 @@ public:
private: private:
napi_env env_ = nullptr; napi_env env_ = nullptr;
napi_ref callbackRef_ = nullptr; std::shared_ptr<NapiCallbackRef> callback_;
napi_deferred deferred_ = nullptr; napi_deferred deferred_ = nullptr;
std::mutex mutex_; std::mutex mutex_;
bool onResultCalled_ = false;
}; };
#endif // HAS_USER_AUTH_PART #endif // HAS_USER_AUTH_PART
@ -274,6 +293,7 @@ private:
}; };
#endif // HAS_PIN_AUTH_PART #endif // HAS_PIN_AUTH_PART
void CallbackAsyncOrPromise(const CommonCallbackInfo &callbackInfo);
void CallbackAsyncOrPromise(napi_env env, CommonAsyncContext *context, napi_value errJs, napi_value dataJs); void CallbackAsyncOrPromise(napi_env env, CommonAsyncContext *context, napi_value errJs, napi_value dataJs);
napi_value CreateErrorObject(napi_env env, int32_t code); napi_value CreateErrorObject(napi_env env, int32_t code);
napi_status ParseUInt32Array(napi_env env, napi_value value, std::vector<uint32_t> &data); napi_status ParseUInt32Array(napi_env env, napi_value value, std::vector<uint32_t> &data);

View File

@ -557,30 +557,31 @@ void NapiUserAuthCallback::OnAcquireInfo(int32_t module, uint32_t acquireInfo, c
} }
NapiGetInfoCallback::NapiGetInfoCallback(napi_env env, napi_ref callbackRef, napi_deferred deferred) NapiGetInfoCallback::NapiGetInfoCallback(napi_env env, napi_ref callbackRef, napi_deferred deferred)
: env_(env), callbackRef_(callbackRef), deferred_(deferred) : env_(env), deferred_(deferred)
{} {
callback_ = std::make_shared<NapiCallbackRef>(env, callbackRef);
}
NapiGetInfoCallback::~NapiGetInfoCallback() NapiGetInfoCallback::~NapiGetInfoCallback()
{ {}
if (callbackRef_ != nullptr) {
ReleaseNapiRefAsync(env_, callbackRef_);
callbackRef_ = nullptr;
}
deferred_ = nullptr;
}
void NapiGetInfoCallback::OnCredentialInfo(int32_t result, const std::vector<AccountSA::CredentialInfo> &infoList) void NapiGetInfoCallback::OnCredentialInfo(int32_t result, const std::vector<AccountSA::CredentialInfo> &infoList)
{ {
std::lock_guard<std::mutex> lock(mutex_);
if (onResultCalled_) {
ACCOUNT_LOGE("Call twice is not allowed");
return;
}
onResultCalled_ = true;
std::shared_ptr<GetAuthInfoContext> context = std::make_shared<GetAuthInfoContext>(env_); std::shared_ptr<GetAuthInfoContext> context = std::make_shared<GetAuthInfoContext>(env_);
if (context == nullptr) { if (context == nullptr) {
ACCOUNT_LOGE("Failed for nullptr"); ACCOUNT_LOGE("Failed for nullptr");
return; return;
} }
context->callbackRef = callbackRef_; context->callback = callback_;
context->deferred = deferred_; context->deferred = deferred_;
context->errCode = result; context->errCode = result;
context->credInfo = infoList; context->credInfo = infoList;
callbackRef_ = nullptr;
auto task = [context = std::move(context)]() { auto task = [context = std::move(context)]() {
ACCOUNT_LOGI("Enter NapiGetInfoCallback::OnCredentialInfo task"); ACCOUNT_LOGI("Enter NapiGetInfoCallback::OnCredentialInfo task");
napi_handle_scope scope = nullptr; napi_handle_scope scope = nullptr;
@ -590,17 +591,19 @@ void NapiGetInfoCallback::OnCredentialInfo(int32_t result, const std::vector<Acc
return; return;
} }
napi_env env = context->env; napi_env env = context->env;
napi_value errJs = nullptr; CommonCallbackInfo callbackInfo(env);
napi_value dataJs = nullptr; callbackInfo.callbackRef = context->callback->callbackRef;
callbackInfo.deferred = context->deferred;
callbackInfo.errCode = context->errCode;
if (context->errCode != ERR_OK) { if (context->errCode != ERR_OK) {
int32_t jsErrCode = AccountIAMConvertToJSErrCode(context->errCode); int32_t jsErrCode = AccountIAMConvertToJSErrCode(context->errCode);
errJs = GenerateBusinessError(env, jsErrCode, ConvertToJsErrMsg(jsErrCode)); callbackInfo.errJs = GenerateBusinessError(env, jsErrCode, ConvertToJsErrMsg(jsErrCode));
napi_get_null(env, &dataJs); napi_get_null(env, &callbackInfo.dataJs);
} else { } else {
napi_get_null(env, &errJs); napi_get_null(env, &callbackInfo.errJs);
dataJs = CreateCredInfoArray(env, context->credInfo); callbackInfo.dataJs = CreateCredInfoArray(env, context->credInfo);
} }
CallbackAsyncOrPromise(env, context.get(), errJs, dataJs); CallbackAsyncOrPromise(callbackInfo);
napi_close_handle_scope(context->env, scope); napi_close_handle_scope(context->env, scope);
return; return;
}; };
@ -660,17 +663,13 @@ void NapiGetEnrolledIdCallback::OnEnrolledId(int32_t result, uint64_t enrolledId
NapiGetPropCallback::NapiGetPropCallback( NapiGetPropCallback::NapiGetPropCallback(
napi_env env, napi_ref callbackRef, napi_deferred deferred, const AccountSA::GetPropertyRequest &request) napi_env env, napi_ref callbackRef, napi_deferred deferred, const AccountSA::GetPropertyRequest &request)
: env_(env), callbackRef_(callbackRef), deferred_(deferred), request_(request) : env_(env), deferred_(deferred), request_(request)
{} {
callback_ = std::make_shared<NapiCallbackRef>(env, callbackRef);
}
NapiGetPropCallback::~NapiGetPropCallback() NapiGetPropCallback::~NapiGetPropCallback()
{ {}
if (callbackRef_ != nullptr) {
ReleaseNapiRefAsync(env_, callbackRef_);
callbackRef_ = nullptr;
}
deferred_ = nullptr;
}
void NapiGetPropCallback::GetContextParams( void NapiGetPropCallback::GetContextParams(
const UserIam::UserAuth::Attributes &extraInfo, GetPropertyContext &context) const UserIam::UserAuth::Attributes &extraInfo, GetPropertyContext &context)
@ -726,9 +725,14 @@ void NapiGetPropCallback::GetContextParams(
void NapiGetPropCallback::OnResult(int32_t result, const UserIam::UserAuth::Attributes &extraInfo) void NapiGetPropCallback::OnResult(int32_t result, const UserIam::UserAuth::Attributes &extraInfo)
{ {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
if ((callbackRef_ == nullptr) && (deferred_ == nullptr)) { if ((callback_->callbackRef == nullptr) && (deferred_ == nullptr)) {
return; return;
} }
if (onResultCalled_) {
ACCOUNT_LOGE("Call twice is not allowed");
return;
}
onResultCalled_ = true;
std::shared_ptr<GetPropertyContext> context = std::make_shared<GetPropertyContext>(env_); std::shared_ptr<GetPropertyContext> context = std::make_shared<GetPropertyContext>(env_);
if (context == nullptr) { if (context == nullptr) {
ACCOUNT_LOGE("Failed for nullptr"); ACCOUNT_LOGE("Failed for nullptr");
@ -736,12 +740,11 @@ void NapiGetPropCallback::OnResult(int32_t result, const UserIam::UserAuth::Attr
} }
// create context data // create context data
GetContextParams(extraInfo, *context); GetContextParams(extraInfo, *context);
context->callbackRef = callbackRef_; context->callback = callback_;
context->deferred = deferred_; context->deferred = deferred_;
context->errCode = ERR_OK; context->errCode = ERR_OK;
context->result = result; context->result = result;
context->request = request_; context->request = request_;
callbackRef_ = nullptr;
auto task = [context = std::move(context)]() { auto task = [context = std::move(context)]() {
ACCOUNT_LOGI("Enter NapiGetPropCallback::OnResult task"); ACCOUNT_LOGI("Enter NapiGetPropCallback::OnResult task");
napi_handle_scope scope = nullptr; napi_handle_scope scope = nullptr;
@ -750,10 +753,12 @@ void NapiGetPropCallback::OnResult(int32_t result, const UserIam::UserAuth::Attr
ACCOUNT_LOGE("Failed to open scope"); ACCOUNT_LOGE("Failed to open scope");
return; return;
} }
napi_value errJs = nullptr; CommonCallbackInfo callbackInfo(context->env);
napi_value dataJs = nullptr; callbackInfo.callbackRef = context->callback->callbackRef;
CreateExecutorProperty(context->env, *context, errJs, dataJs); callbackInfo.deferred = context->deferred;
CallbackAsyncOrPromise(context->env, context.get(), errJs, dataJs); CreateExecutorProperty(context->env, *context, callbackInfo.errJs, callbackInfo.dataJs);
callbackInfo.errCode = context->errCode;
CallbackAsyncOrPromise(callbackInfo);
napi_close_handle_scope(context->env, scope); napi_close_handle_scope(context->env, scope);
return; return;
}; };
@ -765,17 +770,13 @@ void NapiGetPropCallback::OnResult(int32_t result, const UserIam::UserAuth::Attr
} }
NapiSetPropCallback::NapiSetPropCallback(napi_env env, napi_ref callbackRef, napi_deferred deferred) NapiSetPropCallback::NapiSetPropCallback(napi_env env, napi_ref callbackRef, napi_deferred deferred)
: env_(env), callbackRef_(callbackRef), deferred_(deferred) : env_(env), deferred_(deferred)
{} {
callback_ = std::make_shared<NapiCallbackRef>(env, callbackRef);
}
NapiSetPropCallback::~NapiSetPropCallback() NapiSetPropCallback::~NapiSetPropCallback()
{ {}
if (callbackRef_ != nullptr) {
ReleaseNapiRefAsync(env_, callbackRef_);
callbackRef_ = nullptr;
}
deferred_ = nullptr;
}
NapiPrepareRemoteAuthCallback::NapiPrepareRemoteAuthCallback(napi_env env, napi_ref callbackRef, napi_deferred deferred) NapiPrepareRemoteAuthCallback::NapiPrepareRemoteAuthCallback(napi_env env, napi_ref callbackRef, napi_deferred deferred)
: env_(env), callbackRef_(callbackRef), deferred_(deferred) : env_(env), callbackRef_(callbackRef), deferred_(deferred)
@ -838,19 +839,23 @@ void NapiPrepareRemoteAuthCallback::OnResult(int32_t result)
void NapiSetPropCallback::OnResult(int32_t result, const UserIam::UserAuth::Attributes &extraInfo) void NapiSetPropCallback::OnResult(int32_t result, const UserIam::UserAuth::Attributes &extraInfo)
{ {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
if ((callbackRef_ == nullptr) && (deferred_ == nullptr)) { if ((callback_->callbackRef == nullptr) && (deferred_ == nullptr)) {
return; return;
} }
if (onResultCalled_) {
ACCOUNT_LOGE("Call twice is not allowed");
return;
}
onResultCalled_ = true;
std::shared_ptr<SetPropertyContext> context = std::make_shared<SetPropertyContext>(env_); std::shared_ptr<SetPropertyContext> context = std::make_shared<SetPropertyContext>(env_);
if (context == nullptr) { if (context == nullptr) {
ACCOUNT_LOGE("Failed for nullptr"); ACCOUNT_LOGE("Failed for nullptr");
return; return;
} }
context->callbackRef = callbackRef_; context->callback = callback_;
context->deferred = deferred_; context->deferred = deferred_;
context->errCode = ERR_OK; context->errCode = ERR_OK;
context->result = result; context->result = result;
callbackRef_ = nullptr;
auto task = [context = std::move(context)]() { auto task = [context = std::move(context)]() {
ACCOUNT_LOGI("Enter NapiSetPropCallback::OnResult task"); ACCOUNT_LOGI("Enter NapiSetPropCallback::OnResult task");
napi_handle_scope scope = nullptr; napi_handle_scope scope = nullptr;
@ -860,18 +865,19 @@ void NapiSetPropCallback::OnResult(int32_t result, const UserIam::UserAuth::Attr
return; return;
} }
napi_env env = context->env; napi_env env = context->env;
napi_value errJs = nullptr; CommonCallbackInfo callbackInfo(env);
napi_value dataJs = nullptr; callbackInfo.callbackRef = context->callback->callbackRef;
context->errCode = context->result; callbackInfo.deferred = context->deferred;
callbackInfo.errCode = context->result;
if (context->result != ERR_OK) { if (context->result != ERR_OK) {
int32_t jsErrCode = AccountIAMConvertToJSErrCode(context->result); int32_t jsErrCode = AccountIAMConvertToJSErrCode(context->result);
errJs = GenerateBusinessError(env, jsErrCode, ConvertToJsErrMsg(jsErrCode)); callbackInfo.errJs = GenerateBusinessError(env, jsErrCode, ConvertToJsErrMsg(jsErrCode));
napi_get_null(env, &dataJs); napi_get_null(env, &callbackInfo.dataJs);
} else { } else {
napi_get_null(env, &errJs); napi_get_null(env, &callbackInfo.errJs);
napi_get_null(env, &dataJs); napi_get_null(env, &callbackInfo.dataJs);
} }
CallbackAsyncOrPromise(env, context.get(), errJs, dataJs); CallbackAsyncOrPromise(callbackInfo);
napi_close_handle_scope(env, scope); napi_close_handle_scope(env, scope);
return; return;
}; };
@ -1038,21 +1044,32 @@ void NapiGetDataCallback::OnGetData(int32_t authSubType, std::vector<uint8_t> ch
} }
#endif // HAS_PIN_AUTH_PART #endif // HAS_PIN_AUTH_PART
void CallbackAsyncOrPromise(napi_env env, CommonAsyncContext *context, napi_value errJs, napi_value dataJs) void CallbackAsyncOrPromise(const CommonCallbackInfo &callbackInfo)
{ {
if (context->callbackRef) { if (callbackInfo.callbackRef) {
napi_value argv[ARG_SIZE_TWO] = {errJs, dataJs}; napi_value argv[ARG_SIZE_TWO] = {callbackInfo.errJs, callbackInfo.dataJs};
ACCOUNT_LOGI("call js function"); ACCOUNT_LOGI("call js function");
NapiCallVoidFunction(env, argv, ARG_SIZE_TWO, context->callbackRef); NapiCallVoidFunction(callbackInfo.env, argv, ARG_SIZE_TWO, callbackInfo.callbackRef);
} else { } else {
if (context->errCode == ERR_OK) { if (callbackInfo.errCode == ERR_OK) {
napi_resolve_deferred(env, context->deferred, dataJs); napi_resolve_deferred(callbackInfo.env, callbackInfo.deferred, callbackInfo.dataJs);
} else { } else {
napi_reject_deferred(env, context->deferred, errJs); napi_reject_deferred(callbackInfo.env, callbackInfo.deferred, callbackInfo.errJs);
} }
} }
} }
void CallbackAsyncOrPromise(napi_env env, CommonAsyncContext *context, napi_value errJs, napi_value dataJs)
{
CommonCallbackInfo callbackInfo(env);
callbackInfo.callbackRef = context->callbackRef;
callbackInfo.deferred = context->deferred;
callbackInfo.errJs = errJs;
callbackInfo.dataJs = dataJs;
callbackInfo.errCode = context->errCode;
CallbackAsyncOrPromise(callbackInfo);
}
napi_status ParseUInt32Array(napi_env env, napi_value value, std::vector<uint32_t> &data) napi_status ParseUInt32Array(napi_env env, napi_value value, std::vector<uint32_t> &data)
{ {
data.clear(); data.clear();

View File

@ -546,7 +546,11 @@ void ReleaseNapiRefArray(napi_env env, const std::vector<napi_ref> &napiRefVec)
NapiCallbackRef::~NapiCallbackRef() NapiCallbackRef::~NapiCallbackRef()
{ {
if (callbackRef == nullptr) {
return;
}
ReleaseNapiRefArray(env, {callbackRef}); ReleaseNapiRefArray(env, {callbackRef});
callbackRef = nullptr;
} }
bool InitUvWorkCallbackEnv(uv_work_t *work, napi_handle_scope &scope) bool InitUvWorkCallbackEnv(uv_work_t *work, napi_handle_scope &scope)