From 555a4cb0b217cf105372b344c723bd714fca9c41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E8=9C=9C?= Date: Wed, 23 Apr 2025 10:09:08 +0800 Subject: [PATCH] =?UTF-8?q?arkts=E9=9D=99=E6=80=81=E5=8C=960423?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 李蜜 --- .../src/ohos.userIAM.userAccessCtrl.impl.cpp | 2 +- frameworks/ets/ani/user_auth/BUILD.gn | 88 +++- .../user_auth/idl/ohos.userIAM.userAuth.taihe | 22 +- .../idl/ohos.userIAM.userAuth.userAuth.taihe | 130 ++++++ .../ets/ani/user_auth/inc/auth_common.h | 103 +++++ .../user_auth/inc/modal_extension_callback.h | 58 +++ .../ani/user_auth/inc/user_auth_ani_helper.h | 49 +++ .../user_auth/inc/user_auth_callback_v10.h | 57 +++ .../user_auth/inc/user_auth_instance_v10.h | 78 ++++ .../user_auth/inc/user_auth_modal_callback.h | 53 +++ .../inc/user_auth_widget_callback_v10.h | 54 +++ .../user_auth/inc/user_auth_widget_mgr_v10.h | 52 +++ .../ets/ani/user_auth/src/ani_constructor.cpp | 36 ++ .../src/modal_extension_callback.cpp | 142 ++++++ .../ohos.userIAM.userAuth.userAuth.impl.cpp | 195 +++++++++ .../user_auth/src/user_auth_ani_helper.cpp | 171 ++++++++ .../user_auth/src/user_auth_callback_v10.cpp | 107 +++++ .../user_auth/src/user_auth_instance_v10.cpp | 412 ++++++++++++++++++ .../src/user_auth_modal_callback.cpp | 195 +++++++++ .../src/user_auth_widget_callback_v10.cpp | 59 +++ .../src/user_auth_widget_mgr_v10.cpp | 101 +++++ 21 files changed, 2133 insertions(+), 31 deletions(-) create mode 100644 frameworks/ets/ani/user_auth/idl/ohos.userIAM.userAuth.userAuth.taihe create mode 100644 frameworks/ets/ani/user_auth/inc/auth_common.h create mode 100644 frameworks/ets/ani/user_auth/inc/modal_extension_callback.h create mode 100644 frameworks/ets/ani/user_auth/inc/user_auth_ani_helper.h create mode 100644 frameworks/ets/ani/user_auth/inc/user_auth_callback_v10.h create mode 100644 frameworks/ets/ani/user_auth/inc/user_auth_instance_v10.h create mode 100644 frameworks/ets/ani/user_auth/inc/user_auth_modal_callback.h create mode 100644 frameworks/ets/ani/user_auth/inc/user_auth_widget_callback_v10.h create mode 100644 frameworks/ets/ani/user_auth/inc/user_auth_widget_mgr_v10.h create mode 100644 frameworks/ets/ani/user_auth/src/ani_constructor.cpp create mode 100644 frameworks/ets/ani/user_auth/src/modal_extension_callback.cpp create mode 100644 frameworks/ets/ani/user_auth/src/ohos.userIAM.userAuth.userAuth.impl.cpp create mode 100644 frameworks/ets/ani/user_auth/src/user_auth_ani_helper.cpp create mode 100644 frameworks/ets/ani/user_auth/src/user_auth_callback_v10.cpp create mode 100644 frameworks/ets/ani/user_auth/src/user_auth_instance_v10.cpp create mode 100644 frameworks/ets/ani/user_auth/src/user_auth_modal_callback.cpp create mode 100644 frameworks/ets/ani/user_auth/src/user_auth_widget_callback_v10.cpp create mode 100644 frameworks/ets/ani/user_auth/src/user_auth_widget_mgr_v10.cpp diff --git a/frameworks/ets/ani/user_access_ctrl/src/ohos.userIAM.userAccessCtrl.impl.cpp b/frameworks/ets/ani/user_access_ctrl/src/ohos.userIAM.userAccessCtrl.impl.cpp index 27cd7c522..221bfd145 100644 --- a/frameworks/ets/ani/user_access_ctrl/src/ohos.userIAM.userAccessCtrl.impl.cpp +++ b/frameworks/ets/ani/user_access_ctrl/src/ohos.userIAM.userAccessCtrl.impl.cpp @@ -32,7 +32,7 @@ #define LOG_TAG "USER_ACCESS_CTRL_ANI" namespace userAccessCtrl = ohos::userIAM::userAccessCtrl; -namespace userAuth = ohos::userIAM::userAuth; +namespace userAuth = ohos::userIAM::userAuth::userAuth; namespace UserAuth = OHOS::UserIam::UserAuth; using namespace taihe; using namespace OHOS::UserIam::Common; diff --git a/frameworks/ets/ani/user_auth/BUILD.gn b/frameworks/ets/ani/user_auth/BUILD.gn index b6119d04b..0c381e9cf 100644 --- a/frameworks/ets/ani/user_auth/BUILD.gn +++ b/frameworks/ets/ani/user_auth/BUILD.gn @@ -17,38 +17,98 @@ import("//build/ohos/taihe_idl/taihe.gni") import("../../../../user_auth_framework.gni") copy_taihe_idl("user_auth_copy_taihe_idl") { - sources = [ "idl/ohos.userIAM.userAuth.taihe" ] + sources = [ + "idl/ohos.userIAM.userAuth.taihe", + "idl/ohos.userIAM.userAuth.userAuth.taihe", + ] } -taihe_generated_file_path = - "$taihe_file_path/out/useriam/user_auth_frameworks/user_auth" +subsystem_name = "useriam" +part_name = "user_auth_framework" +taihe_generated_file_path = "$taihe_file_path/out/$subsystem_name/$part_name" + ohos_taihe("user_auth_taihe") { taihe_generated_file_path = "$taihe_generated_file_path" deps = [ ":user_auth_copy_taihe_idl" ] outputs = [ - "$taihe_generated_file_path/src/ohos.userIAM.userAuth.ani.cpp", - "$taihe_generated_file_path/src/ohos.userIAM.userAuth.abi.c", + "$taihe_generated_file_path/src/ohos.userIAM.userAuth.userAuth.ani.cpp", + "$taihe_generated_file_path/src/ohos.userIAM.userAuth.userAuth.abi.c", ] } -generate_static_abc("user_auth_abc") { +taihe_shared_library("userauth_ani") { + include_dirs = [ "inc" ] + sources = get_target_outputs(":user_auth_taihe") + sources += [ + "src/ani_constructor.cpp", + "src/modal_extension_callback.cpp", + "src/ohos.userIAM.userAuth.userAuth.impl.cpp", + "src/user_auth_ani_helper.cpp", + "src/user_auth_callback_v10.cpp", + "src/user_auth_instance_v10.cpp", + "src/user_auth_modal_callback.cpp", + "src/user_auth_widget_callback_v10.cpp", + "src/user_auth_widget_mgr_v10.cpp", + ] + external_deps = [ + "ability_base:want", + "ability_base:want", + "ability_runtime:ability_context_native", + "ability_runtime:ability_manager", + "ability_runtime:abilitykit_native", + "ability_runtime:ani_base_context", + "ability_runtime:app_context", + "ability_runtime:ui_extension", + "ace_engine:ace_uicontent", + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_single", + "runtime_core:ani", + ] + + sanitize = { + integer_overflow = true + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + } + + configs = [ + "../../../../common:iam_log_config", + "../../../../common:iam_utils_config", + ] + + deps = [ + ":user_auth_taihe", + "../../../native/client:userauth_client", + ] + remove_configs = [ "//build/config/compiler:no_exceptions" ] + taihe_generated_file_path = "$taihe_generated_file_path" + output_extension = "so" + part_name = "$part_name" + subsystem_name = "$subsystem_name" +} + +generate_static_abc("user_auth") { base_url = "$taihe_generated_file_path" files = [ "$taihe_generated_file_path/@ohos.userIAM.userAuth.ets" ] is_boot_abc = "True" - device_dst_file = "system/framework/ohos.userIAM.userAuth.abc" - dst_file = "$target_out_dir/ohos.userIAM.userAuth.abc" - out_puts = [ "$target_out_dir/ohos.userIAM.userAuth.abc" ] + device_dst_file = "system/framework/user_auth.abc" dependencies = [ ":user_auth_taihe" ] } ohos_prebuilt_etc("user_auth_abc_etc") { - source = "$target_out_dir/ohos.userIAM.userAuth.abc" + source = "$target_out_dir/user_auth.abc" module_install_dir = "framework" - deps = [ ":user_auth_abc" ] - part_name = "user_auth_framework" - subsystem_name = "useriam" + deps = [ ":user_auth" ] + part_name = "$part_name" + subsystem_name = "$subsystem_name" } group("user_auth_ani") { - deps = [ ":user_auth_abc_etc" ] + deps = [ + ":user_auth_abc_etc", + ":userauth_ani", + ] } diff --git a/frameworks/ets/ani/user_auth/idl/ohos.userIAM.userAuth.taihe b/frameworks/ets/ani/user_auth/idl/ohos.userIAM.userAuth.taihe index a93ab6a90..000e3ab7c 100644 --- a/frameworks/ets/ani/user_auth/idl/ohos.userIAM.userAuth.taihe +++ b/frameworks/ets/ani/user_auth/idl/ohos.userIAM.userAuth.taihe @@ -12,19 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -@!namespace("@ohos.userIAM.userAuth", "userAuth") - -enum UserAuthType : i32 { - PIN = 1, - FACE = 2, - FINGERPRINT = 4, - PRIVATE_PIN = 16 -} - -enum AuthTrustLevel : i32 { - ATL1 = 10000, - ATL2 = 20000, - ATL3 = 30000, - ATL4 = 40000 -} \ No newline at end of file + +@!namespace("@ohos.userIAM.userAuth") + +@!sts_inject(""" +import Context from 'application.Context'; +""") diff --git a/frameworks/ets/ani/user_auth/idl/ohos.userIAM.userAuth.userAuth.taihe b/frameworks/ets/ani/user_auth/idl/ohos.userIAM.userAuth.userAuth.taihe new file mode 100644 index 000000000..da58d82d1 --- /dev/null +++ b/frameworks/ets/ani/user_auth/idl/ohos.userIAM.userAuth.userAuth.taihe @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@!namespace("@ohos.userIAM.userAuth", "userAuth") + +@!sts_inject(""" +static { loadLibrary("userauth_ani.z"); } +const MAX_ALLOWABLE_REUSE_DURATION : int = 300000; +""") + +enum UserAuthType : i32 { + PIN = 1, + FACE = 2, + FINGERPRINT = 4, + PRIVATE_PIN = 16 +} + +enum AuthTrustLevel : i32 { + ATL1 = 10000, + ATL2 = 20000, + ATL3 = 30000, + ATL4 = 40000 +} + +enum WindowModeType : i32 { + DIALOG_BOX = 1, + FULLSCREEN = 2 +} + +enum ReuseMode : i32 { + AUTH_TYPE_RELEVANT = 1, + AUTH_TYPE_IRRELEVANT = 2, + CALLER_IRRELEVANT_AUTH_TYPE_RELEVANT = 3, + CALLER_IRRELEVANT_AUTH_TYPE_IRRELEVANT = 4 +} + +enum NoticeType : i32 { + WIDGET_NOTICE = 1 +} + +enum UserAuthResultCode : i32 { + SUCCESS = 12500000, + FAIL = 12500001, + GENERAL_ERROR = 12500002, + CANCELED = 12500003, + TIMEOUT = 12500004, + TYPE_NOT_SUPPORT = 12500005, + TRUST_LEVEL_NOT_SUPPORT = 12500006, + BUSY = 12500007, + LOCKED = 12500009, + NOT_ENROLLED = 12500010, + CANCELED_FROM_WIDGET = 12500011, + PIN_EXPIRED = 12500013, + AUTH_TOKEN_CHECK_FAILED = 12500015, + AUTH_TOKEN_EXPIRED = 12500016 +} + +struct EnrolledState { + credentialDigest: f64; + credentialCount: f64; +} + +struct ReuseUnlockResult { + reuseMode: ReuseMode; + reuseDuration: f64; +} + +struct AuthParam { + challenge: @typedarray Array; + authType: Array; + authTrustLevel: AuthTrustLevel; + reuseUnlockResult: Optional; + userId: Optional; +} + +struct WidgetParam { + title: String; + navigationButtonText: Optional; + windowMode: Optional; + uiContext: Optional<@sts_type("Context") Opaque>; +} + +struct UserAuthResult { + result: f64; + token: Optional<@typedarray Array>; + authType: Optional; + enrolledState: Optional; +} + +struct IAuthCallback { + onResult: (result: UserAuthResult) => void; +} + +struct IAuthWidgetCallback { + sendCommand: (cmdData: String) => void; +} + +interface UserAuthInstance { + on(type: String, callback: IAuthCallback): void; + off(type: String, callback: Optional): void; + start(): void; + cancel(): void; +} + +interface UserAuthWidgetMgr { + on(type: String, callback: IAuthWidgetCallback): void; + off(type: String, callback: Optional): void; +} + +function GetAvailableStatus(authType: UserAuthType, authTrustLevel: AuthTrustLevel): void; + +function GetEnrolledState(authType: UserAuthType): EnrolledState; + +function GetUserAuthInstance(authParam: AuthParam, widgetParam: WidgetParam): UserAuthInstance; + +function SendNotice(noticeType: NoticeType, eventData: String): void; + +function GetUserAuthWidgetMgr(version: f64): UserAuthWidgetMgr; diff --git a/frameworks/ets/ani/user_auth/inc/auth_common.h b/frameworks/ets/ani/user_auth/inc/auth_common.h new file mode 100644 index 000000000..c6f904fae --- /dev/null +++ b/frameworks/ets/ani/user_auth/inc/auth_common.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #ifndef OHOS_USERAUTH_COMMON_H + #define OHOS_USERAUTH_COMMON_H + + #include + #include + + #include "iam_common_defines.h" + + namespace OHOS { + namespace UserIam { + namespace UserAuth { + constexpr int32_t API_VERSION_9 = 9; + constexpr int32_t API_VERSION_10 = 10; + constexpr int32_t API_VERSION_12 = 12; + + constexpr const char *NOTICE_EVENT_AUTH_READY = "EVENT_AUTH_TYPE_READY"; + constexpr const char *NOTICE_EVENT_CANCEL_AUTH = "EVENT_AUTH_USER_CANCEL"; + constexpr const char *NOTICE_EVENT_USER_NAVIGATION = "EVENT_AUTH_USER_NAVIGATION"; + constexpr const char *NOTICE_EVENT_WIDGET_PARA_INVALID = "EVENT_AUTH_WIDGET_PARA_INVALID"; + constexpr const char *NOTICE_EVENT_END = "EVENT_AUTH_END"; + constexpr const char *NOTICE_EVENT_RELOAD = "EVENT_AUTH_RELOAD"; + + // For API6 + enum class AuthenticationResult : int32_t { + NO_SUPPORT = -1, + SUCCESS = 0, + COMPARE_FAILURE = 1, + CANCELED = 2, + TIMEOUT = 3, + CAMERA_FAIL = 4, + BUSY = 5, + INVALID_PARAMETERS = 6, + LOCKED = 7, + NOT_ENROLLED = 8, + GENERAL_ERROR = 100, + }; + + enum class UserAuthResultCode : int32_t { + OHOS_CHECK_PERMISSION_FAILED = 201, + OHOS_CHECK_SYSTEM_APP_FAILED = 202, + OHOS_INVALID_PARAM = 401, + RESULT_CODE_V9_MIN = 12500000, + RESULT_CODE_V10_MIN = 12500000, + SUCCESS = 12500000, + FAIL = 12500001, + GENERAL_ERROR = 12500002, + CANCELED = 12500003, + TIMEOUT = 12500004, + TYPE_NOT_SUPPORT = 12500005, + TRUST_LEVEL_NOT_SUPPORT = 12500006, + BUSY = 12500007, + LOCKED = 12500009, + NOT_ENROLLED = 12500010, + RESULT_CODE_V9_MAX = 12500010, + CANCELED_FROM_WIDGET = 12500011, + PIN_EXPIRED = 12500013, + RESULT_CODE_V10_MAX = 12500013, + }; + + enum FaceTipsCode { + FACE_AUTH_TIP_TOO_BRIGHT = 1, + FACE_AUTH_TIP_TOO_DARK = 2, + FACE_AUTH_TIP_TOO_CLOSE = 3, + FACE_AUTH_TIP_TOO_FAR = 4, + FACE_AUTH_TIP_TOO_HIGH = 5, + FACE_AUTH_TIP_TOO_LOW = 6, + FACE_AUTH_TIP_TOO_RIGHT = 7, + FACE_AUTH_TIP_TOO_LEFT = 8, + FACE_AUTH_TIP_TOO_MUCH_MOTION = 9, + FACE_AUTH_TIP_POOR_GAZE = 10, + FACE_AUTH_TIP_NOT_DETECTED = 11, + FACE_AUTH_TIP_MAX = FACE_AUTH_TIP_NOT_DETECTED, + }; + + enum FingerprintTips { + FINGERPRINT_AUTH_TIP_GOOD = 0, + FINGERPRINT_AUTH_TIP_IMAGER_DIRTY = 1, + FINGERPRINT_AUTH_TIP_INSUFFICIENT = 2, + FINGERPRINT_AUTH_TIP_PARTIAL = 3, + FINGERPRINT_AUTH_TIP_TOO_FAST = 4, + FINGERPRINT_AUTH_TIP_TOO_SLOW = 5, + FINGERPRINT_AUTH_TIP_MAX = FINGERPRINT_AUTH_TIP_TOO_SLOW, + }; + } // namespace UserAuth + } // namespace UserIam + } // namespace OHOS + #endif /* OHOS_USERAUTH_COMMON_H */ + \ No newline at end of file diff --git a/frameworks/ets/ani/user_auth/inc/modal_extension_callback.h b/frameworks/ets/ani/user_auth/inc/modal_extension_callback.h new file mode 100644 index 000000000..f50ab5f68 --- /dev/null +++ b/frameworks/ets/ani/user_auth/inc/modal_extension_callback.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #ifndef MODAL_EXTENSION_CALLBACK_H + #define MODAL_EXTENSION_CALLBACK_H + + #include + + #include "ui_content.h" + #include "ui_extension_context.h" + + namespace OHOS { + namespace UserIam { + namespace UserAuth { + class ModalExtensionCallback { + public: + ModalExtensionCallback(); + ~ModalExtensionCallback(); + void OnRelease(int32_t code); + void OnResult(int32_t code, const OHOS::AAFwk::Want &result); + void OnReceive(const OHOS::AAFwk::WantParams &request); + void OnError(int32_t code, const std::string &name, const std::string &message); + void OnRemoteReady(const std::shared_ptr &uiProxy); + void OnDestroy(); + void SetSessionId(int32_t sessionId); + void SetContextId(uint64_t contextId); + void SetAbilityContext(std::shared_ptr abilityContext); + void SetHolderContext(std::shared_ptr uiHolderContext); + void ReleaseOrErrorHandle(int32_t code); + bool IsModalDestroy(); + + private: + void CancelAuthentication(); + + int32_t sessionId_ = 0; + uint64_t contextId_ = 0; + std::shared_ptr abilityContext_; + std::shared_ptr uiHolderContext_; + bool isDestroy_{false}; + std::recursive_mutex mutex_; + }; + } // namespace UserAuth + } // namespace UserIam + } // namespace OHOS + #endif // MODAL_EXTENSION_CALLBACK_H + \ No newline at end of file diff --git a/frameworks/ets/ani/user_auth/inc/user_auth_ani_helper.h b/frameworks/ets/ani/user_auth/inc/user_auth_ani_helper.h new file mode 100644 index 000000000..c63bebc09 --- /dev/null +++ b/frameworks/ets/ani/user_auth/inc/user_auth_ani_helper.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #ifndef USER_AUTH_ANI_HELPER + #define USER_AUTH_ANI_HELPER + + #include + + #include "nocopyable.h" + #include "ohos.userIAM.userAuth.userAuth.proj.hpp" + + #include "auth_common.h" + #include "user_auth_client_defines.h" + + namespace userAuth = ohos::userIAM::userAuth::userAuth; + + namespace OHOS { + namespace UserIam { + namespace UserAuth { + class UserAuthAniHelper { + public: + static bool CheckUserAuthType(userAuth::UserAuthType authType); + static bool CheckReuseUnlockResult(ReuseUnlockResult reuseUnlockResult); + static UserAuthResultCode ThrowBusinessError(UserAuthResultCode error, std::string message); + static int32_t GetResultCodeV10(int32_t result); + static bool VerifyNoticeParam(const std::string &eventData); + static bool ConvertUserAuthType(int32_t userAuthType, userAuth::UserAuthType &userAuthTypeOut); + + private: + UserAuthAniHelper() = default; + ~UserAuthAniHelper() = default; + }; + } // namespace UserAuth + } // namespace UserIam + } // namespace OHOS + #endif // USER_AUTH_ANI_HELPER + \ No newline at end of file diff --git a/frameworks/ets/ani/user_auth/inc/user_auth_callback_v10.h b/frameworks/ets/ani/user_auth/inc/user_auth_callback_v10.h new file mode 100644 index 000000000..deaef0f71 --- /dev/null +++ b/frameworks/ets/ani/user_auth/inc/user_auth_callback_v10.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #ifndef USER_AUTH_CALLBACK_V10_H + #define USER_AUTH_CALLBACK_V10_H + + #include + + #include "nocopyable.h" + #include "ohos.userIAM.userAuth.userAuth.proj.hpp" + + #include "iam_ptr.h" + #include "auth_common.h" + #include "iam_common_defines.h" + #include "user_auth_ani_helper.h" + #include "user_auth_client.h" + #include "user_auth_common_defines.h" + + namespace userAuth = ohos::userIAM::userAuth::userAuth; + + namespace OHOS { + namespace UserIam { + namespace UserAuth { + class UserAuthCallbackV10 : public AuthenticationCallback, + public std::enable_shared_from_this, + public NoCopyable { + public: + explicit UserAuthCallbackV10(); + ~UserAuthCallbackV10() override; + void OnAcquireInfo(int32_t module, uint32_t acquireInfo, const Attributes &extraInfo) override; + void OnResult(int32_t result, const Attributes &extraInfo) override; + void SetResultCallback(const userAuth::IAuthCallback &resultCallback); + void ClearResultCallback(); + bool HasResultCallback(); + + private: + bool DoResultCallback( + int32_t result, const std::vector &token, int32_t authType, EnrolledState enrolledState); + std::mutex mutex_; + std::shared_ptr resultCallback_ = nullptr; + }; + } // namespace UserAuth + } // namespace UserIam + } // namespace OHOS + #endif // USER_AUTH_CALLBACK_V10_H diff --git a/frameworks/ets/ani/user_auth/inc/user_auth_instance_v10.h b/frameworks/ets/ani/user_auth/inc/user_auth_instance_v10.h new file mode 100644 index 000000000..baeb16c19 --- /dev/null +++ b/frameworks/ets/ani/user_auth/inc/user_auth_instance_v10.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #ifndef USER_AUTH_INSTANCE_V10_H + #define USER_AUTH_INSTANCE_V10_H + + #include + + #include "ability.h" + #include "nocopyable.h" + + #include "iam_ptr.h" + #include "auth_common.h" + #include "user_auth_client_defines.h" + #include "user_auth_callback_v10.h" + #include "user_auth_napi_client_impl.h" + #include "user_auth_modal_callback.h" + + #include "ohos.userIAM.userAuth.userAuth.proj.hpp" + + namespace userAuth = ohos::userIAM::userAuth::userAuth; + + namespace OHOS { + namespace UserIam { + namespace UserAuth { + class UserAuthInstanceV10 : public NoCopyable { + public: + explicit UserAuthInstanceV10(); + ~UserAuthInstanceV10() = default; + + UserAuthResultCode Init(userAuth::AuthParam const &authParam, userAuth::WidgetParam const &widgetParam); + UserAuthResultCode On(std::string type, userAuth::IAuthCallback const &callback); + UserAuthResultCode Off(std::string type, taihe::optional_view callback); + UserAuthResultCode Start(); + UserAuthResultCode Cancel(); + + private: + UserAuthResultCode InitAuthParam(userAuth::AuthParam const &authParam); + UserAuthResultCode InitWidgetParam(userAuth::WidgetParam const &widgetParam); + UserAuthResultCode InitChallenge(userAuth::AuthParam const &authParam); + UserAuthResultCode InitAuthType(userAuth::AuthParam const &authParam); + UserAuthResultCode InitAuthTrustLevel(userAuth::AuthParam const &authParam); + UserAuthResultCode InitReuseUnlockResult(userAuth::AuthParam const &authParam); + UserAuthResultCode InitUserId(userAuth::AuthParam const &authParam); + UserAuthResultCode InitTitle(userAuth::WidgetParam const &widgetParam); + UserAuthResultCode InitNavigationButtonText(userAuth::WidgetParam const &widgetParam); + UserAuthResultCode InitWindowMode(userAuth::WidgetParam const &widgetParam); + UserAuthResultCode InitContext(userAuth::WidgetParam const &widgetParam); + bool CheckUIContext(const std::shared_ptr context); + + uint64_t contextId_ = 0; + bool isAuthStarted_ = false; + + AuthParamInner authParam_ = {}; + UserAuthNapiClientImpl::WidgetParamNapi widgetParam_ = {}; + + std::mutex mutex_; + std::shared_ptr callback_ = nullptr; + std::shared_ptr modalCallback_ = nullptr; + std::shared_ptr context_ = nullptr; + }; + } // namespace UserAuth + } // namespace UserIam + } // namespace OHOS + #endif // USER_AUTH_INSTANCE_V10_H + \ No newline at end of file diff --git a/frameworks/ets/ani/user_auth/inc/user_auth_modal_callback.h b/frameworks/ets/ani/user_auth/inc/user_auth_modal_callback.h new file mode 100644 index 000000000..cb9284eb2 --- /dev/null +++ b/frameworks/ets/ani/user_auth/inc/user_auth_modal_callback.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #ifndef USER_AUTH_MODAL_CALLBACK_H + #define USER_AUTH_MODAL_CALLBACK_H + + #include + + #include "modal_extension_callback.h" + #include "user_auth_modal_client_callback.h" + + namespace OHOS { + namespace UserIam { + namespace UserAuth { + class UserAuthModalCallback : public UserAuthModalClientCallback { + public: + explicit UserAuthModalCallback(const std::shared_ptr context); + ~UserAuthModalCallback(); + void SendCommand(uint64_t contextId, const std::string &cmdData) override; + bool IsModalInit() override; + bool IsModalDestroy() override; + + private: + void CancelAuthentication(uint64_t contextId, int32_t cancelReason) override; + Ace::UIContent *InitAndGetUIContent(const std::shared_ptr context); + bool CreateUIExtension( + const std::shared_ptr context, uint64_t contextId, const std::string &cmdData); + void ReleaseModal(); + + std::shared_ptr context_{nullptr}; + std::shared_ptr uiExtCallback_{nullptr}; + uint64_t contextId_{0}; + bool isInit_{false}; + bool isInitError_{false}; + std::recursive_mutex mutex_; + }; + } // namespace UserAuth + } // namespace UserIam + } // namespace OHOS + #endif // USER_AUTH_MODAL_CALLBACK_H + \ No newline at end of file diff --git a/frameworks/ets/ani/user_auth/inc/user_auth_widget_callback_v10.h b/frameworks/ets/ani/user_auth/inc/user_auth_widget_callback_v10.h new file mode 100644 index 000000000..a8015bf19 --- /dev/null +++ b/frameworks/ets/ani/user_auth/inc/user_auth_widget_callback_v10.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #ifndef USER_AUTH_WIDGET_CALLBACK_V10_H + #define USER_AUTH_WIDGET_CALLBACK_V10_H + + #include + + #include "nocopyable.h" + #include "ohos.userIAM.userAuth.userAuth.proj.hpp" + + #include "iam_common_defines.h" + #include "auth_common.h" + #include "iuser_auth_widget_callback.h" + #include "user_auth_ani_helper.h" + #include "user_auth_common_defines.h" + + namespace userAuth = ohos::userIAM::userAuth::userAuth; + + namespace OHOS { + namespace UserIam { + namespace UserAuth { + class UserAuthWidgetCallback : public IUserAuthWidgetCallback, + public std::enable_shared_from_this, + public NoCopyable { + public: + explicit UserAuthWidgetCallback(); + ~UserAuthWidgetCallback() override; + void SendCommand(const std::string &cmdData) override; + void SetCommandCallback(userAuth::IAuthWidgetCallback const &callback); + void ClearCommandCallback(); + bool HasCommandCallback(); + + private: + std::mutex mutex_; + std::shared_ptr commandCallback_ = nullptr; + }; + } // namespace UserAuth + } // namespace UserIam + } // namespace OHOS + #endif // USER_AUTH_WIDGET_CALLBACK_V10_H + \ No newline at end of file diff --git a/frameworks/ets/ani/user_auth/inc/user_auth_widget_mgr_v10.h b/frameworks/ets/ani/user_auth/inc/user_auth_widget_mgr_v10.h new file mode 100644 index 000000000..5f5cfb324 --- /dev/null +++ b/frameworks/ets/ani/user_auth/inc/user_auth_widget_mgr_v10.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #ifndef USER_AUTH_WIDGET_MGR_V10 + #define USER_AUTH_WIDGET_MGR_V10 + + #include + + #include "nocopyable.h" + + #include "iam_common_defines.h" + #include "auth_common.h" + #include "user_auth_ani_helper.h" + #include "user_auth_client.h" + #include "user_auth_common_defines.h" + #include "user_auth_widget_callback_v10.h" + + namespace userAuth = ohos::userIAM::userAuth::userAuth; + + namespace OHOS { + namespace UserIam { + namespace UserAuth { + class UserAuthWidgetMgr : public NoCopyable { + public: + explicit UserAuthWidgetMgr(); + ~UserAuthWidgetMgr() = default; + + UserAuthResultCode Init(int32_t version); + UserAuthResultCode On(std::string type, userAuth::IAuthWidgetCallback const &callback); + UserAuthResultCode Off(std::string type, taihe::optional_view callback); + + private: + int32_t version_ = 1; + std::shared_ptr callback_ = nullptr; + }; + } // namespace UserAuth + } // namespace UserIam + } // namespace OHOS + #endif // USER_AUTH_WIDGET_MGR_V10 + \ No newline at end of file diff --git a/frameworks/ets/ani/user_auth/src/ani_constructor.cpp b/frameworks/ets/ani/user_auth/src/ani_constructor.cpp new file mode 100644 index 000000000..21cdc8b8e --- /dev/null +++ b/frameworks/ets/ani/user_auth/src/ani_constructor.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #include "ohos.userIAM.userAuth.userAuth.ani.hpp" + + #include "iam_logger.h" + + #define LOG_TAG "USER_AUTH_ANI" + + ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) { + IAM_LOGI("ANI_Constructor begin"); + ani_env *env; + if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) { + return ANI_ERROR; + } + if (ANI_OK != ohos::userIAM::userAuth::userAuth::ANIRegister(env)) { + IAM_LOGE("Error from ohos::userIAM::userAuth::userAuth::ANIRegister"); + return ANI_ERROR; + } + *result = ANI_VERSION_1; + IAM_LOGI("ANI_Constructor end"); + return ANI_OK; + } + \ No newline at end of file diff --git a/frameworks/ets/ani/user_auth/src/modal_extension_callback.cpp b/frameworks/ets/ani/user_auth/src/modal_extension_callback.cpp new file mode 100644 index 000000000..b6809ebf7 --- /dev/null +++ b/frameworks/ets/ani/user_auth/src/modal_extension_callback.cpp @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #include "modal_extension_callback.h" + + #include "ability.h" + #include "system_ability_definition.h" + #include "ui_holder_extension_context.h" + + #include "iam_logger.h" + #include "iam_ptr.h" + #include "user_auth_napi_client_impl.h" + + #define LOG_TAG "USER_AUTH_ANI" + + namespace OHOS { + namespace UserIam { + namespace UserAuth { + ModalExtensionCallback::ModalExtensionCallback() + {} + + ModalExtensionCallback::~ModalExtensionCallback() + {} + + void ModalExtensionCallback::OnResult(int32_t code, const AAFwk::Want &result) + { + IAM_LOGI("OnResult, code: %{public}d", code); + } + + void ModalExtensionCallback::OnReceive(const AAFwk::WantParams &receive) + { + IAM_LOGI("OnReceive"); + } + + void ModalExtensionCallback::OnRelease(int32_t code) + { + IAM_LOGI("OnRelease, code: %{public}d", code); + std::lock_guard lock(mutex_); + if (code != 0) { + CancelAuthentication(); + } + ReleaseOrErrorHandle(code); + } + + void ModalExtensionCallback::OnError(int32_t code, const std::string &name, const std::string &message) + { + IAM_LOGE("OnError, name: %{public}s, message: %{public}s", name.c_str(), message.c_str()); + std::lock_guard lock(mutex_); + CancelAuthentication(); + ReleaseOrErrorHandle(code); + } + + void ModalExtensionCallback::OnRemoteReady(const std::shared_ptr &uiProxy) + { + IAM_LOGI("OnRemoteReady"); + } + + void ModalExtensionCallback::OnDestroy() + { + IAM_LOGI("OnDestroy"); + std::lock_guard lock(mutex_); + isDestroy_ = true; + } + + void ModalExtensionCallback::SetSessionId(int32_t sessionId) + { + std::lock_guard lock(mutex_); + sessionId_ = sessionId; + } + + void ModalExtensionCallback::SetContextId(uint64_t contextId) + { + std::lock_guard lock(mutex_); + contextId_ = contextId; + } + + void ModalExtensionCallback::SetAbilityContext(std::shared_ptr abilityContext) + { + std::lock_guard lock(mutex_); + abilityContext_ = abilityContext; + } + + void ModalExtensionCallback::SetHolderContext( + std::shared_ptr uiHolderContext) + { + std::lock_guard lock(mutex_); + uiHolderContext_ = uiHolderContext; + } + + void ModalExtensionCallback::ReleaseOrErrorHandle(int32_t code) + { + IAM_LOGI("ReleaseOrErrorHandle start, code: %{public}d", code); + std::lock_guard lock(mutex_); + if (abilityContext_ != nullptr) { + Ace::UIContent *uiContent = abilityContext_->GetUIContent(); + if (uiContent == nullptr) { + IAM_LOGE("uiContent is null"); + return; + } + uiContent->CloseModalUIExtension(sessionId_); + } + if (uiHolderContext_ != nullptr) { + Ace::UIContent *uiContent = uiHolderContext_->GetUIContent(); + if (uiContent == nullptr) { + IAM_LOGE("uiContent is null"); + return; + } + uiContent->CloseModalUIExtension(sessionId_); + } + IAM_LOGI("ReleaseOrErrorHandle end"); + isDestroy_ = true; + return; + } + + bool ModalExtensionCallback::IsModalDestroy() + { + std::lock_guard lock(mutex_); + return isDestroy_; + } + + void ModalExtensionCallback::CancelAuthentication() + { + // cancel for failed + int32_t code = UserAuthNapiClientImpl::Instance().CancelAuthentication(contextId_, CancelReason::MODAL_RUN_ERROR); + IAM_LOGI("CancelAuthentication, code: %{public}d", code); + } + } // namespace UserAuth + } // namespace UserIam + } // namespace OHOS + \ No newline at end of file diff --git a/frameworks/ets/ani/user_auth/src/ohos.userIAM.userAuth.userAuth.impl.cpp b/frameworks/ets/ani/user_auth/src/ohos.userIAM.userAuth.userAuth.impl.cpp new file mode 100644 index 000000000..74f6c4cd7 --- /dev/null +++ b/frameworks/ets/ani/user_auth/src/ohos.userIAM.userAuth.userAuth.impl.cpp @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #include "ohos.userIAM.userAuth.userAuth.proj.hpp" + #include "ohos.userIAM.userAuth.userAuth.impl.hpp" + #include "taihe/runtime.hpp" + #include "stdexcept" + + #include "iam_ptr.h" + #include "iam_logger.h" + #include "auth_common.h" + #include "user_auth_ani_helper.h" + #include "user_auth_client_impl.h" + #include "user_auth_common_defines.h" + #include "user_auth_instance_v10.h" + #include "user_auth_widget_mgr_v10.h" + + #define LOG_TAG "USER_AUTH_ANI" + + namespace UserAuth = OHOS::UserIam::UserAuth; + using namespace taihe; + using namespace ohos::userIAM::userAuth::userAuth; + using namespace OHOS::UserIam::Common; + + namespace { + + class UserAuthInstanceImpl { + public: + UserAuthInstanceImpl() + { + userAuthInstanceV10_ = MakeShared(); + } + + void init(AuthParam const &authParam, WidgetParam const &widgetParam) + { + UserAuth::UserAuthResultCode initResult = userAuthInstanceV10_->Init(authParam, widgetParam); + if (initResult != UserAuth::UserAuthResultCode::SUCCESS) { + IAM_LOGE("userAuthInstanceV10_ init fail"); + UserAuth::UserAuthAniHelper::ThrowBusinessError(initResult, ""); + } + } + + void on(string_view type, IAuthCallback const &callback) + { + userAuthInstanceV10_->On(type.c_str(), callback); + } + + void off(string_view type, optional_view callback) + { + userAuthInstanceV10_->Off(type.c_str(), callback); + } + + void start() + { + userAuthInstanceV10_->Start(); + } + + void cancel() + { + userAuthInstanceV10_->Cancel(); + } + + private: + std::shared_ptr userAuthInstanceV10_ = nullptr; + }; + + class UserAuthWidgetMgrImpl { + public: + UserAuthWidgetMgrImpl() + { + userAuthWidgetMgr_ = MakeShared(); + } + + void init(int32_t version) + { + UserAuth::UserAuthResultCode initResult = userAuthWidgetMgr_->Init(version); + if (initResult != UserAuth::UserAuthResultCode::SUCCESS) { + IAM_LOGE("userAuthWidgetMgr_ init fail"); + UserAuth::UserAuthAniHelper::ThrowBusinessError(initResult, ""); + } + } + + void on(string_view type, IAuthWidgetCallback const &callback) + { + userAuthWidgetMgr_->On(type.c_str(), callback); + } + + void off(string_view type, optional_view callback) + { + userAuthWidgetMgr_->Off(type.c_str(), callback); + } + + private: + std::shared_ptr userAuthWidgetMgr_ = nullptr; + }; + + void GetAvailableStatus(UserAuthType authType, AuthTrustLevel authTrustLevel) + { + IAM_LOGI("GetAvailableStatus begin"); + if (authType.get_value() != UserAuth::AuthType::PIN && authType.get_value() != UserAuth::AuthType::FACE && + authType.get_value() != UserAuth::AuthType::FINGERPRINT) { + IAM_LOGE("authType check fail:%{public}d", authType.get_value()); + UserAuth::UserAuthAniHelper::ThrowBusinessError(UserAuth::UserAuthResultCode::TYPE_NOT_SUPPORT, ""); + } + if (authTrustLevel.get_value() != UserAuth::AuthTrustLevel::ATL1 && + authTrustLevel.get_value() != UserAuth::AuthTrustLevel::ATL2 && + authTrustLevel.get_value() != UserAuth::AuthTrustLevel::ATL3 && + authTrustLevel.get_value() != UserAuth::AuthTrustLevel::ATL4) { + IAM_LOGE("authTrustLevel check fail:%{public}d", authTrustLevel.get_value()); + UserAuth::UserAuthAniHelper::ThrowBusinessError(UserAuth::UserAuthResultCode::TRUST_LEVEL_NOT_SUPPORT, ""); + } + int32_t status = UserAuth::UserAuthClientImpl::Instance().GetNorthAvailableStatus(UserAuth::API_VERSION_9, + UserAuth::AuthType(authType.get_value()), + UserAuth::AuthTrustLevel(authTrustLevel.get_value())); + IAM_LOGI("result = %{public}d", status); + if (status == static_cast(UserAuth::UserAuthResultCode::PIN_EXPIRED)) { + UserAuth::UserAuthAniHelper::ThrowBusinessError(UserAuth::UserAuthResultCode::PIN_EXPIRED, ""); + } + } + + EnrolledState GetEnrolledState(UserAuthType authType) + { + IAM_LOGI("GetEnrolledState begin"); + if (!UserAuth::UserAuthAniHelper::CheckUserAuthType(authType)) { + IAM_LOGE("authType check fail:%{public}d", authType.get_value()); + UserAuth::UserAuthAniHelper::ThrowBusinessError(UserAuth::UserAuthResultCode::TYPE_NOT_SUPPORT, ""); + } + UserAuth::EnrolledState enrolledState = {}; + int32_t code = UserAuth::UserAuthClientImpl::Instance().GetEnrolledState( + UserAuth::API_VERSION_12, UserAuth::AuthType(authType.get_value()), enrolledState); + if (code != static_cast(UserAuth::AuthenticationResult::SUCCESS)) { + IAM_LOGE("failed to get enrolled state %{public}d", code); + UserAuth::UserAuthAniHelper::ThrowBusinessError( + UserAuth::UserAuthResultCode(UserAuth::UserAuthAniHelper::GetResultCodeV10(code)), ""); + } + EnrolledState result{enrolledState.credentialDigest, enrolledState.credentialCount}; + return result; + } + + UserAuthInstance GetUserAuthInstance(AuthParam const &authParam, WidgetParam const &widgetParam) + { + IAM_LOGI("GetUserAuthInstance begin"); + auto userAuthInstance = make_holder(); + userAuthInstance->init(authParam, widgetParam); + return userAuthInstance; + } + + void SendNotice(NoticeType noticeType, string_view eventData) + { + IAM_LOGI("SendNotice begin"); + UserAuth::NoticeType type = UserAuth::NoticeType(noticeType.get_value()); + IAM_LOGI("recv SendNotice noticeType:%{public}d eventData:%{public}s", type, eventData.c_str()); + if (!UserAuth::UserAuthAniHelper::VerifyNoticeParam(eventData.c_str())) { + IAM_LOGE("Invalid notice parameter"); + std::string msgStr = "Parameter error. The value of \"eventData\" for WIDGET_NOTICE must be json string."; + UserAuth::UserAuthAniHelper::ThrowBusinessError(UserAuth::UserAuthResultCode::OHOS_INVALID_PARAM, msgStr); + } + + int32_t result = UserAuth::UserAuthClientImpl::Instance().Notice(type, eventData.c_str()); + UserAuth::UserAuthResultCode errCode = UserAuth::UserAuthResultCode::SUCCESS; + if (result != static_cast(UserAuth::ResultCode::SUCCESS)) { + errCode = UserAuth::UserAuthResultCode(UserAuth::UserAuthAniHelper::GetResultCodeV10(result)); + IAM_LOGE("SendNotice fail. result: %{public}d, errCode: %{public}d", result, errCode); + UserAuth::UserAuthAniHelper::ThrowBusinessError(errCode, ""); + } + IAM_LOGI("end SendNotice"); + } + + UserAuthWidgetMgr GetUserAuthWidgetMgr(double version) + { + IAM_LOGI("GetUserAuthWidgetMgr begin"); + auto userAuthWidgetMgr = make_holder(); + userAuthWidgetMgr->init(version); + return userAuthWidgetMgr; + } + } // namespace + + TH_EXPORT_CPP_API_GetAvailableStatus(GetAvailableStatus); + TH_EXPORT_CPP_API_GetEnrolledState(GetEnrolledState); + TH_EXPORT_CPP_API_GetUserAuthInstance(GetUserAuthInstance); + TH_EXPORT_CPP_API_SendNotice(SendNotice); + TH_EXPORT_CPP_API_GetUserAuthWidgetMgr(GetUserAuthWidgetMgr); + \ No newline at end of file diff --git a/frameworks/ets/ani/user_auth/src/user_auth_ani_helper.cpp b/frameworks/ets/ani/user_auth/src/user_auth_ani_helper.cpp new file mode 100644 index 000000000..24ef115aa --- /dev/null +++ b/frameworks/ets/ani/user_auth/src/user_auth_ani_helper.cpp @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #include "user_auth_ani_helper.h" + + #include + #include + #include + #include "nlohmann/json.hpp" + + #include "taihe/runtime.hpp" + #include "iam_logger.h" + + #define LOG_TAG "USER_AUTH_ANI" + + namespace OHOS { + namespace UserIam { + namespace UserAuth { + + namespace { + static const std::map g_resultV92Str = { + {UserAuthResultCode::OHOS_INVALID_PARAM, "Invalid authentication parameters."}, + {UserAuthResultCode::OHOS_CHECK_PERMISSION_FAILED, "Permission denied."}, + {UserAuthResultCode::OHOS_CHECK_SYSTEM_APP_FAILED, "The caller is not a system application."}, + {UserAuthResultCode::SUCCESS, "Authentication succeeded."}, + {UserAuthResultCode::FAIL, "Authentication failed."}, + {UserAuthResultCode::GENERAL_ERROR, "Unknown errors."}, + {UserAuthResultCode::CANCELED, "Authentication canceled."}, + {UserAuthResultCode::TIMEOUT, "Authentication timeout."}, + {UserAuthResultCode::TYPE_NOT_SUPPORT, "Unsupport authentication type."}, + {UserAuthResultCode::TRUST_LEVEL_NOT_SUPPORT, "Unsupport authentication trust level."}, + {UserAuthResultCode::BUSY, "Authentication service is busy."}, + {UserAuthResultCode::LOCKED, "Authentication is lockout."}, + {UserAuthResultCode::NOT_ENROLLED, "Authentication template has not been enrolled."}, + {UserAuthResultCode::CANCELED_FROM_WIDGET, "Authentication is canceled from widget."}, + {UserAuthResultCode::PIN_EXPIRED, "Operation failed because of PIN expired."}}; + + struct DeleteRefHolder { + ani_env *env{nullptr}; + ani_ref ref{nullptr}; + }; + + const std::string NOTICE_EVENT_TYPE = "event"; + const std::string NOTICE_PAYLOAD = "payload"; + const std::string NOTICE_PAYLOAD_TYPE = "type"; + } // namespace + + bool UserAuthAniHelper::CheckUserAuthType(userAuth::UserAuthType authType) +{ + if (authType.get_value() != AuthType::PIN && authType.get_value() != AuthType::FACE && + authType.get_value() != AuthType::FINGERPRINT && authType.get_value() != AuthType::PRIVATE_PIN) { + IAM_LOGE("authType check fail:%{public}d", authType.get_value()); + return false; + } + return true; +} + + bool UserAuthAniHelper::ConvertUserAuthType(int32_t userAuthType, userAuth::UserAuthType &userAuthTypeOut) + { + switch (userAuthType) { + case AuthType::PIN: + userAuthTypeOut = userAuth::UserAuthType::key_t::PIN; + return true; + case AuthType::FACE: + userAuthTypeOut = userAuth::UserAuthType::key_t::FACE; + return true; + case AuthType::FINGERPRINT: + userAuthTypeOut = userAuth::UserAuthType::key_t::FINGERPRINT; + return true; + case AuthType::PRIVATE_PIN: + userAuthTypeOut = userAuth::UserAuthType::key_t::PRIVATE_PIN; + return true; + default: + IAM_LOGE("invalid userAuthType:%{public}d", userAuthType); + return false; + } + } + + UserAuthResultCode UserAuthAniHelper::ThrowBusinessError(UserAuthResultCode error, std::string message) + { + std::string msgStr; + auto res = g_resultV92Str.find(error); + if (res == g_resultV92Str.end()) { + IAM_LOGE("result %{public}d not found", static_cast(error)); + error = UserAuthResultCode::GENERAL_ERROR; + } + msgStr = g_resultV92Str.at(error); + IAM_LOGI("ThrowBusinessError, errorCode: %{public}d, errmsg: %{public}s", error, msgStr.c_str()); + taihe::set_business_error(static_cast(error), msgStr); + return error; + } + + bool UserAuthAniHelper::CheckReuseUnlockResult(ReuseUnlockResult reuseUnlockResult) + { + if (reuseUnlockResult.reuseMode != ReuseMode::AUTH_TYPE_RELEVANT && + reuseUnlockResult.reuseMode != ReuseMode::AUTH_TYPE_IRRELEVANT) { + IAM_LOGE("reuseMode check fail:%{public}u", reuseUnlockResult.reuseMode); + return false; + } + if (reuseUnlockResult.reuseDuration <= 0 || reuseUnlockResult.reuseDuration > MAX_ALLOWABLE_REUSE_DURATION) { + IAM_LOGE("reuseDuration check fail:%{public}" PRIu64, reuseUnlockResult.reuseDuration); + return false; + } + return true; + } + + int32_t UserAuthAniHelper::GetResultCodeV10(int32_t result) + { + if (result == CHECK_PERMISSION_FAILED) { + return static_cast(UserAuthResultCode::OHOS_CHECK_PERMISSION_FAILED); + } + if (result == INVALID_PARAMETERS) { + return static_cast(UserAuthResultCode::OHOS_INVALID_PARAM); + } + if (result == CHECK_SYSTEM_APP_FAILED) { + return static_cast(UserAuthResultCode::OHOS_CHECK_SYSTEM_APP_FAILED); + } + if (result == HARDWARE_NOT_SUPPORTED) { + return static_cast(UserAuthResultCode::GENERAL_ERROR); + } + if (result > (INT32_MAX - static_cast(UserAuthResultCode::RESULT_CODE_V10_MIN))) { + return static_cast(UserAuthResultCode::GENERAL_ERROR); + } + int32_t resultCodeV10 = result + static_cast(UserAuthResultCode::RESULT_CODE_V10_MIN); + if (resultCodeV10 >= static_cast(UserAuthResultCode::RESULT_CODE_V10_MIN) && + resultCodeV10 <= static_cast(UserAuthResultCode::RESULT_CODE_V10_MAX)) { + IAM_LOGI("version GetResultCodeV10 resultCodeV10 result: %{public}d", resultCodeV10); + return resultCodeV10; + } + IAM_LOGE("version GetResultCodeV10 resultCodeV10 error"); + return static_cast(UserAuthResultCode::GENERAL_ERROR); + } + + bool UserAuthAniHelper::VerifyNoticeParam(const std::string &eventData) + { + auto json = nlohmann::json::parse(eventData.c_str(), nullptr, false); + if (json.is_null() || json.is_discarded()) { + IAM_LOGE("Notice data is invalid json object"); + return false; + } + + if (json.find(NOTICE_EVENT_TYPE) == json.end() || !json[NOTICE_EVENT_TYPE].is_string()) { + IAM_LOGE("Invalid event type exist in notice data"); + return false; + } + + if (json.find(NOTICE_PAYLOAD) == json.end() || + json[NOTICE_PAYLOAD].find(NOTICE_PAYLOAD_TYPE) == json[NOTICE_PAYLOAD].end() || + !json[NOTICE_PAYLOAD][NOTICE_PAYLOAD_TYPE].is_array()) { + IAM_LOGE("Invalid payload exist in notice data"); + return false; + } + IAM_LOGI("valid notice parameter"); + return true; + } + } // namespace UserAuth + } // namespace UserIam + } // namespace OHOS + \ No newline at end of file diff --git a/frameworks/ets/ani/user_auth/src/user_auth_callback_v10.cpp b/frameworks/ets/ani/user_auth/src/user_auth_callback_v10.cpp new file mode 100644 index 000000000..bf8934e18 --- /dev/null +++ b/frameworks/ets/ani/user_auth/src/user_auth_callback_v10.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #include "user_auth_callback_v10.h" + + #include "iam_logger.h" + #include "iam_ptr.h" + #include "user_auth_client_impl.h" + #include "user_auth_ani_helper.h" + + #define LOG_TAG "USER_AUTH_ANI" + + namespace OHOS { + namespace UserIam { + namespace UserAuth { + + UserAuthCallbackV10::UserAuthCallbackV10() + {} + + UserAuthCallbackV10::~UserAuthCallbackV10() + {} + + void UserAuthCallbackV10::SetResultCallback(const userAuth::IAuthCallback &resultCallback) + { + std::lock_guard guard(mutex_); + resultCallback_ = Common::MakeShared(resultCallback); + } + + void UserAuthCallbackV10::ClearResultCallback() + { + std::lock_guard guard(mutex_); + resultCallback_ = nullptr; + } + + bool UserAuthCallbackV10::HasResultCallback() + { + std::lock_guard guard(mutex_); + return resultCallback_ != nullptr; + } + + bool UserAuthCallbackV10::DoResultCallback( + int32_t result, const std::vector &token, int32_t authType, EnrolledState enrolledState) + { + IAM_LOGI("start"); + userAuth::UserAuthResult userAuthResult = {0}; + userAuthResult.result = UserAuthAniHelper::GetResultCodeV10(result); + if (!token.empty()) { + userAuthResult.token = taihe::optional>(std::in_place_t{}, taihe::copy_data_t{}, token.data(), token.size()); + } + if (authType == AuthType::PIN || authType == AuthType::FACE || authType == AuthType::FINGERPRINT || + authType == AuthType::PRIVATE_PIN) { + userAuth::UserAuthType authTypeAni(userAuth::UserAuthType::key_t::PIN); + if (!UserAuthAniHelper::ConvertUserAuthType(authType, authTypeAni)) { + IAM_LOGE("Set authType error. authType: %{public}d", authType); + return false; + } + userAuthResult.authType = taihe::optional::make(authTypeAni); + } + if (UserAuthResultCode(result) == UserAuthResultCode::SUCCESS) { + userAuth::EnrolledState enrolledStateAni = {enrolledState.credentialDigest, enrolledState.credentialCount}; + userAuthResult.enrolledState = taihe::optional::make(enrolledStateAni); + } + resultCallback_->onResult(userAuthResult); + return true; + } + + void UserAuthCallbackV10::OnAcquireInfo( + int32_t module, uint32_t acquireInfo, const UserIam::UserAuth::Attributes &extraInfo) + {} + + void UserAuthCallbackV10::OnResult(int32_t result, const Attributes &extraInfo) + { + IAM_LOGI("start, result:%{public}d", result); + std::vector token = {}; + int32_t authType = {0}; + EnrolledState enrolledState = {}; + if (!extraInfo.GetUint8ArrayValue(Attributes::ATTR_SIGNATURE, token)) { + IAM_LOGE("ATTR_SIGNATURE is null"); + } + if (!extraInfo.GetInt32Value(Attributes::ATTR_AUTH_TYPE, authType)) { + IAM_LOGE("ATTR_AUTH_TYPE is null"); + } + if (!extraInfo.GetUint64Value(Attributes::ATTR_CREDENTIAL_DIGEST, enrolledState.credentialDigest)) { + IAM_LOGE("ATTR_CREDENTIAL_DIGEST is null"); + } + if (!extraInfo.GetUint16Value(Attributes::ATTR_CREDENTIAL_COUNT, enrolledState.credentialCount)) { + IAM_LOGE("ATTR_CREDENTIAL_COUNT is null"); + } + bool ret = DoResultCallback(result, token, authType, enrolledState); + IAM_LOGD("DoResultCallback ret = %{public}d", ret); + } + } // namespace UserAuth + } // namespace UserIam + } // namespace OHOS + \ No newline at end of file diff --git a/frameworks/ets/ani/user_auth/src/user_auth_instance_v10.cpp b/frameworks/ets/ani/user_auth/src/user_auth_instance_v10.cpp new file mode 100644 index 000000000..bacf0902e --- /dev/null +++ b/frameworks/ets/ani/user_auth/src/user_auth_instance_v10.cpp @@ -0,0 +1,412 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #include "user_auth_instance_v10.h" + + #include + #include + #include + + #include "taihe/runtime.hpp" + #include "securec.h" + #include "ani_base_context.h" + #include "ui_content.h" + #include "ui_extension_context.h" + #include "ui_holder_extension_context.h" + + #include "iam_logger.h" + #include "user_auth_ani_helper.h" + #include "user_auth_common_defines.h" + #include "user_auth_client_impl.h" + + #define LOG_TAG "USER_AUTH_ANI" + + namespace userAuth = ohos::userIAM::userAuth::userAuth; + + namespace OHOS { + namespace UserIam { + namespace UserAuth { + const std::string AUTH_EVENT_RESULT = "result"; + const std::string AUTH_PARAM_CHALLENGE = "challenge"; + const std::string AUTH_PARAM_AUTHTYPE = "authType"; + const std::string AUTH_PARAM_AUTHTRUSTLEVEL = "authTrustLevel"; + const std::string AUTH_PARAM_REUSEUNLOCKRESULT = "reuseUnlockResult"; + const std::string AUTH_PARAM_USER_ID = "userId"; + const std::string WIDGET_PARAM_TITLE = "title"; + const std::string WIDGET_PARAM_NAVIBTNTEXT = "navigationButtonText"; + const std::string WIDGET_PARAM_WINDOWMODE = "windowMode"; + const std::string WIDGET_PARAM_CONTEXT = "uiContext"; + const std::string NOTICETYPE = "noticeType"; + const std::string REUSEMODE = "reuseMode"; + const std::string REUSEDURATION = "reuseDuration"; + + namespace WidgetType { + constexpr int32_t TITLE_MAX = 500; + constexpr int32_t BUTTON_MAX = 60; + } // namespace WidgetType + + UserAuthInstanceV10::UserAuthInstanceV10() : callback_(Common::MakeShared()) + { + if (callback_ == nullptr) { + IAM_LOGE("get null callback"); + } + authParam_.authTrustLevel = AuthTrustLevel::ATL1; + authParam_.userId = INVALID_USER_ID; + widgetParam_.navigationButtonText = ""; + widgetParam_.title = ""; + widgetParam_.windowMode = WindowModeType::UNKNOWN_WINDOW_MODE; + } + + UserAuthResultCode UserAuthInstanceV10::Init( + userAuth::AuthParam const &authParam, userAuth::WidgetParam const &widgetParam) + { + IAM_LOGI("Init start"); + UserAuthResultCode errCode = InitAuthParam(authParam); + if (errCode != UserAuthResultCode::SUCCESS) { + IAM_LOGE("AuthParamInner type error, errorCode: %{public}d", errCode); + return errCode; + } + + errCode = InitWidgetParam(widgetParam); + if (errCode != UserAuthResultCode::SUCCESS) { + IAM_LOGE("WidgetParam type error, errorCode: %{public}d", errCode); + return errCode; + } + IAM_LOGI("Init SUCCESS"); + return UserAuthResultCode::SUCCESS; + } + + UserAuthResultCode UserAuthInstanceV10::InitAuthParam(userAuth::AuthParam const &authParam) + { + IAM_LOGI("InitAuthParam start"); + std::vector challenge(authParam.challenge.begin(), authParam.challenge.end()); + authParam_.challenge = challenge; + + UserAuthResultCode errorCode = InitAuthType(authParam); + if (errorCode != UserAuthResultCode::SUCCESS) { + IAM_LOGE("InitAuthType fail:%{public}d", errorCode); + return errorCode; + } + + errorCode = InitAuthTrustLevel(authParam); + if (errorCode != UserAuthResultCode::SUCCESS) { + IAM_LOGE("InitAuthTrustLevel fail:%{public}d", errorCode); + return errorCode; + } + + errorCode = InitReuseUnlockResult(authParam); + if (errorCode != UserAuthResultCode::SUCCESS) { + IAM_LOGE("InitAuthTrustLevel fail:%{public}d", errorCode); + return errorCode; + } + + errorCode = InitUserId(authParam); + if (errorCode != UserAuthResultCode::SUCCESS) { + IAM_LOGE("InitUserId fail:%{public}d", errorCode); + return errorCode; + } + return UserAuthResultCode::SUCCESS; + } + + UserAuthResultCode UserAuthInstanceV10::InitAuthType(userAuth::AuthParam const &authParam) + { + IAM_LOGI("InitAuthType start."); + int32_t length = authParam.authType.size(); + for (int32_t index = 0; index < length; index++) { + userAuth::UserAuthType type = authParam.authType[index]; + if (!UserAuthAniHelper::CheckUserAuthType(type)) { + IAM_LOGE("authType is illegal, %{public}d", type.get_value()); + return UserAuthResultCode::TYPE_NOT_SUPPORT; + } + authParam_.authTypes.push_back(static_cast(static_cast(type.get_value()))); + } + IAM_LOGI("authType size:%{public}zu", authParam_.authTypes.size()); + return UserAuthResultCode::SUCCESS; + } + + UserAuthResultCode UserAuthInstanceV10::InitAuthTrustLevel(userAuth::AuthParam const &authParam) + { + IAM_LOGI("InitAuthTrustLevel start."); + auto authTrustLevel = authParam.authTrustLevel; + if (authTrustLevel.get_value() != AuthTrustLevel::ATL1 && authTrustLevel.get_value() != AuthTrustLevel::ATL2 && + authTrustLevel.get_value() != AuthTrustLevel::ATL3 && authTrustLevel.get_value() != AuthTrustLevel::ATL4) { + IAM_LOGE("AuthTrustLevel fail:%{public}u", authTrustLevel.get_value()); + return UserAuthResultCode::TRUST_LEVEL_NOT_SUPPORT; + } + authParam_.authTrustLevel = AuthTrustLevel(static_cast(authTrustLevel)); + IAM_LOGI("authTrustLevel:%{public}u", authParam_.authTrustLevel); + return UserAuthResultCode::SUCCESS; + } + + UserAuthResultCode UserAuthInstanceV10::InitReuseUnlockResult(userAuth::AuthParam const &authParam) + { + IAM_LOGI("InitReuseUnlockResult start."); + if (authParam.reuseUnlockResult.has_value()) { + authParam_.reuseUnlockResult.isReuse = true; + authParam_.reuseUnlockResult.reuseMode = + ReuseMode(static_cast(authParam.reuseUnlockResult->reuseMode.get_value())); + if (!UserAuthAniHelper::CheckReuseUnlockResult(authParam_.reuseUnlockResult)) { + IAM_LOGE("ReuseUnlockResult fail"); + std::string msgStr = "Parameter error. The type of \"reuseUnlockResult\" must be ReuseUnlockResult."; + } + authParam_.reuseUnlockResult.reuseDuration = authParam.reuseUnlockResult->reuseDuration; + IAM_LOGI("reuseMode: %{public}u, reuseDuration: %{public}" PRIu64, + authParam_.reuseUnlockResult.reuseMode, + authParam_.reuseUnlockResult.reuseDuration); + } else { + IAM_LOGI("propertyName: %{public}s not exists.", AUTH_PARAM_REUSEUNLOCKRESULT.c_str()); + authParam_.reuseUnlockResult.isReuse = false; + } + return UserAuthResultCode::SUCCESS; + } + + UserAuthResultCode UserAuthInstanceV10::InitUserId(userAuth::AuthParam const &authParam) + { + IAM_LOGI("InitUserId start."); + if (authParam.userId.has_value()) { + authParam_.userId = authParam.userId.value(); + if (authParam_.userId < 0) { + IAM_LOGE("userId error."); + std::string msgStr = "Parameter error. The \"userId\" must be greater than or equal to 0"; + return UserAuthAniHelper::ThrowBusinessError(UserAuthResultCode::OHOS_INVALID_PARAM, msgStr); + } + IAM_LOGI("InitUserId userId: %{public}d", authParam_.userId); + } else { + IAM_LOGI("propertyName: %{public}s not exists.", AUTH_PARAM_USER_ID.c_str()); + } + return UserAuthResultCode::SUCCESS; + } + + UserAuthResultCode UserAuthInstanceV10::InitWidgetParam(userAuth::WidgetParam const &widgetParam) + { + IAM_LOGI("InitWidgetParam start."); + UserAuthResultCode errorCode = InitTitle(widgetParam); + if (errorCode != UserAuthResultCode::SUCCESS) { + IAM_LOGE("InitTitle fail:%{public}d", errorCode); + return UserAuthResultCode::OHOS_INVALID_PARAM; + } + + errorCode = InitNavigationButtonText(widgetParam); + if (errorCode != UserAuthResultCode::SUCCESS) { + IAM_LOGE("InitNavigationButtonText fail:%{public}d", errorCode); + return UserAuthResultCode::OHOS_INVALID_PARAM; + } + + errorCode = InitWindowMode(widgetParam); + if (errorCode != UserAuthResultCode::SUCCESS) { + IAM_LOGE("InitWindowMode fail:%{public}d", errorCode); + return UserAuthResultCode::OHOS_INVALID_PARAM; + } + + errorCode = InitContext(widgetParam); + if (errorCode != UserAuthResultCode::SUCCESS) { + IAM_LOGE("InitContext fail:%{public}d", errorCode); + return UserAuthResultCode::OHOS_INVALID_PARAM; + } + return UserAuthResultCode::SUCCESS; + } + + UserAuthResultCode UserAuthInstanceV10::InitTitle(userAuth::WidgetParam const &widgetParam) + { + IAM_LOGI("InitTitle start."); + std::string title = widgetParam.title.c_str(); + if (title == "" || title.size() > WidgetType::TITLE_MAX) { + IAM_LOGE("title is invalid. size: %{public}zu", title.size()); + std::string msgStr = "Parameter error. The length of \"title\" connot exceed 500."; + return UserAuthAniHelper::ThrowBusinessError(UserAuthResultCode::OHOS_INVALID_PARAM, msgStr); + } + widgetParam_.title = title; + return UserAuthResultCode::SUCCESS; + } + + UserAuthResultCode UserAuthInstanceV10::InitNavigationButtonText(userAuth::WidgetParam const &widgetParam) + { + IAM_LOGI("InitNavigationButtonText start."); + if (widgetParam.navigationButtonText.has_value()) { + std::string naviBtnTxt = widgetParam.navigationButtonText->c_str(); + if (naviBtnTxt == "" || naviBtnTxt.size() > WidgetType::BUTTON_MAX) { + IAM_LOGE("navigation button text is invalid, size: %{public}zu", naviBtnTxt.size()); + std::string msgStr = "Parameter error. The length of \"navigationButtonText\" connot exceed 60."; + return UserAuthAniHelper::ThrowBusinessError(UserAuthResultCode::OHOS_INVALID_PARAM, msgStr); + } + widgetParam_.navigationButtonText = naviBtnTxt; + } + return UserAuthResultCode::SUCCESS; + } + + UserAuthResultCode UserAuthInstanceV10::InitWindowMode(userAuth::WidgetParam const &widgetParam) + { + IAM_LOGI("InitWindowMode start."); + if (widgetParam.windowMode.has_value()) { + switch (widgetParam.windowMode->get_key()) { + case userAuth::WindowModeType::key_t::DIALOG_BOX: + widgetParam_.windowMode = WindowModeType::DIALOG_BOX; + break; + case userAuth::WindowModeType::key_t::FULLSCREEN: + widgetParam_.windowMode = WindowModeType::FULLSCREEN; + break; + default: + IAM_LOGE("windowMode type not support."); + std::string msgStr = "Parameter error. The type of \"windowMode\" must be WindowModeType."; + return UserAuthAniHelper::ThrowBusinessError(UserAuthResultCode::OHOS_INVALID_PARAM, msgStr); + } + IAM_LOGI("widgetParam title:%{public}s, navBtnText:%{public}s, winMode:%{public}u", + widgetParam_.title.c_str(), + widgetParam_.navigationButtonText.c_str(), + static_cast(widgetParam_.windowMode)); + } + return UserAuthResultCode::SUCCESS; + } + + UserAuthResultCode UserAuthInstanceV10::InitContext(userAuth::WidgetParam const &widgetParam) + { + IAM_LOGI("InitContext start."); + if (widgetParam.uiContext.has_value()) { + IAM_LOGI("widgetParam has uiContext"); + ani_env *env = taihe::get_env(); + ani_object uiContext = widgetParam.uiContext; + ani_boolean stageMode = false; + ani_status status = OHOS::AbilityRuntime::IsStageContext(env, uiContext, stageMode); + if (status != ANI_OK || !stageMode) { + IAM_LOGE("uiContext must be stage mode: %{public}d", status); + std::string msgStr = "Parameter error. The type of \"uiContext\" must be stage mode."; + return UserAuthAniHelper::ThrowBusinessError(UserAuthResultCode::OHOS_INVALID_PARAM, msgStr); + } + auto context = OHOS::AbilityRuntime::GetStageModeContext(env, uiContext); + if (CheckUIContext(context)) { + context_ = context; + widgetParam_.hasContext = true; + IAM_LOGI("widgetParam has valid uiContext"); + } else { + // Default as modal system + IAM_LOGI("widgetParam has invalid uiContext, not base on valid AbilityContext or UIExtensionContext."); + } + } + return UserAuthResultCode::SUCCESS; + } + + bool UserAuthInstanceV10::CheckUIContext(const std::shared_ptr context) + { + if (context == nullptr) { + IAM_LOGE("get context failed"); + return false; + } + + auto abilityContext = AbilityRuntime::Context::ConvertTo(context); + if (abilityContext == nullptr) { + IAM_LOGE("abilityContext is null"); + auto holderContext = AbilityRuntime::Context::ConvertTo(context); + if (holderContext == nullptr) { + IAM_LOGE("uiExtensionContext is null"); + return false; + } + if (holderContext->GetUIContent() == nullptr) { + IAM_LOGE("uiContent is null"); + return false; + } + } else { + if (abilityContext->GetUIContent() == nullptr) { + IAM_LOGE("uiContent is null"); + return false; + } + } + return true; + } + + UserAuthResultCode UserAuthInstanceV10::On(std::string type, userAuth::IAuthCallback const &callback) + { + IAM_LOGI("UserAuthInstanceV10 on."); + static const size_t maxLen = 10; + if (type.size() <= 0 || type.size() > maxLen) { + IAM_LOGE("getAuthInstance on GetStrValue fail."); + std::string msgStr = "Parameter error. The type of \"type\" must be string."; + return UserAuthAniHelper::ThrowBusinessError(UserAuthResultCode::OHOS_INVALID_PARAM, msgStr); + } + if (type == AUTH_EVENT_RESULT) { + IAM_LOGI("getAuthInstance on SetResultCallback"); + callback_->SetResultCallback(callback); + return UserAuthResultCode::SUCCESS; + } else { + IAM_LOGE("getAuthInstance on invalid event:%{public}s", type.c_str()); + std::string msgStr = "Parameter error. The value of \"type\" must be \"result\"."; + return UserAuthAniHelper::ThrowBusinessError(UserAuthResultCode::OHOS_INVALID_PARAM, msgStr); + } + } + + UserAuthResultCode UserAuthInstanceV10::Off(std::string type, taihe::optional_view callback) + { + IAM_LOGI("UserAuthInstanceV10 off."); + if (callback_ == nullptr) { + IAM_LOGE("userAuthInstance off callback is null"); + return UserAuthResultCode::GENERAL_ERROR; + } + + if (type == AUTH_EVENT_RESULT) { + if (!callback_->HasResultCallback()) { + IAM_LOGE("no callback registerred yet"); + return UserAuthResultCode::GENERAL_ERROR; + } + callback_->ClearResultCallback(); + IAM_LOGI("UserAuthResultCode off clear result callback"); + return UserAuthResultCode::SUCCESS; + } else { + IAM_LOGE("invalid event:%{public}s", type.c_str()); + std::string msgStr = "Parameter error. The value of \"type\" must be \"result\"."; + return UserAuthAniHelper::ThrowBusinessError(UserAuthResultCode::OHOS_INVALID_PARAM, msgStr); + } + return UserAuthResultCode::SUCCESS; + } + + UserAuthResultCode UserAuthInstanceV10::Start() + { + IAM_LOGI("UserAuthInstanceV10 start."); + if (callback_ == nullptr) { + IAM_LOGE("callback is null"); + return UserAuthResultCode::GENERAL_ERROR; + } + + std::lock_guard guard(mutex_); + if (isAuthStarted_) { + IAM_LOGE("auth already started"); + return UserAuthResultCode::GENERAL_ERROR; + } + + modalCallback_ = Common::MakeShared(context_); + contextId_ = UserAuthNapiClientImpl::Instance().BeginWidgetAuth( + API_VERSION_10, authParam_, widgetParam_, callback_, modalCallback_); + isAuthStarted_ = true; + return UserAuthResultCode::SUCCESS; + } + + UserAuthResultCode UserAuthInstanceV10::Cancel() + { + IAM_LOGI("UserAuthInstanceV10 cancel."); + std::lock_guard guard(mutex_); + if (!isAuthStarted_) { + IAM_LOGE("auth not started"); + return UserAuthResultCode::GENERAL_ERROR; + } + int32_t result = UserAuthClient::GetInstance().CancelAuthentication(contextId_); + if (result != ResultCode::SUCCESS) { + IAM_LOGE("CancelAuthentication fail:%{public}d", result); + return UserAuthResultCode(UserAuthAniHelper::GetResultCodeV10(result)); + } + isAuthStarted_ = false; + return UserAuthResultCode::SUCCESS; + } + } // namespace UserAuth + } // namespace UserIam + } // namespace OHOS + \ No newline at end of file diff --git a/frameworks/ets/ani/user_auth/src/user_auth_modal_callback.cpp b/frameworks/ets/ani/user_auth/src/user_auth_modal_callback.cpp new file mode 100644 index 000000000..5024fb0d5 --- /dev/null +++ b/frameworks/ets/ani/user_auth/src/user_auth_modal_callback.cpp @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #include "user_auth_modal_callback.h" + + #include "ability.h" + #include "system_ability_definition.h" + #include "ui_holder_extension_context.h" + + #include "iam_logger.h" + #include "iam_ptr.h" + #include "user_auth_napi_client_impl.h" + + #define LOG_TAG "USER_AUTH_SDK" + + namespace OHOS { + namespace UserIam { + namespace UserAuth { + UserAuthModalCallback::UserAuthModalCallback(const std::shared_ptr context) : context_(context) + {} + + UserAuthModalCallback::~UserAuthModalCallback() + {} + + void UserAuthModalCallback::SendCommand(uint64_t contextId, const std::string &cmdData) + { + IAM_LOGI("SendCommand start"); + std::lock_guard lock(mutex_); + if (context_ != nullptr) { + if (contextId == contextId_ && cmdData.empty()) { + IAM_LOGI("stop modal"); + ReleaseModal(); + return; + } + IAM_LOGI("widgetParam context not null, process as modal application"); + if (contextId == 0 || cmdData.empty()) { + IAM_LOGI("stop modal for invalid request"); + isInitError_ = true; + CancelAuthentication(contextId, CancelReason::MODAL_CREATE_ERROR); + return; + } + contextId_ = contextId; + bool createModalRet = CreateUIExtension(context_, contextId, cmdData); + // Cancel for failed + if (!createModalRet) { + IAM_LOGE("create modal error, createModalRet: %{public}d", createModalRet); + isInitError_ = true; + CancelAuthentication(contextId, CancelReason::MODAL_CREATE_ERROR); + return; + } + IAM_LOGI("create modal success"); + isInit_ = true; + return; + } + IAM_LOGI("widgetParam.context is nullptr"); + } + + bool UserAuthModalCallback::IsModalInit() + { + IAM_LOGI("get is modal init"); + std::lock_guard lock(mutex_); + return isInit_; + } + + bool UserAuthModalCallback::IsModalDestroy() + { + IAM_LOGI("get is modal on destroy"); + std::lock_guard lock(mutex_); + if (isInitError_ || (uiExtCallback_ != nullptr && uiExtCallback_->IsModalDestroy())) { + IAM_LOGI("modal on destroy"); + return true; + } + return false; + } + + Ace::UIContent *UserAuthModalCallback::InitAndGetUIContent(const std::shared_ptr context) + { + if (context == nullptr) { + IAM_LOGE("context is nullptr"); + return nullptr; + } + Ace::UIContent *uiContent = nullptr; + auto abilityContext = AbilityRuntime::Context::ConvertTo(context); + std::shared_ptr holderContext; + if (abilityContext == nullptr) { + IAM_LOGE("abilityContext is nullptr"); + holderContext = AbilityRuntime::Context::ConvertTo(context); + if (holderContext == nullptr) { + IAM_LOGE("uiExtensionContext is nullptr"); + return nullptr; + } + uiContent = holderContext->GetUIContent(); + if (uiContent == nullptr) { + IAM_LOGE("uiContent is nullptr"); + return nullptr; + } + } else { + uiContent = abilityContext->GetUIContent(); + if (uiContent == nullptr) { + IAM_LOGE("uiContent is nullptr"); + return nullptr; + } + } + + uiExtCallback_ = std::make_shared(); + uiExtCallback_->SetAbilityContext(abilityContext); + uiExtCallback_->SetHolderContext(holderContext); + + return uiContent; + } + + bool UserAuthModalCallback::CreateUIExtension( + const std::shared_ptr context, uint64_t contextId, const std::string &cmdData) + { + Ace::UIContent *uiContent = InitAndGetUIContent(context); + if (uiContent == nullptr) { + IAM_LOGE("uiContent invalid"); + return false; + } + + AAFwk::Want want; + std::string targetBundleName = "com.ohos.useriam.authwidget"; + std::string targetAbilityName = "UserAuthModalUIAbility"; + want.SetElementName(targetBundleName, targetAbilityName); + + std::string typeKey = "ability.want.params.uiExtensionType"; + std::string typeValue = "sys/commonUI"; + want.SetParam(typeKey, typeValue); + std::string commandKey = "parameters"; + want.SetParam(commandKey, cmdData); + + uiExtCallback_->SetContextId(contextId); + Ace::ModalUIExtensionCallbacks uiExtensionCallbacks = { + .onRelease = std::bind(&ModalExtensionCallback::OnRelease, uiExtCallback_, std::placeholders::_1), + .onResult = + std::bind(&ModalExtensionCallback::OnResult, uiExtCallback_, std::placeholders::_1, std::placeholders::_2), + .onReceive = std::bind(&ModalExtensionCallback::OnReceive, uiExtCallback_, std::placeholders::_1), + .onError = std::bind(&ModalExtensionCallback::OnError, + uiExtCallback_, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3), + .onRemoteReady = std::bind(&ModalExtensionCallback::OnRemoteReady, uiExtCallback_, std::placeholders::_1), + .onDestroy = std::bind(&ModalExtensionCallback::OnDestroy, uiExtCallback_), + }; + + Ace::ModalUIExtensionConfig config; + config.isProhibitBack = true; + + int32_t sessionId = uiContent->CreateModalUIExtension(want, uiExtensionCallbacks, config); + IAM_LOGI("Create end, sessionId: %{public}d", sessionId); + if (sessionId == 0) { + IAM_LOGE("Create component failed, sessionId is 0"); + return false; + } + uiExtCallback_->SetSessionId(sessionId); + return true; + } + + void UserAuthModalCallback::CancelAuthentication(uint64_t contextId, int32_t cancelReason) + { + // cancel for failed + int32_t code = UserAuthNapiClientImpl::Instance().CancelAuthentication(contextId, cancelReason); + IAM_LOGI("CancelAuthentication, code: %{public}d, contextId: ****%{public}hx, code: %{public}d", + code, + static_cast(contextId), + cancelReason); + ReleaseModal(); + } + + void UserAuthModalCallback::ReleaseModal() + { + // release modal widget + if (uiExtCallback_ != nullptr) { + IAM_LOGI("release modal"); + isInitError_ = true; + uiExtCallback_->ReleaseOrErrorHandle(0); + } + } + } // namespace UserAuth + } // namespace UserIam + } // namespace OHOS + \ No newline at end of file diff --git a/frameworks/ets/ani/user_auth/src/user_auth_widget_callback_v10.cpp b/frameworks/ets/ani/user_auth/src/user_auth_widget_callback_v10.cpp new file mode 100644 index 000000000..a0fc7cf2c --- /dev/null +++ b/frameworks/ets/ani/user_auth/src/user_auth_widget_callback_v10.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #include "user_auth_widget_callback_v10.h" + + #include "iam_ptr.h" + #include "iam_logger.h" + + #define LOG_TAG "USER_AUTH_ANI" + + namespace OHOS { + namespace UserIam { + namespace UserAuth { + + UserAuthWidgetCallback::UserAuthWidgetCallback() + {} + + UserAuthWidgetCallback::~UserAuthWidgetCallback() + {} + + void UserAuthWidgetCallback::SetCommandCallback(userAuth::IAuthWidgetCallback const &callback) + { + std::lock_guard guard(mutex_); + commandCallback_ = Common::MakeShared(callback); + } + + void UserAuthWidgetCallback::ClearCommandCallback() + { + std::lock_guard guard(mutex_); + commandCallback_ = nullptr; + } + + bool UserAuthWidgetCallback::HasCommandCallback() + { + std::lock_guard guard(mutex_); + return commandCallback_ != nullptr; + } + + void UserAuthWidgetCallback::SendCommand(const std::string &cmdData) + { + IAM_LOGI("start"); + commandCallback_->sendCommand(cmdData); + } + } // namespace UserAuth + } // namespace UserIam + } // namespace OHOS + \ No newline at end of file diff --git a/frameworks/ets/ani/user_auth/src/user_auth_widget_mgr_v10.cpp b/frameworks/ets/ani/user_auth/src/user_auth_widget_mgr_v10.cpp new file mode 100644 index 000000000..5c652d501 --- /dev/null +++ b/frameworks/ets/ani/user_auth/src/user_auth_widget_mgr_v10.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #include "user_auth_widget_mgr_v10.h" + + #include + #include + + #include "iam_logger.h" + #include "iam_ptr.h" + #include "user_auth_client_impl.h" + + #define LOG_TAG "USER_AUTH_ANI" + + namespace OHOS { + namespace UserIam { + namespace UserAuth { + const std::string TYPE_COMMAND = "command"; + + UserAuthWidgetMgr::UserAuthWidgetMgr() : callback_(Common::MakeShared()) + {} + + UserAuthResultCode UserAuthWidgetMgr::Init(int32_t version) + { + IAM_LOGI("UserAuthWidgetMgr init"); + if (callback_ == nullptr) { + IAM_LOGE("callback is null"); + return UserAuthResultCode::GENERAL_ERROR; + } + IAM_LOGI("UserAuthWidgetMgr version: %{public}d", version); + + if (version != WIDGET_NOTICE) { + IAM_LOGE("version error: %{public}d", version); + return UserAuthResultCode::TYPE_NOT_SUPPORT; + } + version_ = version; + int32_t result = UserAuthClientImpl::Instance().SetWidgetCallback(version_, callback_); + IAM_LOGI("version SetWidgetCallback result: %{public}d", result); + return static_cast(UserAuthAniHelper::GetResultCodeV10(result)); + } + + UserAuthResultCode UserAuthWidgetMgr::On(std::string type, userAuth::IAuthWidgetCallback const &callback) + { + IAM_LOGI("UserAuthWidgetMgr on"); + if (callback_ == nullptr) { + IAM_LOGE("callback is null"); + return UserAuthResultCode::GENERAL_ERROR; + } + if (type == TYPE_COMMAND) { + IAM_LOGI("SetCommandCallback"); + if (callback_->HasCommandCallback()) { + IAM_LOGE("command callback has been registerred"); + return UserAuthAniHelper::ThrowBusinessError(UserAuthResultCode::GENERAL_ERROR, ""); + } + callback_->SetCommandCallback(callback); + return UserAuthResultCode::SUCCESS; + } else { + IAM_LOGE("invalid event:%{public}s", type.c_str()); + std::string msgStr = "Parameter error. The value of \"type\" must be \"command\"."; + return UserAuthAniHelper::ThrowBusinessError(UserAuthResultCode::OHOS_INVALID_PARAM, msgStr); + } + } + + UserAuthResultCode UserAuthWidgetMgr::Off( + std::string type, taihe::optional_view callback) + { + IAM_LOGI("UserAuthWidgetMgr off"); + if (callback_ == nullptr) { + IAM_LOGE("callback is null"); + return UserAuthResultCode::GENERAL_ERROR; + } + if (type == TYPE_COMMAND) { + IAM_LOGI("ClearCommandCallback"); + if (callback_->HasCommandCallback()) { + IAM_LOGE("no command callback register yet"); + return UserAuthAniHelper::ThrowBusinessError(UserAuthResultCode::GENERAL_ERROR, ""); + } + callback_->ClearCommandCallback(); + return UserAuthResultCode::SUCCESS; + } else { + IAM_LOGE("invalid event:%{public}s", type.c_str()); + std::string msgStr = "Parameter error. The value of \"type\" must be \"command\"."; + return UserAuthAniHelper::ThrowBusinessError(UserAuthResultCode::OHOS_INVALID_PARAM, msgStr); + } + } + } // namespace UserAuth + } // namespace UserIam + } // namespace OHOS + \ No newline at end of file -- Gitee