mirror of
https://gitee.com/openharmony/account_os_account
synced 2024-11-23 10:10:11 +00:00
!2265 【账号iam】napi层callbackRef生命周期管理问题修复
Merge pull request !2265 from lichenchen/master
This commit is contained in:
commit
169d9c6d43
@ -56,6 +56,16 @@ struct JsIAMCallback {
|
||||
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
|
||||
struct IDMCallbackParam : public CommonAsyncContext {
|
||||
explicit IDMCallbackParam(napi_env napiEnv) : CommonAsyncContext(napiEnv) {};
|
||||
@ -136,6 +146,7 @@ struct GetAuthInfoContext : public CommonAsyncContext {
|
||||
bool parseHasAccountId = false;
|
||||
AccountSA::AuthType authType {0};
|
||||
std::vector<AccountSA::CredentialInfo> credInfo;
|
||||
std::shared_ptr<NapiCallbackRef> callback;
|
||||
};
|
||||
|
||||
struct GetEnrolledIdContext : public CommonAsyncContext {
|
||||
@ -158,6 +169,7 @@ struct GetPropertyContext : public CommonAsyncContext {
|
||||
int32_t accountId = -1;
|
||||
bool parseHasAccountId = false;
|
||||
int32_t nextPhaseFreezingTime = -1;
|
||||
std::shared_ptr<NapiCallbackRef> callback;
|
||||
};
|
||||
|
||||
struct SetPropertyContext : public CommonAsyncContext {
|
||||
@ -165,6 +177,7 @@ struct SetPropertyContext : public CommonAsyncContext {
|
||||
AccountSA::SetPropertyRequest request;
|
||||
int32_t result = 0;
|
||||
int32_t accountId = -1;
|
||||
std::shared_ptr<NapiCallbackRef> callback;
|
||||
};
|
||||
|
||||
class NapiIDMCallback : public AccountSA::IDMCallback {
|
||||
@ -187,10 +200,13 @@ public:
|
||||
virtual ~NapiGetInfoCallback();
|
||||
|
||||
void OnCredentialInfo(int32_t result, const std::vector<AccountSA::CredentialInfo> &infoList) override;
|
||||
|
||||
private:
|
||||
napi_env env_;
|
||||
napi_ref callbackRef_;
|
||||
std::shared_ptr<NapiCallbackRef> callback_;
|
||||
napi_deferred deferred_;
|
||||
std::mutex mutex_;
|
||||
bool onResultCalled_ = false;
|
||||
};
|
||||
|
||||
class NapiGetEnrolledIdCallback : public AccountSA::GetEnrolledIdCallback {
|
||||
@ -228,12 +244,14 @@ public:
|
||||
virtual ~NapiGetPropCallback();
|
||||
void GetContextParams(const UserIam::UserAuth::Attributes &extraInfo, GetPropertyContext &context);
|
||||
void OnResult(int32_t result, const AccountSA::Attributes &extraInfo) override;
|
||||
|
||||
private:
|
||||
napi_env env_ = nullptr;
|
||||
napi_ref callbackRef_ = nullptr;
|
||||
std::shared_ptr<NapiCallbackRef> callback_;
|
||||
napi_deferred deferred_ = nullptr;
|
||||
AccountSA::GetPropertyRequest request_;
|
||||
std::mutex mutex_;
|
||||
bool onResultCalled_ = false;
|
||||
};
|
||||
|
||||
class NapiSetPropCallback : public AccountSA::GetSetPropCallback {
|
||||
@ -245,9 +263,10 @@ public:
|
||||
|
||||
private:
|
||||
napi_env env_ = nullptr;
|
||||
napi_ref callbackRef_ = nullptr;
|
||||
std::shared_ptr<NapiCallbackRef> callback_;
|
||||
napi_deferred deferred_ = nullptr;
|
||||
std::mutex mutex_;
|
||||
bool onResultCalled_ = false;
|
||||
};
|
||||
#endif // HAS_USER_AUTH_PART
|
||||
|
||||
@ -274,6 +293,7 @@ private:
|
||||
};
|
||||
#endif // HAS_PIN_AUTH_PART
|
||||
|
||||
void CallbackAsyncOrPromise(const CommonCallbackInfo &callbackInfo);
|
||||
void CallbackAsyncOrPromise(napi_env env, CommonAsyncContext *context, napi_value errJs, napi_value dataJs);
|
||||
napi_value CreateErrorObject(napi_env env, int32_t code);
|
||||
napi_status ParseUInt32Array(napi_env env, napi_value value, std::vector<uint32_t> &data);
|
||||
|
@ -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)
|
||||
: env_(env), callbackRef_(callbackRef), deferred_(deferred)
|
||||
{}
|
||||
: env_(env), deferred_(deferred)
|
||||
{
|
||||
callback_ = std::make_shared<NapiCallbackRef>(env, callbackRef);
|
||||
}
|
||||
|
||||
NapiGetInfoCallback::~NapiGetInfoCallback()
|
||||
{
|
||||
if (callbackRef_ != nullptr) {
|
||||
ReleaseNapiRefAsync(env_, callbackRef_);
|
||||
callbackRef_ = nullptr;
|
||||
}
|
||||
deferred_ = nullptr;
|
||||
}
|
||||
{}
|
||||
|
||||
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_);
|
||||
if (context == nullptr) {
|
||||
ACCOUNT_LOGE("Failed for nullptr");
|
||||
return;
|
||||
}
|
||||
context->callbackRef = callbackRef_;
|
||||
context->callback = callback_;
|
||||
context->deferred = deferred_;
|
||||
context->errCode = result;
|
||||
context->credInfo = infoList;
|
||||
callbackRef_ = nullptr;
|
||||
auto task = [context = std::move(context)]() {
|
||||
ACCOUNT_LOGI("Enter NapiGetInfoCallback::OnCredentialInfo task");
|
||||
napi_handle_scope scope = nullptr;
|
||||
@ -590,17 +591,19 @@ void NapiGetInfoCallback::OnCredentialInfo(int32_t result, const std::vector<Acc
|
||||
return;
|
||||
}
|
||||
napi_env env = context->env;
|
||||
napi_value errJs = nullptr;
|
||||
napi_value dataJs = nullptr;
|
||||
CommonCallbackInfo callbackInfo(env);
|
||||
callbackInfo.callbackRef = context->callback->callbackRef;
|
||||
callbackInfo.deferred = context->deferred;
|
||||
callbackInfo.errCode = context->errCode;
|
||||
if (context->errCode != ERR_OK) {
|
||||
int32_t jsErrCode = AccountIAMConvertToJSErrCode(context->errCode);
|
||||
errJs = GenerateBusinessError(env, jsErrCode, ConvertToJsErrMsg(jsErrCode));
|
||||
napi_get_null(env, &dataJs);
|
||||
callbackInfo.errJs = GenerateBusinessError(env, jsErrCode, ConvertToJsErrMsg(jsErrCode));
|
||||
napi_get_null(env, &callbackInfo.dataJs);
|
||||
} else {
|
||||
napi_get_null(env, &errJs);
|
||||
dataJs = CreateCredInfoArray(env, context->credInfo);
|
||||
napi_get_null(env, &callbackInfo.errJs);
|
||||
callbackInfo.dataJs = CreateCredInfoArray(env, context->credInfo);
|
||||
}
|
||||
CallbackAsyncOrPromise(env, context.get(), errJs, dataJs);
|
||||
CallbackAsyncOrPromise(callbackInfo);
|
||||
napi_close_handle_scope(context->env, scope);
|
||||
return;
|
||||
};
|
||||
@ -660,17 +663,13 @@ void NapiGetEnrolledIdCallback::OnEnrolledId(int32_t result, uint64_t enrolledId
|
||||
|
||||
NapiGetPropCallback::NapiGetPropCallback(
|
||||
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()
|
||||
{
|
||||
if (callbackRef_ != nullptr) {
|
||||
ReleaseNapiRefAsync(env_, callbackRef_);
|
||||
callbackRef_ = nullptr;
|
||||
}
|
||||
deferred_ = nullptr;
|
||||
}
|
||||
{}
|
||||
|
||||
void NapiGetPropCallback::GetContextParams(
|
||||
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)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
if ((callbackRef_ == nullptr) && (deferred_ == nullptr)) {
|
||||
if ((callback_->callbackRef == nullptr) && (deferred_ == nullptr)) {
|
||||
return;
|
||||
}
|
||||
if (onResultCalled_) {
|
||||
ACCOUNT_LOGE("Call twice is not allowed");
|
||||
return;
|
||||
}
|
||||
onResultCalled_ = true;
|
||||
std::shared_ptr<GetPropertyContext> context = std::make_shared<GetPropertyContext>(env_);
|
||||
if (context == nullptr) {
|
||||
ACCOUNT_LOGE("Failed for nullptr");
|
||||
@ -736,12 +740,11 @@ void NapiGetPropCallback::OnResult(int32_t result, const UserIam::UserAuth::Attr
|
||||
}
|
||||
// create context data
|
||||
GetContextParams(extraInfo, *context);
|
||||
context->callbackRef = callbackRef_;
|
||||
context->callback = callback_;
|
||||
context->deferred = deferred_;
|
||||
context->errCode = ERR_OK;
|
||||
context->result = result;
|
||||
context->request = request_;
|
||||
callbackRef_ = nullptr;
|
||||
auto task = [context = std::move(context)]() {
|
||||
ACCOUNT_LOGI("Enter NapiGetPropCallback::OnResult task");
|
||||
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");
|
||||
return;
|
||||
}
|
||||
napi_value errJs = nullptr;
|
||||
napi_value dataJs = nullptr;
|
||||
CreateExecutorProperty(context->env, *context, errJs, dataJs);
|
||||
CallbackAsyncOrPromise(context->env, context.get(), errJs, dataJs);
|
||||
CommonCallbackInfo callbackInfo(context->env);
|
||||
callbackInfo.callbackRef = context->callback->callbackRef;
|
||||
callbackInfo.deferred = context->deferred;
|
||||
CreateExecutorProperty(context->env, *context, callbackInfo.errJs, callbackInfo.dataJs);
|
||||
callbackInfo.errCode = context->errCode;
|
||||
CallbackAsyncOrPromise(callbackInfo);
|
||||
napi_close_handle_scope(context->env, scope);
|
||||
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)
|
||||
: env_(env), callbackRef_(callbackRef), deferred_(deferred)
|
||||
{}
|
||||
: env_(env), deferred_(deferred)
|
||||
{
|
||||
callback_ = std::make_shared<NapiCallbackRef>(env, callbackRef);
|
||||
}
|
||||
|
||||
NapiSetPropCallback::~NapiSetPropCallback()
|
||||
{
|
||||
if (callbackRef_ != nullptr) {
|
||||
ReleaseNapiRefAsync(env_, callbackRef_);
|
||||
callbackRef_ = nullptr;
|
||||
}
|
||||
deferred_ = nullptr;
|
||||
}
|
||||
{}
|
||||
|
||||
NapiPrepareRemoteAuthCallback::NapiPrepareRemoteAuthCallback(napi_env env, napi_ref callbackRef, napi_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)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
if ((callbackRef_ == nullptr) && (deferred_ == nullptr)) {
|
||||
if ((callback_->callbackRef == nullptr) && (deferred_ == nullptr)) {
|
||||
return;
|
||||
}
|
||||
if (onResultCalled_) {
|
||||
ACCOUNT_LOGE("Call twice is not allowed");
|
||||
return;
|
||||
}
|
||||
onResultCalled_ = true;
|
||||
std::shared_ptr<SetPropertyContext> context = std::make_shared<SetPropertyContext>(env_);
|
||||
if (context == nullptr) {
|
||||
ACCOUNT_LOGE("Failed for nullptr");
|
||||
return;
|
||||
}
|
||||
context->callbackRef = callbackRef_;
|
||||
context->callback = callback_;
|
||||
context->deferred = deferred_;
|
||||
context->errCode = ERR_OK;
|
||||
context->result = result;
|
||||
callbackRef_ = nullptr;
|
||||
auto task = [context = std::move(context)]() {
|
||||
ACCOUNT_LOGI("Enter NapiSetPropCallback::OnResult task");
|
||||
napi_handle_scope scope = nullptr;
|
||||
@ -860,18 +865,19 @@ void NapiSetPropCallback::OnResult(int32_t result, const UserIam::UserAuth::Attr
|
||||
return;
|
||||
}
|
||||
napi_env env = context->env;
|
||||
napi_value errJs = nullptr;
|
||||
napi_value dataJs = nullptr;
|
||||
context->errCode = context->result;
|
||||
CommonCallbackInfo callbackInfo(env);
|
||||
callbackInfo.callbackRef = context->callback->callbackRef;
|
||||
callbackInfo.deferred = context->deferred;
|
||||
callbackInfo.errCode = context->result;
|
||||
if (context->result != ERR_OK) {
|
||||
int32_t jsErrCode = AccountIAMConvertToJSErrCode(context->result);
|
||||
errJs = GenerateBusinessError(env, jsErrCode, ConvertToJsErrMsg(jsErrCode));
|
||||
napi_get_null(env, &dataJs);
|
||||
callbackInfo.errJs = GenerateBusinessError(env, jsErrCode, ConvertToJsErrMsg(jsErrCode));
|
||||
napi_get_null(env, &callbackInfo.dataJs);
|
||||
} else {
|
||||
napi_get_null(env, &errJs);
|
||||
napi_get_null(env, &dataJs);
|
||||
napi_get_null(env, &callbackInfo.errJs);
|
||||
napi_get_null(env, &callbackInfo.dataJs);
|
||||
}
|
||||
CallbackAsyncOrPromise(env, context.get(), errJs, dataJs);
|
||||
CallbackAsyncOrPromise(callbackInfo);
|
||||
napi_close_handle_scope(env, scope);
|
||||
return;
|
||||
};
|
||||
@ -1038,19 +1044,30 @@ void NapiGetDataCallback::OnGetData(int32_t authSubType, std::vector<uint8_t> ch
|
||||
}
|
||||
#endif // HAS_PIN_AUTH_PART
|
||||
|
||||
void CallbackAsyncOrPromise(const CommonCallbackInfo &callbackInfo)
|
||||
{
|
||||
if (callbackInfo.callbackRef) {
|
||||
napi_value argv[ARG_SIZE_TWO] = {callbackInfo.errJs, callbackInfo.dataJs};
|
||||
ACCOUNT_LOGI("call js function");
|
||||
NapiCallVoidFunction(callbackInfo.env, argv, ARG_SIZE_TWO, callbackInfo.callbackRef);
|
||||
} else {
|
||||
if (callbackInfo.errCode == ERR_OK) {
|
||||
napi_resolve_deferred(callbackInfo.env, callbackInfo.deferred, callbackInfo.dataJs);
|
||||
} else {
|
||||
napi_reject_deferred(callbackInfo.env, callbackInfo.deferred, callbackInfo.errJs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CallbackAsyncOrPromise(napi_env env, CommonAsyncContext *context, napi_value errJs, napi_value dataJs)
|
||||
{
|
||||
if (context->callbackRef) {
|
||||
napi_value argv[ARG_SIZE_TWO] = {errJs, dataJs};
|
||||
ACCOUNT_LOGI("call js function");
|
||||
NapiCallVoidFunction(env, argv, ARG_SIZE_TWO, context->callbackRef);
|
||||
} else {
|
||||
if (context->errCode == ERR_OK) {
|
||||
napi_resolve_deferred(env, context->deferred, dataJs);
|
||||
} else {
|
||||
napi_reject_deferred(env, context->deferred, errJs);
|
||||
}
|
||||
}
|
||||
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)
|
||||
|
@ -546,7 +546,11 @@ void ReleaseNapiRefArray(napi_env env, const std::vector<napi_ref> &napiRefVec)
|
||||
|
||||
NapiCallbackRef::~NapiCallbackRef()
|
||||
{
|
||||
if (callbackRef == nullptr) {
|
||||
return;
|
||||
}
|
||||
ReleaseNapiRefArray(env, {callbackRef});
|
||||
callbackRef = nullptr;
|
||||
}
|
||||
|
||||
bool InitUvWorkCallbackEnv(uv_work_t *work, napi_handle_scope &scope)
|
||||
|
Loading…
Reference in New Issue
Block a user